diff --git a/.gitignore b/.gitignore index 1b22604..8da9d52 100755 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,20 @@ -Build/CMake -Build/Windows -Build/Linux -Core/DX10ASM/Lib/VS2015/Win32/Release* -Core/DX10ASM/Lib/VS2015/x64 -Core/DX12/DXC/dxcompiler.dll -Core/LC/Disassembler -Core/Vulkan/tools/Win64/lib/Debug -Core/VulkanOffline +build/CMake +build/windows +build/linux +external/dx10_asm/lib/VS2015/Win32/Release* +external/dx10_asm/lib/VS2015/x64 +external/dxc/dxcompiler.dll +external/lc/disassembler +external/vulkan/tools/windows/lib/Debug +external/vulkan_offline Output .vscode Output_Test *.vs -BuildOutput -Documentation/build +buildOutput +documentation/build *.csproj.user obj bin -Build/__pycache__ +build/__pycache__ +external/code_sanitizer diff --git a/Build/Prebuild.bat b/Build/Prebuild.bat index 15c413d..9f8f682 100755 --- a/Build/Prebuild.bat +++ b/Build/Prebuild.bat @@ -1,5 +1,6 @@ @echo off -:: Prebuild.bat --vs 2017 --qt +:: prebuild.bat --vs 2017 --qt + SETLOCAL rem Print help message @@ -15,7 +16,7 @@ goto :start echo: echo This script generates Visual Studio project and solution files for RGA on Windows. echo: -echo Usage: Prebuild.bat ^[options^] +echo Usage: prebuild.bat ^[options^] echo: echo Options: echo --no-fetch Do not call fetch_dependencies.py script before running cmake. The default is "false". @@ -27,12 +28,13 @@ echo --gui-only Build GUI only (do not build RGA command-line tool) echo --no-vulkan Build RGA without live Vulkan mode support. If this option is used, Vulkan SDK is not required. The default is "false". echo --vk-include Path to the Vulkan SDK include folder. echo --vk-lib Path to the Vulkan SDK library folder. +echo --cppcheck Add "-DCMAKE_CXX_CPPCHECK" to cmake command echo: echo Examples: -echo Prebuild.bat -echo Prebuild.bat --vs 2017 --qt C:\Qt\5.7\msvc2015_64 -echo Prebuild.bat --vs 2015 --cli-only -echo Prebuild.bat --no-vulkan +echo prebuild.bat +echo prebuild.bat --vs 2017 --qt C:\Qt\5.7\msvc2015_64 +echo prebuild.bat --vs 2015 --cli-only +echo prebuild.bat --no-vulkan goto :exit :start @@ -45,6 +47,7 @@ set VS_VER=2017 set QT_ROOT= set VK_INCLUDE= set VK_LIB= +set CPPCHECK= :begin if [%1]==[] goto :start_cmake @@ -60,6 +63,7 @@ if "%1"=="--no-fetch" goto :set_no_fetch if "%1"=="--automation" goto :set_automation if "%1"=="--internal" goto :set_internal if "%1"=="--verbose" goto :set_verbose +if "%1"=="--cppcheck" goto :set_cppcheck goto :bad_arg :set_cmake @@ -100,7 +104,7 @@ goto :shift_arg :set_automation set AUTOMATION=-DGUI_AUTOMATION^=ON -set TEST_DIR_SUFFIX=_Test +set TEST_DIR_SUFFIX=_test goto :shift_arg :set_internal @@ -112,6 +116,10 @@ goto :shift_arg @echo on goto :shift_arg +:set_cppcheck +set CPPCHECK=-DCMAKE_CXX_CPPCHECK="C:\Program Files\Cppcheck\cppcheck.exe" +goto :shift_arg + :shift_2args rem Shift to the next pair of arguments shift @@ -135,7 +143,7 @@ if "%VS_VER%"=="2015" ( set CMAKE_VS="Visual Studio 16 2019" set CMAKE_VSARCH=-A x64 ) else ( - echo Error: Unknows VisualStudio version provided. Aborting... + echo Error: Unknown VisualStudio version provided. Aborting... exit /b 1 ) ) @@ -154,8 +162,8 @@ if not [%VK_LIB%]==[] ( ) rem Create an output folder -set VS_FOLDER=VS%VS_VER% -set OUTPUT_FOLDER=%SCRIPT_DIR%Windows\%VS_FOLDER%%TEST_DIR_SUFFIX% +set VS_FOLDER=vs%VS_VER% +set OUTPUT_FOLDER=%SCRIPT_DIR%windows\%VS_FOLDER%%TEST_DIR_SUFFIX% if not exist %OUTPUT_FOLDER% ( mkdir %OUTPUT_FOLDER% ) @@ -185,7 +193,7 @@ rem Invoke cmake with required arguments. echo: echo Running cmake to generate a VisualStudio solution... cd %OUTPUT_FOLDER% -%CMAKE_PATH% -G %CMAKE_VS% %CMAKE_VSARCH% %CMAKE_QT% %CMAKE_VK_INCLUDE% %CMAKE_VK_LIB% %CLI_ONLY% %GUI_ONLY% %NO_VULKAN% %AUTOMATION% %AMD_INTERNAL% ..\..\.. +%CMAKE_PATH% -G %CMAKE_VS% %CMAKE_VSARCH% %CMAKE_QT% %CMAKE_VK_INCLUDE% %CMAKE_VK_LIB% %CLI_ONLY% %GUI_ONLY% %NO_VULKAN% %AUTOMATION% %AMD_INTERNAL% %CPPCHECK% ..\..\.. if not %ERRORLEVEL%==0 ( echo "ERROR: cmake failed. Aborting..." exit /b 1 diff --git a/Build/Prebuild.sh b/Build/Prebuild.sh index 1eb1640..55d40b7 100755 --- a/Build/Prebuild.sh +++ b/Build/Prebuild.sh @@ -5,7 +5,7 @@ if [[ "$1" == "-h" ]] || [[ "$1" == "-help" ]] || [[ "$1" == "--h" ]] || [[ "$1" echo "" echo "This script generates Makefiles for RGA on Linux." echo "" - echo "Usage: Prebuild.sh [options]" + echo "Usage: prebuild.sh [options]" echo "" echo "Options:" echo " --no-fetch Do not call fetch_dependencies.py script before running cmake. The default is \"false\"." @@ -18,13 +18,14 @@ if [[ "$1" == "-h" ]] || [[ "$1" == "-help" ]] || [[ "$1" == "--h" ]] || [[ "$1" echo " --vulkan-sdk Path to the Vulkan SDK. The Vulkan SDK is required to build the RGA vulkan backend." echo " --vk-include Path to the Vulkan SDK include folder." echo " --vk-lib Path to the Vulkan SDK library folder." + echo " --cppcheck Add CMAKE_CXX_CPPCHECK preprocess option to cmake." echo "" echo "Examples:" - echo " Prebuild.sh" - echo " Prebuild.sh --build release" - echo " Prebuild.sh --qt C:\Qt\5.7\msvc2015_64" - echo " Prebuild.sh --build release --cli-only" - echo " Prebuild.sh --no-vulkan" + echo " prebuild.sh" + echo " prebuild.sh --build release" + echo " prebuild.sh --qt C:\Qt\5.7\msvc2015_64" + echo " prebuild.sh --build release --cli-only" + echo " prebuild.sh --no-vulkan" echo "" exit 0 fi @@ -42,6 +43,7 @@ CLI_ONLY= GUI_ONLY= NO_VULKAN= TEST_DIR_SUFFIX="" +CMAKE_CPPCHECK= # Parse command line arguments args=("$@") @@ -78,7 +80,9 @@ for ((i=0; i<$#; i++)); do NO_UPDATE="TRUE" elif [ "$arg" == "--automation" ]; then AUTOMATION="-DGUI_AUTOMATION=ON" - TEST_DIR_SUFFIX="_Test" + TEST_DIR_SUFFIX="_test" + elif [ "$arg" == "--cppcheck" ]; then + CMAKE_CPPCHECK="-DCMAKE_CXX_CPPCHECK=cppcheck" else echo "Unexpected argument: $arg. Aborting..."; exit 1 @@ -99,8 +103,8 @@ fi CURRENT_DIR=$(pwd) SCRIPT_DIR=$(dirname "$0") -OUTPUT_LINUX_DIR="$SCRIPT_DIR/Linux" -OUTPUT_DIR="$OUTPUT_LINUX_DIR/Make$TEST_DIR_SUFFIX" +OUTPUT_LINUX_DIR="$SCRIPT_DIR/linux" +OUTPUT_DIR="$OUTPUT_LINUX_DIR/make$TEST_DIR_SUFFIX" # Create output folder if [ ! -d "$OUTPUT_LINUX_DIR" ]; then @@ -120,23 +124,12 @@ if [ "$NO_UPDATE" != "TRUE" ]; then echo "Error: encountered an error while fetching dependencies. Aborting..." exit 1 fi - - if [ -e $SCRIPT_DIR/FetchDependencies-Internal.py ]; then - python $SCRIPT_DIR/FetchDependencies-Internal.py - - if [ $? -ne 0 ]; then - echo "Error: encountered an error while fetching internal dependencies. Aborting..." - exit 1 - fi - fi fi - - # Launch cmake echo "" echo "Running cmake to generate Makefiles..." cd $OUTPUT_DIR -$CMAKE_PATH -DCMAKE_BUILD_TYPE=$BUILD_TYPE $CMAKE_QT $CMAKE_VK_INC $CMAKE_VK_LIB $CLI_ONLY $GUI_ONLY $NO_VULKAN $AUTOMATION ../../.. +$CMAKE_PATH -DCMAKE_BUILD_TYPE=$BUILD_TYPE $CMAKE_QT $CMAKE_VK_INC $CMAKE_VK_LIB $CLI_ONLY $GUI_ONLY $NO_VULKAN $AUTOMATION $CMAKE_CPPCHECK ../../.. cd $CURRENT_DIR echo "Done." diff --git a/Build/Util/Linux/copy_post_build_cli.sh b/Build/Util/Linux/copy_post_build_cli.sh index 88dd52b..74ee57e 100755 --- a/Build/Util/Linux/copy_post_build_cli.sh +++ b/Build/Util/Linux/copy_post_build_cli.sh @@ -10,41 +10,45 @@ set -x X64_DIR=$OUTPUT_DIR/utils # Get the build version string -export MAJOR=`python3 ../../../Build/Util/get_version.py --major` -export MINOR=`python3 ../../../Build/Util/get_version.py --minor` +export MAJOR=`python3 ../../../build/util/get_version.py --major` +export MINOR=`python3 ../../../build/util/get_version.py --minor` # Copy the Vulkan offline backend. if [ ! -d "$X64_DIR" ]; then mkdir -p $X64_DIR fi -cp ../../../Core/VulkanOffline/lnx64/* $X64_DIR/ +cp ../../../external/vulkan_offline/linux/* $X64_DIR/ chmod +x $X64_DIR/amdspv chmod +x $X64_DIR/spvgen.so # Copy the OpenGL backend. -cp ../../../Core/OpenGL/VirtualContext/Release/lnx64/VirtualContext $X64_DIR/ +cp ../../../external/opengl/VirtualContext/linux/VirtualContext $X64_DIR/ chmod +x $X64_DIR/VirtualContext # Copy the LC Compiler. if [ ! -d "$X64_DIR/LC" ]; then mkdir -p $X64_DIR/LC fi -cp -rf ../../../Core/LC/OpenCL/linux $X64_DIR/LC/OpenCL -cp -f ../../../Core/LC/OpenCL/additional-targets $X64_DIR/LC/OpenCL/ +mkdir -p $X64_DIR/LC/OpenCL/lib/clang/13.0.0/include +cp -rf ../../../external/lc/opencl/linux/* $X64_DIR/LC/OpenCL +rm -f $X64_DIR/LC/OpenCL/include/opencl-c-base.h +cp -f ../../../external/lc/opencl/additional-targets $X64_DIR/LC/OpenCL/ +cp -f ../../../external/lc/opencl/linux/include/opencl-c-base.h $X64_DIR/LC/OpenCL/lib/clang/13.0.0/include/ # Copy the LC disassembler. if [ ! -d "$X64_DIR/LC/Disassembler" ]; then mkdir $X64_DIR/LC/Disassembler fi -cp ../../../Core/LC/Disassembler/Linux/amdgpu-dis $X64_DIR/LC/Disassembler +cp ../../../external/lc/disassembler/linux/amdgpu-dis $X64_DIR/LC/Disassembler -# make sure LC/OpenCL/bin/clang is link to clang-7 +# make sure LC/OpenCL/bin/clang is link to clang-13 CURDIR=`pwd` rm -f $X64_DIR/LC/OpenCL/bin/clang cd $X64_DIR/LC/OpenCL/bin/ -ln -s clang-7 clang +ln -s clang-13 clang cd $CURDIR -chmod +x $X64_DIR/LC/OpenCL/bin/l* $X64_DIR/LC/OpenCL/bin/clang* + +chmod +x $X64_DIR/LC/OpenCL/bin/lld $X64_DIR/LC/OpenCL/bin/clang-13 $X64_DIR/LC/OpenCL/bin/llvm-objdump $X64_DIR/LC/OpenCL/bin/llvm-readobj chmod +x $X64_DIR/LC/OpenCL/lib/bitcode/*.bc # Copy the static analysis backend. @@ -58,7 +62,7 @@ if [ "$INTERNAL" = true ]; then rm $OUTPUT_DIR/rga-bin fi else - cp ../../../Core/ShaderAnalysis/Linux/x64/shae $X64_DIR/ + cp ../../../source/utils/shader_analysis/linux/x64/shae $X64_DIR/ chmod +x $X64_DIR/shae if [ -e b$X64_DIR/shae-internal ]; then rm $X64_DIR/shae-internal @@ -72,7 +76,7 @@ fi if [ ! -d "$X64_DIR/Vulkan" ]; then mkdir -p $X64_DIR/Vulkan fi -cp ../../../Core/Vulkan/tools/Lnx64/bin/* "$X64_DIR/Vulkan/" +cp ../../../external/vulkan/tools/linux/bin/* "$X64_DIR/Vulkan/" chmod +x $X64_DIR/Vulkan/* # Copy the Radeon Tools Download Assistant. @@ -88,5 +92,5 @@ cp ../../../License.txt $OUTPUT_DIR/ cp ../../../RGA_NOTICES.txt $OUTPUT_DIR/ # Copy README.md and Release notes -cp ../../../README.md $OUTPUT_DIR/README.md -cp ../../../Documentation/RGA_RELEASE_NOTES.txt $OUTPUT_DIR/ +cp ../../../README.md $OUTPUT_DIR/ +cp ../../../documentation/RGA_RELEASE_NOTES.txt $OUTPUT_DIR/ diff --git a/Build/Util/Linux/copy_post_build_gui.sh b/Build/Util/Linux/copy_post_build_gui.sh index 39a0f71..e181b9f 100755 --- a/Build/Util/Linux/copy_post_build_gui.sh +++ b/Build/Util/Linux/copy_post_build_gui.sh @@ -14,9 +14,9 @@ if [ -n "$QT_LIB_DIR" ]; then cp $QT_LIB_DIR/libQt5Gui.so.5 $OUTPUT_DIR/lib/ cp $QT_LIB_DIR/libQt5Widgets.so.5 $OUTPUT_DIR/lib/ cp $QT_LIB_DIR/libQt5XcbQpa.so.5 $OUTPUT_DIR/lib/ - cp $QT_LIB_DIR/libicui18n.so.56 $OUTPUT_DIR/lib/ - cp $QT_LIB_DIR/libicudata.so.56 $OUTPUT_DIR/lib/ - cp $QT_LIB_DIR/libicuuc.so.56 $OUTPUT_DIR/lib/ + cp $QT_LIB_DIR/libicui18n.so.50 $OUTPUT_DIR/lib/ + cp $QT_LIB_DIR/libicudata.so.50 $OUTPUT_DIR/lib/ + cp $QT_LIB_DIR/libicuuc.so.50 $OUTPUT_DIR/lib/ cp $QT_LIB_DIR/libQt5Svg.so.5 $OUTPUT_DIR/lib/ cp $QT_PLUGINS_DIR/imageformats/libqsvg.so $OUTPUT_DIR/lib/platforms/imageformats/ cp $QT_PLUGINS_DIR/platforms/libqxcb.so $OUTPUT_DIR/lib/platforms/ diff --git a/Build/Util/Windows/copy_post_build_cli.bat b/Build/Util/Windows/copy_post_build_cli.bat index 3ce88a6..e9857d6 100755 --- a/Build/Util/Windows/copy_post_build_cli.bat +++ b/Build/Util/Windows/copy_post_build_cli.bat @@ -2,6 +2,7 @@ rem Make all variables defined in this script local. SETLOCAL +SETLOCAL ENABLEEXTENSIONS set OUTPUT_DIR=%1 @@ -26,10 +27,10 @@ set INTERNAL=TRUE :no_internal REM Get version information to use in package name. -for /F "tokens=* USEBACKQ" %%F in (`python ..\..\..\Build\Util\get_version.py --major`) do ( +for /F "tokens=* USEBACKQ" %%F in (`python ..\..\..\build\util\get_version.py --major`) do ( set MAJOR=%%F ) -for /F "tokens=* USEBACKQ" %%F in (`python ..\..\..\Build\Util\get_version.py --minor`) do ( +for /F "tokens=* USEBACKQ" %%F in (`python ..\..\..\build\util\get_version.py --minor`) do ( set MINOR=%%F ) @@ -40,22 +41,24 @@ IF NOT exist %OUTPUT_DIR%\utils\DX12\ mkdir %OUTPUT_DIR%\utils\DX12\ IF NOT exist %OUTPUT_DIR%\utils\DX12\DXC\ mkdir %OUTPUT_DIR%\utils\DX12\DXC\ IF NOT exist %OUTPUT_DIR%\utils\LC\ mkdir %OUTPUT_DIR%\utils\LC\ IF NOT exist %OUTPUT_DIR%\utils\LC\Disassembler\ mkdir %OUTPUT_DIR%\utils\LC\Disassembler\ -IF NOT exist %OUTPUT_DIR%\utils\LC\OpenCL\ mkdir %OUTPUT_DIR%\utils\LC\OpenCL\ +IF NOT exist %OUTPUT_DIR%\utils\LC\OpenCL\ mkdir %OUTPUT_DIR%\utils\LC\OpenCL\lib\clang\13.0.0\include\ echo -XCopy /r /d /y "..\..\..\Core\OpenGL\VirtualContext\Release\win64\VirtualContext.exe" "%OUTPUT_DIR%\utils\" -XCopy /r /d /y "..\..\..\Core\ShaderAnalysis\Windows\x64\shae.exe" "%OUTPUT_DIR%\utils\" -XCopy /r /d /y "..\..\..\Core\DX\DX10\bin\RGADX11.exe" "%OUTPUT_DIR%\utils\" -XCopy /r /e /d /y "..\..\..\Core\LC\OpenCL\win64\*" "%OUTPUT_DIR%\utils\LC\OpenCL\" -XCopy /r /d /y "..\..\..\Core\LC\OpenCL\additional-targets" "%OUTPUT_DIR%\utils\LC\OpenCL\" -XCopy /r /d /y "..\..\..\Core\LC\Disassembler\Windows\amdgpu-dis.exe" "%OUTPUT_DIR%\utils\LC\Disassembler\" -XCopy /r /e /d /y "..\..\..\Core\Vulkan\tools\Win64\bin" "%OUTPUT_DIR%\utils\Vulkan\" -XCopy /r /e /d /y "..\..\..\Core\DX12\DXC\*" "%OUTPUT_DIR%\utils\DX12\DXC\" +XCopy /r /d /y "..\..\..\external\opengl\VirtualContext\windows\VirtualContext.exe" "%OUTPUT_DIR%\utils\" +XCopy /r /d /y "..\..\..\source\utils\shader_analysis\windows\x64\shae.exe" "%OUTPUT_DIR%\utils\" +XCopy /r /d /y "..\..\..\source\utils\dx11\bin\dx11_adapter.exe" "%OUTPUT_DIR%\utils\" +XCopy /r /e /d /y "..\..\..\external\lc\opencl\windows\*" "%OUTPUT_DIR%\utils\LC\OpenCL\" +del /f "%OUTPUT_DIR%\utils\LC\OpenCL\include\opencl-c-base.h" +XCopy /r /d /y "..\..\..\external\lc\opencl\windows\include\opencl-c-base.h" "%OUTPUT_DIR%\utils\LC\OpenCL\lib\clang\13.0.0\include\" +XCopy /r /d /y "..\..\..\external\lc\opencl\additional-targets" "%OUTPUT_DIR%\utils\LC\OpenCL\" +XCopy /r /d /y "..\..\..\external\lc\disassembler\windows\amdgpu-dis.exe" "%OUTPUT_DIR%\utils\LC\Disassembler\" +XCopy /r /e /d /y "..\..\..\external\vulkan\tools\windows\bin" "%OUTPUT_DIR%\utils\Vulkan\" +XCopy /r /e /d /y "..\..\..\external\dxc\*" "%OUTPUT_DIR%\utils\DX12\DXC\" XCopy /r /d /y "..\..\..\License.txt" "%OUTPUT_DIR%\License.txt*" XCopy /r /d /y "..\..\..\RGA_NOTICES.txt" "%OUTPUT_DIR%\RGA_NOTICES.txt*" XCopy /r /d /y "..\..\..\README.md" "%OUTPUT_DIR%\README.md*" -XCopy /r /d /y "..\..\..\Documentation\RGA_RELEASE_NOTES.txt" "%OUTPUT_DIR%\RGA_RELEASE_NOTES.txt*" +XCopy /r /d /y "..\..\..\documentation\RGA_RELEASE_NOTES.txt" "%OUTPUT_DIR%\RGA_RELEASE_NOTES.txt*" XCopy /r /d /y "..\..\..\..\Common\Src\UpdateCheckAPI\rtda\windows\rtda.exe" "%OUTPUT_DIR%\rtda.exe*" -XCopy /r /d /y "..\..\..\Core\VulkanOffline\win64\amdspv.exe" "%OUTPUT_DIR%\utils\" -XCopy /r /d /y "..\..\..\Core\VulkanOffline\win64\spvgen.dll" "%OUTPUT_DIR%\utils\" +XCopy /r /d /y "..\..\..\external\vulkan_offline\windows\amdspv.exe" "%OUTPUT_DIR%\utils\" +XCopy /r /d /y "..\..\..\external\vulkan_offline\windows\spvgen.dll" "%OUTPUT_DIR%\utils\" diff --git a/Build/Util/Windows/copy_post_build_gui.bat b/Build/Util/Windows/copy_post_build_gui.bat index d03e5e5..71430d2 100755 --- a/Build/Util/Windows/copy_post_build_gui.bat +++ b/Build/Util/Windows/copy_post_build_gui.bat @@ -2,6 +2,7 @@ rem Make all variables defined in this script local. SETLOCAL +SETLOCAL ENABLEEXTENSIONS set OUTPUT_DIR=%1 set QT_LIB_DIR=%2 diff --git a/Build/Util/get_version.py b/Build/Util/get_version.py index 7e85710..b95357d 100644 --- a/Build/Util/get_version.py +++ b/Build/Util/get_version.py @@ -1,13 +1,13 @@ #!python # -# Get RGA version from RGA/Utils/include/rgaVersionInfo.h. +# Get RGA version from RGA/source/common/rga_version_info.h. # # Usage: # python RGA/Build/Util/get_version.py [--major] [--minor] [--update] [--versionfile ] # --major Return major version number # --minor Return minor version number # --update Return update version number -# --versionfile Use as the full path name of for rgaVersionInfo.h +# --versionfile Use as the full path name of for rga_version_info.h # import os import argparse @@ -24,7 +24,7 @@ VERSIONARGS = PARSER.parse_args() # Initialize file for search. -RGAVERSIONFILE = os.path.normpath(os.path.join(SCRIPTROOT, '../..', 'Utils/Include/rgaVersionInfo.h')) +RGAVERSIONFILE = os.path.normpath(os.path.join(SCRIPTROOT, '../..', 'source/common/rga_version_info.h')) RGAVERSIONDATA = None if not VERSIONARGS.versionfile == None: RGAVERSIONFILE = os.path.normpath(VERSIONARGS.versionfile) diff --git a/Build/dependency_map.py b/Build/dependency_map.py index 7aa125f..47a9376 100644 --- a/Build/dependency_map.py +++ b/Build/dependency_map.py @@ -4,11 +4,11 @@ # Binaries dependencies in zip files zip_files = { - "DX10ASM.zip" : "Core/DX10ASM/Lib/VS2015/", - "LC.zip" : "Core/LC/", - "dxcompiler.dll": "Core/DX12/DXC/", - "VkOffline.zip" : "Core/VulkanOffline/", - "Vulkan.zip" : "Core/Vulkan/" + "dx10_asm.zip" : "external/", + "lc.zip" : "external/", + "dxc.zip" : "external/", + "vulkan_offline.zip" : "external/", + "vulkan.zip" : "external/" } # key = GitHub release link @@ -22,43 +22,48 @@ # Some repos are only hosted on github - these are defined with an absolute URL based here github_root = "https://github.com/GPUOpen-Tools/" -git_root = "ssh://gerritgit/DevTools/ec/" # repositories. git_mapping = { # Lib. - "common-lib-AMD-ACL.git" : ["Common/Lib/AMD/ACL", "master"], - "common-lib-amd-ADL.git" : ["Common/Lib/AMD/ADL", "master"], - "common-lib-amd-APPSDK-3.0.git" : ["Common/Lib/AMD/APPSDK", "master"], - "common-lib-AMD-CAL-8.95.git" : ["Common/Lib/AMD/CAL", "master"], - "common-lib-amd-ags-4.0.0.git" : ["Common/Lib/AMD/ags", "master"], - "common-lib-ext-Boost-1.59.git" : ["Common/Lib/Ext/Boost", "master"], - "common-lib-ext-tinyxml-2.6.2.git" : ["Common/Lib/Ext/tinyxml", "master"], - "common-lib-ext-utf8cpp.git" : ["Common/Lib/Ext/utf8cpp", "master"], - "common-lib-ext-WindowsKits.git" : ["Common/Lib/Ext/Windows-Kits", "master"], - "common-lib-ext-zlib-1.2.8.git" : ["Common/Lib/Ext/zlib", "master"], + "common-lib-AMD-ACL" : ["Common/Lib/AMD/ACL", "master"], + "common-lib-amd-ADL" : ["Common/Lib/AMD/ADL", "master"], + "common-lib-amd-APPSDK-3.0" : ["Common/Lib/AMD/APPSDK", "master"], + "common-lib-AMD-CAL-8.95" : ["Common/Lib/AMD/CAL", "master"], + "common-lib-amd-ags-4.0.0" : ["Common/Lib/AMD/ags", "master"], + "common-lib-ext-Boost-1.59" : ["Common/Lib/Ext/Boost", "master"], + "common-lib-ext-tinyxml-2.6.2" : ["Common/Lib/Ext/tinyxml", "master"], + "common-lib-ext-utf8cpp" : ["Common/Lib/Ext/utf8cpp", "master"], + "common-lib-ext-WindowsKits" : ["Common/Lib/Ext/Windows-Kits", "master"], + "common-lib-ext-zlib-1.2.8" : ["Common/Lib/Ext/zlib", "master"], # Src. - "common-src-ACLModuleManager.git" : ["Common/Src/ACLModuleManager", "master"], - "common-src-ADLUtil.git" : ["Common/Src/ADLUtil", "master"], - "common-src-AMDTBaseTools.git" : ["Common/Src/AMDTBaseTools", "master"], - "common-src-AMDTOSWrappers.git" : ["Common/Src/AMDTOSWrappers", "6a5293d6a4f00c70747f935a4122a1b986129396"], - "common-src-AMDTMutex.git" : ["Common/Src/AMDTMutex", "master"], - "common-src-CElf.git" : ["Common/Src/CElf", "master"], - "common-src-DeviceInfo.git" : ["Common/Src/DeviceInfo", "rga-v2.4.2"], - "common-src-DynamicLibraryModule.git" : ["Common/Src/DynamicLibraryModule", "master"], - "common-src-TSingleton.git" : ["Common/Src/TSingleton", "master"], - "common-src-VersionInfo.git" : ["Common/Src/VersionInfo", "master"], - "common-src-Vsprops.git" : ["Common/Src/Vsprops", "master"], - "common-src-Miniz.git" : ["Common/Src/Miniz", "master"], - "common-src-Misc.git" : ["Common/Src/Misc", "master"], - "UpdateCheckAPI.git" : ["Common/Src/UpdateCheckAPI", "v1.1.0"], + "common-src-ACLModuleManager" : ["Common/Src/ACLModuleManager", "master"], + "common-src-ADLUtil" : ["Common/Src/ADLUtil", "master"], + "common-src-AMDTBaseTools" : ["Common/Src/AMDTBaseTools", "master"], + "common-src-AMDTOSWrappers" : ["Common/Src/AMDTOSWrappers", "6a5293d6a4f00c70747f935a4122a1b986129396"], + "common-src-AMDTMutex" : ["Common/Src/AMDTMutex", "master"], + "common-src-CElf" : ["Common/Src/CElf", "master"], + "common-src-DeviceInfo" : ["Common/Src/DeviceInfo", "rga-v2.5"], + "common-src-DynamicLibraryModule" : ["Common/Src/DynamicLibraryModule", "master"], + "common-src-TSingleton" : ["Common/Src/TSingleton", "master"], + "common-src-VersionInfo" : ["Common/Src/VersionInfo", "master"], + "common-src-Vsprops" : ["Common/Src/Vsprops", "master"], + "common-src-Miniz" : ["Common/Src/Miniz", "master"], + "common-src-Misc" : ["Common/Src/Misc", "master"], + "UpdateCheckAPI" : ["Common/Src/UpdateCheckAPI", "v2.0.0"], # QtCommon. - "QtCommon" : ["QtCommon", "rga-2.4"] + "QtCommon" : ["QtCommon", "rga-2.5"] } github_mapping = { "common-lib-ext-tinyxml2-5.0.1" : ["Common/Lib/Ext/tinyxml2", "master"], "common-lib-ext-yaml-cpp" : ["Common/Lib/Ext/yaml-cpp", "master"], - "cxxopts.git" : ["Common/Lib/Ext/cxxopts", "master"], - "volk.git" : ["Common/Lib/Ext/volk", "master"], -} \ No newline at end of file + "cxxopts" : ["Common/Lib/Ext/cxxopts", "master"], + "volk" : ["Common/Lib/Ext/volk", "master"], +} + +git_private_mapping = { + "code_sanitizer" : ["RGA/external/code_sanitizer", "master"], + "common-Scripts" : ["common-Scripts", "master"], + "RGA-Internal" : ["RGA-Internal", None] +} diff --git a/Build/fetch_dependencies.py b/Build/fetch_dependencies.py index e77255e..036f472 100644 --- a/Build/fetch_dependencies.py +++ b/Build/fetch_dependencies.py @@ -2,11 +2,16 @@ # # Simple script to update a set of common directories that are needed as dependencies of the current project # Usage: -# FetchDependencies.py [latest] +# fetch_dependencies.py [--latest] [--binary-path ] # -# If "latest" is specified, the latest commit will be checked out. +# If "--latest" is specified, the latest commit will be checked out. # Otherwise, the repos will be updated to the commit specified in the "git_mapping" table. # If the required commit in the "git_mapping" is None, the repo will be updated to the latest commit. +# +# If "--binary-path" is specified, the script will use the "rga_dependencies_.zip" file +# specified by the argument, for example "/home/someuser/Downloads/rga_dependencies_2.5.2.zip", +# instead of downloading rga_dependencies_.zip from Artifactory. +# import argparse import os @@ -26,7 +31,7 @@ import urllib.request SHELLARG = False -if ( sys.platform.startswith("win32")): +if sys.platform.startswith("win32"): SHELLARG = True # to allow the script to be run from anywhere - not just the cwd - store the absolute path to the script file @@ -35,7 +40,6 @@ # Assume workspace root is two folders up from script_root (RGA/Build) workspace = os.path.abspath(os.path.normpath(os.path.join(script_root, "../.."))) rga_root = os.path.abspath(os.path.normpath(os.path.join(script_root, ".."))) -rga_internal_root = os.path.abspath(os.path.normpath(os.path.join(script_root, "../../RGA-Internal"))) # add path to project build directory to python dependency path sys.path.insert(0, script_root) @@ -49,21 +53,18 @@ # Calculate the root of the git server - all git and zip file dependencies should be retrieved from the same server. git_url = subprocess.check_output(["git", "-C", script_root, "remote", "get-url", "origin"], shell=SHELLARG) git_url_string = (str(git_url).lstrip("b'")) -if git_url == None: +if git_url is None: print("Error: Unable to determine origin for RGA git project") exit(1) -elif "github" not in git_url_string: - sys.path.insert(0, os.path.join(rga_internal_root, "build")) - from artifactory_helper import ArtifactoryHelper - from artifactory_helper import artifactory_root - from artifactory_helper import artifactory_server # URL to root of radeon_gpu_analyzer releases on github.com. github_release_root = "https://github.com/GPUOpen-Tools/radeon_gpu_analyzer/releases/download/" + def parse_arguments(): parser = argparse.ArgumentParser(description="A script that updates the build enviroment") parser.add_argument('--latest', action='store_true', default=False, help='Use latest version on the default branch') + parser.add_argument('--binary-path', action='store', default=None, help='Use rga_dependencies zip file at specified path') return (parser.parse_args()) @@ -97,33 +98,41 @@ def make_executable(file_path): def downloadandunzip(key, value): - # convert targetPath to OS specific format + # convert target_path to OS specific format tmppath = os.path.join(script_root, value) # clean up path, collapsing any ../ and converting / to \ for Windows - targetPath = os.path.normpath(tmppath) + target_path = os.path.normpath(tmppath) # Create target folder if necessary. - if False == os.path.isdir(targetPath): - os.makedirs(targetPath) + if not os.path.isdir(target_path): + os.makedirs(target_path) zip_file_name = key.split('/')[-1].split('#')[0].split('?')[0] - zipPath = os.path.join(targetPath, zip_file_name) - if False == os.path.isfile(zipPath): - print("\nDownloading " + key + " into " + zipPath) + zip_path = os.path.join(target_path, zip_file_name) + if not os.path.isfile(zip_path): + print("\nDownloading " + key + " into " + zip_path) if isPython3OrAbove: - urllib.request.urlretrieve(key, zipPath) + urllib.request.urlretrieve(key, zip_path) else: - urllib.urlretrieve(key, zipPath) - if os.path.splitext(zipPath)[1] == ".zip": - zipfile.ZipFile(zipPath).extractall(targetPath) - os.remove(zipPath) - elif os.path.splitext(zipPath)[1] == ".gz": - tarfile.open(zipPath).extractall(targetPath) - os.remove(zipPath) + urllib.urlretrieve(key, zip_path) + if os.path.splitext(zip_path)[1] == ".zip": + try: + zipfile.ZipFile(zip_path).extractall(target_path) + os.remove(zip_path) + except (RuntimeError, ValueError): + print("Unable to expand package %s.\n"%key) + sys.exit(1) + elif os.path.splitext(zip_path)[1] == ".gz": + try: + tarfile.open(zip_path).extractall(target_path) + os.remove(zip_path) + except (RuntimeError, ValueError): + print("Unable to expand package %s.\n"%key) + sys.exit(1) def getVersion(): - rga_version_file = os.path.normpath(os.path.join(rga_root, 'Utils/Include/rgaVersionInfo.h')) + rga_version_file = os.path.normpath(os.path.join(rga_root, 'source/common/rga_version_info.h')) rga_version_data = None if os.path.exists(rga_version_file): rga_version_data = open(rga_version_file) @@ -149,20 +158,93 @@ def getVersion(): def artifactoryDownload(file_path, value): + from artifactory_helper import ArtifactoryHelper + from artifactory_helper import artifactory_server # path is artifactory server relative path to zip file. # value is . zip_file_name = file_path.split('/')[-1].split('#')[0].split('?')[0] target_path = os.path.normpath(os.path.join(rga_root, value)) + print("Downloading %s into %s"%(zip_file_name, target_path)) artifactory_download = ArtifactoryHelper(artifactory_server) artifactory_path = artifactory_server + file_path artifactory_download.DownloadFile(artifactory_path) - if os.path.splitext(zip_file_name)[1] == ".zip": + try: zipfile.ZipFile(zip_file_name).extractall(target_path) - if (get_os() == "Linux"): - make_executable(target_path) - os.remove(zip_file_name) - else: - os.rename(zip_file_name, os.path.join(target_path, zip_file_name)) + except (RuntimeError, ValueError): + print("Unable to expand package %s.\n"%file_path) + sys.exit(1) + if (get_os() == "Linux"): + make_executable(target_path) + os.remove(zip_file_name) + + +def do_fetch(repo_target, repo_branch): + status = True + + print("Directory " + repo_target + " exists. \n\tUsing 'git fetch' to get the latest revision.") + sys.stdout.flush() + try: + subprocess.check_call(["git", "-C", repo_target, "fetch", "origin"], shell=SHELLARG) + except subprocess.CalledProcessError as e: + print ("ERROR: 'git fetch' failed with return code: %d\n"%e.returncode) + status = False + + if status is True: + try: + subprocess.check_call(["git", "-C", repo_target, "checkout", repo_branch], shell=SHELLARG) + except subprocess.CalledProcessError as e: + print ("ERROR: 'git checkout' failed with return code: %d\n"%e.returncode) + status = False + sys.stderr.flush() + sys.stdout.flush() + + return status + + +def do_clone(repo_git_path, repo_target, repo_branch): + status = True + + print("Directory %s does not exist. \n\tUsing 'git clone' to get latest from %s"%(repo_target, repo_git_path)) + sys.stdout.flush() + try: + subprocess.check_call(["git", "clone", repo_git_path, repo_target], shell=SHELLARG) + subprocess.check_call(["git", "-C", repo_target, "checkout", repo_branch], shell=SHELLARG) + except subprocess.CalledProcessError as e: + print("ERROR: 'git clone' failed with return code: %d\n"%e.returncode) + status = False + sys.stderr.flush() + sys.stdout.flush() + + return status + + +def fetch_private_map(git_server, repo_target): + # Clone repositories in git_private_mapping if they don't exist. + from dependency_map import git_private_mapping + + # Determine checked out branch of RGA. + git_output = subprocess.check_output(["git", "-C", script_root, "branch", "--show-current"], shell=SHELLARG) + git_branch = git_output.decode() + rga_branch = git_branch.rstrip() + + os.chdir(workspace) + for key in git_private_mapping: + if git_private_mapping[key][1] is None: + git_private_mapping[key][1] = rga_branch + private_git_path = git_server + key + private_repo_target = os.path.normpath(os.path.join(repo_target, git_private_mapping[key][0])) + + print("\nChecking out commit: " + git_private_mapping[key][1] + " for " + key) + if os.path.isdir(private_repo_target): + # directory exists - get latest from git using pull + status = do_fetch(private_repo_target, git_private_mapping[key][1]) + if not status: + sys.exit(1) + else: + # directory doesn't exist - clone from git + status = do_clone(private_git_path, private_repo_target, git_private_mapping[key][1]) + if not status: + sys.exit(1) def fetch_git_map(arguments, git_branch, git_root): @@ -171,40 +253,24 @@ def fetch_git_map(arguments, git_branch, git_root): path = git_mapping[key][0] source = git_root + key - reqdCommit = git_mapping[key][1] - # reqdCommit may be "None" - or user may override commit via command line. In this case, use tip of tree - if( reqdCommit is None): - reqdCommit = git_branch + required_commit = git_mapping[key][1] + # required_commit may be "None" - or user may override commit via command line. In this case, use tip of tree + if required_commit is None: + required_commit = git_branch - print("\nChecking out commit: " + reqdCommit + " for " + key) + print("\nChecking out commit: " + required_commit + " for " + key) os.chdir(workspace) if os.path.isdir(path): # directory exists - get latest from git using pull - print("Directory " + path + " exists. \n\tUsing 'git fetch' to get latest from " + source) - sys.stdout.flush() - try: - subprocess.check_call(["git", "-C", path, "fetch", "origin"], shell=SHELLARG) - except subprocess.CalledProcessError as e: - print ("'git fetch' failed with return code: %d\n" % e.returncode) - try: - subprocess.check_call(["git", "-C", path, "checkout", reqdCommit], shell=SHELLARG) - except subprocess.CalledProcessError as e: - print ("'git checkout' failed with return code: %d\n" % e.returncode) - sys.stderr.flush() - sys.stdout.flush() + status = do_fetch(os.path.normpath(os.path.join(workspace, path)), required_commit) + if not status: + sys.exit(1) else: # directory doesn't exist - clone from git - print("Directory " + path + " does not exist. \n\tUsing 'git clone' to get latest from " + source) - sys.stdout.flush() - try: - subprocess.check_call(["git", "clone", source, path], shell=SHELLARG) - subprocess.check_call(["git", "-C", path, "checkout", reqdCommit], shell=SHELLARG) - except subprocess.CalledProcessError as e: - print ("'git clone' failed with return code: %d\n" % e.returncode) + status = do_clone(source, os.path.normpath(os.path.join(workspace, path)), required_commit) + if not status: sys.exit(1) - sys.stderr.flush() - sys.stdout.flush() def fetch_github_map(arguments, git_branch): @@ -213,48 +279,32 @@ def fetch_github_map(arguments, git_branch): path = github_mapping[key][0] source = github_root + key - reqdCommit = github_mapping[key][1] + required_commit = github_mapping[key][1] - # reqdCommit may be "None" - or user may override commit via command line. In this case, use tip of tree - if(reqdCommit is None): - reqdCommit = git_branch + # required_commit may be "None" - or user may override commit via command line. In this case, use tip of tree + if required_commit is None: + required_commit = git_branch - print("\nChecking out commit: " + reqdCommit + " for " + key) + print("\nChecking out commit: " + required_commit + " for " + key) os.chdir(workspace) if os.path.isdir(path): # directory exists - get latest from git using pull - print("Directory " + path + " exists. \n\tUsing 'git fetch' to get latest from " + source) - sys.stdout.flush() - try: - subprocess.check_call(["git", "-C", path, "fetch", "origin"], shell=SHELLARG) - except subprocess.CalledProcessError as e: - print ("'git fetch' failed with return code: %d\n" % e.returncode) - try: - subprocess.check_call(["git", "-C", path, "checkout", reqdCommit], shell=SHELLARG) - except subprocess.CalledProcessError as e: - print ("'git checkout' failed with return code: %d\n" % e.returncode) - sys.stderr.flush() - sys.stdout.flush() + status = do_fetch(os.path.normpath(os.path.join(workspace, path)), required_commit) + if not status: + sys.exit(1) else: # directory doesn't exist - clone from git - print("Directory " + path + " does not exist. \n\tUsing 'git clone' to get latest from " + source) - sys.stdout.flush() - try: - subprocess.check_call(["git", "clone", source, path], shell=SHELLARG) - subprocess.check_call(["git", "-C", path, "checkout", reqdCommit], shell=SHELLARG) - except subprocess.CalledProcessError as e: - print ("'git clone' failed with return code: %d\n" % e.returncode) + status = do_clone(source, os.path.normpath(os.path.join(workspace, path)), required_commit) + if not status: sys.exit(1) - sys.stderr.flush() - sys.stdout.flush() def do_fetch_dependencies(arguments): # When running this script on Windows (and not under cygwin), we need to set the shell=True argument to Popen and similar calls # Without this option, Jenkins builds fail to find the correct version of git SHELLARG = False - if (sys.platform.startswith("win32")): + if sys.platform.startswith("win32"): # running on windows under default shell SHELLARG = True @@ -270,21 +320,22 @@ def do_fetch_dependencies(arguments): # If cloning from github - use the master branch as the default branch - otherwise use amd-master git_branch = "amd-master" - if "github" in git_url_string: + if "github.com" in git_url_string: git_branch = "master" - # temporary for testing print("\nFetching dependencies from: " + git_root + " - using branch: " + git_branch) - # Define a set of dependencies that exist as separate git projects. The parameters are: - # "git repo name" : ["Directory for clone relative to this script", "branch or commit to checkout (or None for top of tree)" - # The following section contains OS-specific dependencies that are downloaded and placed in the specified target directory. # for each dependency - test if it has already been fetched - if not, then fetch it, otherwise update it to top of tree fetch_git_map(arguments, git_branch, git_root) fetch_github_map(arguments, git_branch) - # detect the OS + # Handle git_private_mapping. + if "github.com" not in git_url_string: + if "JENKINS_URL" not in os.environ: + fetch_private_map(git_root, workspace) + + # Capture the operating system. machine_os = get_os() # reference the correct archive path @@ -299,33 +350,44 @@ def do_fetch_dependencies(arguments): for key in download_mapping: downloadandunzip(key, download_mapping[key]) - # If one of the binaries exists, assume they all do. - if os.path.isfile(os.path.normpath(os.path.join(rga_root, "Core/LC/OpenCL/win64/bin/clang.exe"))): - print("\nBinaries already exist\n") + # If one of the large binaries exists, assume they all do. + if os.path.isfile(os.path.normpath(os.path.join(rga_root, "external/lc/opencl/windows/bin/clang.exe"))): + print("\nBinaries already exist, skipping rga_dependencies.zip download\n") return else: # Download and extract additional zip files if necessary. - if "github" in git_url_string: - version = getVersion() - rga_dependencies_zip_file = github_release_root + version + "/" + "rga_dependencies.zip" - downloadandunzip(rga_dependencies_zip_file, workspace) - for key in zip_files: - zip_file_path = os.path.join(workspace, key) - target_path = os.path.normpath(os.path.join(rga_root, zip_files[key])) - if os.path.splitext(zip_file_path)[1] == ".zip": - zipfile.ZipFile(zip_file_path).extractall(target_path) - # extractall doesn't retain execute permissions on Linux binaries. - if (machine_os == "Linux"): - make_executable(target_path) - os.remove(zip_file_path) - else: - # Support file dxcompiler.dll. - target_path = os.path.join(target_path, key) - os.rename(zip_file_path, target_path) + version = getVersion() + dependency_zip_file_name = "rga_dependencies_" + version + ".zip" + if arguments.binary_path is None: + # Download dependency zip file and unzip. + if "github" in git_url_string: + # Download from github. + rga_dependencies_zip_file = github_release_root + version + "/" + dependency_zip_file_name + downloadandunzip(rga_dependencies_zip_file, workspace) + else: + # Download from Artifactory. + # Import the artifactory_helper.py from RGA-Internal. + internal_repo_root = os.path.abspath(os.path.normpath(os.path.join(script_root, "../.."))) + sys.path.insert(0, os.path.normpath(os.path.join(internal_repo_root, "RGA-Internal/build"))) + from artifactory_helper import artifactory_root + os.chdir(workspace) + + # Download and unzip dependency file from Artifactory. + artifactory_path = artifactory_root + version +"/" + dependency_zip_file_name + artifactoryDownload(artifactory_path, workspace) else: - for key in zip_files: - artifactory_path = artifactory_root + key - artifactoryDownload(artifactory_path, zip_files[key]) + zipfile.ZipFile(arguments.binary_path).extractall(workspace) + + # Copy extracted files to RGA folders. + for key in zip_files: + zip_file_path = os.path.join(workspace, key) + target_path = os.path.normpath(os.path.join(rga_root, zip_files[key])) + print("Extracting %s files into %s"%(key, target_path)) + zipfile.ZipFile(zip_file_path).extractall(target_path) + # extractall doesn't retain execute permissions on Linux binaries. + if machine_os == "Linux": + make_executable(target_path) + os.remove(zip_file_path) if __name__ == '__main__': diff --git a/CMakeLists.txt b/CMakeLists.txt index af1eb7e..a1573de 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,21 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8) option(CMAKE_64BIT_TARGET "On if the target architecture is 64-bit" ON) endif() +# Define cppcheck options +if (CMAKE_CXX_CPPCHECK) + if (NOT ${CMAKE_GENERATOR} MATCHES "^.*Makefiles$|^Ninja$") + add_custom_target(ANALYZE_CPPCHECK DEPENDS RGA + COMMAND ${CMAKE_CXX_CPPCHECK} ${CMAKE_SOURCE_DIR} + ) + else() + list( + APPEND CMAKE_CXX_CPPCHECK + "--xml" + ${CMAKE_SOURCE_DIR} + ) + endif() +endif() + # Pass the build number and build date if (NOT "$ENV{BUILD_NUMBER}" STREQUAL "") add_definitions(-DRGA_BUILD_NUMBER=$ENV{BUILD_NUMBER}) @@ -102,7 +117,6 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") set(CMAKE_CONFIGURATION_TYPES "Release;Debug") endif() - # Vulkan support if (RGA_ENABLE_VULKAN) add_definitions("-DRGA_ENABLE_VULKAN") @@ -120,25 +134,18 @@ endif() # Add RGA CLI projects if(NOT BUILD_GUI_ONLY) - add_subdirectory (RadeonGPUAnalyzerBackend) - add_subdirectory (RadeonGPUAnalyzerCLI) if (RGA_ENABLE_VULKAN) - add_subdirectory (Core/Vulkan/Backend) - add_dependencies (radeon_gpu_analyzer_cli VulkanBackend) + add_subdirectory (source/utils/vulkan/backend) endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - add_subdirectory (Core/DX12/Backend) - add_dependencies (radeon_gpu_analyzer_cli dx12_backend) + add_subdirectory (source/utils/dx12/backend) endif() endif() -# Add RGA GUI -if(NOT BUILD_CLI_ONLY) - add_subdirectory (RadeonGPUAnalyzerGUI) - add_dependencies (RadeonGPUAnalyzer radeon_gpu_analyzer_cli) -endif() +# Add source folder +add_subdirectory (source) # Add Tests if(AMD_INTERNAL) - add_subdirectory (${PROJECT_SOURCE_DIR}/../RGA-Internal/Tests ${CMAKE_CURRENT_BINARY_DIR}/Tests) + add_subdirectory (${PROJECT_SOURCE_DIR}/../RGA-Internal/tests ${CMAKE_CURRENT_BINARY_DIR}/tests) endif() diff --git a/Core/DX/DX10/bin/RGADX11.exe b/Core/DX/DX10/bin/RGADX11.exe deleted file mode 100755 index 6457a09..0000000 Binary files a/Core/DX/DX10/bin/RGADX11.exe and /dev/null differ diff --git a/Core/DX12/Backend/CMakeLists.txt b/Core/DX12/Backend/CMakeLists.txt deleted file mode 100644 index 13dda09..0000000 --- a/Core/DX12/Backend/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -cmake_minimum_required(VERSION 3.5.0) -project(dx12_backend) - -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/") - -file(GLOB SOURCE_FILES - "${PROJECT_SOURCE_DIR}/src/*.cpp" - "${PROJECT_SOURCE_DIR}/../../../RadeonGPUAnalyzerBackend/src/be_d3d_include_manager.cpp" -) - -# API symbol export definition. -add_definitions(-DRGA_API_EXPORTS -DINITGUID -DNOMINMAX -DRGA_DXR_ENABLED) - -file(GLOB INCLUDES - "${PROJECT_SOURCE_DIR}/src/*.h" - "${PROJECT_SOURCE_DIR}/src/extension/*.h" - "${PROJECT_SOURCE_DIR}/../../../RadeonGPUAnalyzerBackend/Src/be_d3d_include_manager.h" -# TinyXML2. - "${PROJECT_SOURCE_DIR}/../../../../Common/Lib/Ext/tinyxml2/tinyxml2.h" -) - -include_directories("${PROJECT_SOURCE_DIR}/src") -include_directories("${PROJECT_SOURCE_DIR}/src/extension") -include_directories("${PROJECT_SOURCE_DIR}/../../../../Common/Lib/Ext/tinyxml2/Include") -include_directories("${PROJECT_SOURCE_DIR}/../../../../Common/Lib/Ext") -include_directories("${PROJECT_SOURCE_DIR}/../../../../RGA/") -include_directories("${PROJECT_SOURCE_DIR}/../../../RadeonGPUAnalyzerBackend/Src") - -find_library(TINYXML_LIB "tinyxml2.lib" HINTS "${PROJECT_SOURCE_DIR}/../../../../Common/Lib/Ext/tinyxml2/Lib/VS2015/Win64/Release/MD") -find_library(TINYXML_LIBD "tinyxml2-d.lib" HINTS "${PROJECT_SOURCE_DIR}/../../../../Common/Lib/Ext/tinyxml2/Lib/VS2015/Win64/Debug/MDd") - -add_executable(dx12_backend ${SOURCE_FILES} ${INCLUDES}) - -# Set output folder and executable name. -set_target_properties(dx12_backend PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/utils/DX12") -set_target_properties(dx12_backend PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/utils/DX12") - -# Set link properties -set_target_properties(dx12_backend PROPERTIES OUTPUT_NAME dx12_backend) - -# Set link libraries -target_link_libraries (dx12_backend d3dcompiler.lib d3d12.lib dxgi.lib optimized ${TINYXML_LIB} debug ${TINYXML_LIBD}) - -# Custom command: create DXC folder for post-build script -file(MAKE_DIRECTORY ${RUNTIME_OUTPUT_DIRECTORY}/DXC) diff --git a/Core/LC/OpenCL/linux/bin/clang b/Core/LC/OpenCL/linux/bin/clang deleted file mode 120000 index 44854f6..0000000 --- a/Core/LC/OpenCL/linux/bin/clang +++ /dev/null @@ -1 +0,0 @@ -clang-7 \ No newline at end of file diff --git a/Core/LC/OpenCL/linux/bin/ld.lld b/Core/LC/OpenCL/linux/bin/ld.lld deleted file mode 120000 index 02416ac..0000000 --- a/Core/LC/OpenCL/linux/bin/ld.lld +++ /dev/null @@ -1 +0,0 @@ -lld \ No newline at end of file diff --git a/Core/LC/OpenCL/linux/bin/lld-link b/Core/LC/OpenCL/linux/bin/lld-link deleted file mode 120000 index 02416ac..0000000 --- a/Core/LC/OpenCL/linux/bin/lld-link +++ /dev/null @@ -1 +0,0 @@ -lld \ No newline at end of file diff --git a/Core/LC/OpenCL/linux/bin/llvm-readelf b/Core/LC/OpenCL/linux/bin/llvm-readelf deleted file mode 120000 index a39a921..0000000 --- a/Core/LC/OpenCL/linux/bin/llvm-readelf +++ /dev/null @@ -1 +0,0 @@ -llvm-readobj \ No newline at end of file diff --git a/Core/LC/OpenCL/linux/bin/llvm-readobj b/Core/LC/OpenCL/linux/bin/llvm-readobj deleted file mode 100755 index 2418842..0000000 Binary files a/Core/LC/OpenCL/linux/bin/llvm-readobj and /dev/null differ diff --git a/Core/LC/OpenCL/linux/lib/bitcode/ockl.amdgcn.bc b/Core/LC/OpenCL/linux/lib/bitcode/ockl.amdgcn.bc deleted file mode 100755 index bb7836d..0000000 Binary files a/Core/LC/OpenCL/linux/lib/bitcode/ockl.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/linux/lib/bitcode/oclc_correctly_rounded_sqrt_off.amdgcn.bc b/Core/LC/OpenCL/linux/lib/bitcode/oclc_correctly_rounded_sqrt_off.amdgcn.bc deleted file mode 100755 index 6feaa66..0000000 Binary files a/Core/LC/OpenCL/linux/lib/bitcode/oclc_correctly_rounded_sqrt_off.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/linux/lib/bitcode/oclc_correctly_rounded_sqrt_on.amdgcn.bc b/Core/LC/OpenCL/linux/lib/bitcode/oclc_correctly_rounded_sqrt_on.amdgcn.bc deleted file mode 100755 index a434bf9..0000000 Binary files a/Core/LC/OpenCL/linux/lib/bitcode/oclc_correctly_rounded_sqrt_on.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/linux/lib/bitcode/oclc_daz_opt_off.amdgcn.bc b/Core/LC/OpenCL/linux/lib/bitcode/oclc_daz_opt_off.amdgcn.bc deleted file mode 100755 index e14c51a..0000000 Binary files a/Core/LC/OpenCL/linux/lib/bitcode/oclc_daz_opt_off.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/linux/lib/bitcode/oclc_daz_opt_on.amdgcn.bc b/Core/LC/OpenCL/linux/lib/bitcode/oclc_daz_opt_on.amdgcn.bc deleted file mode 100755 index 0cadfbe..0000000 Binary files a/Core/LC/OpenCL/linux/lib/bitcode/oclc_daz_opt_on.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/linux/lib/bitcode/oclc_finite_only_off.amdgcn.bc b/Core/LC/OpenCL/linux/lib/bitcode/oclc_finite_only_off.amdgcn.bc deleted file mode 100755 index c78b52a..0000000 Binary files a/Core/LC/OpenCL/linux/lib/bitcode/oclc_finite_only_off.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/linux/lib/bitcode/oclc_finite_only_on.amdgcn.bc b/Core/LC/OpenCL/linux/lib/bitcode/oclc_finite_only_on.amdgcn.bc deleted file mode 100755 index b0412b2..0000000 Binary files a/Core/LC/OpenCL/linux/lib/bitcode/oclc_finite_only_on.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/linux/lib/bitcode/oclc_isa_version_900.amdgcn.bc b/Core/LC/OpenCL/linux/lib/bitcode/oclc_isa_version_900.amdgcn.bc deleted file mode 100755 index 1a12a26..0000000 Binary files a/Core/LC/OpenCL/linux/lib/bitcode/oclc_isa_version_900.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/linux/lib/bitcode/oclc_isa_version_901.amdgcn.bc b/Core/LC/OpenCL/linux/lib/bitcode/oclc_isa_version_901.amdgcn.bc deleted file mode 100755 index 638a07b..0000000 Binary files a/Core/LC/OpenCL/linux/lib/bitcode/oclc_isa_version_901.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/linux/lib/bitcode/oclc_isa_version_902.amdgcn.bc b/Core/LC/OpenCL/linux/lib/bitcode/oclc_isa_version_902.amdgcn.bc deleted file mode 100755 index 6a152aa..0000000 Binary files a/Core/LC/OpenCL/linux/lib/bitcode/oclc_isa_version_902.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/linux/lib/bitcode/oclc_unsafe_math_off.amdgcn.bc b/Core/LC/OpenCL/linux/lib/bitcode/oclc_unsafe_math_off.amdgcn.bc deleted file mode 100755 index b273b70..0000000 Binary files a/Core/LC/OpenCL/linux/lib/bitcode/oclc_unsafe_math_off.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/linux/lib/bitcode/oclc_unsafe_math_on.amdgcn.bc b/Core/LC/OpenCL/linux/lib/bitcode/oclc_unsafe_math_on.amdgcn.bc deleted file mode 100755 index d8fd68d..0000000 Binary files a/Core/LC/OpenCL/linux/lib/bitcode/oclc_unsafe_math_on.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/linux/lib/bitcode/ocml.amdgcn.bc b/Core/LC/OpenCL/linux/lib/bitcode/ocml.amdgcn.bc deleted file mode 100755 index 1d9e555..0000000 Binary files a/Core/LC/OpenCL/linux/lib/bitcode/ocml.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/linux/lib/bitcode/opencl.amdgcn.bc b/Core/LC/OpenCL/linux/lib/bitcode/opencl.amdgcn.bc deleted file mode 100755 index a5d0f50..0000000 Binary files a/Core/LC/OpenCL/linux/lib/bitcode/opencl.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/win64/bin/gen_devices.py b/Core/LC/OpenCL/win64/bin/gen_devices.py deleted file mode 100644 index 9e5f76e..0000000 --- a/Core/LC/OpenCL/win64/bin/gen_devices.py +++ /dev/null @@ -1,92 +0,0 @@ -# ===================================================================== -# Copyright 2017 (c), Advanced Micro Devices, Inc. All rights reserved. -# ===================================================================== - -import sys -import os.path -from subprocess import Popen -import subprocess -import re - -DEVICES_HDR_NAME = 'lc_targets.h' -LLC_OPTIONS = '-mtriple=amdgcn-amd-amdhsa -mcpu=help' -SUPPORTED_DEVICES = {'gfx900'} - -HDR_TITLE = '//=====================================================================\n' \ - '// Copyright 2017 (c), Advanced Micro Devices, Inc. All rights reserved.\n' \ - '//\n' \ - '// This file is auto-generated by the LC Device Generator utility.\n' \ - '//=====================================================================\n\n' - -def GetDeiveNames(llc_output_lines): - deviceNames = [] - numLines = len(llc_output_lines) - for i in range(0, numLines): - if re.search(r'Available CPUs', llc_output_lines[i]): - i += 1 - # skip empty lines before the list of devices - while llc_output_lines[i] == "" and i < numLines: - i += 1 - if i == numLines: - return [] - # Process the list of devices - while llc_output_lines[i] != "" and i < numLines: - deviceInfo = re.search('(.+)\-', llc_output_lines[i]) - if deviceInfo: - deviceName = deviceInfo.group(1).strip() - if len(deviceName) > 0: - deviceNames.append(deviceName) - i += 1 - # while .. - return deviceNames - # if re.search(r'Available CPUs') - # for i in range(0, numLines) - return [] -# GetDeiveNames() - -def GenDevicesHdr(hdrFileDir, deviceNames): - hdrFilePath = hdrFileDir + '/' + DEVICES_HDR_NAME - hdrFile = open(hdrFilePath, 'w') - if not hdrFile: - print('Failed to create a header file.') - return False - hdrFile.write(HDR_TITLE) - hdrFile.write('#include \n\n') - devicesDeclString = 'static const std::vector LC_TARGET_NAMES = { ' - first = True; - for deviceName in deviceNames: - if deviceName in SUPPORTED_DEVICES: - if not first: - devicesDeclString += ', ' - devicesDeclString += '"' + deviceName + '"' - first = False - devicesDeclString += ' };\n' - hdrFile.write(devicesDeclString) - hdrFile.flush() - hdrFile.close() - return True -# GenDevicesHdr() - -if __name__ == '__main__': - if len(sys.argv) == 3: - llc_path = sys.argv[1] - hdr_dir = sys.argv[2] - if os.path.exists(llc_path) and os.path.exists(hdr_dir): - llc_proc = Popen(llc_path + ' ' + LLC_OPTIONS, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE) - result = llc_proc.communicate('', 10) - if llc_proc.returncode == 1: - print('Failed to execute LLC\n') - sys.exit(1) - llc_output = result[1] # stderr - deviceNames = GetDeiveNames(llc_output.decode().splitlines()) - if (len(deviceNames) == 0): - print('Failed to get the device list.') - sys.exit(1) - else: - if GenDevicesHdr(hdr_dir, deviceNames) == False: - sys.exit(1) - else: - # Something went wrong - print('LC Device List Generator. (C) Advanced Micro Devices.') - print('Usage:') - print(' gen_devices ') diff --git a/Core/LC/OpenCL/win64/bin/llvm-readobj.exe b/Core/LC/OpenCL/win64/bin/llvm-readobj.exe deleted file mode 100644 index d85fcc4..0000000 Binary files a/Core/LC/OpenCL/win64/bin/llvm-readobj.exe and /dev/null differ diff --git a/Core/LC/OpenCL/win64/lib/bitcode/ockl.amdgcn.bc b/Core/LC/OpenCL/win64/lib/bitcode/ockl.amdgcn.bc deleted file mode 100644 index bb7836d..0000000 Binary files a/Core/LC/OpenCL/win64/lib/bitcode/ockl.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/win64/lib/bitcode/oclc_correctly_rounded_sqrt_off.amdgcn.bc b/Core/LC/OpenCL/win64/lib/bitcode/oclc_correctly_rounded_sqrt_off.amdgcn.bc deleted file mode 100644 index 6feaa66..0000000 Binary files a/Core/LC/OpenCL/win64/lib/bitcode/oclc_correctly_rounded_sqrt_off.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/win64/lib/bitcode/oclc_correctly_rounded_sqrt_on.amdgcn.bc b/Core/LC/OpenCL/win64/lib/bitcode/oclc_correctly_rounded_sqrt_on.amdgcn.bc deleted file mode 100644 index a434bf9..0000000 Binary files a/Core/LC/OpenCL/win64/lib/bitcode/oclc_correctly_rounded_sqrt_on.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/win64/lib/bitcode/oclc_daz_opt_off.amdgcn.bc b/Core/LC/OpenCL/win64/lib/bitcode/oclc_daz_opt_off.amdgcn.bc deleted file mode 100644 index e14c51a..0000000 Binary files a/Core/LC/OpenCL/win64/lib/bitcode/oclc_daz_opt_off.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/win64/lib/bitcode/oclc_daz_opt_on.amdgcn.bc b/Core/LC/OpenCL/win64/lib/bitcode/oclc_daz_opt_on.amdgcn.bc deleted file mode 100644 index 0cadfbe..0000000 Binary files a/Core/LC/OpenCL/win64/lib/bitcode/oclc_daz_opt_on.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/win64/lib/bitcode/oclc_finite_only_off.amdgcn.bc b/Core/LC/OpenCL/win64/lib/bitcode/oclc_finite_only_off.amdgcn.bc deleted file mode 100644 index c78b52a..0000000 Binary files a/Core/LC/OpenCL/win64/lib/bitcode/oclc_finite_only_off.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/win64/lib/bitcode/oclc_finite_only_on.amdgcn.bc b/Core/LC/OpenCL/win64/lib/bitcode/oclc_finite_only_on.amdgcn.bc deleted file mode 100644 index b0412b2..0000000 Binary files a/Core/LC/OpenCL/win64/lib/bitcode/oclc_finite_only_on.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/win64/lib/bitcode/oclc_isa_version_900.amdgcn.bc b/Core/LC/OpenCL/win64/lib/bitcode/oclc_isa_version_900.amdgcn.bc deleted file mode 100644 index 1a12a26..0000000 Binary files a/Core/LC/OpenCL/win64/lib/bitcode/oclc_isa_version_900.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/win64/lib/bitcode/oclc_isa_version_901.amdgcn.bc b/Core/LC/OpenCL/win64/lib/bitcode/oclc_isa_version_901.amdgcn.bc deleted file mode 100644 index 638a07b..0000000 Binary files a/Core/LC/OpenCL/win64/lib/bitcode/oclc_isa_version_901.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/win64/lib/bitcode/oclc_isa_version_902.amdgcn.bc b/Core/LC/OpenCL/win64/lib/bitcode/oclc_isa_version_902.amdgcn.bc deleted file mode 100644 index 6a152aa..0000000 Binary files a/Core/LC/OpenCL/win64/lib/bitcode/oclc_isa_version_902.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/win64/lib/bitcode/oclc_unsafe_math_off.amdgcn.bc b/Core/LC/OpenCL/win64/lib/bitcode/oclc_unsafe_math_off.amdgcn.bc deleted file mode 100644 index b273b70..0000000 Binary files a/Core/LC/OpenCL/win64/lib/bitcode/oclc_unsafe_math_off.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/win64/lib/bitcode/oclc_unsafe_math_on.amdgcn.bc b/Core/LC/OpenCL/win64/lib/bitcode/oclc_unsafe_math_on.amdgcn.bc deleted file mode 100644 index d8fd68d..0000000 Binary files a/Core/LC/OpenCL/win64/lib/bitcode/oclc_unsafe_math_on.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/win64/lib/bitcode/ocml.amdgcn.bc b/Core/LC/OpenCL/win64/lib/bitcode/ocml.amdgcn.bc deleted file mode 100644 index 1d9e555..0000000 Binary files a/Core/LC/OpenCL/win64/lib/bitcode/ocml.amdgcn.bc and /dev/null differ diff --git a/Core/LC/OpenCL/win64/lib/bitcode/opencl.amdgcn.bc b/Core/LC/OpenCL/win64/lib/bitcode/opencl.amdgcn.bc deleted file mode 100644 index a5d0f50..0000000 Binary files a/Core/LC/OpenCL/win64/lib/bitcode/opencl.amdgcn.bc and /dev/null differ diff --git a/Core/OpenGL/VirtualContext/Release/win32/VirtualContext.exe b/Core/OpenGL/VirtualContext/Release/win32/VirtualContext.exe deleted file mode 100644 index 1022883..0000000 Binary files a/Core/OpenGL/VirtualContext/Release/win32/VirtualContext.exe and /dev/null differ diff --git a/Core/ShaderAnalysis/Linux/x64/shae b/Core/ShaderAnalysis/Linux/x64/shae deleted file mode 100755 index a116aa1..0000000 Binary files a/Core/ShaderAnalysis/Linux/x64/shae and /dev/null differ diff --git a/Core/ShaderAnalysis/Windows/x64/shae.exe b/Core/ShaderAnalysis/Windows/x64/shae.exe deleted file mode 100644 index 89d8f6b..0000000 Binary files a/Core/ShaderAnalysis/Windows/x64/shae.exe and /dev/null differ diff --git a/Core/Vulkan/tools/Lnx64/bin/spirv-as b/Core/Vulkan/tools/Lnx64/bin/spirv-as deleted file mode 100644 index 0b38ef4..0000000 Binary files a/Core/Vulkan/tools/Lnx64/bin/spirv-as and /dev/null differ diff --git a/Core/Vulkan/tools/Lnx64/bin/spirv-dis b/Core/Vulkan/tools/Lnx64/bin/spirv-dis deleted file mode 100644 index 68638af..0000000 Binary files a/Core/Vulkan/tools/Lnx64/bin/spirv-dis and /dev/null differ diff --git a/Core/Vulkan/tools/Lnx64/lib/libspirv-cross-core.a b/Core/Vulkan/tools/Lnx64/lib/libspirv-cross-core.a deleted file mode 100644 index 5fa5ea1..0000000 Binary files a/Core/Vulkan/tools/Lnx64/lib/libspirv-cross-core.a and /dev/null differ diff --git a/Core/Vulkan/tools/Win64/bin/glslangValidator.exe b/Core/Vulkan/tools/Win64/bin/glslangValidator.exe deleted file mode 100644 index 8d258ee..0000000 Binary files a/Core/Vulkan/tools/Win64/bin/glslangValidator.exe and /dev/null differ diff --git a/Core/Vulkan/tools/Win64/bin/spirv-as.exe b/Core/Vulkan/tools/Win64/bin/spirv-as.exe deleted file mode 100644 index 0872eef..0000000 Binary files a/Core/Vulkan/tools/Win64/bin/spirv-as.exe and /dev/null differ diff --git a/Core/Vulkan/tools/Win64/bin/spirv-dis.exe b/Core/Vulkan/tools/Win64/bin/spirv-dis.exe deleted file mode 100644 index 16beee5..0000000 Binary files a/Core/Vulkan/tools/Win64/bin/spirv-dis.exe and /dev/null differ diff --git a/Core/Vulkan/tools/Win64/lib/Release/spirv-cross-core.lib b/Core/Vulkan/tools/Win64/lib/Release/spirv-cross-core.lib deleted file mode 100644 index d068a31..0000000 Binary files a/Core/Vulkan/tools/Win64/lib/Release/spirv-cross-core.lib and /dev/null differ diff --git a/Core/Vulkan/tools/include/spirv_cross/spirv.hpp b/Core/Vulkan/tools/include/spirv_cross/spirv.hpp deleted file mode 100644 index 1fc24fb..0000000 --- a/Core/Vulkan/tools/include/spirv_cross/spirv.hpp +++ /dev/null @@ -1,1081 +0,0 @@ -// Copyright (c) 2014-2018 The Khronos Group Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and/or associated documentation files (the "Materials"), -// to deal in the Materials without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Materials, and to permit persons to whom the -// Materials are furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Materials. -// -// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS -// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND -// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ -// -// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS -// IN THE MATERIALS. - -// This header is automatically generated by the same tool that creates -// the Binary Section of the SPIR-V specification. - -// Enumeration tokens for SPIR-V, in various styles: -// C, C++, C++11, JSON, Lua, Python -// -// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL -// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL -// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL -// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL -// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] -// -// Some tokens act like mask values, which can be OR'd together, -// while others are mutually exclusive. The mask-like ones have -// "Mask" in their name, and a parallel enum that has the shift -// amount (1 << x) for each corresponding enumerant. - -#ifndef spirv_HPP -#define spirv_HPP - -namespace spv { - -typedef unsigned int Id; - -#define SPV_VERSION 0x10300 -#define SPV_REVISION 1 - -static const unsigned int MagicNumber = 0x07230203; -static const unsigned int Version = 0x00010300; -static const unsigned int Revision = 1; -static const unsigned int OpCodeMask = 0xffff; -static const unsigned int WordCountShift = 16; - -enum SourceLanguage { - SourceLanguageUnknown = 0, - SourceLanguageESSL = 1, - SourceLanguageGLSL = 2, - SourceLanguageOpenCL_C = 3, - SourceLanguageOpenCL_CPP = 4, - SourceLanguageHLSL = 5, - SourceLanguageMax = 0x7fffffff, -}; - -enum ExecutionModel { - ExecutionModelVertex = 0, - ExecutionModelTessellationControl = 1, - ExecutionModelTessellationEvaluation = 2, - ExecutionModelGeometry = 3, - ExecutionModelFragment = 4, - ExecutionModelGLCompute = 5, - ExecutionModelKernel = 6, - ExecutionModelMax = 0x7fffffff, -}; - -enum AddressingModel { - AddressingModelLogical = 0, - AddressingModelPhysical32 = 1, - AddressingModelPhysical64 = 2, - AddressingModelMax = 0x7fffffff, -}; - -enum MemoryModel { - MemoryModelSimple = 0, - MemoryModelGLSL450 = 1, - MemoryModelOpenCL = 2, - MemoryModelMax = 0x7fffffff, -}; - -enum ExecutionMode { - ExecutionModeInvocations = 0, - ExecutionModeSpacingEqual = 1, - ExecutionModeSpacingFractionalEven = 2, - ExecutionModeSpacingFractionalOdd = 3, - ExecutionModeVertexOrderCw = 4, - ExecutionModeVertexOrderCcw = 5, - ExecutionModePixelCenterInteger = 6, - ExecutionModeOriginUpperLeft = 7, - ExecutionModeOriginLowerLeft = 8, - ExecutionModeEarlyFragmentTests = 9, - ExecutionModePointMode = 10, - ExecutionModeXfb = 11, - ExecutionModeDepthReplacing = 12, - ExecutionModeDepthGreater = 14, - ExecutionModeDepthLess = 15, - ExecutionModeDepthUnchanged = 16, - ExecutionModeLocalSize = 17, - ExecutionModeLocalSizeHint = 18, - ExecutionModeInputPoints = 19, - ExecutionModeInputLines = 20, - ExecutionModeInputLinesAdjacency = 21, - ExecutionModeTriangles = 22, - ExecutionModeInputTrianglesAdjacency = 23, - ExecutionModeQuads = 24, - ExecutionModeIsolines = 25, - ExecutionModeOutputVertices = 26, - ExecutionModeOutputPoints = 27, - ExecutionModeOutputLineStrip = 28, - ExecutionModeOutputTriangleStrip = 29, - ExecutionModeVecTypeHint = 30, - ExecutionModeContractionOff = 31, - ExecutionModeInitializer = 33, - ExecutionModeFinalizer = 34, - ExecutionModeSubgroupSize = 35, - ExecutionModeSubgroupsPerWorkgroup = 36, - ExecutionModeSubgroupsPerWorkgroupId = 37, - ExecutionModeLocalSizeId = 38, - ExecutionModeLocalSizeHintId = 39, - ExecutionModePostDepthCoverage = 4446, - ExecutionModeStencilRefReplacingEXT = 5027, - ExecutionModeMax = 0x7fffffff, -}; - -enum StorageClass { - StorageClassUniformConstant = 0, - StorageClassInput = 1, - StorageClassUniform = 2, - StorageClassOutput = 3, - StorageClassWorkgroup = 4, - StorageClassCrossWorkgroup = 5, - StorageClassPrivate = 6, - StorageClassFunction = 7, - StorageClassGeneric = 8, - StorageClassPushConstant = 9, - StorageClassAtomicCounter = 10, - StorageClassImage = 11, - StorageClassStorageBuffer = 12, - StorageClassMax = 0x7fffffff, -}; - -enum Dim { - Dim1D = 0, - Dim2D = 1, - Dim3D = 2, - DimCube = 3, - DimRect = 4, - DimBuffer = 5, - DimSubpassData = 6, - DimMax = 0x7fffffff, -}; - -enum SamplerAddressingMode { - SamplerAddressingModeNone = 0, - SamplerAddressingModeClampToEdge = 1, - SamplerAddressingModeClamp = 2, - SamplerAddressingModeRepeat = 3, - SamplerAddressingModeRepeatMirrored = 4, - SamplerAddressingModeMax = 0x7fffffff, -}; - -enum SamplerFilterMode { - SamplerFilterModeNearest = 0, - SamplerFilterModeLinear = 1, - SamplerFilterModeMax = 0x7fffffff, -}; - -enum ImageFormat { - ImageFormatUnknown = 0, - ImageFormatRgba32f = 1, - ImageFormatRgba16f = 2, - ImageFormatR32f = 3, - ImageFormatRgba8 = 4, - ImageFormatRgba8Snorm = 5, - ImageFormatRg32f = 6, - ImageFormatRg16f = 7, - ImageFormatR11fG11fB10f = 8, - ImageFormatR16f = 9, - ImageFormatRgba16 = 10, - ImageFormatRgb10A2 = 11, - ImageFormatRg16 = 12, - ImageFormatRg8 = 13, - ImageFormatR16 = 14, - ImageFormatR8 = 15, - ImageFormatRgba16Snorm = 16, - ImageFormatRg16Snorm = 17, - ImageFormatRg8Snorm = 18, - ImageFormatR16Snorm = 19, - ImageFormatR8Snorm = 20, - ImageFormatRgba32i = 21, - ImageFormatRgba16i = 22, - ImageFormatRgba8i = 23, - ImageFormatR32i = 24, - ImageFormatRg32i = 25, - ImageFormatRg16i = 26, - ImageFormatRg8i = 27, - ImageFormatR16i = 28, - ImageFormatR8i = 29, - ImageFormatRgba32ui = 30, - ImageFormatRgba16ui = 31, - ImageFormatRgba8ui = 32, - ImageFormatR32ui = 33, - ImageFormatRgb10a2ui = 34, - ImageFormatRg32ui = 35, - ImageFormatRg16ui = 36, - ImageFormatRg8ui = 37, - ImageFormatR16ui = 38, - ImageFormatR8ui = 39, - ImageFormatMax = 0x7fffffff, -}; - -enum ImageChannelOrder { - ImageChannelOrderR = 0, - ImageChannelOrderA = 1, - ImageChannelOrderRG = 2, - ImageChannelOrderRA = 3, - ImageChannelOrderRGB = 4, - ImageChannelOrderRGBA = 5, - ImageChannelOrderBGRA = 6, - ImageChannelOrderARGB = 7, - ImageChannelOrderIntensity = 8, - ImageChannelOrderLuminance = 9, - ImageChannelOrderRx = 10, - ImageChannelOrderRGx = 11, - ImageChannelOrderRGBx = 12, - ImageChannelOrderDepth = 13, - ImageChannelOrderDepthStencil = 14, - ImageChannelOrdersRGB = 15, - ImageChannelOrdersRGBx = 16, - ImageChannelOrdersRGBA = 17, - ImageChannelOrdersBGRA = 18, - ImageChannelOrderABGR = 19, - ImageChannelOrderMax = 0x7fffffff, -}; - -enum ImageChannelDataType { - ImageChannelDataTypeSnormInt8 = 0, - ImageChannelDataTypeSnormInt16 = 1, - ImageChannelDataTypeUnormInt8 = 2, - ImageChannelDataTypeUnormInt16 = 3, - ImageChannelDataTypeUnormShort565 = 4, - ImageChannelDataTypeUnormShort555 = 5, - ImageChannelDataTypeUnormInt101010 = 6, - ImageChannelDataTypeSignedInt8 = 7, - ImageChannelDataTypeSignedInt16 = 8, - ImageChannelDataTypeSignedInt32 = 9, - ImageChannelDataTypeUnsignedInt8 = 10, - ImageChannelDataTypeUnsignedInt16 = 11, - ImageChannelDataTypeUnsignedInt32 = 12, - ImageChannelDataTypeHalfFloat = 13, - ImageChannelDataTypeFloat = 14, - ImageChannelDataTypeUnormInt24 = 15, - ImageChannelDataTypeUnormInt101010_2 = 16, - ImageChannelDataTypeMax = 0x7fffffff, -}; - -enum ImageOperandsShift { - ImageOperandsBiasShift = 0, - ImageOperandsLodShift = 1, - ImageOperandsGradShift = 2, - ImageOperandsConstOffsetShift = 3, - ImageOperandsOffsetShift = 4, - ImageOperandsConstOffsetsShift = 5, - ImageOperandsSampleShift = 6, - ImageOperandsMinLodShift = 7, - ImageOperandsMax = 0x7fffffff, -}; - -enum ImageOperandsMask { - ImageOperandsMaskNone = 0, - ImageOperandsBiasMask = 0x00000001, - ImageOperandsLodMask = 0x00000002, - ImageOperandsGradMask = 0x00000004, - ImageOperandsConstOffsetMask = 0x00000008, - ImageOperandsOffsetMask = 0x00000010, - ImageOperandsConstOffsetsMask = 0x00000020, - ImageOperandsSampleMask = 0x00000040, - ImageOperandsMinLodMask = 0x00000080, -}; - -enum FPFastMathModeShift { - FPFastMathModeNotNaNShift = 0, - FPFastMathModeNotInfShift = 1, - FPFastMathModeNSZShift = 2, - FPFastMathModeAllowRecipShift = 3, - FPFastMathModeFastShift = 4, - FPFastMathModeMax = 0x7fffffff, -}; - -enum FPFastMathModeMask { - FPFastMathModeMaskNone = 0, - FPFastMathModeNotNaNMask = 0x00000001, - FPFastMathModeNotInfMask = 0x00000002, - FPFastMathModeNSZMask = 0x00000004, - FPFastMathModeAllowRecipMask = 0x00000008, - FPFastMathModeFastMask = 0x00000010, -}; - -enum FPRoundingMode { - FPRoundingModeRTE = 0, - FPRoundingModeRTZ = 1, - FPRoundingModeRTP = 2, - FPRoundingModeRTN = 3, - FPRoundingModeMax = 0x7fffffff, -}; - -enum LinkageType { - LinkageTypeExport = 0, - LinkageTypeImport = 1, - LinkageTypeMax = 0x7fffffff, -}; - -enum AccessQualifier { - AccessQualifierReadOnly = 0, - AccessQualifierWriteOnly = 1, - AccessQualifierReadWrite = 2, - AccessQualifierMax = 0x7fffffff, -}; - -enum FunctionParameterAttribute { - FunctionParameterAttributeZext = 0, - FunctionParameterAttributeSext = 1, - FunctionParameterAttributeByVal = 2, - FunctionParameterAttributeSret = 3, - FunctionParameterAttributeNoAlias = 4, - FunctionParameterAttributeNoCapture = 5, - FunctionParameterAttributeNoWrite = 6, - FunctionParameterAttributeNoReadWrite = 7, - FunctionParameterAttributeMax = 0x7fffffff, -}; - -enum Decoration { - DecorationRelaxedPrecision = 0, - DecorationSpecId = 1, - DecorationBlock = 2, - DecorationBufferBlock = 3, - DecorationRowMajor = 4, - DecorationColMajor = 5, - DecorationArrayStride = 6, - DecorationMatrixStride = 7, - DecorationGLSLShared = 8, - DecorationGLSLPacked = 9, - DecorationCPacked = 10, - DecorationBuiltIn = 11, - DecorationNoPerspective = 13, - DecorationFlat = 14, - DecorationPatch = 15, - DecorationCentroid = 16, - DecorationSample = 17, - DecorationInvariant = 18, - DecorationRestrict = 19, - DecorationAliased = 20, - DecorationVolatile = 21, - DecorationConstant = 22, - DecorationCoherent = 23, - DecorationNonWritable = 24, - DecorationNonReadable = 25, - DecorationUniform = 26, - DecorationSaturatedConversion = 28, - DecorationStream = 29, - DecorationLocation = 30, - DecorationComponent = 31, - DecorationIndex = 32, - DecorationBinding = 33, - DecorationDescriptorSet = 34, - DecorationOffset = 35, - DecorationXfbBuffer = 36, - DecorationXfbStride = 37, - DecorationFuncParamAttr = 38, - DecorationFPRoundingMode = 39, - DecorationFPFastMathMode = 40, - DecorationLinkageAttributes = 41, - DecorationNoContraction = 42, - DecorationInputAttachmentIndex = 43, - DecorationAlignment = 44, - DecorationMaxByteOffset = 45, - DecorationAlignmentId = 46, - DecorationMaxByteOffsetId = 47, - DecorationExplicitInterpAMD = 4999, - DecorationOverrideCoverageNV = 5248, - DecorationPassthroughNV = 5250, - DecorationViewportRelativeNV = 5252, - DecorationSecondaryViewportRelativeNV = 5256, - DecorationHlslCounterBufferGOOGLE = 5634, - DecorationHlslSemanticGOOGLE = 5635, - DecorationMax = 0x7fffffff, -}; - -enum BuiltIn { - BuiltInPosition = 0, - BuiltInPointSize = 1, - BuiltInClipDistance = 3, - BuiltInCullDistance = 4, - BuiltInVertexId = 5, - BuiltInInstanceId = 6, - BuiltInPrimitiveId = 7, - BuiltInInvocationId = 8, - BuiltInLayer = 9, - BuiltInViewportIndex = 10, - BuiltInTessLevelOuter = 11, - BuiltInTessLevelInner = 12, - BuiltInTessCoord = 13, - BuiltInPatchVertices = 14, - BuiltInFragCoord = 15, - BuiltInPointCoord = 16, - BuiltInFrontFacing = 17, - BuiltInSampleId = 18, - BuiltInSamplePosition = 19, - BuiltInSampleMask = 20, - BuiltInFragDepth = 22, - BuiltInHelperInvocation = 23, - BuiltInNumWorkgroups = 24, - BuiltInWorkgroupSize = 25, - BuiltInWorkgroupId = 26, - BuiltInLocalInvocationId = 27, - BuiltInGlobalInvocationId = 28, - BuiltInLocalInvocationIndex = 29, - BuiltInWorkDim = 30, - BuiltInGlobalSize = 31, - BuiltInEnqueuedWorkgroupSize = 32, - BuiltInGlobalOffset = 33, - BuiltInGlobalLinearId = 34, - BuiltInSubgroupSize = 36, - BuiltInSubgroupMaxSize = 37, - BuiltInNumSubgroups = 38, - BuiltInNumEnqueuedSubgroups = 39, - BuiltInSubgroupId = 40, - BuiltInSubgroupLocalInvocationId = 41, - BuiltInVertexIndex = 42, - BuiltInInstanceIndex = 43, - BuiltInSubgroupEqMask = 4416, - BuiltInSubgroupEqMaskKHR = 4416, - BuiltInSubgroupGeMask = 4417, - BuiltInSubgroupGeMaskKHR = 4417, - BuiltInSubgroupGtMask = 4418, - BuiltInSubgroupGtMaskKHR = 4418, - BuiltInSubgroupLeMask = 4419, - BuiltInSubgroupLeMaskKHR = 4419, - BuiltInSubgroupLtMask = 4420, - BuiltInSubgroupLtMaskKHR = 4420, - BuiltInBaseVertex = 4424, - BuiltInBaseInstance = 4425, - BuiltInDrawIndex = 4426, - BuiltInDeviceIndex = 4438, - BuiltInViewIndex = 4440, - BuiltInBaryCoordNoPerspAMD = 4992, - BuiltInBaryCoordNoPerspCentroidAMD = 4993, - BuiltInBaryCoordNoPerspSampleAMD = 4994, - BuiltInBaryCoordSmoothAMD = 4995, - BuiltInBaryCoordSmoothCentroidAMD = 4996, - BuiltInBaryCoordSmoothSampleAMD = 4997, - BuiltInBaryCoordPullModelAMD = 4998, - BuiltInFragStencilRefEXT = 5014, - BuiltInViewportMaskNV = 5253, - BuiltInSecondaryPositionNV = 5257, - BuiltInSecondaryViewportMaskNV = 5258, - BuiltInPositionPerViewNV = 5261, - BuiltInViewportMaskPerViewNV = 5262, - BuiltInFullyCoveredEXT = 5264, - BuiltInMax = 0x7fffffff, -}; - -enum SelectionControlShift { - SelectionControlFlattenShift = 0, - SelectionControlDontFlattenShift = 1, - SelectionControlMax = 0x7fffffff, -}; - -enum SelectionControlMask { - SelectionControlMaskNone = 0, - SelectionControlFlattenMask = 0x00000001, - SelectionControlDontFlattenMask = 0x00000002, -}; - -enum LoopControlShift { - LoopControlUnrollShift = 0, - LoopControlDontUnrollShift = 1, - LoopControlDependencyInfiniteShift = 2, - LoopControlDependencyLengthShift = 3, - LoopControlMax = 0x7fffffff, -}; - -enum LoopControlMask { - LoopControlMaskNone = 0, - LoopControlUnrollMask = 0x00000001, - LoopControlDontUnrollMask = 0x00000002, - LoopControlDependencyInfiniteMask = 0x00000004, - LoopControlDependencyLengthMask = 0x00000008, -}; - -enum FunctionControlShift { - FunctionControlInlineShift = 0, - FunctionControlDontInlineShift = 1, - FunctionControlPureShift = 2, - FunctionControlConstShift = 3, - FunctionControlMax = 0x7fffffff, -}; - -enum FunctionControlMask { - FunctionControlMaskNone = 0, - FunctionControlInlineMask = 0x00000001, - FunctionControlDontInlineMask = 0x00000002, - FunctionControlPureMask = 0x00000004, - FunctionControlConstMask = 0x00000008, -}; - -enum MemorySemanticsShift { - MemorySemanticsAcquireShift = 1, - MemorySemanticsReleaseShift = 2, - MemorySemanticsAcquireReleaseShift = 3, - MemorySemanticsSequentiallyConsistentShift = 4, - MemorySemanticsUniformMemoryShift = 6, - MemorySemanticsSubgroupMemoryShift = 7, - MemorySemanticsWorkgroupMemoryShift = 8, - MemorySemanticsCrossWorkgroupMemoryShift = 9, - MemorySemanticsAtomicCounterMemoryShift = 10, - MemorySemanticsImageMemoryShift = 11, - MemorySemanticsMax = 0x7fffffff, -}; - -enum MemorySemanticsMask { - MemorySemanticsMaskNone = 0, - MemorySemanticsAcquireMask = 0x00000002, - MemorySemanticsReleaseMask = 0x00000004, - MemorySemanticsAcquireReleaseMask = 0x00000008, - MemorySemanticsSequentiallyConsistentMask = 0x00000010, - MemorySemanticsUniformMemoryMask = 0x00000040, - MemorySemanticsSubgroupMemoryMask = 0x00000080, - MemorySemanticsWorkgroupMemoryMask = 0x00000100, - MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, - MemorySemanticsAtomicCounterMemoryMask = 0x00000400, - MemorySemanticsImageMemoryMask = 0x00000800, -}; - -enum MemoryAccessShift { - MemoryAccessVolatileShift = 0, - MemoryAccessAlignedShift = 1, - MemoryAccessNontemporalShift = 2, - MemoryAccessMax = 0x7fffffff, -}; - -enum MemoryAccessMask { - MemoryAccessMaskNone = 0, - MemoryAccessVolatileMask = 0x00000001, - MemoryAccessAlignedMask = 0x00000002, - MemoryAccessNontemporalMask = 0x00000004, -}; - -enum Scope { - ScopeCrossDevice = 0, - ScopeDevice = 1, - ScopeWorkgroup = 2, - ScopeSubgroup = 3, - ScopeInvocation = 4, - ScopeMax = 0x7fffffff, -}; - -enum GroupOperation { - GroupOperationReduce = 0, - GroupOperationInclusiveScan = 1, - GroupOperationExclusiveScan = 2, - GroupOperationClusteredReduce = 3, - GroupOperationMax = 0x7fffffff, -}; - -enum KernelEnqueueFlags { - KernelEnqueueFlagsNoWait = 0, - KernelEnqueueFlagsWaitKernel = 1, - KernelEnqueueFlagsWaitWorkGroup = 2, - KernelEnqueueFlagsMax = 0x7fffffff, -}; - -enum KernelProfilingInfoShift { - KernelProfilingInfoCmdExecTimeShift = 0, - KernelProfilingInfoMax = 0x7fffffff, -}; - -enum KernelProfilingInfoMask { - KernelProfilingInfoMaskNone = 0, - KernelProfilingInfoCmdExecTimeMask = 0x00000001, -}; - -enum Capability { - CapabilityMatrix = 0, - CapabilityShader = 1, - CapabilityGeometry = 2, - CapabilityTessellation = 3, - CapabilityAddresses = 4, - CapabilityLinkage = 5, - CapabilityKernel = 6, - CapabilityVector16 = 7, - CapabilityFloat16Buffer = 8, - CapabilityFloat16 = 9, - CapabilityFloat64 = 10, - CapabilityInt64 = 11, - CapabilityInt64Atomics = 12, - CapabilityImageBasic = 13, - CapabilityImageReadWrite = 14, - CapabilityImageMipmap = 15, - CapabilityPipes = 17, - CapabilityGroups = 18, - CapabilityDeviceEnqueue = 19, - CapabilityLiteralSampler = 20, - CapabilityAtomicStorage = 21, - CapabilityInt16 = 22, - CapabilityTessellationPointSize = 23, - CapabilityGeometryPointSize = 24, - CapabilityImageGatherExtended = 25, - CapabilityStorageImageMultisample = 27, - CapabilityUniformBufferArrayDynamicIndexing = 28, - CapabilitySampledImageArrayDynamicIndexing = 29, - CapabilityStorageBufferArrayDynamicIndexing = 30, - CapabilityStorageImageArrayDynamicIndexing = 31, - CapabilityClipDistance = 32, - CapabilityCullDistance = 33, - CapabilityImageCubeArray = 34, - CapabilitySampleRateShading = 35, - CapabilityImageRect = 36, - CapabilitySampledRect = 37, - CapabilityGenericPointer = 38, - CapabilityInt8 = 39, - CapabilityInputAttachment = 40, - CapabilitySparseResidency = 41, - CapabilityMinLod = 42, - CapabilitySampled1D = 43, - CapabilityImage1D = 44, - CapabilitySampledCubeArray = 45, - CapabilitySampledBuffer = 46, - CapabilityImageBuffer = 47, - CapabilityImageMSArray = 48, - CapabilityStorageImageExtendedFormats = 49, - CapabilityImageQuery = 50, - CapabilityDerivativeControl = 51, - CapabilityInterpolationFunction = 52, - CapabilityTransformFeedback = 53, - CapabilityGeometryStreams = 54, - CapabilityStorageImageReadWithoutFormat = 55, - CapabilityStorageImageWriteWithoutFormat = 56, - CapabilityMultiViewport = 57, - CapabilitySubgroupDispatch = 58, - CapabilityNamedBarrier = 59, - CapabilityPipeStorage = 60, - CapabilityGroupNonUniform = 61, - CapabilityGroupNonUniformVote = 62, - CapabilityGroupNonUniformArithmetic = 63, - CapabilityGroupNonUniformBallot = 64, - CapabilityGroupNonUniformShuffle = 65, - CapabilityGroupNonUniformShuffleRelative = 66, - CapabilityGroupNonUniformClustered = 67, - CapabilityGroupNonUniformQuad = 68, - CapabilitySubgroupBallotKHR = 4423, - CapabilityDrawParameters = 4427, - CapabilitySubgroupVoteKHR = 4431, - CapabilityStorageBuffer16BitAccess = 4433, - CapabilityStorageUniformBufferBlock16 = 4433, - CapabilityStorageUniform16 = 4434, - CapabilityUniformAndStorageBuffer16BitAccess = 4434, - CapabilityStoragePushConstant16 = 4435, - CapabilityStorageInputOutput16 = 4436, - CapabilityDeviceGroup = 4437, - CapabilityMultiView = 4439, - CapabilityVariablePointersStorageBuffer = 4441, - CapabilityVariablePointers = 4442, - CapabilityAtomicStorageOps = 4445, - CapabilitySampleMaskPostDepthCoverage = 4447, - CapabilityFloat16ImageAMD = 5008, - CapabilityImageGatherBiasLodAMD = 5009, - CapabilityFragmentMaskAMD = 5010, - CapabilityStencilExportEXT = 5013, - CapabilityImageReadWriteLodAMD = 5015, - CapabilitySampleMaskOverrideCoverageNV = 5249, - CapabilityGeometryShaderPassthroughNV = 5251, - CapabilityShaderViewportIndexLayerEXT = 5254, - CapabilityShaderViewportIndexLayerNV = 5254, - CapabilityShaderViewportMaskNV = 5255, - CapabilityShaderStereoViewNV = 5259, - CapabilityPerViewAttributesNV = 5260, - CapabilityFragmentFullyCoveredEXT = 5265, - CapabilitySubgroupShuffleINTEL = 5568, - CapabilitySubgroupBufferBlockIOINTEL = 5569, - CapabilitySubgroupImageBlockIOINTEL = 5570, - CapabilityMax = 0x7fffffff, -}; - -enum Op { - OpNop = 0, - OpUndef = 1, - OpSourceContinued = 2, - OpSource = 3, - OpSourceExtension = 4, - OpName = 5, - OpMemberName = 6, - OpString = 7, - OpLine = 8, - OpExtension = 10, - OpExtInstImport = 11, - OpExtInst = 12, - OpMemoryModel = 14, - OpEntryPoint = 15, - OpExecutionMode = 16, - OpCapability = 17, - OpTypeVoid = 19, - OpTypeBool = 20, - OpTypeInt = 21, - OpTypeFloat = 22, - OpTypeVector = 23, - OpTypeMatrix = 24, - OpTypeImage = 25, - OpTypeSampler = 26, - OpTypeSampledImage = 27, - OpTypeArray = 28, - OpTypeRuntimeArray = 29, - OpTypeStruct = 30, - OpTypeOpaque = 31, - OpTypePointer = 32, - OpTypeFunction = 33, - OpTypeEvent = 34, - OpTypeDeviceEvent = 35, - OpTypeReserveId = 36, - OpTypeQueue = 37, - OpTypePipe = 38, - OpTypeForwardPointer = 39, - OpConstantTrue = 41, - OpConstantFalse = 42, - OpConstant = 43, - OpConstantComposite = 44, - OpConstantSampler = 45, - OpConstantNull = 46, - OpSpecConstantTrue = 48, - OpSpecConstantFalse = 49, - OpSpecConstant = 50, - OpSpecConstantComposite = 51, - OpSpecConstantOp = 52, - OpFunction = 54, - OpFunctionParameter = 55, - OpFunctionEnd = 56, - OpFunctionCall = 57, - OpVariable = 59, - OpImageTexelPointer = 60, - OpLoad = 61, - OpStore = 62, - OpCopyMemory = 63, - OpCopyMemorySized = 64, - OpAccessChain = 65, - OpInBoundsAccessChain = 66, - OpPtrAccessChain = 67, - OpArrayLength = 68, - OpGenericPtrMemSemantics = 69, - OpInBoundsPtrAccessChain = 70, - OpDecorate = 71, - OpMemberDecorate = 72, - OpDecorationGroup = 73, - OpGroupDecorate = 74, - OpGroupMemberDecorate = 75, - OpVectorExtractDynamic = 77, - OpVectorInsertDynamic = 78, - OpVectorShuffle = 79, - OpCompositeConstruct = 80, - OpCompositeExtract = 81, - OpCompositeInsert = 82, - OpCopyObject = 83, - OpTranspose = 84, - OpSampledImage = 86, - OpImageSampleImplicitLod = 87, - OpImageSampleExplicitLod = 88, - OpImageSampleDrefImplicitLod = 89, - OpImageSampleDrefExplicitLod = 90, - OpImageSampleProjImplicitLod = 91, - OpImageSampleProjExplicitLod = 92, - OpImageSampleProjDrefImplicitLod = 93, - OpImageSampleProjDrefExplicitLod = 94, - OpImageFetch = 95, - OpImageGather = 96, - OpImageDrefGather = 97, - OpImageRead = 98, - OpImageWrite = 99, - OpImage = 100, - OpImageQueryFormat = 101, - OpImageQueryOrder = 102, - OpImageQuerySizeLod = 103, - OpImageQuerySize = 104, - OpImageQueryLod = 105, - OpImageQueryLevels = 106, - OpImageQuerySamples = 107, - OpConvertFToU = 109, - OpConvertFToS = 110, - OpConvertSToF = 111, - OpConvertUToF = 112, - OpUConvert = 113, - OpSConvert = 114, - OpFConvert = 115, - OpQuantizeToF16 = 116, - OpConvertPtrToU = 117, - OpSatConvertSToU = 118, - OpSatConvertUToS = 119, - OpConvertUToPtr = 120, - OpPtrCastToGeneric = 121, - OpGenericCastToPtr = 122, - OpGenericCastToPtrExplicit = 123, - OpBitcast = 124, - OpSNegate = 126, - OpFNegate = 127, - OpIAdd = 128, - OpFAdd = 129, - OpISub = 130, - OpFSub = 131, - OpIMul = 132, - OpFMul = 133, - OpUDiv = 134, - OpSDiv = 135, - OpFDiv = 136, - OpUMod = 137, - OpSRem = 138, - OpSMod = 139, - OpFRem = 140, - OpFMod = 141, - OpVectorTimesScalar = 142, - OpMatrixTimesScalar = 143, - OpVectorTimesMatrix = 144, - OpMatrixTimesVector = 145, - OpMatrixTimesMatrix = 146, - OpOuterProduct = 147, - OpDot = 148, - OpIAddCarry = 149, - OpISubBorrow = 150, - OpUMulExtended = 151, - OpSMulExtended = 152, - OpAny = 154, - OpAll = 155, - OpIsNan = 156, - OpIsInf = 157, - OpIsFinite = 158, - OpIsNormal = 159, - OpSignBitSet = 160, - OpLessOrGreater = 161, - OpOrdered = 162, - OpUnordered = 163, - OpLogicalEqual = 164, - OpLogicalNotEqual = 165, - OpLogicalOr = 166, - OpLogicalAnd = 167, - OpLogicalNot = 168, - OpSelect = 169, - OpIEqual = 170, - OpINotEqual = 171, - OpUGreaterThan = 172, - OpSGreaterThan = 173, - OpUGreaterThanEqual = 174, - OpSGreaterThanEqual = 175, - OpULessThan = 176, - OpSLessThan = 177, - OpULessThanEqual = 178, - OpSLessThanEqual = 179, - OpFOrdEqual = 180, - OpFUnordEqual = 181, - OpFOrdNotEqual = 182, - OpFUnordNotEqual = 183, - OpFOrdLessThan = 184, - OpFUnordLessThan = 185, - OpFOrdGreaterThan = 186, - OpFUnordGreaterThan = 187, - OpFOrdLessThanEqual = 188, - OpFUnordLessThanEqual = 189, - OpFOrdGreaterThanEqual = 190, - OpFUnordGreaterThanEqual = 191, - OpShiftRightLogical = 194, - OpShiftRightArithmetic = 195, - OpShiftLeftLogical = 196, - OpBitwiseOr = 197, - OpBitwiseXor = 198, - OpBitwiseAnd = 199, - OpNot = 200, - OpBitFieldInsert = 201, - OpBitFieldSExtract = 202, - OpBitFieldUExtract = 203, - OpBitReverse = 204, - OpBitCount = 205, - OpDPdx = 207, - OpDPdy = 208, - OpFwidth = 209, - OpDPdxFine = 210, - OpDPdyFine = 211, - OpFwidthFine = 212, - OpDPdxCoarse = 213, - OpDPdyCoarse = 214, - OpFwidthCoarse = 215, - OpEmitVertex = 218, - OpEndPrimitive = 219, - OpEmitStreamVertex = 220, - OpEndStreamPrimitive = 221, - OpControlBarrier = 224, - OpMemoryBarrier = 225, - OpAtomicLoad = 227, - OpAtomicStore = 228, - OpAtomicExchange = 229, - OpAtomicCompareExchange = 230, - OpAtomicCompareExchangeWeak = 231, - OpAtomicIIncrement = 232, - OpAtomicIDecrement = 233, - OpAtomicIAdd = 234, - OpAtomicISub = 235, - OpAtomicSMin = 236, - OpAtomicUMin = 237, - OpAtomicSMax = 238, - OpAtomicUMax = 239, - OpAtomicAnd = 240, - OpAtomicOr = 241, - OpAtomicXor = 242, - OpPhi = 245, - OpLoopMerge = 246, - OpSelectionMerge = 247, - OpLabel = 248, - OpBranch = 249, - OpBranchConditional = 250, - OpSwitch = 251, - OpKill = 252, - OpReturn = 253, - OpReturnValue = 254, - OpUnreachable = 255, - OpLifetimeStart = 256, - OpLifetimeStop = 257, - OpGroupAsyncCopy = 259, - OpGroupWaitEvents = 260, - OpGroupAll = 261, - OpGroupAny = 262, - OpGroupBroadcast = 263, - OpGroupIAdd = 264, - OpGroupFAdd = 265, - OpGroupFMin = 266, - OpGroupUMin = 267, - OpGroupSMin = 268, - OpGroupFMax = 269, - OpGroupUMax = 270, - OpGroupSMax = 271, - OpReadPipe = 274, - OpWritePipe = 275, - OpReservedReadPipe = 276, - OpReservedWritePipe = 277, - OpReserveReadPipePackets = 278, - OpReserveWritePipePackets = 279, - OpCommitReadPipe = 280, - OpCommitWritePipe = 281, - OpIsValidReserveId = 282, - OpGetNumPipePackets = 283, - OpGetMaxPipePackets = 284, - OpGroupReserveReadPipePackets = 285, - OpGroupReserveWritePipePackets = 286, - OpGroupCommitReadPipe = 287, - OpGroupCommitWritePipe = 288, - OpEnqueueMarker = 291, - OpEnqueueKernel = 292, - OpGetKernelNDrangeSubGroupCount = 293, - OpGetKernelNDrangeMaxSubGroupSize = 294, - OpGetKernelWorkGroupSize = 295, - OpGetKernelPreferredWorkGroupSizeMultiple = 296, - OpRetainEvent = 297, - OpReleaseEvent = 298, - OpCreateUserEvent = 299, - OpIsValidEvent = 300, - OpSetUserEventStatus = 301, - OpCaptureEventProfilingInfo = 302, - OpGetDefaultQueue = 303, - OpBuildNDRange = 304, - OpImageSparseSampleImplicitLod = 305, - OpImageSparseSampleExplicitLod = 306, - OpImageSparseSampleDrefImplicitLod = 307, - OpImageSparseSampleDrefExplicitLod = 308, - OpImageSparseSampleProjImplicitLod = 309, - OpImageSparseSampleProjExplicitLod = 310, - OpImageSparseSampleProjDrefImplicitLod = 311, - OpImageSparseSampleProjDrefExplicitLod = 312, - OpImageSparseFetch = 313, - OpImageSparseGather = 314, - OpImageSparseDrefGather = 315, - OpImageSparseTexelsResident = 316, - OpNoLine = 317, - OpAtomicFlagTestAndSet = 318, - OpAtomicFlagClear = 319, - OpImageSparseRead = 320, - OpSizeOf = 321, - OpTypePipeStorage = 322, - OpConstantPipeStorage = 323, - OpCreatePipeFromPipeStorage = 324, - OpGetKernelLocalSizeForSubgroupCount = 325, - OpGetKernelMaxNumSubgroups = 326, - OpTypeNamedBarrier = 327, - OpNamedBarrierInitialize = 328, - OpMemoryNamedBarrier = 329, - OpModuleProcessed = 330, - OpExecutionModeId = 331, - OpDecorateId = 332, - OpGroupNonUniformElect = 333, - OpGroupNonUniformAll = 334, - OpGroupNonUniformAny = 335, - OpGroupNonUniformAllEqual = 336, - OpGroupNonUniformBroadcast = 337, - OpGroupNonUniformBroadcastFirst = 338, - OpGroupNonUniformBallot = 339, - OpGroupNonUniformInverseBallot = 340, - OpGroupNonUniformBallotBitExtract = 341, - OpGroupNonUniformBallotBitCount = 342, - OpGroupNonUniformBallotFindLSB = 343, - OpGroupNonUniformBallotFindMSB = 344, - OpGroupNonUniformShuffle = 345, - OpGroupNonUniformShuffleXor = 346, - OpGroupNonUniformShuffleUp = 347, - OpGroupNonUniformShuffleDown = 348, - OpGroupNonUniformIAdd = 349, - OpGroupNonUniformFAdd = 350, - OpGroupNonUniformIMul = 351, - OpGroupNonUniformFMul = 352, - OpGroupNonUniformSMin = 353, - OpGroupNonUniformUMin = 354, - OpGroupNonUniformFMin = 355, - OpGroupNonUniformSMax = 356, - OpGroupNonUniformUMax = 357, - OpGroupNonUniformFMax = 358, - OpGroupNonUniformBitwiseAnd = 359, - OpGroupNonUniformBitwiseOr = 360, - OpGroupNonUniformBitwiseXor = 361, - OpGroupNonUniformLogicalAnd = 362, - OpGroupNonUniformLogicalOr = 363, - OpGroupNonUniformLogicalXor = 364, - OpGroupNonUniformQuadBroadcast = 365, - OpGroupNonUniformQuadSwap = 366, - OpSubgroupBallotKHR = 4421, - OpSubgroupFirstInvocationKHR = 4422, - OpSubgroupAllKHR = 4428, - OpSubgroupAnyKHR = 4429, - OpSubgroupAllEqualKHR = 4430, - OpSubgroupReadInvocationKHR = 4432, - OpGroupIAddNonUniformAMD = 5000, - OpGroupFAddNonUniformAMD = 5001, - OpGroupFMinNonUniformAMD = 5002, - OpGroupUMinNonUniformAMD = 5003, - OpGroupSMinNonUniformAMD = 5004, - OpGroupFMaxNonUniformAMD = 5005, - OpGroupUMaxNonUniformAMD = 5006, - OpGroupSMaxNonUniformAMD = 5007, - OpFragmentMaskFetchAMD = 5011, - OpFragmentFetchAMD = 5012, - OpSubgroupShuffleINTEL = 5571, - OpSubgroupShuffleDownINTEL = 5572, - OpSubgroupShuffleUpINTEL = 5573, - OpSubgroupShuffleXorINTEL = 5574, - OpSubgroupBlockReadINTEL = 5575, - OpSubgroupBlockWriteINTEL = 5576, - OpSubgroupImageBlockReadINTEL = 5577, - OpSubgroupImageBlockWriteINTEL = 5578, - OpDecorateStringGOOGLE = 5632, - OpMemberDecorateStringGOOGLE = 5633, - OpMax = 0x7fffffff, -}; - -// Overload operator| for mask bit combining - -inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } -inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } -inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } -inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } -inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } -inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } -inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } -inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } - -} // end namespace spv - -#endif // #ifndef spirv_HPP - diff --git a/Core/Vulkan/tools/include/spirv_cross/spirv_common.hpp b/Core/Vulkan/tools/include/spirv_cross/spirv_common.hpp deleted file mode 100644 index 6e783dd..0000000 --- a/Core/Vulkan/tools/include/spirv_cross/spirv_common.hpp +++ /dev/null @@ -1,1280 +0,0 @@ -/* - * Copyright 2015-2018 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SPIRV_CROSS_COMMON_HPP -#define SPIRV_CROSS_COMMON_HPP - -#include "spirv.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace spirv_cross -{ - -#ifdef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS -#ifndef _MSC_VER -[[noreturn]] -#endif - inline void - report_and_abort(const std::string &msg) -{ -#ifdef NDEBUG - (void)msg; -#else - fprintf(stderr, "There was a compiler error: %s\n", msg.c_str()); -#endif - fflush(stderr); - abort(); -} - -#define SPIRV_CROSS_THROW(x) report_and_abort(x) -#else -class CompilerError : public std::runtime_error -{ -public: - CompilerError(const std::string &str) - : std::runtime_error(str) - { - } -}; - -#define SPIRV_CROSS_THROW(x) throw CompilerError(x) -#endif - -#if __cplusplus >= 201402l -#define SPIRV_CROSS_DEPRECATED(reason) [[deprecated(reason)]] -#elif defined(__GNUC__) -#define SPIRV_CROSS_DEPRECATED(reason) __attribute__((deprecated)) -#elif defined(_MSC_VER) -#define SPIRV_CROSS_DEPRECATED(reason) __declspec(deprecated(reason)) -#else -#define SPIRV_CROSS_DEPRECATED(reason) -#endif - -namespace inner -{ -template -void join_helper(std::ostringstream &stream, T &&t) -{ - stream << std::forward(t); -} - -template -void join_helper(std::ostringstream &stream, T &&t, Ts &&... ts) -{ - stream << std::forward(t); - join_helper(stream, std::forward(ts)...); -} -} // namespace inner - -class Bitset -{ -public: - Bitset() = default; - explicit inline Bitset(uint64_t lower_) - : lower(lower_) - { - } - - inline bool get(uint32_t bit) const - { - if (bit < 64) - return (lower & (1ull << bit)) != 0; - else - return higher.count(bit) != 0; - } - - inline void set(uint32_t bit) - { - if (bit < 64) - lower |= 1ull << bit; - else - higher.insert(bit); - } - - inline void clear(uint32_t bit) - { - if (bit < 64) - lower &= ~(1ull << bit); - else - higher.erase(bit); - } - - inline uint64_t get_lower() const - { - return lower; - } - - inline void reset() - { - lower = 0; - higher.clear(); - } - - inline void merge_and(const Bitset &other) - { - lower &= other.lower; - std::unordered_set tmp_set; - for (auto &v : higher) - if (other.higher.count(v) != 0) - tmp_set.insert(v); - higher = std::move(tmp_set); - } - - inline void merge_or(const Bitset &other) - { - lower |= other.lower; - for (auto &v : other.higher) - higher.insert(v); - } - - inline bool operator==(const Bitset &other) const - { - if (lower != other.lower) - return false; - - if (higher.size() != other.higher.size()) - return false; - - for (auto &v : higher) - if (other.higher.count(v) == 0) - return false; - - return true; - } - - inline bool operator!=(const Bitset &other) const - { - return !(*this == other); - } - - template - void for_each_bit(const Op &op) const - { - // TODO: Add ctz-based iteration. - for (uint32_t i = 0; i < 64; i++) - { - if (lower & (1ull << i)) - op(i); - } - - if (higher.empty()) - return; - - // Need to enforce an order here for reproducible results, - // but hitting this path should happen extremely rarely, so having this slow path is fine. - std::vector bits; - bits.reserve(higher.size()); - for (auto &v : higher) - bits.push_back(v); - std::sort(std::begin(bits), std::end(bits)); - - for (auto &v : bits) - op(v); - } - - inline bool empty() const - { - return lower == 0 && higher.empty(); - } - -private: - // The most common bits to set are all lower than 64, - // so optimize for this case. Bits spilling outside 64 go into a slower data structure. - // In almost all cases, higher data structure will not be used. - uint64_t lower = 0; - std::unordered_set higher; -}; - -// Helper template to avoid lots of nasty string temporary munging. -template -std::string join(Ts &&... ts) -{ - std::ostringstream stream; - inner::join_helper(stream, std::forward(ts)...); - return stream.str(); -} - -inline std::string merge(const std::vector &list) -{ - std::string s; - for (auto &elem : list) - { - s += elem; - if (&elem != &list.back()) - s += ", "; - } - return s; -} - -template -inline std::string convert_to_string(T &&t) -{ - return std::to_string(std::forward(t)); -} - -// Allow implementations to set a convenient standard precision -#ifndef SPIRV_CROSS_FLT_FMT -#define SPIRV_CROSS_FLT_FMT "%.32g" -#endif - -#ifdef _MSC_VER -// sprintf warning. -// We cannot rely on snprintf existing because, ..., MSVC. -#pragma warning(push) -#pragma warning(disable : 4996) -#endif - -inline std::string convert_to_string(float t) -{ - // std::to_string for floating point values is broken. - // Fallback to something more sane. - char buf[64]; - sprintf(buf, SPIRV_CROSS_FLT_FMT, t); - // Ensure that the literal is float. - if (!strchr(buf, '.') && !strchr(buf, 'e')) - strcat(buf, ".0"); - return buf; -} - -inline std::string convert_to_string(double t) -{ - // std::to_string for floating point values is broken. - // Fallback to something more sane. - char buf[64]; - sprintf(buf, SPIRV_CROSS_FLT_FMT, t); - // Ensure that the literal is float. - if (!strchr(buf, '.') && !strchr(buf, 'e')) - strcat(buf, ".0"); - return buf; -} - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -struct Instruction -{ - Instruction(const std::vector &spirv, uint32_t &index); - - uint16_t op; - uint16_t count; - uint32_t offset; - uint32_t length; -}; - -// Helper for Variant interface. -struct IVariant -{ - virtual ~IVariant() = default; - uint32_t self = 0; -}; - -enum Types -{ - TypeNone, - TypeType, - TypeVariable, - TypeConstant, - TypeFunction, - TypeFunctionPrototype, - TypePointer, - TypeBlock, - TypeExtension, - TypeExpression, - TypeConstantOp, - TypeCombinedImageSampler, - TypeAccessChain, - TypeUndef -}; - -struct SPIRUndef : IVariant -{ - enum - { - type = TypeUndef - }; - SPIRUndef(uint32_t basetype_) - : basetype(basetype_) - { - } - uint32_t basetype; -}; - -// This type is only used by backends which need to access the combined image and sampler IDs separately after -// the OpSampledImage opcode. -struct SPIRCombinedImageSampler : IVariant -{ - enum - { - type = TypeCombinedImageSampler - }; - SPIRCombinedImageSampler(uint32_t type_, uint32_t image_, uint32_t sampler_) - : combined_type(type_) - , image(image_) - , sampler(sampler_) - { - } - uint32_t combined_type; - uint32_t image; - uint32_t sampler; -}; - -struct SPIRConstantOp : IVariant -{ - enum - { - type = TypeConstantOp - }; - - SPIRConstantOp(uint32_t result_type, spv::Op op, const uint32_t *args, uint32_t length) - : opcode(op) - , arguments(args, args + length) - , basetype(result_type) - { - } - - spv::Op opcode; - std::vector arguments; - uint32_t basetype; -}; - -struct SPIRType : IVariant -{ - enum - { - type = TypeType - }; - - enum BaseType - { - Unknown, - Void, - Boolean, - Char, - Int, - UInt, - Int64, - UInt64, - AtomicCounter, - Half, - Float, - Double, - Struct, - Image, - SampledImage, - Sampler - }; - - // Scalar/vector/matrix support. - BaseType basetype = Unknown; - uint32_t width = 0; - uint32_t vecsize = 1; - uint32_t columns = 1; - - // Arrays, support array of arrays by having a vector of array sizes. - std::vector array; - - // Array elements can be either specialization constants or specialization ops. - // This array determines how to interpret the array size. - // If an element is true, the element is a literal, - // otherwise, it's an expression, which must be resolved on demand. - // The actual size is not really known until runtime. - std::vector array_size_literal; - - // Pointers - bool pointer = false; - spv::StorageClass storage = spv::StorageClassGeneric; - - std::vector member_types; - - struct ImageType - { - uint32_t type; - spv::Dim dim; - bool depth; - bool arrayed; - bool ms; - uint32_t sampled; - spv::ImageFormat format; - spv::AccessQualifier access; - } image; - - // Structs can be declared multiple times if they are used as part of interface blocks. - // We want to detect this so that we only emit the struct definition once. - // Since we cannot rely on OpName to be equal, we need to figure out aliases. - uint32_t type_alias = 0; - - // Denotes the type which this type is based on. - // Allows the backend to traverse how a complex type is built up during access chains. - uint32_t parent_type = 0; - - // Used in backends to avoid emitting members with conflicting names. - std::unordered_set member_name_cache; -}; - -struct SPIRExtension : IVariant -{ - enum - { - type = TypeExtension - }; - - enum Extension - { - Unsupported, - GLSL, - SPV_AMD_shader_ballot, - SPV_AMD_shader_explicit_vertex_parameter, - SPV_AMD_shader_trinary_minmax, - SPV_AMD_gcn_shader - }; - - SPIRExtension(Extension ext_) - : ext(ext_) - { - } - - Extension ext; -}; - -// SPIREntryPoint is not a variant since its IDs are used to decorate OpFunction, -// so in order to avoid conflicts, we can't stick them in the ids array. -struct SPIREntryPoint -{ - SPIREntryPoint(uint32_t self_, spv::ExecutionModel execution_model, const std::string &entry_name) - : self(self_) - , name(entry_name) - , orig_name(entry_name) - , model(execution_model) - { - } - SPIREntryPoint() = default; - - uint32_t self = 0; - std::string name; - std::string orig_name; - std::vector interface_variables; - - Bitset flags; - struct - { - uint32_t x = 0, y = 0, z = 0; - uint32_t constant = 0; // Workgroup size can be expressed as a constant/spec-constant instead. - } workgroup_size; - uint32_t invocations = 0; - uint32_t output_vertices = 0; - spv::ExecutionModel model; -}; - -struct SPIRExpression : IVariant -{ - enum - { - type = TypeExpression - }; - - // Only created by the backend target to avoid creating tons of temporaries. - SPIRExpression(std::string expr, uint32_t expression_type_, bool immutable_) - : expression(move(expr)) - , expression_type(expression_type_) - , immutable(immutable_) - { - } - - // If non-zero, prepend expression with to_expression(base_expression). - // Used in amortizing multiple calls to to_expression() - // where in certain cases that would quickly force a temporary when not needed. - uint32_t base_expression = 0; - - std::string expression; - uint32_t expression_type = 0; - - // If this expression is a forwarded load, - // allow us to reference the original variable. - uint32_t loaded_from = 0; - - // If this expression will never change, we can avoid lots of temporaries - // in high level source. - // An expression being immutable can be speculative, - // it is assumed that this is true almost always. - bool immutable = false; - - // Before use, this expression must be transposed. - // This is needed for targets which don't support row_major layouts. - bool need_transpose = false; - - // A list of expressions which this expression depends on. - std::vector expression_dependencies; -}; - -struct SPIRFunctionPrototype : IVariant -{ - enum - { - type = TypeFunctionPrototype - }; - - SPIRFunctionPrototype(uint32_t return_type_) - : return_type(return_type_) - { - } - - uint32_t return_type; - std::vector parameter_types; -}; - -struct SPIRBlock : IVariant -{ - enum - { - type = TypeBlock - }; - - enum Terminator - { - Unknown, - Direct, // Emit next block directly without a particular condition. - - Select, // Block ends with an if/else block. - MultiSelect, // Block ends with switch statement. - - Return, // Block ends with return. - Unreachable, // Noop - Kill // Discard - }; - - enum Merge - { - MergeNone, - MergeLoop, - MergeSelection - }; - - enum Method - { - MergeToSelectForLoop, - MergeToDirectForLoop, - MergeToSelectContinueForLoop - }; - - enum ContinueBlockType - { - ContinueNone, - - // Continue block is branchless and has at least one instruction. - ForLoop, - - // Noop continue block. - WhileLoop, - - // Continue block is conditional. - DoWhileLoop, - - // Highly unlikely that anything will use this, - // since it is really awkward/impossible to express in GLSL. - ComplexLoop - }; - - enum - { - NoDominator = 0xffffffffu - }; - - Terminator terminator = Unknown; - Merge merge = MergeNone; - uint32_t next_block = 0; - uint32_t merge_block = 0; - uint32_t continue_block = 0; - - uint32_t return_value = 0; // If 0, return nothing (void). - uint32_t condition = 0; - uint32_t true_block = 0; - uint32_t false_block = 0; - uint32_t default_block = 0; - - std::vector ops; - - struct Phi - { - uint32_t local_variable; // flush local variable ... - uint32_t parent; // If we're in from_block and want to branch into this block ... - uint32_t function_variable; // to this function-global "phi" variable first. - }; - - // Before entering this block flush out local variables to magical "phi" variables. - std::vector phi_variables; - - // Declare these temporaries before beginning the block. - // Used for handling complex continue blocks which have side effects. - std::vector> declare_temporary; - - // Declare these temporaries, but only conditionally if this block turns out to be - // a complex loop header. - std::vector> potential_declare_temporary; - - struct Case - { - uint32_t value; - uint32_t block; - }; - std::vector cases; - - // If we have tried to optimize code for this block but failed, - // keep track of this. - bool disable_block_optimization = false; - - // If the continue block is complex, fallback to "dumb" for loops. - bool complex_continue = false; - - // The dominating block which this block might be within. - // Used in continue; blocks to determine if we really need to write continue. - uint32_t loop_dominator = 0; - - // All access to these variables are dominated by this block, - // so before branching anywhere we need to make sure that we declare these variables. - std::vector dominated_variables; - - // These are variables which should be declared in a for loop header, if we - // fail to use a classic for-loop, - // we remove these variables, and fall back to regular variables outside the loop. - std::vector loop_variables; - - // Some expressions are control-flow dependent, i.e. any instruction which relies on derivatives or - // sub-group-like operations. - // Make sure that we only use these expressions in the original block. - std::vector invalidate_expressions; -}; - -struct SPIRFunction : IVariant -{ - enum - { - type = TypeFunction - }; - - SPIRFunction(uint32_t return_type_, uint32_t function_type_) - : return_type(return_type_) - , function_type(function_type_) - { - } - - struct Parameter - { - uint32_t type; - uint32_t id; - uint32_t read_count; - uint32_t write_count; - - // Set to true if this parameter aliases a global variable, - // used mostly in Metal where global variables - // have to be passed down to functions as regular arguments. - // However, for this kind of variable, we should not care about - // read and write counts as access to the function arguments - // is not local to the function in question. - bool alias_global_variable; - }; - - // When calling a function, and we're remapping separate image samplers, - // resolve these arguments into combined image samplers and pass them - // as additional arguments in this order. - // It gets more complicated as functions can pull in their own globals - // and combine them with parameters, - // so we need to distinguish if something is local parameter index - // or a global ID. - struct CombinedImageSamplerParameter - { - uint32_t id; - uint32_t image_id; - uint32_t sampler_id; - bool global_image; - bool global_sampler; - bool depth; - }; - - uint32_t return_type; - uint32_t function_type; - std::vector arguments; - - // Can be used by backends to add magic arguments. - // Currently used by combined image/sampler implementation. - - std::vector shadow_arguments; - std::vector local_variables; - uint32_t entry_block = 0; - std::vector blocks; - std::vector combined_parameters; - - void add_local_variable(uint32_t id) - { - local_variables.push_back(id); - } - - void add_parameter(uint32_t parameter_type, uint32_t id, bool alias_global_variable = false) - { - // Arguments are read-only until proven otherwise. - arguments.push_back({ parameter_type, id, 0u, 0u, alias_global_variable }); - } - - // Statements to be emitted when the function returns. - // Mostly used for lowering internal data structures onto flattened structures. - std::vector fixup_statements; - - bool active = false; - bool flush_undeclared = true; - bool do_combined_parameters = true; - bool analyzed_variable_scope = false; -}; - -struct SPIRAccessChain : IVariant -{ - enum - { - type = TypeAccessChain - }; - - SPIRAccessChain(uint32_t basetype_, spv::StorageClass storage_, std::string base_, std::string dynamic_index_, - int32_t static_index_) - : basetype(basetype_) - , storage(storage_) - , base(base_) - , dynamic_index(std::move(dynamic_index_)) - , static_index(static_index_) - { - } - - // The access chain represents an offset into a buffer. - // Some backends need more complicated handling of access chains to be able to use buffers, like HLSL - // which has no usable buffer type ala GLSL SSBOs. - // StructuredBuffer is too limited, so our only option is to deal with ByteAddressBuffer which works with raw addresses. - - uint32_t basetype; - spv::StorageClass storage; - std::string base; - std::string dynamic_index; - int32_t static_index; - - uint32_t loaded_from = 0; - uint32_t matrix_stride = 0; - bool row_major_matrix = false; - bool immutable = false; -}; - -struct SPIRVariable : IVariant -{ - enum - { - type = TypeVariable - }; - - SPIRVariable() = default; - SPIRVariable(uint32_t basetype_, spv::StorageClass storage_, uint32_t initializer_ = 0, uint32_t basevariable_ = 0) - : basetype(basetype_) - , storage(storage_) - , initializer(initializer_) - , basevariable(basevariable_) - { - } - - uint32_t basetype = 0; - spv::StorageClass storage = spv::StorageClassGeneric; - uint32_t decoration = 0; - uint32_t initializer = 0; - uint32_t basevariable = 0; - - std::vector dereference_chain; - bool compat_builtin = false; - - // If a variable is shadowed, we only statically assign to it - // and never actually emit a statement for it. - // When we read the variable as an expression, just forward - // shadowed_id as the expression. - bool statically_assigned = false; - uint32_t static_expression = 0; - - // Temporaries which can remain forwarded as long as this variable is not modified. - std::vector dependees; - bool forwardable = true; - - bool deferred_declaration = false; - bool phi_variable = false; - bool remapped_variable = false; - uint32_t remapped_components = 0; - - // The block which dominates all access to this variable. - uint32_t dominator = 0; - // If true, this variable is a loop variable, when accessing the variable - // outside a loop, - // we should statically forward it. - bool loop_variable = false; - // Set to true while we're inside the for loop. - bool loop_variable_enable = false; - - SPIRFunction::Parameter *parameter = nullptr; -}; - -struct SPIRConstant : IVariant -{ - enum - { - type = TypeConstant - }; - - union Constant { - uint32_t u32; - int32_t i32; - float f32; - - uint64_t u64; - int64_t i64; - double f64; - }; - - struct ConstantVector - { - Constant r[4]; - // If != 0, this element is a specialization constant, and we should keep track of it as such. - uint32_t id[4]; - uint32_t vecsize = 1; - - // Workaround for MSVC 2013, initializing an array breaks. - ConstantVector() - { - memset(r, 0, sizeof(r)); - for (unsigned i = 0; i < 4; i++) - id[i] = 0; - } - }; - - struct ConstantMatrix - { - ConstantVector c[4]; - // If != 0, this column is a specialization constant, and we should keep track of it as such. - uint32_t id[4]; - uint32_t columns = 1; - - // Workaround for MSVC 2013, initializing an array breaks. - ConstantMatrix() - { - for (unsigned i = 0; i < 4; i++) - id[i] = 0; - } - }; - - static inline float f16_to_f32(uint16_t u16_value) - { - // Based on the GLM implementation. - int s = (u16_value >> 15) & 0x1; - int e = (u16_value >> 10) & 0x1f; - int m = (u16_value >> 0) & 0x3ff; - - union { - float f32; - uint32_t u32; - } u; - - if (e == 0) - { - if (m == 0) - { - u.u32 = uint32_t(s) << 31; - return u.f32; - } - else - { - while ((m & 0x400) == 0) - { - m <<= 1; - e--; - } - - e++; - m &= ~0x400; - } - } - else if (e == 31) - { - if (m == 0) - { - u.u32 = (uint32_t(s) << 31) | 0x7f800000u; - return u.f32; - } - else - { - u.u32 = (uint32_t(s) << 31) | 0x7f800000u | (m << 13); - return u.f32; - } - } - - e += 127 - 15; - m <<= 13; - u.u32 = (uint32_t(s) << 31) | (e << 23) | m; - return u.f32; - } - - inline uint32_t specialization_constant_id(uint32_t col, uint32_t row) const - { - return m.c[col].id[row]; - } - - inline uint32_t specialization_constant_id(uint32_t col) const - { - return m.id[col]; - } - - inline uint32_t scalar(uint32_t col = 0, uint32_t row = 0) const - { - return m.c[col].r[row].u32; - } - - inline uint16_t scalar_u16(uint32_t col = 0, uint32_t row = 0) const - { - return uint16_t(m.c[col].r[row].u32 & 0xffffu); - } - - inline float scalar_f16(uint32_t col = 0, uint32_t row = 0) const - { - return f16_to_f32(scalar_u16(col, row)); - } - - inline float scalar_f32(uint32_t col = 0, uint32_t row = 0) const - { - return m.c[col].r[row].f32; - } - - inline int32_t scalar_i32(uint32_t col = 0, uint32_t row = 0) const - { - return m.c[col].r[row].i32; - } - - inline double scalar_f64(uint32_t col = 0, uint32_t row = 0) const - { - return m.c[col].r[row].f64; - } - - inline int64_t scalar_i64(uint32_t col = 0, uint32_t row = 0) const - { - return m.c[col].r[row].i64; - } - - inline uint64_t scalar_u64(uint32_t col = 0, uint32_t row = 0) const - { - return m.c[col].r[row].u64; - } - - inline const ConstantVector &vector() const - { - return m.c[0]; - } - - inline uint32_t vector_size() const - { - return m.c[0].vecsize; - } - - inline uint32_t columns() const - { - return m.columns; - } - - inline void make_null(const SPIRType &constant_type_) - { - m = {}; - m.columns = constant_type_.columns; - for (auto &c : m.c) - c.vecsize = constant_type_.vecsize; - } - - explicit SPIRConstant(uint32_t constant_type_) - : constant_type(constant_type_) - { - } - - SPIRConstant() = default; - - SPIRConstant(uint32_t constant_type_, const uint32_t *elements, uint32_t num_elements, bool specialized) - : constant_type(constant_type_) - , specialization(specialized) - { - subconstants.insert(end(subconstants), elements, elements + num_elements); - specialization = specialized; - } - - // Construct scalar (32-bit). - SPIRConstant(uint32_t constant_type_, uint32_t v0, bool specialized) - : constant_type(constant_type_) - , specialization(specialized) - { - m.c[0].r[0].u32 = v0; - m.c[0].vecsize = 1; - m.columns = 1; - } - - // Construct scalar (64-bit). - SPIRConstant(uint32_t constant_type_, uint64_t v0, bool specialized) - : constant_type(constant_type_) - , specialization(specialized) - { - m.c[0].r[0].u64 = v0; - m.c[0].vecsize = 1; - m.columns = 1; - } - - // Construct vectors and matrices. - SPIRConstant(uint32_t constant_type_, const SPIRConstant *const *vector_elements, uint32_t num_elements, - bool specialized) - : constant_type(constant_type_) - , specialization(specialized) - { - bool matrix = vector_elements[0]->m.c[0].vecsize > 1; - - if (matrix) - { - m.columns = num_elements; - - for (uint32_t i = 0; i < num_elements; i++) - { - m.c[i] = vector_elements[i]->m.c[0]; - if (vector_elements[i]->specialization) - m.id[i] = vector_elements[i]->self; - } - } - else - { - m.c[0].vecsize = num_elements; - m.columns = 1; - - for (uint32_t i = 0; i < num_elements; i++) - { - m.c[0].r[i] = vector_elements[i]->m.c[0].r[0]; - if (vector_elements[i]->specialization) - m.c[0].id[i] = vector_elements[i]->self; - } - } - } - - uint32_t constant_type; - ConstantMatrix m; - - // If this constant is a specialization constant (i.e. created with OpSpecConstant*). - bool specialization = false; - // If this constant is used as an array length which creates specialization restrictions on some backends. - bool is_used_as_array_length = false; - - // For composites which are constant arrays, etc. - std::vector subconstants; -}; - -class Variant -{ -public: - // MSVC 2013 workaround, we shouldn't need these constructors. - Variant() = default; - Variant(Variant &&other) - { - *this = std::move(other); - } - Variant &operator=(Variant &&other) - { - if (this != &other) - { - holder = move(other.holder); - type = other.type; - other.type = TypeNone; - } - return *this; - } - - void set(std::unique_ptr val, uint32_t new_type) - { - holder = std::move(val); - if (!allow_type_rewrite && type != TypeNone && type != new_type) - SPIRV_CROSS_THROW("Overwriting a variant with new type."); - type = new_type; - allow_type_rewrite = false; - } - - template - T &get() - { - if (!holder) - SPIRV_CROSS_THROW("nullptr"); - if (T::type != type) - SPIRV_CROSS_THROW("Bad cast"); - return *static_cast(holder.get()); - } - - template - const T &get() const - { - if (!holder) - SPIRV_CROSS_THROW("nullptr"); - if (T::type != type) - SPIRV_CROSS_THROW("Bad cast"); - return *static_cast(holder.get()); - } - - uint32_t get_type() const - { - return type; - } - uint32_t get_id() const - { - return holder ? holder->self : 0; - } - bool empty() const - { - return !holder; - } - void reset() - { - holder.reset(); - type = TypeNone; - } - - void set_allow_type_rewrite() - { - allow_type_rewrite = true; - } - -private: - std::unique_ptr holder; - uint32_t type = TypeNone; - bool allow_type_rewrite = false; -}; - -template -T &variant_get(Variant &var) -{ - return var.get(); -} - -template -const T &variant_get(const Variant &var) -{ - return var.get(); -} - -template -T &variant_set(Variant &var, P &&... args) -{ - auto uptr = std::unique_ptr(new T(std::forward

(args)...)); - auto ptr = uptr.get(); - var.set(std::move(uptr), T::type); - return *ptr; -} - -struct Meta -{ - struct Decoration - { - std::string alias; - std::string qualified_alias; - std::string hlsl_semantic; - Bitset decoration_flags; - spv::BuiltIn builtin_type; - uint32_t location = 0; - uint32_t set = 0; - uint32_t binding = 0; - uint32_t offset = 0; - uint32_t array_stride = 0; - uint32_t matrix_stride = 0; - uint32_t input_attachment = 0; - uint32_t spec_id = 0; - uint32_t index = 0; - bool builtin = false; - }; - - Decoration decoration; - std::vector members; - uint32_t sampler = 0; - - std::unordered_map decoration_word_offset; - - // Used when the parser has detected a candidate identifier which matches - // known "magic" counter buffers as emitted by HLSL frontends. - // We will need to match the identifiers by name later when reflecting resources. - // We could use the regular alias later, but the alias will be mangled when parsing SPIR-V because the identifier - // is not a valid identifier in any high-level language. - std::string hlsl_magic_counter_buffer_name; - bool hlsl_magic_counter_buffer_candidate = false; - - // For SPV_GOOGLE_hlsl_functionality1, this avoids the workaround. - bool hlsl_is_magic_counter_buffer = false; - // ID for the sibling counter buffer. - uint32_t hlsl_magic_counter_buffer = 0; -}; - -// A user callback that remaps the type of any variable. -// var_name is the declared name of the variable. -// name_of_type is the textual name of the type which will be used in the code unless written to by the callback. -using VariableTypeRemapCallback = - std::function; - -class ClassicLocale -{ -public: - ClassicLocale() - { - old = std::locale::global(std::locale::classic()); - } - ~ClassicLocale() - { - std::locale::global(old); - } - -private: - std::locale old; -}; - -class Hasher -{ -public: - inline void u32(uint32_t value) - { - h = (h * 0x100000001b3ull) ^ value; - } - - inline uint64_t get() const - { - return h; - } - -private: - uint64_t h = 0xcbf29ce484222325ull; -}; - -static inline bool type_is_floating_point(const SPIRType &type) -{ - return type.basetype == SPIRType::Half || type.basetype == SPIRType::Float || type.basetype == SPIRType::Double; -} -} // namespace spirv_cross - -#endif diff --git a/Documentation/RGA_RELEASE_NOTES.docx b/Documentation/RGA_RELEASE_NOTES.docx index f785468..a73fbe0 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 10584de..497f813 100644 --- a/Documentation/RGA_RELEASE_NOTES.txt +++ b/Documentation/RGA_RELEASE_NOTES.txt @@ -1,66 +1,52 @@ -Radeonâ„¢ GPU Analyzer 2.4.2 – Release Notes ------------------------------------------- - +Radeon™ GPU Analyzer 2.5 – Release Notes +======================================== Highlights ----------- -- Added support for gfx1031 (RX 6700 XT) in Vulkan, DX12, DXR, DX11 and OpenGL modes. -- DXR: - o Improved error reporting to help diagnose State Object creation failures. - o You can now extract pipeline binaries even in cases where the driver generated multiple raytracing pipelines. -- Improved static analysis engine’s stability. -- The following RDNA and RDNA2 instructions are now supported by the static analysis engine: - o V_DOT2C_F32_F16 - o V_DOT4C_I32_I8 - o V_DOT2_F32_F16 - o V_DOT2_I32_I16 - o V_DOT2_U32_U16 - o V_DOT4_I32_I8 - o V_DOT4_U32_U8 - o V_DOT8_I32_I4 - o V_DOT8_U32_U4 - o V_FMAC_LEGACY_F32 - o V_FMA_LEGACY_F32 -- Vulkan offline mode: added support for new SPIR-V extensions and capabilities. See the accompanying Release Notes document for the complete list of supported extensions and capabilities. -- Notable bug fixes: - o DXR: Fixes to the command line tool’s DXR help manual. - o DXR: Auto-generated file name extension is now aligned with DX12 mode. - o Fixed the compute capability for certain APU products (gfx909 -> gfx90C). - +========== +- Added support for gfx1032 as a target in Vulkan, DX12, DXR, DX11, OpenCL and OpenGL modes. +- [GitHub-59] DX12 mode: support for multi-GPU configurations where the primary display adapter is a non-AMD card. The tool will now use the driver that is associated with the first AMD display adapter on the system. +- OpenCL: +o [GitHub-67, GitHub-76] Added support for RDNA targets, including the Radeon Instinct MI100. +o [GitHub-34] Updated the Lightning Compiler package that is bundled with the tool. +o Added support for live VGPR analysis and control-flow graph generation. +o ROCM-CL mode (-s rocm-cl) was replaced with an “Offline OpenCL” mode (-s opencl). +- Vulkan: +o Live VGPR analysis and control-flow graph can now be generated from LLPC disassembly. +o Updated the SPIR-V tools. +- Vulkan offline: updated the Vulkan offline backend. +- Major refactoring of the codebase to conform with Google C++ style guide. You may notice files and folders have been renamed and relocated in the binary package and GitHub repository. +- Notable bug fixes: +o DXR: Disassembly for Wave32 shaders no longer shows references of shared VGPRs. +o [GitHub-82] Vulkan offline compiler assertion when using EXT_buffer_reference. +o [GitHub-66] Added support for Radeon RX Vega M GL and GH in Offline OpenCL mode. + +Note: on Ubuntu, the minimum required OS version is Ubuntu 20.04. Known Issues ------------- -DXR Mode --------- -- Disassembly for Wave32 shaders may show references of shared VGPRs. -- In scenarios where multiple raytracing pipelines are created from the same State Object, some binaries may not be of valid ELF format. A fix will be provided in an upcoming Adrenalin software release (users do not need to update the tool to consume the fix). - -Vulkan Live Driver Mode +============ +Vulkan Live Driver Mode ----------------------- -- Source to disassembly correlation is not supported by AMD’s shader compiler at the moment and is therefore not supported in the UI. -- Keyboard navigation is not supported from some views in the GUI application. -- The RGA layer is a beta feature. It fails to extract the shaders and pipeline state from certain Vulkan apps. -- Notifications about the fact that modified SPIR-V binary does not match the disassembly will not appear for loaded projects (in case that you changed the SPIR-V code, did not build and re-loaded the project). - -ROCM OpenCL Mode ----------------- -- RDNA targets are not supported as targets for ROCM-CL modes. -- The Lightning Compiler does not support disassembling of binaries for Graphics IP v7 targets. -- OpenCL C++ kernels are not yet supported by the Lightning Compiler. -- No support for live register analysis and control-flow graph generation in this mode. -- Cycle estimate for certain VALU instructions appears as “Varies†instead of 4. +- Source to disassembly correlation is not supported by AMD’s shader compiler at the moment and is therefore not supported in the UI. +- Keyboard navigation is not supported from some views in the GUI application. +- The RGA layer is a beta feature. It fails to extract the shaders and pipeline state from certain Vulkan apps. +- Notifications about the fact that modified SPIR-V binary does not match the disassembly will not appear for loaded projects (in case that you changed the SPIR-V code, did not build and re-loaded the project). + +Offline OpenCL Mode +------------------- +- OpenCL C++ kernels are not yet supported by the Lightning Compiler. +- Cycle estimate for certain VALU instructions appears as “Varies” instead of 4. OpenGL Mode ----------- -Resource usage statistics for OpenGL mode only displays usage of SGPRs and VGPRs. +Resource usage statistics for OpenGL mode only displays usage of SGPRs and VGPRs. DirectX 12 Mode --------------- -Live register analysis & CFG generation require using the --isa option to generate ISA disassembly. +Live register analysis & CFG generation require using the --isa option to generate ISA disassembly. Vulkan Offline Modes (vk-offline, vk-spv-offline, vk-spv-txt-offline) --------------------------------------------------------------------- -SPIR-V support limitations: -a. The following capabilities, which are defined in the SPIR-V spec, are currently supported: +SPIR-V support limitations: +a. The Vulkan Offline modes currently only support the following SPIR-V capabilities: CapabilityMatrix CapabilityShader CapabilityGeometry @@ -168,7 +154,7 @@ CapabilityRayTracingProvisionalKHR CapabilityRayQueryProvisionalKHR CapabilityRayTraversalPrimitiveCullingProvisionalKHR -b. SPIR-V modes currently only support the following extensions: +b. The Vulkan Offline modes currently only support the following extensions: SPV_KHR_shader_ballot SPV_KHR_subgroup_vote SPV_KHR_device_group @@ -212,40 +198,44 @@ SPV_KHR_ray_query GUI Application --------------- -- "Correlation Disabled" notification in the source code editor is not being saved for projects after they were closed. -- Certain SALU instructions are being misclassified as VALU instructions. +- “Correlation Disabled” notification in the source code editor is not being saved for projects after they were closed. +- Certain SALU instructions are being misclassified as VALU instructions. +- Certain GDS instructions are being misclassified as SALU. +- Changing disassembly columns can be sluggish on certain systems in projects with multiple .cl files. + +Notes for OpenCL Mode Users +=========================== +The Offline OpenCL mode uses the Lightning Compiler package that ships with RGA, which is based on clang. +As of version 2.0, RGA allows developers to replace the Lightning Compiler package that ships with the product with a user-provided LLVM-based package. For more information, see the Radeon GPU Analyzer GUI app’s help manual, or run the command line tool with –s opencl –h as arguments (look for the “Alternative OpenCL Lightning Compiler” section). -Notes for OpenCL Mode Users ---------------------------- -The “-s rocm-cl†mode uses the Lightning Compiler package that ships with RGA, which is based on clang. -As of version 2.0, RGA allows developers to replace the Lightning Compiler package that ships with the product with a user-provided LLVM-based package. For more information, see the Radeon GPU Analyzer GUI app’s help manual, or run the command line tool with –s rocm-cl –h as arguments (look for the “Alternative ROCm OpenCL compiler†section). Notes for DirectX 11 Mode Users -RGA’s DirectX 11 (-s dx11) mode will use the driver that is associated with the primary display adapter, by default. If your primary display adapter is not an AMD GPU, or if you would like RGA to use a driver that is associated with a different display adapter that is installed on your system, use the --adapters and --set-adapter command line switches in order to instruct RGA to use the relevant driver. +=============================== +RGA’s DirectX 11 (-s dx11) mode will use the driver that is associated with the primary display adapter, by default. If your primary display adapter is not an AMD GPU, or if you would like RGA to use a driver that is associated with a different display adapter that is installed on your system, use the --adapters and --set-adapter command line switches to instruct RGA to use the relevant driver. System Requirements -------------------- -It is generally recommended to use RGA with the latest Radeon Software version. Specifically, to target the RDNA architecture, the latest Radeon Software version is required (except for all Vulkan® modes and the rocm-cl mode, which are independent of the driver). +=================== +It is generally recommended to use RGA with the latest Radeon Software version. Specifically, to target the RDNA architecture, the latest Radeon Software version is required (except for all Vulkan® modes and the Offline OpenCL mode, which are independent of the driver). Vulkan Mode ----------- To use the installed driver in Vulkan mode: -a. Vulkan SDK 1.1.97.0 or later is required. -b. Latest Adrenalin or amdgpu-pro driver is required. - -RGA ships with a compatible Vulkan driver to support users who do not have an AMD driver installed on their system. In cases where RGA fails to detect the installed driver, it falls back to using the bundled driver. To make sure that you are using the latest compiler and can compile for the latest Radeon targets, we strongly recommend running on a machine that has an AMD driver installed. +a. Vulkan SDK 1.1.97.0 or later is required. +b. Latest Adrenalin or amdgpu-pro driver is required. Vulkan Offline Modes (vk-offline, vk-spv-offline, vk-spv-txt-offline) --------------------------------------------------------------------- -All Vulkan offline modes (vk-offline, vk-spv-offline and vk-spv-txt-offline) are independent of the installed driver and graphics hardware and should work on any x86-based system. +All Vulkan offline modes (vk-offline, vk-spv-offline and vk-spv-txt-offline) are independent of the installed driver and graphics hardware and should work on any x86-based system. DirectX 12 and DirectX 11 Modes ------------------------------- It is recommended to use the latest Adrenalin drivers for the best experience in DirectX 12 and DirectX 11 modes. -ROCM OpenCL Mode ----------------- -ROCM OpenCL mode (rocm-cl) is independent of the installed driver and graphics hardware and should work on any x86-based system. +Offline OpenCL Mode +------------------- +Offline OpenCL mode (-s opencl) is independent of the installed driver and graphics hardware and should work on any x86-based system. OpenGL Mode ----------- -OpenGL mode on Linux requires the latest amdgpu-pro driver. +OpenGL mode requires the latest amdgpu-pro driver on Linux and latest Adrenalin Software on Windows. + + diff --git a/Documentation/source/conf.py b/Documentation/source/conf.py index 6dcf32e..50e3725 100644 --- a/Documentation/source/conf.py +++ b/Documentation/source/conf.py @@ -60,9 +60,9 @@ # built documents. # # The short X.Y version. -version = '2.4.2' +version = '2.5' # The full version, including alpha/beta/rc tags. -release = '2.4.2' +release = '2.5' # 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 cee9c90..0b060cb 100644 --- a/Documentation/source/help_manual.rst +++ b/Documentation/source/help_manual.rst @@ -70,10 +70,10 @@ In the Start tab for Vulkan® mode, you have two options: * May contain a single Compute shader stage. * Within the compute pipeline project, you would be able to configure the Vulkan® compute pipeline state in the UI -You can also create a compute or graphics pipeline this through the File menu by: +You can also create a compute or graphics pipeline through the File menu by: -* Clicking on File -> "Create new Vulkan® graphics pipeline" (Ctrl+Shift+G) -* Clicking on File -> "Create new Vulkan® compute pipeline" (Ctrl+Shift+C) +* Clicking on File -> "Create new Vulkan® graphics pipeline" (Ctrl+Alt+G) +* Clicking on File -> "Create new Vulkan® compute pipeline" (Ctrl+Alt+C) .. image:: images/2_1/file_menu_create_pipeline_vulkan.png @@ -327,7 +327,7 @@ Resource hazards that may require the developer's attention are defined as: * Scratch memory hazard: scratch memory is used. * Instruction cache hazard: code size is larger than the instruction cache. -ROCm OpenCLâ„¢ Mode +OpenCLâ„¢ Offline Mode ----------------- The Home Page @@ -555,19 +555,19 @@ On the left side of the Source Code View, you will find running line numbers. You can use the Ctrl+F (Edit -> Find) and Ctrl+G (Edit -> Go to...) to search for a string or jump to a specific line. -.. image:: images/013_build_view_source_view.png +.. image:: images/013_build_view_source_view_opencl.png After a successful build, when the disassembly view becomes visible alongside the Source Code View, you can double-click on the view's black title bar to maximize it. You can also click on the resize icon at the top right corner to maximize/minimize the view: -.. image:: images/013_build_view_title_bar.png +.. image:: images/013_build_view_title_bar_opencl.png Build Output View ````````````````` When a build is triggered, the RGA command line app is being launched to execute the build. Its output would be streamed into the Build Output View. -.. image:: images/014_build_view_build_output.png +.. image:: images/014_build_view_build_output_opencl.png Double-clicking on the top black title bar (or clicking on the resize button at its right corner) would maximize/minimize the Build Output View. @@ -577,7 +577,7 @@ Disassembly View ```````````````` The disassembly for the relevant kernel will be displayed in the disassembly view on the right: -.. image:: images/006_disassembly_view.png +.. image:: images/023_disassembly_view_opencl.png * Highlighted rows are correlated to the current line in the source code view on the left * Memory instructions are colored in red to help you identify spots with high memory pressure @@ -796,14 +796,14 @@ The RGA Layer Launcher is a Windows-only application that can be used to simplif .. image:: images/2_1/layer_launcher_vulkan.png -ROCm OpenCLâ„¢ Mode +OpenCLâ„¢ Offline Mode ^^^^^^^^^^^^^^^^^ Find Code Object Binary and Build Artifacts ``````````````````````````````````````````` Right click on the disassembly view and click on "Show disassembly file in explorer". -.. image:: images/017_disassembly_view_context_menu.png +.. image:: images/017_disassembly_view_context_menu_opencl.png Use an Alternative Compiler ``````````````````````````` @@ -842,14 +842,14 @@ Go to (source line) Ctrl+G Maximize/minimize views in build view Ctrl+R Save file Ctrl+S Build project Ctrl+Shift+B -Cancel build Ctrl+Shift+C +Cancel build Ctrl+Shift+X Cycle thru various views in build view Ctrl+Tab & Ctrl+Shift+Tab Cycle thru various widgets in build view Tab & Shift+Tab **Settings view** Restore default settings Ctrl+R **Vulkan® mode** -Create new Vulkan® compute pipeline Ctrl+Shift+C -Create new Vulkan® graphics pipeline Ctrl+Shift+G +Create new Vulkan® compute pipeline Ctrl+Alt+C +Create new Vulkan® graphics pipeline Ctrl+Alt+G **OpenCLâ„¢ mode** Create new .cl file Ctrl+N Open existing .cl file Ctrl+O diff --git a/Documentation/source/images/013_build_view_source_view_opencl.png b/Documentation/source/images/013_build_view_source_view_opencl.png new file mode 100644 index 0000000..42e546e Binary files /dev/null and b/Documentation/source/images/013_build_view_source_view_opencl.png differ diff --git a/Documentation/source/images/013_build_view_title_bar_opencl.png b/Documentation/source/images/013_build_view_title_bar_opencl.png new file mode 100644 index 0000000..12fd634 Binary files /dev/null and b/Documentation/source/images/013_build_view_title_bar_opencl.png differ diff --git a/Documentation/source/images/014_build_view_build_output_opencl.png b/Documentation/source/images/014_build_view_build_output_opencl.png new file mode 100644 index 0000000..eb3e34c Binary files /dev/null and b/Documentation/source/images/014_build_view_build_output_opencl.png differ diff --git a/Documentation/source/images/017_disassembly_view_context_menu_opencl.png b/Documentation/source/images/017_disassembly_view_context_menu_opencl.png new file mode 100644 index 0000000..c3562ea Binary files /dev/null and b/Documentation/source/images/017_disassembly_view_context_menu_opencl.png differ diff --git a/Documentation/source/images/020_file_menu_open_project.png b/Documentation/source/images/020_file_menu_open_project.png index c97cce7..fa7b10b 100644 Binary files a/Documentation/source/images/020_file_menu_open_project.png and b/Documentation/source/images/020_file_menu_open_project.png differ diff --git a/Documentation/source/images/023_disassembly_view_opencl.png b/Documentation/source/images/023_disassembly_view_opencl.png new file mode 100644 index 0000000..e5516ed Binary files /dev/null and b/Documentation/source/images/023_disassembly_view_opencl.png differ diff --git a/Documentation/source/images/2_1/build_settings_vulkan.png b/Documentation/source/images/2_1/build_settings_vulkan.png index c3a486e..d1dc0b9 100644 Binary files a/Documentation/source/images/2_1/build_settings_vulkan.png and b/Documentation/source/images/2_1/build_settings_vulkan.png differ diff --git a/Documentation/source/images/2_1/file_menu_create_pipeline_vulkan.png b/Documentation/source/images/2_1/file_menu_create_pipeline_vulkan.png index bd897a9..fe08a3d 100644 Binary files a/Documentation/source/images/2_1/file_menu_create_pipeline_vulkan.png and b/Documentation/source/images/2_1/file_menu_create_pipeline_vulkan.png differ diff --git a/Documentation/source/images/2_1/open_existing_project_vulkan.png b/Documentation/source/images/2_1/open_existing_project_vulkan.png index 2fd67f0..540176b 100644 Binary files a/Documentation/source/images/2_1/open_existing_project_vulkan.png and b/Documentation/source/images/2_1/open_existing_project_vulkan.png differ diff --git a/Documentation/source/index.rst b/Documentation/source/index.rst index dea47b8..5c499b3 100644 --- a/Documentation/source/index.rst +++ b/Documentation/source/index.rst @@ -7,7 +7,7 @@ The GUI application works on top of the RGA command line tool, which supports a This documentation will focus on the GUI application, which currently supports: - Vulkanâ„¢ live-driver mode -- OpenCLâ„¢ for Rocm, on top AMD's LLVM-based Lightning compiler +- OpenCLâ„¢ Offline, on top of AMD's LLVM-based Lightning compiler More information about the RGA command line tool can be found in its help manual ("-h" option), or on the `RGA Github page `_. diff --git a/Documentation/source/quickstart.rst b/Documentation/source/quickstart.rst index 547028a..7b74873 100644 --- a/Documentation/source/quickstart.rst +++ b/Documentation/source/quickstart.rst @@ -123,7 +123,7 @@ And, in case of a successful build, the disassembly and HW resource usage info w That's it - we got our first Vulkan® pipeline built with RGA. -ROCm OpenCLâ„¢ Mode +OpenCLâ„¢ Offline Mode ----------------- The Home Page @@ -170,7 +170,7 @@ Use that list to control which kernel is in focus (highlighted in yellow): The disassembly for the relevant kernel will be displayed in the disassembly view on the right: -.. image:: images/006_disassembly_view.png +.. image:: images/023_disassembly_view_opencl.png * Highlighted rows are correlated to the current line in the source code view on the left * Memory instructions are colored in red to help you identify spots with high memory pressure diff --git a/Installer/RGA-Installer.aip b/Installer/RGA-Installer.aip index 274fcd6..2b2fbb7 100755 --- a/Installer/RGA-Installer.aip +++ b/Installer/RGA-Installer.aip @@ -14,20 +14,19 @@ - - + - - + + - - + + @@ -53,20 +52,22 @@ - + + + @@ -85,15 +86,13 @@ - - + - @@ -105,6 +104,7 @@ + @@ -123,6 +123,7 @@ + @@ -137,10 +138,11 @@ + - + @@ -155,31 +157,32 @@ - - - - - + + + + - + - - + + + - - + + + @@ -189,7 +192,7 @@ - + @@ -219,6 +222,7 @@ + @@ -264,15 +268,29 @@ - - + + + + + + + + + + + + + + + - + + @@ -296,7 +314,7 @@ - + @@ -310,16 +328,17 @@ - + + - + @@ -358,10 +377,9 @@ - - + @@ -396,8 +414,6 @@ - - @@ -411,18 +427,14 @@ - - - - @@ -431,20 +443,16 @@ - + - + - - - - @@ -455,7 +463,6 @@ - @@ -476,7 +483,7 @@ - + @@ -490,7 +497,4 @@ - - - diff --git a/README.md b/README.md index e22cf54..a4aaac4 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ independent of the type of GPU/APU that is physically installed on your system. You can use RGA to produce the following output: * RDNAâ„¢ and GCN ISA disassembly -* Intermediate language disassembly: AMDIL, DXIL and DXBC for DirectX, SPIR-V for Vulkan, LLVM IR for ROCm OpenCL +* Intermediate language disassembly: AMDIL, DXIL and DXBC for DirectX, SPIR-V for Vulkan, LLVM IR for Offline OpenCL * Hardware resource usage statistics, such as register consumption, static memory allocation and more * Compiled binaries * Live register analysis (see http://gpuopen.com/live-vgpr-analysis-radeon-gpu-analyzer/ for more info) @@ -16,7 +16,7 @@ The RGA package contains both a GUI app and a command-line executable. The supported modes by the **GUI app** are: * Vulkan - GLSL/SPIR-V as input, together with the Vulkan pipeline state; compiled through AMD's Vulkan driver -* OpenCL - AMD's LLVM-based Lightning Compiler for ROCm +* OpenCL - AMD's LLVM-based Lightning Compiler for OpenCL The supported modes by the **command-line tool** are: * DX12 (see https://gpuopen.com/radeon-gpu-analyzer-2-2-direct3d12-compute/ and https://gpuopen.com/radeon-gpu-analyzer-2-3-direct3d-12-graphics/ for more details) @@ -24,19 +24,19 @@ The supported modes by the **command-line tool** are: * DXR * Vulkan - compilation of GLSL/SPIR-V together with the API's pipeline state, using AMD's Vulkan driver * Vulkan Offline - using a static compiler, accepts GLSL/SPIR-V as input. Note: to ensure that the results that RGA provides are accurate and reflect the real-world case, please use the new Vulkan live driver mode (which is also supported in the GUI application). -* OpenCL - AMD's LLVM-based Lightning Compiler for ROCm (-s rocm-cl) +* OpenCL - AMD's LLVM-based Lightning Compiler for Offline OpenCL * OpenGL * AMDIL ## System Requirements ## * Windows: 10, 64-bit. Visual Studio 2015 or later. -* Linux: Ubuntu 18.04, Red Hat 6.4 or later. Build with gcc 4.7.2 or later. +* Linux: Ubuntu 20.04. Build with gcc 4.7.2 or later. * Vulkan SDK 1.1.97.0 or later. To download the Vulkan SDK, visit https://vulkan.lunarg.com/ To run the tool, you would need to have the AMD Radeon Adrenalin Software (Windows) or amdgpu-pro driver (Linux) installed for all modes, except for the following "offline" modes, which are independent of the driver and hardware: * Vulkan offline mode -* ROCm OpenCL +* OpenCL offline mode For the non-offline modes, it is strongly recommended to run with the latest drivers so that the latest compiler is used and the latest architectures can be targeted. @@ -49,16 +49,18 @@ to your build output folder (make sure to place the folder in the same folder hi ### Building on Windows ### As a preliminary step, make sure that you have the following installed on your system: -* CMake 3.5 or above. For auto-detecting the Vulkan SDK version 3.7 or above is required. +* CMake 3.10 or above. For auto-detecting the Vulkan SDK version 3.7 or above is required. * Python 2.7 or above -* Qt (in case that you are interested in building the GUI app; you can build the command line executable without Qt). Qt 5.9.2 is recommended. +* Qt (in case that you are interested in building the GUI app; you can build the command line executable without Qt). Qt 5.15.2 is recommended. cd to the Build sub-folder, and run: -Prebuild.bat --qt C:\Qt\Qt5.9.2\msvc2017_64 --vs 2017 +Prebuild.bat --qt --vs 2017 + +Where is the path to the Qt msvc2017_64 folder, such as C:\Qt\Qt5.15.2\msvc2017_64. Running the Prebuild script will fetch all the dependencies and generate the solution file for Visual Studio. -After successfully running the preuild script, open RGA.sln from Build\CMake\VS2017 (or VS2015), and build: +After successfully running the preuild script, open RGA.sln from build\windows\vs2019 (or vs2017), and build: * RadeonGPUAnalyzerCLI project for the command line executable * RadeonGPUAnalyzerGUI project for the GUI app @@ -70,7 +72,7 @@ Some useful options of the Prebuild script: * --no-fetch: do not attempt to update the third-party repositories If you are intending to analyze DirectX 11 shaders using RGA, copy the x64 version of Microsoft's D3D compiler to a subdirectory -named "x64" under the RGA executable's directory (for example, D3DCompiler_47.dll). +named "utils" under the RGA executable's directory (for example, D3DCompiler_47.dll). -=- @@ -81,7 +83,7 @@ To generate the solution file for VS 2017 in x64 configuration, use: cmake.exe -G "Visual Studio 15 2017 Win64" If you are intending to analyze DirectX shaders using RGA, copy the x64 version of Microsoft's D3D compiler to a subdirectory -named "x64" under the RGA executable's directory (for example, D3DCompiler_47.dll). +named "utils" under the RGA executable's directory (for example, D3DCompiler_47.dll). ### Building on Ubuntu ### * One time setup: @@ -90,7 +92,7 @@ named "x64" under the RGA executable's directory (for example, D3DCompiler_47.dl * sudo apt-get install gcc-multilib g++-multilib * sudo apt-get install libglu1-mesa-dev mesa-common-dev libgtk2.0-dev * sudo apt-get install zlib1g-dev libx11-dev:i386 - * Install CMake 3.5 or above. For auto-detecting the Vulkan SDK version 3.7 or above is required. + * Install CMake 3.10 or above. For auto-detecting the Vulkan SDK version 3.7 or above is required. * Install python 2.7 (or above) * To build the GUI app, you should also have Qt installed @@ -100,11 +102,11 @@ named "x64" under the RGA executable's directory (for example, D3DCompiler_47.dl On Linux, it is recommended to explicitly pass to CMake the location of the Vulkan SDK include and lib directories as well as the location of Qt. For example: - ./Prebuild.sh --qt ~/Qt-5.9.2/5.9.2/gcc_64 --vk-include ~/work/vulkan-sdk/1.1.97.0/x86_64/include/ --vk-lib ~/work/vulkan-sdk/1.1.97.0/x86_64/lib/ + ./Prebuild.sh --qt ~/Qt-5.15.2/5.15.2/gcc_64 --vk-include ~/work/vulkan-sdk/1.1.97.0/x86_64/include/ --vk-lib ~/work/vulkan-sdk/1.1.97.0/x86_64/lib/ This will fetch all the dependencies and generate the make files. - Then, cd to the auto-generated subfolder Build/CMake/linux and run make. + Then, cd to the auto-generated subfolder build/linux/make and run make. -=- @@ -136,11 +138,11 @@ Run the rga executable. * DirectX 11: rga -s dx11 -h * DirectX Raytracing: rga -s dxr -h - Note: RGA's DX11 mode requires Microsoft's D3D Compiler DLL in runtime. If you copy the relevant D3D Compiler DLL to the x64 + Note: RGA's DX11 mode requires Microsoft's D3D Compiler DLL in runtime. If you copy the relevant D3D Compiler DLL to the utils subdirectory under the executable's directory, RGA will use that DLL in runtime. The default D3D compiler that RGA public releases ship with is d3dcompiler_47.dll. * OpenGL: rga -s opengl -h - * ROCm OpenCL: rga -s rocm-cl -h + * OpenCL offline: rga -s opencl -h * Vulkan live-driver: rga -s vulkan -h * Vulkan offline - glsl: rga -s vk-offline -h * Vulkan offline - SPIR-V binary input: rga -s vk-offline-spv -h diff --git a/RadeonGPUAnalyzerBackend/CMakeLists.txt b/RadeonGPUAnalyzerBackend/CMakeLists.txt deleted file mode 100755 index d873888..0000000 --- a/RadeonGPUAnalyzerBackend/CMakeLists.txt +++ /dev/null @@ -1,155 +0,0 @@ -cmake_minimum_required (VERSION 2.6) -project (radeon_gpu_analyzer_backend) - -# The version number -set (radeon_gpu_analyzer_backend_VERSION_MAJOR 1) -set (radeon_gpu_analyzer_backend_VERSION_MINOR 2) - -# Project-specific preprocessor directives -add_definitions(-DRGA_BACKEND_EXPORTS) - -# Windows-specific preprocessor directives -if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - add_definitions(-D_CRT_SECURE_NO_WARNINGS) -endif() - -# Add these definitions if static linkage is used with the other projects -add_definitions(-DAMDTBASETOOLS_STATIC -DAMDTOSWRAPPERS_STATIC) - -# Identify if this script runs on a Debian system -set (IsDebian FALSE) -if(EXISTS "/etc/debian_version") - set(IsDebian TRUE) -endif() - -# Configure a header file to pass some of the CMake settings -# to the source code -configure_file ( - "${PROJECT_SOURCE_DIR}/RadeonGPUAnalyzerBackendConfig.h.in" - "${PROJECT_BINARY_DIR}/radeon_gpu_analyzer_backendConfig.h" - ) - -# Include directories -include_directories("${PROJECT_SOURCE_DIR}/../") -include_directories("${PROJECT_SOURCE_DIR}/../../Common/Lib/Ext/") -include_directories("${PROJECT_SOURCE_DIR}/Src/Common") -include_directories("${PROJECT_SOURCE_DIR}/Src/Emulator/Parser") -include_directories("${PROJECT_SOURCE_DIR}") -include_directories("${PROJECT_SOURCE_DIR}/../../Common/Src") -include_directories("${PROJECT_SOURCE_DIR}/../../Common/Src/CElf/Include") -include_directories("${PROJECT_SOURCE_DIR}/../../Common/Src/DeviceInfo") -include_directories("${PROJECT_SOURCE_DIR}/../../Common/Src/DynamicLibraryModule") -include_directories("${PROJECT_SOURCE_DIR}/../../Common/Src/AMDTMutex") -include_directories("${PROJECT_SOURCE_DIR}/../../Common/Src/TSingleton") -include_directories("${PROJECT_SOURCE_DIR}/../../Common/Src/Misc") -include_directories("${PROJECT_SOURCE_DIR}/../../Common/Src/ACLModuleManager") -include_directories("${PROJECT_SOURCE_DIR}/../../Common/Lib/AMD/DX10ASM") -include_directories("${PROJECT_SOURCE_DIR}/../../Common/Lib/AMD/CAL/8.95") -include_directories("${PROJECT_SOURCE_DIR}/../../Common/Lib/AMD/CAL/8.95/include") -include_directories("${PROJECT_SOURCE_DIR}/../../Common/Lib/AMD/ACL/TOT/include") -include_directories("${PROJECT_SOURCE_DIR}/../../Common/Lib/AMD/APPSDK/3-0/include") -include_directories("${PROJECT_SOURCE_DIR}/../../Common/Lib/Ext/yaml-cpp/include") -include_directories("${PROJECT_SOURCE_DIR}/../Utils/Include") - -if (NOT IsDebian) -include_directories("${PROJECT_SOURCE_DIR}/../../Common/Lib/Ext/Boost/boost_1_59_0") -endif() - -# Windows-specific include files -if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - include_directories("${PROJECT_SOURCE_DIR}/../Core/DX10ASM/Include") - include_directories("${PROJECT_SOURCE_DIR}/../../Common/Src/ShaderUtils") - include_directories("${PROJECT_SOURCE_DIR}/../../Common/Src/ShaderUtils/DX10") - include_directories("${PROJECT_SOURCE_DIR}/../../Common/Src/ShaderUtils/DX11") - include_directories("${PROJECT_SOURCE_DIR}/../Core/DX12/Backend/Src") -endif() - -# Source files that are common to Windows and Linux -file(GLOB COMMON_SRC - "Src/*.cpp" - "Src/*.h" - "Src/Emulator/Parser/be_instruction.cpp" - "Src/Emulator/Parser/be_isa_parser.cpp" - "Src/Emulator/Parser/be_isa_program_graph.cpp" - "Src/Emulator/Parser/be_parser_si.cpp" - "Src/Emulator/Parser/be_parser_si_ds.cpp" - "Src/Emulator/Parser/be_parser_si_exp.cpp" - "Src/Emulator/Parser/be_parser_si_mimg.cpp" - "Src/Emulator/Parser/be_parser_si_mtbuf.cpp" - "Src/Emulator/Parser/be_parser_si_mubuf.cpp" - "Src/Emulator/Parser/be_parser_si_smrd.cpp" - "Src/Emulator/Parser/be_parser_si_sop1.cpp" - "Src/Emulator/Parser/be_parser_si_sop2.cpp" - "Src/Emulator/Parser/be_parser_si_sopc.cpp" - "Src/Emulator/Parser/be_parser_si_sopk.cpp" - "Src/Emulator/Parser/be_parser_si_sopp.cpp" - "Src/Emulator/Parser/be_parser_si_vintrp.cpp" - "Src/Emulator/Parser/be_parser_si_vop.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/DynamicLibraryModule/DynamicLibraryModule.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/DynamicLibraryModule/ACLModule.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/ACLModuleManager/ACLModuleManager.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/AMDTMutex/AMDTMutex.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/DynamicLibraryModule/CALModule.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/CElf/Src/CElf.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/CElf/Src/CElfSection.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/CElf/Src/CElfStringTable.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/CElf/Src/CElfSymbolTable.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/Misc/GDT_Memory.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/DynamicLibraryModule/OpenCLModule.cpp" -) - -# Windows-specific source files -file(GLOB WINDOWS_SRC - "${PROJECT_SOURCE_DIR}/../../Common/Src/DynamicLibraryModule/DXXModule.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/ShaderUtils/DX10/D3D10ShaderObject.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/ShaderUtils/DX10/D3D10ShaderUtils.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/ShaderUtils/DX10/DXBCChecksum.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/ShaderUtils/DX10/IBlob.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/ShaderUtils/StringUtils.cpp" - "${PROJECT_SOURCE_DIR}/../Core/DX12/Backend/Src/rg_dxr_state_desc_reader.cpp" - "${PROJECT_SOURCE_DIR}/../Core/DX12/Backend/Src/rg_dxr_output_metadata.cpp" - "${PROJECT_SOURCE_DIR}/../Core/DX12/Backend/Src/rg_dx12_utils.cpp" -) - -# Device Info lib sources -file(GLOB DEVICE_INFO_SRC - "${PROJECT_SOURCE_DIR}/../../Common/Src/DeviceInfo/DeviceInfoUtils.cpp" - "${PROJECT_SOURCE_DIR}/../../Common/Src/DeviceInfo/DeviceInfo.cpp" -) - -if(AMD_INTERNAL) - file(GLOB DEVICE_INFO_SRC - "${PROJECT_SOURCE_DIR}/../../Common/Src/DeviceInfo-Internal/DeviceInfoInternal.cpp" - ${DEVICE_INFO_SRC} - ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DAMD_INTERNAL -DAMDT_INTERNAL") -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}/../Core/DX10ASM/Lib/VS2015/x64/Release_Static") - find_library(DX10ASM_LIBRARY_DEBUG DX10ASMLib_s HINTS "${PROJECT_SOURCE_DIR}/../Core/DX10ASM/Lib/VS2015/x64/Debug_Static") - else() - find_library(DX10ASM_LIBRARY_RELEASE DX10ASMLib_s HINTS "${PROJECT_SOURCE_DIR}/../Core/DX10ASM/Lib/VS2015/Win32/Release_Static") - find_library(DX10ASM_LIBRARY_DEBUG DX10ASMLib_s HINTS "${PROJECT_SOURCE_DIR}/../Core/DX10ASM/Lib/VS2015/Win32/Debug_Static") - 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}) -endif() - -# set binary suffix -set_target_properties(radeon_gpu_analyzer_backend PROPERTIES DEBUG_POSTFIX -d) - -# Link settings -if (CMAKE_64BIT_TARGET) - link_directories(${PROJECT_SOURCE_DIR}/../../Lib/Ext/zlib/1.2.8/contrib/vstudio/vc14/x64/ZlibStatRelease) -else() - link_directories(${PROJECT_SOURCE_DIR}/../../Lib/Ext/zlib/1.2.8/contrib/vstudio/vc14/x86/ZlibStatRelease) -endif() - -# Link libraries -target_link_libraries(radeon_gpu_analyzer_backend AMDTOSWrappers AMDTBaseTools) diff --git a/RadeonGPUAnalyzerBackend/Include/be_data_types.h b/RadeonGPUAnalyzerBackend/Include/be_data_types.h deleted file mode 100644 index 03a1625..0000000 --- a/RadeonGPUAnalyzerBackend/Include/be_data_types.h +++ /dev/null @@ -1,79 +0,0 @@ -//================================================================= -// Copyright 2020 Advanced Micro Devices, Inc. All rights reserved. -//================================================================= - -#ifndef __beDataTypes_h -#define __beDataTypes_h - -#include -#include -#include - -#ifdef _WIN32 - #pragma warning(push) - #pragma warning(disable:4309) -#endif -#include -#ifdef _WIN32 - #pragma warning(pop) -#endif - -// A structure to hold the shader file names of a given pipeline. -struct BeProgramPipeline -{ - // Clears all pipeline shaders. - void ClearAll() - { - vertex_shader.makeEmpty(); - tessellation_control_shader.makeEmpty(); - tessellation_evaluation_shader.makeEmpty(); - geometry_shader.makeEmpty(); - fragment_shader.makeEmpty(); - compute_shader.makeEmpty(); - } - - // Vertex shader. - gtString vertex_shader; - - // Tessellation control shader. - gtString tessellation_control_shader; - - // Tessellation evaluation shader. - gtString tessellation_evaluation_shader; - - // Geometry shader. - gtString geometry_shader; - - // Fragment shader. - gtString fragment_shader; - - // Compute shader. - gtString compute_shader; -}; - -// The type of stage used for a shader module. -enum BePipelineStage : char -{ - kVertex, - kTessellationControl, - kTessellationEvaluation, - kGeometry, - kFragment, - kCompute, - - kCount -}; - -// An array containing per-stage file names. -typedef std::array BeVkPipelineFiles; - -// Physical adapter data. -struct BeVkPhysAdapterInfo -{ - uint32_t id; - std::string name; - std::string vkDriverVersion; - std::string vkAPIVersion; -}; - -#endif // __beDataTypes_h diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgAddCreateMenuItem.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgAddCreateMenuItem.h deleted file mode 100644 index d09f3ab..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgAddCreateMenuItem.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -// Qt. -#include - -// Local. -#include "ui_rgAddCreateMenuItem.h" -#include - -// Forward declarations: -class QPushButton; - -class rgAddCreateMenuItem : - public rgMenuItem -{ - Q_OBJECT - -public: - explicit rgAddCreateMenuItem(rgMenu* pParent = nullptr); - virtual ~rgAddCreateMenuItem() = default; - - // Getter for the Add button. - QPushButton* GetAddButton() const; - - // Getter for the Create button. - QPushButton* GetCreateButton() const; - -private: - // Set the cursor to pointing hand cursor for various widgets. - void SetCursor(); - - // The generated UI object for this view. - Ui::rgAddCreateMenuItem ui; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgBrowseButton.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgBrowseButton.h deleted file mode 100644 index fa892c6..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgBrowseButton.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -// Qt. -#include - -class rgBrowseButton : public QPushButton -{ - Q_OBJECT - -public: - rgBrowseButton(QWidget* pParent); - virtual ~rgBrowseButton() = default; - -protected: - // Re-implement focusInEvent. - virtual void focusInEvent(QFocusEvent* pEvent) override; - - // Re-implement focusOutEvent. - virtual void focusOutEvent(QFocusEvent* pEvent) override; - -signals: - // Signal the focus in event. - void BrowseButtonFocusInEvent(); - - // Signal the focus out event. - void BrowseButtonFocusOutEvent(); -}; - diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgBuildSettingsWidget.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgBuildSettingsWidget.h deleted file mode 100644 index 52576c6..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgBuildSettingsWidget.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -// Qt. -#include - -class rgBuildSettingsWidget : public QFrame -{ - Q_OBJECT - -public: - rgBuildSettingsWidget(QWidget* pParent); - virtual ~rgBuildSettingsWidget() = default; - -protected: - virtual void focusInEvent(QFocusEvent* pEvent) override; - virtual void focusOutEvent(QFocusEvent* pEvent) override; - -signals: - void FrameFocusInEventSignal(); - void FrameFocusOutEventSignal(); -}; - diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgCheckBox.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgCheckBox.h deleted file mode 100644 index 3050b1f..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgCheckBox.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -// Qt. -#include - -class rgCheckBox : public QCheckBox -{ - Q_OBJECT - -public: - rgCheckBox(QWidget* pParent); - virtual ~rgCheckBox() = default; - -protected: - virtual void focusInEvent(QFocusEvent* pEvent) override; - virtual void focusOutEvent(QFocusEvent* pEvent) override; - virtual void mouseMoveEvent(QMouseEvent* pEvent) override; - -signals: - void CheckBoxFocusInEvent(); - void CheckBoxFocusOutEvent(); -}; - diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgComboBox.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgComboBox.h deleted file mode 100644 index c126a9d..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgComboBox.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -// Qt. -#include - -class rgComboBox : public QComboBox -{ - Q_OBJECT - -public: - rgComboBox(QWidget* pParent); - virtual ~rgComboBox() = default; - -protected: - virtual void mousePressEvent(QMouseEvent* pEvent) override; - -signals: - void ComboBoxFocusInEvent(); -}; - diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgEditorElementArrayElementAdd.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgEditorElementArrayElementAdd.h deleted file mode 100644 index 877878f..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgEditorElementArrayElementAdd.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -// Local. -#include -#include - -// Forward declarations. -class rgPipelineStateEditorWidgetArrayElementAdd; - -class rgEditorElementArrayElementAdd : public rgEditorElement -{ - Q_OBJECT - -public: - rgEditorElementArrayElementAdd(QWidget* pParent, const std::string& memberName, std::function elementRemovedCallback = nullptr); - virtual ~rgEditorElementArrayElementAdd() = default; - - // Retrieve the editor widget used by the row. - virtual rgPipelineStateEditorWidget* GetEditorWidget() override; - - // Resize the array by adding 1 new element to the end. - void AddNewElement(); - - // Remove the array element at the given index. - void RemoveElement(int elementIndex); - - // A method used to invoke the resize callback. - void InvokeElementResizedCallback(); - - // Retrieve the element containing the array size. - rgEditorElementNumeric* GetArraySizeElement() const; - - // Set the array size element. This element is used to dictate the dimension of an array. - void SetArraySizeElement(rgEditorElementNumeric* pArraySizeElement); - - // Set the maximum dimension that the array can be increased to. - void SetMaximumArraySize(uint32_t size); - - // Set the resize callback, which is invoked when the array is resized. - void SetResizeCallback(std::function resizeCallback); - -private: - // The editor element containing the associated array's size. - rgEditorElementNumeric* m_pArraySizeElement = nullptr; - - // The widget used to edit the array dimension. - rgPipelineStateEditorWidgetArrayElementAdd* m_pEditorWidget = nullptr; - - // A callback invoked when the element value is changed. - std::function m_elementRemovedCallback = nullptr; - - // A callback invoked when the array is finished being resized. - std::function m_arrayResizedCallback = nullptr; - - // The maximum array size. When -1, the array dimension is not limited. - int32_t m_maximumSize = -1; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgEditorElementArrayElementRemove.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgEditorElementArrayElementRemove.h deleted file mode 100644 index 27b8ab0..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgEditorElementArrayElementRemove.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -// Local. -#include - -// Forward declarations. -class rgEditorElementArrayElementAdd; -class rgPipelineStateEditorWidgetArrayElementRemove; - -class rgEditorElementArrayElementRemove : public rgEditorElement -{ - Q_OBJECT - -public: - rgEditorElementArrayElementRemove(QWidget* pParent, const std::string& memberName); - virtual ~rgEditorElementArrayElementRemove() = default; - - // Retrieve the editor widget used by the row. - virtual rgPipelineStateEditorWidget* GetEditorWidget() override; - - // Update the array root element and child element index. - void SetElementIndex(rgEditorElementArrayElementAdd* pParentArray, int childIndex); - -private slots: - // A handler invoked when the delete button is clicked. - void HandleDeleteButtonClicked(); - -private: - // Connect signals to slots. - void ConnectSignals(); - - // The index of the associated child element. - int m_childIndex; - - // The array element being resized. - rgEditorElementArrayElementAdd* m_pArrayRootElement = nullptr; - - // The widget used to remove a single array element. - rgPipelineStateEditorWidgetArrayElementRemove* m_pEditorWidget = nullptr; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgEditorElementBool.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgEditorElementBool.h deleted file mode 100644 index baf9a3d..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgEditorElementBool.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -// Local. -#include - -// Forward declarations. -class rgPipelineStateEditorWidgetBool; - -class rgEditorElementBool : public rgEditorElement -{ - Q_OBJECT - -public: - rgEditorElementBool(QWidget* pParent, const std::string& memberName, uint32_t* pValue); - virtual ~rgEditorElementBool() = default; - - // Get the data held within this item. - virtual QVariant Data(int column) const; - - // Retrieve the editor widget used by the row. - virtual rgPipelineStateEditorWidget* GetEditorWidget() override; - - // Get the current value of the element. - bool GetValue() const; - - // Set the current value of the element. - void SetValue(bool value); - -protected: - // A handler invoked when the user has changed the editable value. - virtual void ValueChangedHandler() override; - -private: - // The current value of the element. - uint32_t* m_pValue = nullptr; - - // The widget used to edit the boolean value. - rgPipelineStateEditorWidgetBool* m_pEditorWidget = nullptr; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgEditorElementNumeric.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgEditorElementNumeric.h deleted file mode 100644 index 0ef9fe3..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgEditorElementNumeric.h +++ /dev/null @@ -1,169 +0,0 @@ -#pragma once - -// C++ -#include - -// Qt. -#include - -// Local. -#include -#include - -// A type mapping struct. -template -struct rgEditorTypeMap {}; - -// Specializations of type mapping struct. -// This mapping allows a templated type to map to a given enum type declaration, -// which can then be provided to the base class. -template<> struct rgEditorTypeMap { static const rgEditorDataType dataType = rgEditorDataType::Int8; }; -template<> struct rgEditorTypeMap { static const rgEditorDataType dataType = rgEditorDataType::Int16; }; -template<> struct rgEditorTypeMap { static const rgEditorDataType dataType = rgEditorDataType::Int32; }; -template<> struct rgEditorTypeMap { static const rgEditorDataType dataType = rgEditorDataType::UInt8; }; -template<> struct rgEditorTypeMap { static const rgEditorDataType dataType = rgEditorDataType::UInt16; }; -template<> struct rgEditorTypeMap { static const rgEditorDataType dataType = rgEditorDataType::UInt32; }; -template<> struct rgEditorTypeMap { static const rgEditorDataType dataType = rgEditorDataType::Float; }; -template<> struct rgEditorTypeMap { static const rgEditorDataType dataType = rgEditorDataType::Double; }; - -// A templated element that can be used to edit multiple types of numeric data. -template -class rgEditorElementNumeric : public rgEditorElement -{ -public: - rgEditorElementNumeric(QWidget* pParent, const std::string& memberName, T* pDataPtr, std::function valueChangedCallback = nullptr) - : rgEditorElement(pParent, memberName, rgEditorTypeMap::dataType, valueChangedCallback), m_pValue(pDataPtr) - { - m_pEditorWidget = new rgPipelineStateEditorWidgetNumeric(this); - assert(m_pEditorWidget != nullptr); - if (m_pEditorWidget != nullptr) - { - // Set the type being edited by the widget. - m_pEditorWidget->SetType(rgEditorTypeMap::dataType); - m_pEditorWidget->SetValue(GetValue()); - - // Insert the editor widget into the row. - ui.editorLayout->insertWidget(0, m_pEditorWidget); - - // Connect internal editor signals. - bool isConnected = connect(m_pEditorWidget, &rgPipelineStateEditorWidgetNumeric::EditingFinished, this, &rgEditorElement::HandleValueChanged); - assert(isConnected); - - // Connect the editor widget focus in signal. - isConnected = connect(m_pEditorWidget, &rgPipelineStateEditorWidgetNumeric::FocusInSignal, this, &rgEditorElement::HandleEditorFocusIn); - assert(isConnected); - - // Connect the editor widget focus out signal. - isConnected = connect(m_pEditorWidget, &rgPipelineStateEditorWidgetNumeric::FocusOutSignal, this, &rgEditorElement::HandleEditorFocusOut); - assert(isConnected); - } - } - virtual ~rgEditorElementNumeric() = default; - - // Retrieve the editor widget used by the row. - virtual rgPipelineStateEditorWidget* GetEditorWidget() override - { - return m_pEditorWidget; - } - - // Get the data held within this item. - virtual QVariant Data(int column) const override - { - if (column == static_cast(rgRowData::RowDataMemberValue)) - { - return GetValue(); - } - else - { - return rgEditorElement::Data(column); - } - } - - // Get the current value of the element. - T GetValue() const - { - assert(m_pValue != nullptr); - return *m_pValue; - } - - // Set the current value of the element. - void SetValue(T value) - { - assert(m_pValue != nullptr); - if (m_pValue != nullptr) - { - // Update the value bound to this element. - *m_pValue = value; - - if (m_valueChangedCallback != nullptr) - { - m_valueChangedCallback(); - } - } - } - -protected: - // Handle changes to the value. - virtual void ValueChangedHandler() - { - assert(m_pEditorWidget != nullptr); - if (m_pEditorWidget != nullptr) - { - QVariant editorValue = m_pEditorWidget->GetValue(); - bool conversionSuccessful = false; - - switch (m_type) - { - case rgEditorDataType::Int8: - case rgEditorDataType::Int16: - case rgEditorDataType::Int32: - { - int value = editorValue.toInt(&conversionSuccessful); - if (conversionSuccessful) - { - SetValue(value); - } - } - break; - case rgEditorDataType::UInt8: - case rgEditorDataType::UInt16: - case rgEditorDataType::UInt32: - { - uint value = editorValue.toUInt(&conversionSuccessful); - if (conversionSuccessful) - { - SetValue(value); - } - } - break; - case rgEditorDataType::Float: - case rgEditorDataType::Double: - { - double value = editorValue.toFloat(&conversionSuccessful); - if (conversionSuccessful) - { - SetValue(value); - } - } - break; - default: - // If we got here, the data type is not editable. - assert(false); - } - } - } - -private: - // The widget used to edit the numeric value. - rgPipelineStateEditorWidgetNumeric* m_pEditorWidget = nullptr; - - // The current value of the element. - T* m_pValue = nullptr; -}; - -// A helper function used to create a numeric element without having to provide a template type argument. -template static -rgEditorElement* MakeNumericElement(QWidget* pParent, const std::string& memberName, J* pDataPtr, std::function valueChangedCallback = nullptr) -{ - return new rgEditorElementNumeric(pParent, memberName, pDataPtr, valueChangedCallback); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgHandleTabFocusEventFilter.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgHandleTabFocusEventFilter.h deleted file mode 100644 index e4ba098..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgHandleTabFocusEventFilter.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -// Qt. -#include - -class QEvent; - -// This class is used as a memberless filter for qt events, and as such it -// only needs to exist once. -class rgHandleTabFocusEventFilter : public QObject -{ - Q_OBJECT - -public: - // Singleton get function. - static rgHandleTabFocusEventFilter& Get(); - -signals: - // A signal emitted when the user presses the tab key. - void TabPressed(); - - // A signal emitted when the user presses the shift+tab keys. - void ShiftTabPressed(); - -private: - rgHandleTabFocusEventFilter(QObject* pParent = nullptr) : QObject(pParent) {} - ~rgHandleTabFocusEventFilter() = default; - -protected: - // Event filtering function. - virtual bool eventFilter(QObject *pObject, QEvent *pEvent) override; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgIsaDisassemblyViewGraphics.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgIsaDisassemblyViewGraphics.h deleted file mode 100644 index fce5a03..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgIsaDisassemblyViewGraphics.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -// Local. -#include - -// A class responsible for displaying ISA code for graphics or compute pipelines. -class rgIsaDisassemblyViewGraphics : public rgIsaDisassemblyView -{ - Q_OBJECT - -public: - explicit rgIsaDisassemblyViewGraphics(QWidget* pParent = nullptr); - virtual ~rgIsaDisassemblyViewGraphics() = default; - - // Populate the disassembly view using the given clone and build outputs. - virtual bool PopulateBuildOutput(const std::shared_ptr pProjectClone, const rgBuildOutputsMap& buildOutputs) override; - -private: - bool PopulateDisassemblyView(const ShaderInputFileArray& shaderStageArray, const rgBuildOutputsMap& buildOutput); -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgIsaDisassemblyViewOpenCL.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgIsaDisassemblyViewOpenCL.h deleted file mode 100644 index 552919f..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgIsaDisassemblyViewOpenCL.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -// Local. -#include - -// A class responsible for displaying ISA code for multiple GPU architectures. -class rgIsaDisassemblyViewOpenCL : public rgIsaDisassemblyView -{ - Q_OBJECT - -public: - rgIsaDisassemblyViewOpenCL(QWidget* pParent); - virtual ~rgIsaDisassemblyViewOpenCL() = default; - - // Populate the disassembly view using the given clone and build outputs. - virtual bool PopulateBuildOutput(const std::shared_ptr pProjectClone, const rgBuildOutputsMap& buildOutputs) override; - -protected: - - // Populate the disassembly view with the given CLI build output. - bool PopulateDisassemblyView(const std::vector& sourceFiles, const rgBuildOutputsMap& buildOutput); -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgIsaDisassemblyViewTitlebar.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgIsaDisassemblyViewTitlebar.h deleted file mode 100644 index 1265585..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgIsaDisassemblyViewTitlebar.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -// Qt. -#include - -// A title bar inserted above the disassembly view. -class rgIsaDisassemblyViewTitlebar : public QWidget -{ - Q_OBJECT - -public: - rgIsaDisassemblyViewTitlebar(QWidget* pParent = nullptr); - virtual ~rgIsaDisassemblyViewTitlebar() = default; - -signals: - // A signal to indicate that the frame has gained focus. - void FrameFocusInSignal(); - - // A signal to indicate that the title bar was double clicked. - void ViewTitleBarDoubleClickedSignal(); - -protected: - // Re-implement paintEvent. - virtual void paintEvent(QPaintEvent* pEvent) override; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgIsaDisassemblyViewVulkan.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgIsaDisassemblyViewVulkan.h deleted file mode 100644 index d1f19e8..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgIsaDisassemblyViewVulkan.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -// Qt. -#include - -// Local. -#include - -// A class responsible for displaying ISA code for multiple GPU architectures. -class rgIsaDisassemblyViewVulkan : public rgIsaDisassemblyViewGraphics -{ - Q_OBJECT - -public: - rgIsaDisassemblyViewVulkan(QWidget* pParent); - virtual ~rgIsaDisassemblyViewVulkan() = default; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgListWidget.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgListWidget.h deleted file mode 100644 index 7426aab..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgListWidget.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -// Qt. -#include - -// Local. -#include - -class rgListWidget : public QListWidget -{ - Q_OBJECT - -public: - rgListWidget(QWidget* pParent = nullptr); - virtual ~rgListWidget() = default; - -protected: - // Re-implement the mouseMoveEvent method. - virtual void mouseMoveEvent(QMouseEvent* pEvent) override; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgMainWindowTabWidget.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgMainWindowTabWidget.h deleted file mode 100644 index 310b44a..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgMainWindowTabWidget.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -// Qt. -#include - -// Local. -#include - -/// Support for the custom Tab Widget. -class rgMainWindowTabWidget : public QTabWidget -{ - Q_OBJECT -public: - explicit rgMainWindowTabWidget(QWidget* pParent = nullptr); - virtual ~rgMainWindowTabWidget() {}; - void SetTabEnabled(int index, bool); - void SetSpacerIndex(const int index); - void SetTabTool(int index, QWidget* pToolWidget); - int TabHeight() const; - rgMainWindowTabBar* GetTabBar(); - -protected: - // Get a pointer to the tab bar. - QTabBar* tabBar() const; - - // The overridden resizeEvent. - virtual void resizeEvent(QResizeEvent* pResizeEvent) override; - -private: - // Custom tab bar. - rgMainWindowTabBar* m_pTabBar = nullptr; -}; diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgMenuItem.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgMenuItem.h deleted file mode 100644 index 888c181..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgMenuItem.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -// Qt. -#include - -// Forward declarations. -class rgMenu; - -class rgMenuItem : public QWidget -{ - Q_OBJECT - -public: - rgMenuItem(rgMenu* pParent = nullptr); - virtual ~rgMenuItem() = default; - - // The parent menu that this item lives within. - rgMenu* GetParentMenu() const; - -private: - // The parent menu for the item. - rgMenu* m_pParentMenu = nullptr; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgMenuPipelineStateItem.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgMenuPipelineStateItem.h deleted file mode 100644 index b1597e0..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgMenuPipelineStateItem.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -// Local. -#include -#include -#include - -// Forward declarations: -class QPushButton; - -class rgMenuPipelineStateItem - : public rgMenuItem -{ - Q_OBJECT - -public: - explicit rgMenuPipelineStateItem(rgPipelineType pipelineType, rgMenu* pParent = nullptr); - virtual ~rgMenuPipelineStateItem() = default; - - // Handler invoked when the user drags a file over. - virtual void dragEnterEvent(QDragEnterEvent* pEvent) override; - - // Handler invoked when the user drops a dragged file. - virtual void dropEvent(QDropEvent *pEvent) override; - - // Handler invoked when the user leaves the button. - virtual void dragLeaveEvent(QDragLeaveEvent* pEvent); - - // Get a pointer to the pipeline state button within the item. - QPushButton* GetPipelineStateButton() const; - - // Set the cursor to the specified type. - void SetCursor(const QCursor& cursor); - - // Alter the visual style of the item if it is currently selected. - void SetCurrent(bool isCurrent); - - // Get the current state. - bool IsCurrent() const; - - // Simulate a click on the menu item. - void ClickMenuItem() const; - -signals: - // A signal emitted when a PSO editor file is dragged and dropped. - void DragAndDropExistingFile(const std::string& filePath); - - // Signal emitted when the pipeline state button is clicked. - void PipelineStateButtonClicked(rgMenuPipelineStateItem* pItem); - -private slots: - // Handler invoked when the Pipeline State button is clicked. - void HandlePipelineStateButtonClicked(bool checked); - -private: - // Connect signals. - void ConnectSignals(); - - // Set the text for the build settings item. - void SetItemText(const std::string& itemText); - - // Change appearance to "focus in". - void GotFocus(); - - // Change appearance to "focus out". - void LostFocus(); - - // The Build Settings file item interface. - Ui::rgMenuPipelineStateItem ui; - - // Flag to keep track of whether this item is currently selected. - bool m_current = false; - - // The pipeline type. - rgPipelineType m_pipelineType; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgModePushButton.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgModePushButton.h deleted file mode 100644 index 021b4cd..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgModePushButton.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -// Qt. -#include - -class Qwidget; - -class rgModePushButton : public QPushButton -{ - Q_OBJECT - -public: - explicit rgModePushButton(QWidget* pParent = nullptr); - virtual ~rgModePushButton() {} - void SetText(const std::string& string); - void SetColor(const QColor& color); - void SetHoverColor(const QColor& hoverColor); - void SetNonHoverColor(const QColor& nonHoverColor); - -protected: - // Re-implement paintEvent method. - virtual void paintEvent(QPaintEvent *pEvent) override; - - // Re-implement key press event method. - virtual void keyPressEvent(QKeyEvent* pEvent) override; - - // Create vertices for the up arrow. - void CreateVertices(); - - // The number of vertices for the up arrow. - static const int s_NUMBER_OF_VERTICES = 3; - - // The vertices for the up arrow. - QPointF m_vertices[s_NUMBER_OF_VERTICES]; - - // The color of the arrow. - QColor m_color; - - // The font color for the button text. - QColor m_fontColor; - - // The color to use when the user hovers over the button. - QColor m_hoverColor; - - // The color to use when the user is not hovering over the button. - QColor m_nonHoverColor; - - // The text to display on the button. - std::string m_text; - - // The width of the pen to use for the text. - int m_penWidth; - - // The size of the button. - int m_size; - - // The size of the text font. - int m_fontSize; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateEditorWidget.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateEditorWidget.h deleted file mode 100644 index 23e7a3a..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateEditorWidget.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -// Qt. -#include - - // Local. -#include - -// The base class for all state item editor widgets. -class rgPipelineStateEditorWidget : public QWidget -{ - Q_OBJECT - -public: - rgPipelineStateEditorWidget(QWidget* pParent = nullptr); - virtual ~rgPipelineStateEditorWidget() = default; - - // An overridden keyPressEvent handler. - virtual void keyPressEvent(QKeyEvent* pEvent) override; - -signals: - // A signal emitted when the user has changed the editable value. - void EditingFinished(); - - // A signal emitted when the editor widget gets focus. - void FocusInSignal(); - - // A signal emitted when the editor widget loses focus. - void FocusOutSignal(); - -protected: - // The type of value being edited. - rgEditorDataType m_type; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateEditorWidgetArrayElementAdd.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateEditorWidgetArrayElementAdd.h deleted file mode 100644 index d6bd2a3..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateEditorWidgetArrayElementAdd.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -// Local. -#include -#include - -// Forward declarations. -class QValidator; -namespace Ui { -class rgPipelineStateEditorWidgetArrayElementAdd; -} -class rgEditorElementArrayElementAdd; - -class rgPipelineStateEditorWidgetArrayElementAdd : public rgPipelineStateEditorWidget -{ - Q_OBJECT - -public: - explicit rgPipelineStateEditorWidgetArrayElementAdd(rgEditorElementArrayElementAdd* pParent = nullptr); - virtual ~rgPipelineStateEditorWidgetArrayElementAdd() = default; - -private slots: - // Handler invoked when the add button is clicked. - void HandleAddButtonClicked(); - -private: - // Connect the widget's internal signals. - void ConnectSignals(); - - // Update the array size label. - void UpdateArraySizeLabel(); - - // The array element being resized. - rgEditorElementArrayElementAdd* m_pArrayRootElement = nullptr; - - // The generated UI object. - Ui::rgPipelineStateEditorWidgetArrayElementAdd ui; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateEditorWidgetArrayElementRemove.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateEditorWidgetArrayElementRemove.h deleted file mode 100644 index ad94f23..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateEditorWidgetArrayElementRemove.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -// Local. -#include -#include - -// Forward declarations. -class QValidator; -namespace Ui { -class rgPipelineStateEditorWidgetArrayElementRemove; -} -class rgEditorElementArrayElementAdd; - -class rgPipelineStateEditorWidgetArrayElementRemove : public rgPipelineStateEditorWidget -{ - Q_OBJECT - -public: - explicit rgPipelineStateEditorWidgetArrayElementRemove(QWidget* pParent = nullptr); - virtual ~rgPipelineStateEditorWidgetArrayElementRemove() = default; - - // Set the tooltip for the trash can icon (being built dynamically based on the element's index). - void SetTrashCanIconTooltip(const std::string& tooltipStr); - -signals: - // A signal emitted when the delete button is clicked. - void DeleteButtonClicked(); - -private: - // Connect the widget's internal signals. - void ConnectSignals(); - - // The array element being resized. - rgEditorElementArrayElementAdd* m_pArrayRootElement = nullptr; - - // The generated UI object. - Ui::rgPipelineStateEditorWidgetArrayElementRemove ui; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateEditorWidgetBool.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateEditorWidgetBool.h deleted file mode 100644 index 357ab56..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateEditorWidgetBool.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -// Local. -#include -#include - -namespace Ui { -class rgPipelineStateEditorWidgetBool; -} - -class rgPipelineStateEditorWidgetBool : public rgPipelineStateEditorWidget -{ - Q_OBJECT - -public: - explicit rgPipelineStateEditorWidgetBool(QWidget* pParent = nullptr); - virtual ~rgPipelineStateEditorWidgetBool() = default; - - // Get the state of the editor checkbox. - bool GetValue() const; - - // Set the state of the editor checkbox. - void SetValue(bool value); - -private: - // Connect internal signals. - void ConnectSignals(); - - // The generated UI object. - Ui::rgPipelineStateEditorWidgetBool ui; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateEditorWidgetNumeric.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateEditorWidgetNumeric.h deleted file mode 100644 index 27461b6..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateEditorWidgetNumeric.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -// Local. -#include -#include - -// Forward declarations. -class QValidator; -namespace Ui { -class rgPipelineStateEditorWidgetNumeric; -} - -class rgPipelineStateEditorWidgetNumeric : public rgPipelineStateEditorWidget -{ - Q_OBJECT - -public: - explicit rgPipelineStateEditorWidgetNumeric(QWidget* pParent = nullptr); - virtual ~rgPipelineStateEditorWidgetNumeric() = default; - - // Get the state of the editor checkbox. - QVariant GetValue() const; - - // Set the type of numeric data being edited. - void SetType(rgEditorDataType type); - - // Set the state of the editor checkbox. - void SetValue(QVariant value); - - // Highlight the substring. - void HighlightSubString(int startLocation, const std::string& searchString); - - // Update the matched substrings. - void UpdateStringMatchingLocation(int startLocation, int length, const std::string& searchString); - -protected: - // The generated UI object. - Ui::rgPipelineStateEditorWidgetNumeric ui; - -private: - // Connect internal signals. - void ConnectSignals(); - - // A vector to store string highlight data. - QVector m_stringHighlightData = {}; - - // Boolean to indicate substring highlight is requested. - bool m_highlightSubString; - - // The validator used to restrict editing to specific numeric types. - QValidator* m_pValidator = nullptr; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateModel.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateModel.h deleted file mode 100644 index 41832e4..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateModel.h +++ /dev/null @@ -1,217 +0,0 @@ -#pragma once - -// C++. -#include - -// Qt. -#include - -// Infra. -#include - -// Local. -#include -#include -#include -#include -#include - -// Forward declarations. -class rgPsoCreateInfo; -enum class rgPipelineType : char; -enum class rgEditorDataType : char; - -// rgPipelineStateModel is the object manages the PipelineStateView's tree data structure. -class rgPipelineStateModel : public QObject -{ - Q_OBJECT - -public: - rgPipelineStateModel(QWidget* pParent = nullptr); - virtual ~rgPipelineStateModel() = default; - - // Get the root element for the tree model. - rgEditorElement* GetRootElement() const; - - // Initialize the model with API-specific CreateInfo structures. - void InitializeDefaultPipelineState(QWidget* pParent, rgPipelineType pipelineType); - - // Search the model for the given string. - void Search(const QString& searchString, rgPipelineStateSearcher::SearchResultData& searchResults, rgEditorElement* pRootElement = nullptr); - - // Return the current pipeline type. - rgPipelineType GetPipelineType() const; - -signals: - // A signal emitted when a node should be expanded. - void ExpandNode(rgEditorElementArrayElementAdd* pArrayRoot); - -protected: - // Check that the pipeline state is valid. - virtual bool CheckValidPipelineState(std::string& errorString) const = 0; - - // Initialize the model with the default graphics pipeline state. - virtual void InitializeDefaultGraphicsPipeline() = 0; - - // Initialize the model with the default compute pipeline state. - virtual void InitializeDefaultComputePipeline() = 0; - - // Initialize the Graphics Pipeline CreateInfo tree structure. - virtual rgEditorElement* InitializeGraphicsPipelineCreateInfo(QWidget* pParent) = 0; - - // Initialize the Compute Pipeline CreateInfo tree structure. - virtual rgEditorElement* InitializeComputePipelineCreateInfo(QWidget* pParent) = 0; - - // Resize the given array, and copy existing element data into the new array where possible. - template - T* ResizeArray(const T* pOriginalArray, uint32_t oldSize, uint32_t newSize) - { - // Create an array of object with the new dimension. - T* pResizedArray = new T[newSize]{}; - - // If the element count was increased, copy all old contents. - // If it was reduced, copy as many as will fit in the new array. - uint32_t elementCount = newSize > oldSize ? oldSize : newSize; - - if (pOriginalArray != nullptr) - { - // Copy existing element data into the resized elements. - for (uint32_t index = 0; index < elementCount; ++index) - { - // Copy all member data into the new array elements. - memcpy(pResizedArray + index, pOriginalArray + index, sizeof(T)); - } - } - - return pResizedArray; - } - - // Remove the given element in the provided array and shift the following elements forward. - template - void RemoveElement(const T* pOriginalArray, int elementCount, int elementIndex) - { - // If we remove the given element, is it necessary to shift other subsequent elements? - if (elementCount > 1 && elementIndex < elementCount - 1) - { - // Shift all elements after the removed element. - for (int copyIndex = elementIndex; copyIndex < (elementCount - 1); ++copyIndex) - { - memcpy((void*)(pOriginalArray + copyIndex), pOriginalArray + (copyIndex + 1), sizeof(T)); - } - } - } - - // A helper function responsible for resizing element arrays while preserving - // existing element data. - // pRootElement is the root element for the array being resized in the model. - // elementCount is the new number of elements in the array. - // pArrayPointer is a reference to the existing array that is being resized. - // pElementTypeName is the API type name of an element in the array. - // initializationHandler is a callback that gets invoked to initialize each - // new element in the resized array. - // isFirstInit is a flag used to indicate if resize is being called as part of - // a first-time initialization of the tree structure. False indicates that the - // resize was triggered by an array size element being altered in the view. - template (rgEditorElement*, T*, int)> - void ResizeHandler(rgEditorElement* pRootElement, - uint32_t elementCount, - const T*& pArrayPointer, - const char* pElementTypeName, - U initializationHandler, - bool isFirstInit) - { - int numExistingElements = pRootElement->ChildCount(); - int newElementCount = static_cast(elementCount); - - if (newElementCount != numExistingElements) - { - if (isFirstInit) - { - numExistingElements = newElementCount; - } - - rgEditorElementArrayElementAdd* pArrayRoot = static_cast(pRootElement); - if (pArrayRoot != nullptr) - { - if (newElementCount == 0) - { - pRootElement->ClearChildren(); - RG_SAFE_DELETE(pArrayPointer); - - // Let the array root element know that the child elements were resized. - pArrayRoot->InvokeElementResizedCallback(); - } - else - { - // Allocate the new element array with the updated size. - T* pResized = - ResizeArray(pArrayPointer, static_cast(numExistingElements), static_cast(newElementCount)); - - // Remove all existing child element items from the array root node. - pRootElement->ClearChildren(); - - // Create a new element row for each item in the resized array. - CreateArrayElements(newElementCount, pElementTypeName, pArrayRoot, initializationHandler, pResized); - - // Destroy the old model data. - RG_SAFE_DELETE(pArrayPointer); - pArrayPointer = pResized; - - // Invoke the array's resized callback. - pArrayRoot->InvokeElementResizedCallback(); - - if (!isFirstInit) - { - // Expand the array root node that was resized. - emit ExpandNode(pArrayRoot); - } - } - } - } - } - - // Create a row for each element in a given array. - // Each new element will be appended to the given pArrayRoot row, and use the provided - // initializationHandler callback to initialize the new element row. - template (rgEditorElement*, T*, int)> - void CreateArrayElements(int newElementCount, const char* pElementTypeName, rgEditorElementArrayElementAdd* pArrayRoot, U initializationHandler, T* pResized) - { - for (int newChildIndex = 0; newChildIndex < newElementCount; ++newChildIndex) - { - // Show the child index and the API's name for the structure. - std::stringstream elementNameStream; - elementNameStream << newChildIndex; - elementNameStream << " "; - elementNameStream << pElementTypeName; - - // Create an element node for each item in the array. - rgEditorElementArrayElementRemove* pArrayElement = new rgEditorElementArrayElementRemove(pArrayRoot, elementNameStream.str()); - - assert(pArrayElement != nullptr); - assert(pArrayRoot != nullptr); - if (pArrayElement != nullptr && pArrayRoot != nullptr) - { - // Each element in the array needs to know its index and the array root element. - pArrayElement->SetElementIndex(pArrayRoot, newChildIndex); - - // Add the element node to the array root node. - pArrayRoot->AppendChildItem(pArrayElement); - - // Invoke the callback used to initialize each array element. - initializationHandler(pArrayElement, pResized, newChildIndex); - } - } - - // Initialize the newly added rows recursively starting with the parent of all the new rows. - pArrayRoot->InitializeRows(); - } - - // The root editor element item. - rgEditorElement* m_pRootItem = nullptr; - - // The parent widget that all enum ListWidgets are attached to. - QWidget* m_pParent = nullptr; - - // The type of pipeline being edited with the model. - rgPipelineType m_pipelineType; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateModelVulkan.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateModelVulkan.h deleted file mode 100644 index 9a997a4..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgPipelineStateModelVulkan.h +++ /dev/null @@ -1,272 +0,0 @@ -#pragma once - -// C++. -#include - -// Infra. -#include - -// Local. -#include - -// Forward declarations. -class rgPsoGraphicsVulkan; - -// rgPipelineStateModelVulkan is a Pipeline State model used to populate and edit Vulkan-specific -// values within the Pipeline State editor. -class rgPipelineStateModelVulkan : public rgPipelineStateModel -{ - Q_OBJECT - -public: - rgPipelineStateModelVulkan(QWidget* pParent = nullptr); - virtual ~rgPipelineStateModelVulkan() = default; - - // Load a pipeline state configuration from the file at the given path. - bool LoadPipelineStateFile(QWidget* pParent, const std::string& psoFilePath, rgPipelineType pipelineType, std::string& errorString); - - // Save the current pipeline state configuration to the given file path. - bool SavePipelineStateFile(const std::string& psoFilePath, std::string& errorString); - -signals: - // A signal to indicate list widget status change. - void EnumListWidgetStatusSignal(bool isOpen); - - // A signal to indicate change of view. - void HotKeyPressedSignal(); - -protected: - // Check that the pipeline state is valid. - virtual bool CheckValidPipelineState(std::string& errorString) const; - - // Initialize the model with the default graphics pipeline state. - virtual void InitializeDefaultGraphicsPipeline() override; - - // Initialize the model with the default compute pipeline state. - virtual void InitializeDefaultComputePipeline() override; - - // Initialize the Graphics Pipeline CreateInfo tree structure. - virtual rgEditorElement* InitializeGraphicsPipelineCreateInfo(QWidget* pParent) override; - - // Initialize the Compute Pipeline CreateInfo tree structure. - virtual rgEditorElement* InitializeComputePipelineCreateInfo(QWidget* pParent) override; - -private: -// **************** -// Functions and declarations below are used for both graphics and compute pipelines. -// **************** - - // Initialize the Pipeline Layout CreateInfo tree structure. - void InitializePipelineLayoutCreateInfo(rgEditorElement* pRootElement, VkPipelineLayoutCreateInfo* pPipelineLayoutCreateInfo); - - // Initialize the Descriptor Set Layout CreateInfo tree structure. - void InitializeDescriptorSetLayoutCreateInfo(rgEditorElement* pRootElement, VkDescriptorSetLayoutCreateInfo* pDescriptorSetLayoutCreateInfo); - - // Handle resizing the number of Descriptor Set Layout create info structures. - void HandleDescriptorSetLayoutCountChanged(rgEditorElement* pRootElement, rgPsoCreateInfoVulkan* pCreateInfo, bool firstInit = false); - - // Initialize the Descriptor Set Layout array create info rows. - void InitializeDescriptorSetLayoutCreateInfoArray(rgEditorElement* pRootElement, rgPsoCreateInfoVulkan* pCreateInfo); - - // Handler invoked when the Pipeline Layout Descriptor Set Layout count is changed. - void HandlePipelineLayoutDescriptorSetLayoutCountChanged(rgEditorElement* pRootElement, - VkPipelineLayoutCreateInfo* pPipelineLayoutCreateInfo, - bool firstInit = false); - - // Handler invoked when the Pipeline Layout push constants count changes. - void HandlePushConstantsCountChanged(rgEditorElement* pRootElement, - VkPipelineLayoutCreateInfo* pPipelineLayoutCreateInfo, - bool firstInit = false); - - // Handler invoked when the descriptor set layout binding count changes. - void HandleDescriptorSetLayoutBindingCountChanged(rgEditorElement* pRootElement, - VkDescriptorSetLayoutCreateInfo* pDescriptorSetLayoutCreateInfo, - bool firstInit = false); - - // Initialize a Descriptor Set Layout item. - void InitializeDescriptorSetLayout(rgEditorElement* pRootElement, - VkDescriptorSetLayout* pDescriptorSetLayout, int itemIndex); - - // Initialize a Push Constant Range item. - void InitializePushConstantRange(rgEditorElement* pRootElement, - VkPushConstantRange* pPushConstant, int itemIndex); - - // Initialize a descriptor set layout binding item. - void InitializeDescriptorSetLayoutBinding(rgEditorElement* pRootElement, - VkDescriptorSetLayoutBinding* pDescriptorSetLayout, int itemIndex); - - // The number of descriptor set layouts configured by the user. - uint32_t m_descriptorSetLayoutCount; - -// **************** -// Functions below are used to edit VkGraphicsPipelineCreateInfo. -// **************** - - // Initialize the VkGraphicsPipelineCreateInfo element hierarchy. - void InitializeVkGraphicsPipelineCreateInfo(rgEditorElement* pRootElement, rgPsoGraphicsVulkan* pGraphicsPipelineCreateInfo); - - // Initialize the Vertex Input State CreateInfo tree structure. - void InitializeVertexInputStateCreateInfo(rgEditorElement* pRootElement, VkPipelineVertexInputStateCreateInfo* pVertexInputStateCreateInfo); - - // Initialize a "VkVertexInputBindingDescription" create info node. - void InitializeVertexInputBindingDescriptionCreateInfo(rgEditorElement* pRootElement, - VkVertexInputBindingDescription* pItem, int itemIndex); - - // Initialize a "VkVertexInputAttributeDescription" create info node. - void InitializeVertexInputAttributeDescriptionCreateInfo(rgEditorElement* pRootElement, - VkVertexInputAttributeDescription* pInputAttributeDescription, int itemIndex); - - // Initialize the Input Assembly State CreateInfo tree structure. - void InitializeInputAssemblyStateCreateInfo(rgEditorElement* pRootElement, VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyStateCreateInfo); - - // Initialize the Tessellation State CreateInfo tree structure. - void InitializeTessellationStateCreateInfo(rgEditorElement* pRootElement, VkPipelineTessellationStateCreateInfo* pTessellationStateCreateInfo); - - // Initialize the Viewport State CreateInfo tree structure. - void InitializeViewportStateCreateInfo(rgEditorElement* pRootElement, VkPipelineViewportStateCreateInfo* pViewportStateCreateInfo); - - // Handler invoked when the viewport count changes. - void HandlePipelineViewportCountChanged(rgEditorElement* pRootElement, - VkPipelineViewportStateCreateInfo* pViewportStateCreateInfo, - bool firstInit = false); - - // Handler invoked when the scissor count changes. - void HandlePipelineScissorCountChanged(rgEditorElement* pRootElement, - VkPipelineViewportStateCreateInfo* pViewportStateCreateInfo, - bool firstInit = false); - - // Initialize a VkViewport description. - void InitializePipelineViewportDescriptionCreateInfo(rgEditorElement* pRootElement, - VkViewport* pViewportDescription, int itemIndex); - - // Initialize a VkRect2D scissor rectangle description. - void InitializePipelineScissorDescriptionCreateInfo(rgEditorElement* pRootElement, - VkRect2D* pScissorDescription, int itemIndex); - - // Initialize the Rasterization State CreateInfo tree structure. - void InitializeRasterizationStateCreateInfo(rgEditorElement* pRootElement, VkPipelineRasterizationStateCreateInfo* pRasterizationStateCreateInfo); - - // Initialize the Multisample State CreateInfo tree structure. - void InitializeMultisampleStateCreateInfo(rgEditorElement* pRootElement, VkPipelineMultisampleStateCreateInfo* pPipelineMultisampleStateCreateInfo); - - // Handler invoked when the multisampling state pSampleMask array dimension is changed. - void HandleMultisamplingSampleMaskDimensionChanged(rgEditorElement* pRootElement, - VkPipelineMultisampleStateCreateInfo* pMultisampleStateCreateInfo, bool firstInit = false); - - // Initialize a VkSampleMask array element. - void InitializeSampleMask(rgEditorElement* pRootElement, uint32_t* pSampleMask, int itemIndex); - - // Initialize a single VkStencilOpState element. - void InitializeStencilOpState(rgEditorElement* pDepthStencilStateRoot, - VkStencilOpState* pStencilOpState); - - // Initialize the Depth Stencil State CreateInfo tree structure. - void InitializeDepthStencilStateCreateInfo(rgEditorElement* pRootElement, VkPipelineDepthStencilStateCreateInfo* pPipelineDepthStencilStateCreateInfo); - - // Initialize the Color Blend State CreateInfo tree structure. - void InitializeColorBlendStateCreateInfo(rgEditorElement* pRootElement, VkPipelineColorBlendStateCreateInfo* pPipelineColorBlendStateCreateInfo); - - // Handler invoked when the vertex binding description count is changed. - void HandleVertexBindingDescriptionCountChanged(rgEditorElement* pRootElement, - VkPipelineVertexInputStateCreateInfo* pInputStateCreateInfo, - bool firstInit = false); - - // Handler invoked when the vertex attribute description count is changed. - void HandleVertexAttributeDescriptionCountChanged(rgEditorElement* pRootElement, - VkPipelineVertexInputStateCreateInfo* pInputStateCreateInfo, - bool firstInit = false); - - // Handler invoked when the pipeline color blend attachment count is changed. - void HandlePipelineColorBlendAttachmentCountChanged(rgEditorElement* pRootElement, - VkPipelineColorBlendStateCreateInfo* pPipelineColorBlendStateCreateInfo, - bool firstInit = false); - - // Initialize a VkPipelineColorBlendAttachmentState description structure. - void InitializePipelineBlendAttachmentStateCreateInfo(rgEditorElement* pRootElement, - VkPipelineColorBlendAttachmentState* pColorBlendAttachmentState, int itemIndex); - - // A depth stencil attachment reference that can be modified by the editor. This is necessary - // due to the fact that the Vulkan structure uses a const pointer whose values cannot be altered. - VkAttachmentReference* m_pDepthStencilAttachment = nullptr; - - // The graphics pipeline state structure being edited. - rgPsoGraphicsVulkan* m_pGraphicsPipelineState = nullptr; - - // A map of the number of resolve attachments per subpass. - std::map m_resolveAttachmentCountPerSubpass; - - // The dimension of a graphics pipeline's multisampling state VkSampleMask array. - uint32_t m_sampleMaskDimension = 0; - -// **************** -// Functions below are used to edit VkRenderPassCreateInfo. -// **************** - - // Initialize the Render Pass CreateInfo tree structure. - void InitializeRenderPassCreateInfo(rgEditorElement* pRootElement, VkRenderPassCreateInfo* pCreateInfo); - - // Handler invoked when the Render Pass attachment count is changed. - void HandleRenderPassAttachmentCountChanged(rgEditorElement* pRootElement, - VkRenderPassCreateInfo* pRenderPassCreateInfo, - bool firstInit = false); - - // Handler invoked when the Render Pass subpass count is changed. - void HandleRenderPassSubpassCountChanged(rgEditorElement* pRootElement, - VkRenderPassCreateInfo* pRenderPassCreateInfo, - bool firstInit = false); - - // Handler invoked when the Render Pass dependency count is changed. - void HandleRenderPassDependencyCountChanged(rgEditorElement* pRootElement, - VkRenderPassCreateInfo* pRenderPassCreateInfo, - bool firstInit = false); - - // Handler invoked when the Render Pass subpass input attachment count is changed. - void HandleRenderPassSubpassInputAttachmentCountChanged(rgEditorElement* pRootElement, - VkSubpassDescription* pSubpassCreateInfo, - bool firstInit = false); - - // Handler invoked when the Render Pass subpass color attachment count is changed. - void HandleRenderPassSubpassColorAttachmentCountChanged(rgEditorElement* pRootElement, - VkSubpassDescription* pSubpassCreateInfo, - bool firstInit = false); - - // Handler invoked when the Render Pass subpass resolve attachment count is changed. - void HandleRenderPassSubpassResolveAttachmentCountChanged(int subpassIndex, rgEditorElement* pRootElement, - VkSubpassDescription* pSubpassCreateInfo, - bool firstInit = false); - - // Handler invoked when the Render Pass subpass preserve attachment count is changed. - void HandleRenderPassSubpassPreserveAttachmentCountChanged(rgEditorElement* pRootElement, - VkSubpassDescription* pSubpassCreateInfo, - bool firstInit = false); - - // Initialize a Render Pass's attachment CreateInfo. - void InitializeRenderPassAttachmentDescriptionCreateInfo(rgEditorElement* pRootElement, - VkAttachmentDescription* pAttachmentDescription, int itemIndex); - - // Initialize a Render Pass's subpass CreateInfo. - void InitializeRenderPassSubpassDescriptionCreateInfo(rgEditorElement* pRootElement, - VkSubpassDescription* pSubpassDescription, int itemIndex); - - // Initialize a Render Subpass description's AttachmentReference. - void InitializeAttachmentReference(rgEditorElement* pRootElement, - VkAttachmentReference* pAttachmentReference, int itemIndex); - - // Initialize a Render Subpass preserve attachment. - void InitializePreserveAttachment(rgEditorElement* pRootElement, - uint32_t* pAttachmentReference, int itemIndex); - - // Initialize a RenderPass dependency description structure. - void InitializeRenderPassDependencyDescriptionCreateInfo(rgEditorElement* pRootElement, - VkSubpassDependency* pDependencyDescription, int itemIndex); - -// **************** -// Functions and declarations below are used to edit VkComputePipelineCreateInfo. -// **************** - - // Initialize the VkComputePipelineCreateInfo element hierarchy. - void InitializeVkComputePipelineCreateInfo(rgEditorElement* pRootElement, rgPsoComputeVulkan* pComputePipelineCreateInfo); - - // The compute pipeline state structure being edited. - rgPsoComputeVulkan* m_pComputePipelineState = nullptr; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgPreprocessorDirectivesDialog.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgPreprocessorDirectivesDialog.h deleted file mode 100644 index 4eb45d0..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgPreprocessorDirectivesDialog.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -// Local. -#include - -class rgPreprocessorDirectivesDialog : public rgOrderedListDialog -{ - Q_OBJECT - -public: - rgPreprocessorDirectivesDialog(const char* pDelimiter, QWidget* pParent = nullptr); - virtual ~rgPreprocessorDirectivesDialog() = default; - -protected: - // An overridden virtual responsible for determining if an edited list item is valid. - virtual void OnListItemChanged(QListWidgetItem* pItem) override; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgScrollArea.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgScrollArea.h deleted file mode 100644 index 240e43e..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgScrollArea.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -// Qt. -#include - -class rgScrollArea : public QScrollArea -{ - Q_OBJECT - -public: - rgScrollArea(QWidget* pParent); - virtual ~rgScrollArea() = default; - -protected: - // Re-implement the mousePressEvent. - virtual void mousePressEvent(QMouseEvent* pEvent) override; - -signals: - void ScrollAreaClickedEvent(); -}; - diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgSettingsButtonsView.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgSettingsButtonsView.h deleted file mode 100644 index 2d516c3..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgSettingsButtonsView.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -// C++. -#include - -// Infra. -#include -#include - -// Local. -#include "ui_rgSettingsButtonsView.h" -#include - -// Forward declarations. -class QWidget; -class rgOpenCLBuildSettingsModel; - -class rgSettingsButtonsView : public QWidget -{ - Q_OBJECT - -public: - rgSettingsButtonsView(QWidget* pParent); - virtual ~rgSettingsButtonsView(); - - // Enable/disable save button. - void EnableSaveButton(bool isEnabled); - - // Hide / show the Restore defaultSettings button. - void HideRestoreDefaultSettingsButton(bool isHidden); - - // Re-implement mousePressEvent method. - virtual void mousePressEvent(QMouseEvent *pEvent) override; - -signals: - void RestoreDefaultSettingsButtonClickedSignal(); - void SaveSettingsButtonClickedSignal(); - void SettingsButtonsViewClickedSignal(); - -private slots: - void HandleRestoreDefaultSettingsButtonClick(); - void HandleSaveSettingsButtonClick(); - -private: - // Connect the signals. - void ConnectSignals(); - - // Set the cursor to pointing hand cursor for various widgets. - void SetCursor(); - - // The generated interface view object. - Ui::rgSettingsButtonsView ui; - - // The action used to Restore settings. - QAction* m_pRestoreSettingsAction = nullptr; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgSettingsTabOpenCL.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgSettingsTabOpenCL.h deleted file mode 100644 index 23b70e3..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgSettingsTabOpenCL.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -// Local. -#include - -// An OpenCL-specific implementation of the settings tab. -class rgSettingsTabOpenCL : public rgSettingsTab -{ - Q_OBJECT - -public: - rgSettingsTabOpenCL(QWidget* pParent); - virtual ~rgSettingsTabOpenCL() = default; - -protected: - virtual rgProjectAPI GetApiType() override; -}; diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgSettingsTabVulkan.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgSettingsTabVulkan.h deleted file mode 100644 index 5140af0..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgSettingsTabVulkan.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -// Local. -#include - -// A Vulkan-specific implementation of the settings tab. -class rgSettingsTabVulkan : public rgSettingsTab -{ - Q_OBJECT - -public: - rgSettingsTabVulkan(QWidget* pParent); - virtual ~rgSettingsTabVulkan() = default; - -protected: - virtual rgProjectAPI GetApiType() override; -}; diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgSettingsView.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgSettingsView.h deleted file mode 100644 index 8d16eef..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgSettingsView.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -// Qt. -#include - -class rgSettingsView : public QWidget -{ - Q_OBJECT - -public: - rgSettingsView(QWidget* pParent); - virtual ~rgSettingsView() = default; - - // Set the focus to target selection button. - virtual void SetInitialWidgetFocus() = 0; -}; diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgStatusBarOpenCL.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgStatusBarOpenCL.h deleted file mode 100644 index c9e6901..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgStatusBarOpenCL.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -// Local. -#include - -class rgStatusBarOpenCL : public rgStatusBar -{ - Q_OBJECT - -public: - rgStatusBarOpenCL(QStatusBar* pStatusBar, QWidget* pParent = nullptr); - virtual ~rgStatusBarOpenCL() = default; - -private: - // Set style sheets for mode and API push buttons. - virtual void SetStylesheets(QStatusBar* pStatusBar) override; - - // The parent widget. - QWidget* m_pParent = nullptr; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgStatusBarVulkan.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgStatusBarVulkan.h deleted file mode 100644 index ab346ca..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgStatusBarVulkan.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -// C++. -#include - -// Qt. -#include -#include - -// Local. -#include - -class rgStatusBarVulkan : public rgStatusBar -{ - Q_OBJECT - -public: - rgStatusBarVulkan(QStatusBar* pStatusBar, QWidget* pParent = nullptr); - virtual ~rgStatusBarVulkan() = default; - -private: - // Set style sheets for mode and API push buttons. - virtual void SetStylesheets(QStatusBar* pStatusBar) override; - - // The parent widget. - QWidget* m_pParent = nullptr; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgTreeWidget.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgTreeWidget.h deleted file mode 100644 index 3d19032..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgTreeWidget.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -// Qt. -#include - -// Local. -#include - -class rgTreeWidget : public QTreeWidget -{ - Q_OBJECT - -public: - rgTreeWidget(QWidget* pParent = nullptr); - virtual ~rgTreeWidget() = default; - -protected: - // Re-implement the focusOutEvent so we can hide this widget. - virtual void focusOutEvent(QFocusEvent *event) override; - - // Re-implement the mouseMoveEvent method. - virtual void mouseMoveEvent(QMouseEvent* pEvent) override; - - // Re-implement the leaveEvent method. - virtual void leaveEvent(QEvent* pEvent) override; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/Qt/rgUnsavedItemsDialog.h b/RadeonGPUAnalyzerGUI/Include/Qt/rgUnsavedItemsDialog.h deleted file mode 100644 index e92736c..0000000 --- a/RadeonGPUAnalyzerGUI/Include/Qt/rgUnsavedItemsDialog.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include -#include -#include "ui_rgUnsavedItemsDialog.h" - -// Delegate for the rgUnsavedFileDialog which draws the list of unsaved files with truncated text. -class rgUnsavedFileItemDelegate : public QItemDelegate -{ -public: - // Default constructor. - rgUnsavedFileItemDelegate(QWidget* pParent = nullptr) : QItemDelegate(pParent) {}; - - // Drawing operation for text items in the unsaved file dialog. - virtual void drawDisplay(QPainter* pPainter, const QStyleOptionViewItem& option, const QRect& rect, const QString& text) const override; - - // Size hint for text items in the unsaved file dialog. - virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; - - // Empty implementation here because we don't want to draw the focus indication. - virtual void drawFocus(QPainter* pPainter, const QStyleOptionViewItem& option, const QRect& rect) const override {} -}; - -class rgUnsavedItemsDialog : public QDialog -{ - Q_OBJECT - -public: - - // Enum for dialog result (indicates which button was pressed). - enum UnsavedFileDialogResult - { - // Ensure cancel is same behavior as rejection (clicking X on window). - Cancel = QDialog::Rejected, - Yes, - No, - }; - - rgUnsavedItemsDialog(QWidget* pParent = nullptr); - ~rgUnsavedItemsDialog(); - - // Add a file to the unsaved file list. - void AddFile(QString filename); - - // Add multiple files to the unsaved file list. - void AddFiles(QStringList filenames); - -private: - // Connect the signals. - void ConnectSignals(); - - // Delegate for drawing list items in the file list widget. - rgUnsavedFileItemDelegate* m_pItemDelegate = nullptr; - -protected: - Ui::rgUnsavedItemsDialog ui; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/rgCliKernelListParser.h b/RadeonGPUAnalyzerGUI/Include/rgCliKernelListParser.h deleted file mode 100644 index 58e0856..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgCliKernelListParser.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -// C++. -#include -#include - -// Local. -#include -#include -#include - -class rgCliKernelListParser -{ -public: - static bool ReadListKernelsOutput(const std::string& listKernelsOutput, EntryToSourceLineRange& fileLineNumbers) - { - bool isParsingFailed = false; - - // Process the CLI output and return it through an output parameter. - std::stringstream entrypointLinesStream; - entrypointLinesStream.str(listKernelsOutput); - - // Read each line of the lsit-kernels output. - // Example: - // foo: 12-50 - std::string lineString; - while (std::getline(entrypointLinesStream, lineString)) - { - // Skip empty lines. - if (!lineString.empty()) - { - // Split each token using the location of the colon. - std::vector nameAndLines, lines; - rgUtils::splitString(lineString, ':', nameAndLines); - - // Verify that there are only two tokens per line. - bool isTokenCountCorrect = (nameAndLines.size() == 2); - assert(isTokenCountCorrect); - if (isTokenCountCorrect) - { - // The first token is the entry point name. - const std::string& entrypointName = nameAndLines[0]; - - // The second token is the starting and ending line numbers separated by '-' symbol. - rgUtils::splitString(nameAndLines[1], '-', lines); - isTokenCountCorrect = (lines.size() == 2); - assert(isTokenCountCorrect); - if (isTokenCountCorrect) - { - fileLineNumbers[entrypointName] = { std::atoi(lines[0].c_str()), std::atoi(lines[1].c_str()) }; - } - } - else - { - isParsingFailed = true; - } - } - } - - return !isParsingFailed; - } -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/rgCliLauncher.h b/RadeonGPUAnalyzerGUI/Include/rgCliLauncher.h deleted file mode 100644 index fd78515..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgCliLauncher.h +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -// C++. -#include -#include -#include -#include - -// Local. -#include - -// Forward declarations. -struct rgCliBuildOutput; -struct rgProject; - -class rgCliLauncher -{ -public: - // Runs RGA CLI to compile the given ROCm-OpenCL project clone. - // pProject is the project containing the clone to be built. - // cloneIndex is the index of the clone to be built. - // outputPath is where the output files will be generated. - // cliOutputHandlingCallback is a callback used to send CLI output text to the GUI. - // cancelSignal can be used to terminate the operation. - // Returns true for success, false otherwise. - static bool BuildProjectCloneOpenCL(std::shared_ptr pProject, int cloneIndex, const std::string& outputPath, const std::string& binaryName, - std::function cliOutputHandlingCallback, std::vector& gpusBuilt, bool& cancelSignal); - - // Runs RGA CLI to compile the given Vulkan pipeline project clone. - // pProject is the project containing the clone to be built. - // cloneIndex is the index of the clone to be built. - // outputPath is where the output files will be generated. - // cliOutputHandlingCallback is a callback used to send CLI output text to the GUI. - // cancelSignal can be used to terminate the operation. - // Returns true for success, false otherwise. - static bool BuildProjectCloneVulkan(std::shared_ptr pProject, int cloneIndex, const std::string& outputPath, const std::string& binaryName, - std::function cliOutputHandlingCallback, std::vector& gpusBuilt, bool& cancelSignal); - - // Runs RGA CLI to disassemble the given SPIR-V binary into text. - // compilerBinFolder is the folder contaning alternative compiler binaries. If empty, the default spirv-dis tool will be used. - // spvFullFilePath is the input file path to the SPIR-V binary to disassemble. - // outputFilePath is the output file path where disassembly text will be dumped. - // cliOutput is the output message generated by CLI. - static bool DisassembleSpvToText(const std::string& compilerBinFolder, const std::string& spvFullFilePath, - const std::string& outputFilePath, std::string& cliOutput); - - // Runs RGA to generate a version info file for the CLI. - // fullPath is the path to where the version info XML file will be saved to. - // Returns true for success, false otherwise. - static bool GenerateVersionInfoFile(const std::string& fullPath); - - // Runs RGA to retrieve the start line number for each kernel. - // pProject is a pointer to the project being built. - // cloneIndex is the index of the clone to access. - // entrypointLineNumbers A map that gets filled up with the start line numbers for each input file's entrypoints. - static bool ListKernels(std::shared_ptr pProject, int cloneIndex, std::map& entrypointLineNumbers); -private: - rgCliLauncher() = default; - ~rgCliLauncher() = default; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/rgCliUtils.h b/RadeonGPUAnalyzerGUI/Include/rgCliUtils.h deleted file mode 100644 index 81be9a9..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgCliUtils.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -// C++. -#include -#include - -// Forward declarations. -struct rgBuildSettings; -struct rgBuildSettingsOpenCL; -struct rgBuildSettingsVulkan; - -class rgCliUtils -{ -public: - // Generate the build settings string that should be passed to the CLI for rgCLBuildSettings. - // "additionalOptions" flag specifies whether the text from "Additional compiler options" box should be added or not. - static bool GenerateOpenClBuildSettingsString(const rgBuildSettingsOpenCL& buildSettings, std::string& str, bool additionalOptions = true); - - // Generate the build settings string that should be passed to the CLI for rgVulkanBuildSettings. - static bool GenerateVulkanBuildSettingsString(const rgBuildSettingsVulkan& buildSettings, std::string& str, bool additionalOptions = true); - -private: - rgCliUtils() = delete; - ~rgCliUtils() = delete; -}; - diff --git a/RadeonGPUAnalyzerGUI/Include/rgConfigFileDefinitions.h b/RadeonGPUAnalyzerGUI/Include/rgConfigFileDefinitions.h deleted file mode 100644 index dc52e60..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgConfigFileDefinitions.h +++ /dev/null @@ -1,297 +0,0 @@ -#pragma once - -// C++. -#include - -// Local. -#include - -// *********************************************** -// *** Configuration-file-related definitions. *** -// *********************************************** - -// The data model version that RGA uses. -static const std::string RGA_DATA_MODEL_2_0 = "2.0"; -static const std::string RGA_DATA_MODEL_2_1 = "2.1"; -static const std::string RGA_DATA_MODEL_2_2 = "2.2"; -static const std::string RGA_DATA_MODEL = RGA_DATA_MODEL_2_2; - -// The XML declaration string. -static const char* RGA_XML_DECLARATION = "xml version = \"1.0\" encoding = \"UTF-8\""; - -// Data model version node. -static const char* XML_NODE_DATA_MODEL_VERSION = "RGADataModelVersion"; - -// Program node. -static const char* XML_NODE_PROJECT = "Program"; - -// API node. -static const char* XML_NODE_API_NAME = "ProgramAPI"; - -// Program name node. -static const char* XML_NODE_PROJECT_NAME = "ProgramName"; - -// Program clone node. -static const char* XML_NODE_CLONE = "ProgramClone"; - -// Clone ID node. -static const char* XML_NODE_CLONE_ID = "CloneID"; - -// Clone name node. -static const char* XML_NODE_CLONE_NAME = "CloneName"; - -// Clone source files. -static const char* XML_NODE_CLONE_SOURCE_FILES = "SourceFiles"; - -// File path. -static const char* XML_NODE_FILE_PATH = "FullPath"; - -// Build settings node. -static const char* XML_NODE_BUILD_SETTINGS = "BuildSettings"; - -// Target devices settings node. -static const char* XML_NODE_TARGET_DEVICES = "TargetDevices"; - -// Predefined macros settings node. -static const char* XML_NODE_PREDEFINED_MACROS = "PredefinedMacros"; - -// Additional include directories node. -static const char* XML_NODE_ADDITIONAL_INCLUDE_DIRECTORIES = "AdditionalIncludeDirectories"; - -// Additional options provided by user. -static const char* XML_NODE_ADDITIONAL_OPTIONS = "AdditionalOptions"; - -// A switch used to determine if project names will be generated or provided by the user. -static const char* XML_NODE_USE_GENERATED_PROJECT_NAMES = "UseGeneratedProjectNames"; - -// Alternative compiler paths. -static const char* XML_NODE_ALTERNATIVE_COMPILER_BIN_DIR = "AlternativeCompilerBin"; -static const char* XML_NODE_ALTERNATIVE_COMPILER_INC_DIR = "AlternativeCompilerInc"; -static const char* XML_NODE_ALTERNATIVE_COMPILER_LIB_DIR = "AlternativeCompilerLib"; - -// ******************************* -// *** OPENCL-SPECIFIC - BEGIN *** -// ******************************* - -// OpenCL optimization level. -static const char* XML_NODE_OPENCL_OPT_LEVEL = "OptimizationLevel"; - -// Treat double as single. -static const char* XML_NODE_OPENCL_DOUBLE_AS_SINGLE = "TreatDoubleAsSingle"; - -// Denorms as zeros. -static const char* XML_NODE_OPENCL_DENORMS_AS_ZEROS = "DenormsAsZeros"; - -// Strict aliasing. -static const char* XML_NODE_OPENCL_STRICT_ALIASING = "StrictAliasing"; - -// Enable MAD. -static const char* XML_NODE_OPENCL_ENABLE_MAD = "EnableMAD"; - -// Ignore zero signedness. -static const char* XML_NODE_OPENCL_IGNORE_ZERO_SIGNEDNESS = "IgnoreZeroSignedness"; - -// Allow unsafe optimizations. -static const char* XML_NODE_OPENCL_UNSAFE_OPT = "UnsafeOptimizations"; - -// No NaN nor Infinite. -static const char* XML_NODE_OPENCL_NO_NAN_NOR_INF = "NoNanNorInfinite"; - -// Aggressive math optimizations. -static const char* XML_NODE_OPENCL_AGGRESSIVE_MATH_OPT = "AggressiveMathOptimizations"; - -// Correctly round div / sqrt. -static const char* XML_NODE_OPENCL_CORRECT_ROUND_DIV_SQRT = "CorrectlyRoundDivSqrt"; - -// ***************************** -// *** OPENCL-SPECIFIC - END *** -// ***************************** - -// ******************************* -// *** GRAPHICS-SPECIFIC - BEGIN *** -// ******************************* - -// The root node for pipeline data. -static const char* XML_NODE_PIPELINE_SHADERS_ROOT = "Pipeline"; - -// The root node for the backup SPIR-V binary files. -static const char* XML_NODE_BACKUP_SPV_ROOT = "BackupSpvFiles"; - -// The root node for the pipeline state data. -static const char* XML_NODE_PIPELINE_STATE_ROOT = "PipelineState"; - -// The root node for an individual pipeline's state data. -static const char* XML_NODE_PIPELINE_STATE = "State"; - -// The element used to serialize the pipeline name. -static const char* XML_NODE_PIPELINE_NAME = "Name"; - -// The element used to serialize the active pipeline flag. -static const char* XML_NODE_PIPELINE_IS_ACTIVE = "IsActive"; - -// The element used to serialize the pipeline state file path. -static const char* XML_NODE_PIPELINE_STATE_FILE_PATH = "PipelineStateFilePath"; - -// The element used to serialize the original pipeline state file path. -static const char* XML_NODE_ORIGINAL_PIPELINE_STATE_FILE_PATH = "OriginalPipelineStateFilePath"; - -// The type of pipeline being serialized. -static const char* XML_NODE_PIPELINE_TYPE = "Type"; - -// The graphics pipeline type string. -static const char* XML_NODE_PIPELINE_TYPE_GRAPHICS = "Graphics"; - -// The compute pipeline type string. -static const char* XML_NODE_PIPELINE_TYPE_COMPUTE = "Compute"; - -// Used to serialize the path to a shader input file. -static const char* XML_NODE_PIPELINE_VERTEX_STAGE = "Vertex"; - -// Used to serialize the path to a tessellation control shader input file. -static const char* XML_NODE_PIPELINE_TESS_CONTROL_STAGE = "TessellationControl"; - -// Used to serialize the path to a tessellation evaluation shader input file. -static const char* XML_NODE_PIPELINE_TESS_EVAL_STAGE = "TessellationEvaluation"; - -// Used to serialize the path to a geometry shader input file. -static const char* XML_NODE_PIPELINE_GEOMETRY_STAGE = "Geometry"; - -// Used to serialize the path to a fragment shader input file. -static const char* XML_NODE_PIPELINE_FRAGMENT_STAGE = "Fragment"; - -// Used to serialize the path to a compute shader input file. -static const char* XML_NODE_PIPELINE_COMPUTE_STAGE = "Compute"; - -// ******************************* -// *** GRAPHICS-SPECIFIC - END *** -// ******************************* - -// ******************************* -// *** VULKAN-SPECIFIC - BEGIN *** -// ******************************* - -// Used to serialize the Generate Debug Info build setting. -static const char* XML_NODE_VULKAN_GENERATE_DEBUG_INFO = "GenerateDebugInfo"; - -// Used to serialize the No Explicit Bindings build setting. -static const char* XML_NODE_VULKAN_NO_EXPLICIT_BINDINGS = "NoExplicitBindings"; - -// Used to serialize the Use HLSL Block Offsets build setting. -static const char* XML_NODE_VULKAN_USE_HLSL_BLOCK_OFFSETS = "UseHlslBlockOffsets"; - -// Used to serialize the Use HLSL IO Mapping build setting. -static const char* XML_NODE_VULKAN_USE_HLSL_IO_MAPPING = "UseHlslIoMapping"; - -// Used to serialize the ICD location build setting. -static const char* XML_NODE_VULKAN_ICD_LOCATION = "ICDLocation"; - -// Used to serialize the glslang additional options build setting. -static const char* XML_NODE_VULKAN_GLSLANG_OPTIONS_LOCATION = "glslangOptions"; - -// Used to serialize the Enable validation layers build setting. -static const char* XML_NODE_VULKAN_ENABLE_VALIDATION_LAYER = "EnableValidationLayer"; - -// Binary output file association. -static const char* XML_NODE_GLOBAL_BINARY_OUTPUT_FILE_NAME = "BinaryOutputFileName"; - -// ******************************* -// *** VULKAN-SPECIFIC - END *** -// ******************************* - -// ******************************* -// *** GLOBAL SETTINGS - BEGIN *** -// ******************************* - -// Global settings root node. -static const char* XML_NODE_GLOBAL_LOG_FILE_GLOBAL_SETTINGS = "GlobalSettings"; - -// Log file location. -static const char* XML_NODE_GLOBAL_LOG_FILE_LOCATION = "LogFileLocation"; - -// Output directory. -static const char* XML_NODE_GLOBAL_OUTPUT_DIR = "OutputDirectory"; - -// Last selected directory. -static const char* XML_NODE_GLOBAL_LAST_SELECTED_DIRECTORY = "LastSelectedDirectory"; - -// Default API mode (introduced in RGA Data Model 2.1) -static const char* XML_NODE_GLOBAL_DEFAULT_API = "DefaultAPI"; - -// Indicates whether or not to (introduced in RGA Data Model 2.1) -static const char* XML_NODE_GLOBAL_PROMPT_FOR_API = "PromptForAPI"; - -// The recent programs root node. -static const char* XML_NODE_GLOBAL_RECENT_PROJECTS_ROOT = "RecentPrograms"; - -// The recent program root node. -static const char* XML_NODE_GLOBAL_RECENT_PROJECT_ROOT = "RecentProgram"; - -// The program path element. -static const char* XML_NODE_GLOBAL_RECENT_PROJECT_PATH = "Path"; - -// The program api type element. -static const char* XML_NODE_GLOBAL_RECENT_PROJECT_API = "API"; - -// The font root node. -static const char* XML_NODE_GLOBAL_FONT_FAMILY_ROOT = "Font"; - -// The font type element. -static const char* XML_NODE_GLOBAL_FONT_FAMILY_TYPE = "Type"; - -// The font size element. -static const char* XML_NODE_GLOBAL_FONT_SIZE = "Size"; - -// The default include file viewer. -static const char* XML_NODE_GLOBAL_INCLUDE_FILES_VIEWER = "IncludeFilesViewer"; - -// Disassembly view columns. -static const char* XML_NODE_GLOBAL_DISASSEMBLY_COLUMNS = "DisassemblyViewColumns"; - -// GUI elements. -static const char* XML_NODE_GLOBAL_GUI = "GUI"; - -// Gui layout. -static const char* XML_NODE_GLOBAL_GUI_LAYOUT = "Layout"; - -// Gui splitter config. -static const char* XML_NODE_GLOBAL_GUI_SPLITTER = "Splitter"; - -// Splitter config name. -static const char* XML_NODE_GLOBAL_GUI_SPLITTER_NAME = "SplitterName"; - -// Splitter config values. -static const char* XML_NODE_GLOBAL_GUI_SPLITTER_VALUES = "SplitterValues"; - -// RGA window size values. -static const char* XML_NODE_GLOBAL_GUI_WINDOW_GEOMETRY = "WindowGeometry"; - -// RGA window width. -static const char* XML_NODE_GLOBAL_GUI_WINDOW_WIDTH = "WindowWidth"; - -// RGA window height. -static const char* XML_NODE_GLOBAL_GUI_WINDOW_HEIGHT = "WindowHeight"; - -// RGA window state. -static const char* XML_NODE_GLOBAL_GUI_WINDOW_STATE = "WindowState"; - -// RGA window X location. -static const char* XML_NODE_GLOBAL_GUI_WINDOW_X_POS = "WindowXPos"; - -// RGA window Y location. -static const char* XML_NODE_GLOBAL_GUI_WINDOW_Y_POS = "WindowYPos"; - -// Default build settings. -static const char* XML_NODE_GLOBAL_DEFAULT_BUILD_SETTINGS = "DefaultBuildSettings"; - -// Input file associations. -static const char* XML_NODE_GLOBAL_INPUT_FILE_EXT_GLSL = "InputFileExtGLSL"; -static const char* XML_NODE_GLOBAL_INPUT_FILE_EXT_HLSL = "InputFileExtHLSL"; -static const char* XML_NODE_GLOBAL_INPUT_FILE_EXT_SPV_TXT = "InputFileExtSpvTxt"; -static const char* XML_NODE_GLOBAL_INPUT_FILE_EXT_SPV_BIN = "InputFileExtSpvBin"; - -// Default source language. -static const char* XML_NODE_GLOBAL_DEFAULT_SRC_LANG = "DefaultSrcLanguage"; - -// ***************************** -// *** GLOBAL SETTINGS - END *** -// ***************************** diff --git a/RadeonGPUAnalyzerGUI/Include/rgConfigFileOpenCL.h b/RadeonGPUAnalyzerGUI/Include/rgConfigFileOpenCL.h deleted file mode 100644 index 871328d..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgConfigFileOpenCL.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -// Local. -#include -#include - -// Reader for OpenCL config files. -class rgConfigFileReaderOpenCL : public rgXmlConfigFileReaderImpl -{ -public: - // DTOR. - virtual ~rgConfigFileReaderOpenCL() = default; - - // Config file reader used for OpenCL project files. - virtual bool ReadProjectConfigFile(tinyxml2::XMLDocument& doc, const char* pFileDataModelVersion, std::shared_ptr& pRgaProject) override; - - // Parse OpenCL-specific project build settings. - virtual bool ReadApiBuildSettings(tinyxml2::XMLNode* pNode, std::shared_ptr pBuildSettings, const std::string& version) override; -}; - -class rgConfigFileWriterOpenCL : public rgXmlConfigFileWriterImpl -{ -public: - // DTOR. - virtual ~rgConfigFileWriterOpenCL() = default; - - // Writes an OpenCL project into the config file to the given location. - virtual bool WriteProjectConfigFile(const rgProject& project, const std::string& configFilePath) override; - - // Write the given OpenCL build settings structure to the given project config file document. - virtual bool WriteBuildSettingsElement(const std::shared_ptr pBuildSettings, tinyxml2::XMLDocument& doc, tinyxml2::XMLElement*& pBuildSettingsElem) override; - -private: - // Write the given OpenCL project's clones to the config file document. - bool WriteOpenCLCloneElements(const rgProjectOpenCL& project, tinyxml2::XMLDocument& doc, std::vector& elems); -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/rgConfigFileVulkan.h b/RadeonGPUAnalyzerGUI/Include/rgConfigFileVulkan.h deleted file mode 100644 index e0a19ee..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgConfigFileVulkan.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -// Local. -#include -#include - -// XML reader for Vulkan config files. -class rgConfigFileReaderVulkan : public rgXmlGraphicsConfigFileReaderImpl -{ -public: - // DTOR. - virtual ~rgConfigFileReaderVulkan() = default; - - // Config file reader used for Vulkan project files. - virtual bool ReadProjectConfigFile(tinyxml2::XMLDocument& doc, const char* pFileDataModelVersion, std::shared_ptr& pRgaProject) override; - - // Responsible for reading all Vulkan-specific build settings. - virtual bool ReadApiBuildSettings(tinyxml2::XMLNode* pNode, std::shared_ptr pBuildSettings, const std::string& version) override; - -private: - // Read single project clone info. The data is stored to the project structure pointer by "pVulkanProject". - bool ReadProjectClone(tinyxml2::XMLDocument& doc, tinyxml2::XMLNode* pClonesRoot, std::shared_ptr& pVulkanProject); -}; - -// XML writer for Vulkan config files. -class rgConfigFileWriterVulkan : public rgXmlGraphicsConfigFileWriterImpl -{ -public: - // DTOR. - virtual ~rgConfigFileWriterVulkan() = default; - - // Writes an Vulkan project into the config file to the given location. - virtual bool WriteProjectConfigFile(const rgProject& project, const std::string& configFilePath) override; - - // Write the given build settings structure to the given project config file document. - virtual bool WriteBuildSettingsElement(const std::shared_ptr pBuildSettings, tinyxml2::XMLDocument& doc, tinyxml2::XMLElement*& pBuildSettingsElem) override; - -private: - // Write the given project's clones to the config file document. - bool WriteCloneElements(const rgProjectVulkan& project, tinyxml2::XMLDocument& doc, std::vector& elems); -}; - diff --git a/RadeonGPUAnalyzerGUI/Include/rgConfigManager.h b/RadeonGPUAnalyzerGUI/Include/rgConfigManager.h deleted file mode 100644 index 6e538c7..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgConfigManager.h +++ /dev/null @@ -1,226 +0,0 @@ -#pragma once - -// C++. -#include -#include -#include - -// Forward declarations. -struct rgProject; -struct rgBuildSettings; -struct rgGlobalSettings; -struct rgGraphicsProjectClone; -struct rgProjectVulkan; -struct rgCliVersionInfo; -struct rgSourceFileInfo; -struct rgRecentProject; -struct rgWindowConfig; -enum class rgProjectAPI : char; -enum rgPipelineStage : char; - -// A structure with a predicate used to search a rgSourceFileInfo vector for a specific file path. -struct rgSourceFilePathSearcher -{ - // Default constructor used to provide the path to search for. - rgSourceFilePathSearcher(const std::string& targetFilePath) : m_targetFilePath(targetFilePath) {} - - // An overloaded function call operator used to compare file paths between rgSourceFileInfo instances. - bool operator()(const rgSourceFileInfo& fileInfo) const; - - // The target file path to search for. - std::string m_targetFilePath; -}; - -class rgConfigManager -{ -public: - // Initializes the configuration manager. - // Call this function once during startup. - bool Init(); - - // Reset the incoming global settings to the hardcoded default values. - static void ResetToFactoryDefaults(rgGlobalSettings& globalSettings); - - // Get the single instance of the configuration manager. - static rgConfigManager& Instance(); - - // Add the given source file path to the provided project. - void AddSourceFileToProject(const std::string& sourceFilePath, std::shared_ptr pProgram, int cloneIndex) const; - - // Add the given source file to a project's pipeline for the specified shader stage. - void AddShaderStage(rgPipelineStage stage, const std::string& sourceFilePath, std::shared_ptr pProject, int cloneIndex) const; - - // Remove the shader stage from the given project's pipeline. - bool GetShaderStageFilePath(rgPipelineStage stage, std::shared_ptr pGraphicsClone, std::string& fullFilePath) const; - - // Remove the shader stage from the given project's pipeline. - void RemoveShaderStage(rgPipelineStage stage, std::shared_ptr pGraphicsClone) const; - - // Gets the current API being used. - rgProjectAPI GetCurrentAPI() const; - - // Sets the current API to be used. - void SetCurrentAPI(rgProjectAPI projectAPI); - - // Sets whether or not the UI should prompt the user to select an API at startup. - void SetPromptForAPIAtStartup(bool shouldPrompt); - - // Sets the default API to be used if not prompting for an API at startup. - void SetDefaultAPI(rgProjectAPI defaultAPI); - - // Gets the current mode used to build the user's kernels. - std::string GetCurrentModeString() const; - - // Check if the given GPU family is supported in the current mode. - bool IsGpuFamilySupported(const std::string& familyName) const; - - // Remove a source file path from the given program clone. - void RemoveSourceFilePath(std::shared_ptr pProgram, int cloneIndex, const std::string& sourceFilePath) const; - - // Retrieve a source file path from a program by clone index. - void GetProjectSourceFilePaths(std::shared_ptr pProgram, int cloneIndex, std::vector& sourceFilePaths) const; - - // Update the file path to a file that has already been added to a program clone. - static void UpdateSourceFilepath(const std::string& oldFilepath, const std::string& newFilepath, std::shared_ptr pProgram, int cloneIndex); - - // Update the file path for a shader stage source file that has been renamed. - static void UpdateShaderStageFilePath(const std::string& oldFilepath, const std::string& newFilepath, std::shared_ptr pProject, int cloneIndex); - - // Generate a full path to a program's folder on disk. - static void GetProjectFolder(const std::string& programName, std::string& programFolder); - - // Generate a full path to a new source file for the given program. - static void GenerateNewSourceFilepath(const std::string& programName, int cloneIndex, const std::string& sourceFilename, const std::string& sourcefileExtension, std::string& generatedFileName, std::string& fullSourceFilePath); - - // Generate a full path to a new pipeline state file for the given program. - static void GenerateNewPipelineFilepath(const std::string& projectName, int cloneIndex, const std::string& pipelineFilename, const std::string& pipelineFileExtension, std::string& fullPipelineFilePath); - - // Load an existing program. - std::shared_ptr LoadProjectFile(const std::string& programFilePath); - - // Save the program File. - bool SaveProjectFile(std::shared_ptr); - - // Generate a full path to a program file. - static std::string GenerateProjectFilepath(const std::string& programName); - - // Revert the build settings to the default for the given API. - void RevertToDefaultBuildSettings(rgProjectAPI api); - - // Reset the current API Build settings with those supplied. - void SetApiBuildSettings(const std::string& apiName, rgBuildSettings* pBuildSettings); - - // Get the global settings. - std::shared_ptr GetGlobalConfig() const; - - // Get the GPUs supported by RGA. - std::shared_ptr GetVersionInfo() const; - - // Save and close configuration/log files. - void Close() const; - - // Save the global configuration file. - bool SaveGlobalConfigFile() const; - - // Add a recent program to the list of recently-accessed programs. - void AddRecentProjectPath(std::shared_ptr pRecentProject); - - // Update a recent program's file path. - void UpdateRecentProjectPath(const std::string& oldFilePath, const std::string& newFilePath, rgProjectAPI api); - - // Get the user's global build settings for the given API. - // These are the default settings that the user would like to use for the API. - std::shared_ptr GetUserGlobalBuildSettings(rgProjectAPI api) const; - - // Get a read-only version of the RGA default build settings for the given API. - // Use this for performing a "factory reset", i.e. when the user wants to reset the settings to the default. - static std::shared_ptr GetDefaultBuildSettings(rgProjectAPI api); - - // Gets the system's default folder where RGA should store data. - static void GetDefaultDataFolder(std::string& defaultDataFolder); - - // Gets the system's default Documents folder where RGA should store project data. - static void GetDefaultDocumentsFolder(std::string& defaultDocumentsFolder); - - // Gets the default folder where RGA programs should stored. - static void GetDefaultProjectsFolder(std::string& defaultProgramsFolder); - - // Gets the last folder that the user selected in a File Dialog. - std::string GetLastSelectedFolder() const; - - // Retrieve the array of recently-accessed program files. - std::vector> GetRecentProjects() const; - - // Replace the global settings structure with the provided instance. - void SetGlobalConfig(const rgGlobalSettings& pGlobalSettings); - - // Set the last directory navigated to using a file browser dialog. - void SetLastSelectedDirectory(const std::string& lastSelectedDirectory); - - // Set the splitter values for the given splitter name. - void SetSplitterValues(const std::string& splitterName, const std::vector& splitterValues); - - // Get the splitter values for the given splitter name. - bool GetSplitterValues(const std::string& splitterName, std::vector& splitterValues) const; - - // Set the GUI window geometry values. - void SetWindowGeometry(int xPos, int yPos, int width, int height, int windowState); - - // Get the GUI window geometry values. - void GetWindowGeometry(rgWindowConfig& windowValues) const; - - // Set the column visibility based on the supplied vector. - void SetDisassemblyColumnVisibility(const std::vector& columnVisibility); - - // An error message for fatal scenarios that do not allow RGA to be initialized. - std::string GetFatalErrorMessage() const; - - // Getter for the supported APIs. - void GetSupportedApis(std::vector& supportedAPIs); - - // Get path to CLI log file. - const std::string& GetCLILogFilePath(); - - // Get the default app for opening include files. - std::string GetIncludeFileViewer() const; - - // Set the config file data model version. - void SetConfigFileDataModelVersion(const std::string& dataModelVersion); - - // Get the config file data model version. - std::string GetConfigFileDataModelVersion() const; - - // The delimiter character which is used across the system to build and disassemble argument list. - static const char RGA_LIST_DELIMITER = ';'; - -private: - // Non-copyable. - rgConfigManager() = default; - ~rgConfigManager() = default; - rgConfigManager(const rgConfigManager& other); - const rgConfigManager& operator=(const rgConfigManager& other); - - // A pointer to the global settings. - std::shared_ptr m_pGlobalSettings = nullptr; - - // A pointer to the structure containing the CLI version info. - std::shared_ptr m_pVersionInfo = nullptr; - - // The current API being used - rgProjectAPI m_currentAPI; - - // An error message for fatal scenarios that do not allow RGA to be initialized. - std::string m_fatalErrorMsg; - - // Path to the CLI log file. - std::string m_cliLogFilePath; - - // Current RGA config file data model version. - std::string m_configFileDataModelVersion; - - // Current RGA project file data model version. - std::string m_projectFileDataModelVersion; - - // A flag that indicates if this object has been initialized. - bool m_isInitialized = false; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/rgDataTypes.h b/RadeonGPUAnalyzerGUI/Include/rgDataTypes.h deleted file mode 100644 index e908e12..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgDataTypes.h +++ /dev/null @@ -1,561 +0,0 @@ -#pragma once - -// C++. -#include -#include -#include -#include -#include -#include - -// Qt. -#include - -// Infra. -#include - -// Local. -#include -#include - -// The type of the project. -enum class rgProjectAPI : char -{ - // Unknown. - Unknown, - - // OpenCL. - OpenCL, - - // Vulkan. - Vulkan, - - // The count of known APIs. - ApiCount -}; - -// Supported textual source languages. -enum class rgSrcLanguage { - OpenCL, - GLSL, - HLSL, - SPIRV_Text, - - Unknown -}; - -// Indices for disassembly view sub widgets. -enum class DisassemblyViewSubWidgets -{ - TableView, - TargetGpuPushButton, - ColumnPushButton, - OutputWindow, - SourceWindow, - None, - Count -}; - -Q_DECLARE_METATYPE(DisassemblyViewSubWidgets); - -// The type of pipeline. -enum class rgPipelineType : char -{ - // A multi-stage graphics pipeline. - Graphics, - - // A single-stage compute pipeline. - Compute -}; - -// An array of file paths for each pipeline stage. An empty string indicates an unused stage. -typedef std::array ShaderInputFileArray; - -// The base class for pipeline objects. -struct rgPipelineShaders -{ - // The type of pipeline. - rgPipelineType m_type; - - // An array of input source file paths per pipeline stage. - ShaderInputFileArray m_shaderStages; -}; - -// The state for an individual pipeline object. -struct rgPipelineState -{ - // The pipeline name. - std::string m_name; - - // The full path to the serialized pipeline state file. - std::string m_pipelineStateFilePath; - - // The full path to the original pipeline state file loaded to the PSO editor. - std::string m_originalPipelineStateFilePath; - - // A flag used to indicate if the pipeline is currently active. - bool m_isActive = false; -}; - -// General RGA settings structure. -struct rgBuildSettings -{ - rgBuildSettings() = default; - virtual ~rgBuildSettings() = default; - - // A copy constructor used to initialize using another instance. - rgBuildSettings(const rgBuildSettings& other) : - m_targetGpus(other.m_targetGpus), - m_predefinedMacros(other.m_predefinedMacros), - m_additionalIncludeDirectories(other.m_additionalIncludeDirectories), - m_additionalOptions(other.m_additionalOptions), - m_compilerPaths(other.m_compilerPaths), - m_binaryFileName(other.m_binaryFileName) {} - - virtual bool HasSameSettings(const rgBuildSettings& other) const - { - bool isSame = - (m_targetGpus == other.m_targetGpus) && - (m_predefinedMacros == other.m_predefinedMacros) && - (m_additionalIncludeDirectories == other.m_additionalIncludeDirectories) && - (m_additionalOptions == other.m_additionalOptions) && - (m_binaryFileName == other.m_binaryFileName) && - (m_compilerPaths == other.m_compilerPaths); - - return isSame; - } - - // General build settings. - std::vector m_targetGpus; - std::vector m_predefinedMacros; - std::vector m_additionalIncludeDirectories; - std::string m_additionalOptions; - std::string m_binaryFileName; - - // Alternative compiler paths: {bin, include, lib}. - std::tuple m_compilerPaths; -}; - -// An info structure for each source file in a project. -struct rgSourceFileInfo -{ - // The full path to the source file. - std::string m_filePath; - - // A flag indicating if the file is correlated with current build output. - bool m_isCorrelated = false; -}; - -// A base class for project clones. -struct rgProjectClone -{ - rgProjectClone() = default; - virtual ~rgProjectClone() = default; - - rgProjectClone(const std::string& cloneName, std::shared_ptr pBuildSettings) : - m_cloneName(cloneName), m_pBuildSettings(pBuildSettings){} - - // Returns "true" if the clone does not have any source files or "false" otherwise. - virtual bool IsEmpty() const { return m_sourceFiles.empty(); } - - unsigned m_cloneId = 0; - std::string m_cloneName; - std::vector m_sourceFiles; - std::shared_ptr m_pBuildSettings = nullptr; -}; - -// A project clone containing graphics or compute pipeline state info. -struct rgGraphicsProjectClone : rgProjectClone -{ - rgGraphicsProjectClone() = default; - virtual ~rgGraphicsProjectClone() = default; - - // CTOR used to initialize with existing build settings. - rgGraphicsProjectClone(const std::string& cloneName, std::shared_ptr pBuildSettings) : - rgProjectClone(cloneName, pBuildSettings) {} - - // Returns "true" if the clone does not have any source files or "false" otherwise. - virtual bool IsEmpty() const override - { - return std::all_of(m_pipeline.m_shaderStages.cbegin(), m_pipeline.m_shaderStages.cend(), - [&](const std::string& file) { return file.empty(); }); - } - - // A list of pipeline states within the clone. - std::vector m_psoStates; - - // The pipeline object, which specifies the pipeline type, and - // includes full paths to shader files associated with the pipeline's stages. - rgPipelineShaders m_pipeline; -}; - -// This structure represents a family of GPU products. -struct rgGpuFamily -{ - // The GPU family name. - std::string m_familyName; - - // An array of GPU product names. - std::vector m_productNames; -}; - -// This structure represents a GPU architecture. -struct rgGpuArchitecture -{ - // The name of the GPU HW architecture. - std::string m_architectureName; - - // An array of GPU families within this GPU hardware architecture. - std::vector m_gpuFamilies; -}; - -// Structure containing the CLI version info. -struct rgCliVersionInfo -{ - // The CLI version string. - std::string m_version; - - // The build date. - std::string m_buildDate; - - // A map of build mode to an array of all supported GPU architectures for the mode. - std::map> m_gpuArchitectures; -}; - -// Base structure for projects. -struct rgProject -{ - // Default CTOR, DTOR. - rgProject() = default; - virtual ~rgProject() = default; - - // CTOR #1. - rgProject(const std::string& projectName, - const std::string& projectFileFullPath, rgProjectAPI api) : m_projectName(projectName), - m_projectFileFullPath(projectFileFullPath), m_api(api) {} - - // CTOR #2. - rgProject(const std::string& projectName, const std::string& projectFileFullPath, rgProjectAPI api, const std::vector>& clones) : - m_projectName(projectName), m_projectFileFullPath(projectFileFullPath), m_api(api), m_clones(clones) {} - - // Returns "true" if all clones of this project are empty. - bool IsEmpty() - { - return (std::all_of(m_clones.cbegin(), m_clones.cend(), - [](const std::shared_ptr& pClone) { return pClone->IsEmpty(); })); - } - - // Project name. - std::string m_projectName; - - // The full path to the .rga file. - std::string m_projectFileFullPath; - - // Project API: for now, only OpenCL is supported. - rgProjectAPI m_api; - - // Project clones. - std::vector> m_clones; - - // Project data model version. - std::string m_projectDataModelVersion; -}; - -// Splitter config structure for saving/restoring GUI layout. -struct rgSplitterConfig -{ - // Identifying name for the splitter. - std::string m_splitterName; - - // Splitter view sizes. - std::vector m_splitterValues; -}; - -// Window size config structure for saving/restoring GUI window size. -struct rgWindowConfig -{ - // Window position. - int m_windowXPos = 0; - int m_windowYPos = 0; - - // Window width. - int m_windowWidth = 0; - - // Window height. - int m_windowHeight = 0; - - // Window state. - int m_windowState = 0; -}; - -// A structure used to hold all data parsed from a line of a resource usage CSV file. -struct rgResourceUsageData -{ - std::string m_device; - int m_scratchMemory; - int m_threadsPerWorkgroup; - int m_wavefrontSize; - int m_availableLdsBytes; - int m_usedLdsBytes; - int m_availableSgprs; - int m_usedSgprs; - int m_sgprSpills; - int m_availableVgprs; - int m_usedVgprs; - int m_vgprSpills; - int m_clWorkgroupXDimension; - int m_clWorkgroupYDimension; - int m_clWorkgroupZDimension; - int m_isaSize; -}; - -// A structure used to hold project path and api type for each RGA project. -struct rgRecentProject -{ - std::string projectPath; - rgProjectAPI apiType; -}; - -// **************** -// Global settings. -// **************** - -struct rgGlobalSettings -{ - rgGlobalSettings() = default; - - // Initialize a copy of the incoming settings structure. - rgGlobalSettings(const rgGlobalSettings& other) : - m_logFileLocation(other.m_logFileLocation), - m_visibleDisassemblyViewColumns(other.m_visibleDisassemblyViewColumns), - m_guiLayoutSplitters(other.m_guiLayoutSplitters), - m_pDefaultBuildSettings(other.m_pDefaultBuildSettings), - m_recentProjects(other.m_recentProjects), - m_lastSelectedDirectory(other.m_lastSelectedDirectory), - m_useDefaultProjectName(other.m_useDefaultProjectName), - m_shouldPromptForAPI(other.m_shouldPromptForAPI), - m_defaultAPI(other.m_defaultAPI), - m_fontFamily(other.m_fontFamily), - m_fontSize(other.m_fontSize), - m_includeFilesViewer(other.m_includeFilesViewer), - m_inputFileExtGlsl(other.m_inputFileExtGlsl), - m_inputFileExtHlsl(other.m_inputFileExtHlsl), - m_inputFileExtSpvTxt(other.m_inputFileExtSpvTxt), - m_inputFileExtSpvBin(other.m_inputFileExtSpvBin), - m_defaultLang(other.m_defaultLang) - {} - - bool HasSameSettings(const rgGlobalSettings& other) const - { - bool isSame = (m_logFileLocation.compare(other.m_logFileLocation) == 0) && - (m_visibleDisassemblyViewColumns == other.m_visibleDisassemblyViewColumns) && - (m_useDefaultProjectName == other.m_useDefaultProjectName) && - (m_shouldPromptForAPI == other.m_shouldPromptForAPI) && - (m_defaultAPI == other.m_defaultAPI) && - (m_fontFamily == other.m_fontFamily) && - (m_fontSize == other.m_fontSize) && - (m_includeFilesViewer == other.m_includeFilesViewer) && - (m_inputFileExtGlsl == other.m_inputFileExtGlsl) && - (m_inputFileExtHlsl == other.m_inputFileExtHlsl) && - (m_inputFileExtSpvTxt == other.m_inputFileExtSpvTxt) && - (m_inputFileExtSpvBin == other.m_inputFileExtSpvBin) && - (m_defaultLang == other.m_defaultLang); - - return isSame; - } - - // A full path to the location where RGA's log file will be saved. - std::string m_logFileLocation; - - // Visibility flags for each column within the disassembly table. - std::vector m_visibleDisassemblyViewColumns; - - // Splitter configurations. - std::vector m_guiLayoutSplitters; - - // Window geometry values. - rgWindowConfig m_guiWindowConfig; - - // The default build settings, which can be customized by the user. - // We keep a mapping, each API will have its entry pointing to its default settings. - std::map> m_pDefaultBuildSettings; - - // A vector of recently-accessed projects with their api types. - std::vector> m_recentProjects; - - // A full path to the most recently opened directory. - std::string m_lastSelectedDirectory; - - // If true, RGA will always use the auto-generated project name, - // without prompting the user for renaming when creating a new project. - bool m_useDefaultProjectName = false; - - // When RGA starts, should it prompt the user to select the API mode? - // This can be modified by the user using the "Do not ask me again" option in the startup dialog. - bool m_shouldPromptForAPI = true; - - // The default API mode to use in the GUI if the user has selected an API - // and then selected "Do not ask me again" in the startup dialog. - rgProjectAPI m_defaultAPI = rgProjectAPI::Unknown; - - // The font family. - std::string m_fontFamily; - - // The font size. - int m_fontSize; - - // The app to use to open include files. - std::string m_includeFilesViewer = STR_GLOBAL_SETTINGS_SRC_VIEW_INCLUDE_VIEWER_DEFAULT; - - // Extensions of input files: GLSL, HLSL, SPIR-V text, and SPIR-V binary. - std::string m_inputFileExtGlsl; - std::string m_inputFileExtHlsl; - std::string m_inputFileExtSpvTxt; - std::string m_inputFileExtSpvBin; - - // Default high-level language. - rgSrcLanguage m_defaultLang = rgSrcLanguage::GLSL; -}; - -// The possible types of build output files. -enum rgCliOutputFileType -{ - // ISA disassembly in text format. - IsaDisassemblyText, - - // ISA disassembly in CSV format. - IsaDisassemblyCsv, - - // IL disassembly. - IlDisassembly, - - // Project binary. - Binary, - - // HW resource usage file. - HwResourceUsageFile, - - // Live register analysis report. - LiveRegisterAnalysisReport, - - // Control-flow graph. - ControlFlowGraph -}; - -// This structure represents a single build output file. -struct rgOutputItem -{ - // The full path to the file. - std::string m_filePath; - - // The target GPU that the output was generated for. - std::string m_gpuName; - - // The type of the file. - rgCliOutputFileType m_fileType; -}; - -// This structure represents an input file's entry outputs. -struct rgEntryOutput -{ - // The full path to the input file used to build the output. - std::string m_inputFilePath; - - // The name of the kernel that was compiled to emit the outputs. - std::string m_entrypointName; - - // The type of kernel that was compiled. - std::string m_kernelType; - - // A list of outputs generated for the entry. - std::vector m_outputs; -}; - -struct rgFileOutputs -{ - // The input source file path responsible for the entry. - std::string m_inputFilePath; - - // The list of entry outputs built from the specified input source file. - std::vector m_outputs; -}; - -// A map of input file full path to a build output structure for the input. -typedef std::map InputFileToBuildOutputsMap; - -struct rgCliBuildOutput -{ - virtual ~rgCliBuildOutput() = default; - - // The output as printed by the RGA command line. - std::string m_cliConsoleOutput; - - // Mapping between each input file and its outputs. - InputFileToBuildOutputsMap m_perFileOutput; -}; - -// This structure represents the output of the command line backend when building an OpenCL project. -struct rgCliBuildOutputOpenCL : rgCliBuildOutput -{ - virtual ~rgCliBuildOutputOpenCL() = default; - - // The full path to the project binary. - std::string m_projectBinary; -}; - -// This structure represents the output of the command line backend when building a pipeline object. -struct rgCliBuildOutputPipeline : rgCliBuildOutput -{ - virtual ~rgCliBuildOutputPipeline() = default; - - // The type of pipeline built by the CLI. - rgPipelineType m_type; -}; - -// A map of GPU name to the project build outputs for the GPU. -typedef std::map> rgBuildOutputsMap; - -// A predicate used to find an rgOutputItem with a specific file type. -struct OutputFileTypeFinder -{ - OutputFileTypeFinder(rgCliOutputFileType fileType) : m_targetFileType(fileType) {} - - // A predicate that will compare each output item with a target file type to search for. - bool operator()(const rgOutputItem& outputItem) const - { - return (outputItem.m_fileType == m_targetFileType); - } - - // The target file type to search for. - rgCliOutputFileType m_targetFileType; -}; - -// A map that associates an entry point name with the starting line number and ending line number. -typedef std::map> EntryToSourceLineRange; - -// Enum that specifies the alternative compiler folder view: bin, include or lib. -enum CompilerFolderType -{ - Bin, - Include, - Lib -}; - -// This structure has style sheets for various widgets. -struct rgStylesheetPackage -{ - // The file menu stylesheet. - std::string m_fileMenuStylesheet; - - // The API-specific file menu stylesheet. - std::string m_fileMenuApiStylesheet; - - // The main window stylesheet. - std::string m_mainWindowStylesheet; - - // The application stylesheet. - std::string m_applicationStylesheet; - - // The main window api-specific stylesheet. - std::string m_mainWindowAPIStylesheet; -}; diff --git a/RadeonGPUAnalyzerGUI/Include/rgDataTypesVulkan.h b/RadeonGPUAnalyzerGUI/Include/rgDataTypesVulkan.h deleted file mode 100644 index 39b6805..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgDataTypesVulkan.h +++ /dev/null @@ -1,767 +0,0 @@ -#pragma once - -// Local. -#include - -// *** VULKAN STRING CONSTANTS - START *** - -// Shader source file extensions. -static const char* STR_SOURCE_FILE_EXTENSION_VULKAN_GLSL = ".glsl"; -static const char* STR_SOURCE_FILE_EXTENSION_SPIRV = ".spv"; - -// Vulkan API Name. -static const char* STR_API_NAME_VULKAN = "Vulkan"; -static const char* STR_API_ABBREVIATION_VULKAN = "VK"; - -// Create New Vulkan Graphics Pipeline menu item. -static const char* STR_MENU_BAR_CREATE_NEW_GRAPHICS_PSO_VULKAN = "Create new Vulkan graphics pipeline"; -static const char* STR_MENU_BAR_CREATE_NEW_GRAPHICS_PSO_TOOLTIP_VULKAN = "Create a new Vulkan graphics pipeline, which is a container for Vulkan graphics shaders and state, that can be compiled and analyzed through RGA (Ctrl+Shift+G)."; - -// Create New Vulkan Compute Pipeline menu item. -static const char* STR_MENU_BAR_CREATE_NEW_COMPUTE_PSO_VULKAN = "Create new Vulkan compute pipeline"; -static const char* STR_MENU_BAR_CREATE_NEW_COMPUTE_PSO_TOOLTIP_VULKAN = "Create a new Vulkan compute pipeline, which is a container for a Vulkan compute shader and state, that can be compiled and analyzed through RGA (Ctrl+Shift+C)."; - -// Vulkan file menu shortcuts. -static const char* gs_ACTION_HOTKEY_NEW_VULKAN_GRAPHICS_PROJECT = "Ctrl+Shift+G"; -static const char* gs_ACTION_HOTKEY_NEW_VULKAN_COMPUTE_PROJECT = "Ctrl+Shift+C"; - -// Rename project dialog title string. -static const char* STR_RENAME_PROJECT_DIALOG_BOX_TITLE_VULKAN = "New Vulkan project"; - -// Vulkan ICD extension. -#ifdef _WIN32 -static const char* STR_DIALOG_FILTER_ICD = "Vulkan ICD files (*.dll)"; -#else -static const char* STR_DIALOG_FILTER_ICD = "Vulkan ICD files (*.so)"; -#endif // _WIN32 - -// *** VULKAN STRING CONSTANTS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** VULKAN PIPELINE STATE EDITOR STRINGS - START *** - -// Vulkan Pipeline Layout Create Info structure name. -static const char* STR_VULKAN_PIPELINE_LAYOUT_CREATE_INFO = "VkPipelineLayoutCreateInfo"; - -// Vulkan Descriptor Set Layout Create Info structure name. -static const char* STR_VULKAN_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = "VkDescriptorSetLayoutCreateInfo"; - -// Vulkan Graphics Pipeline Create Info structure name. -static const char* STR_VULKAN_GRAPHICS_PIPELINE_CREATE_INFO = "VkGraphicsPipelineCreateInfo"; - -// Vulkan Render Pass Create Info structure name. -static const char* STR_VULKAN_RENDER_PASS_CREATE_INFO = "VkRenderPassCreateInfo"; - -// The root graphics pipeline state node. -static const char* STR_VULKAN_GRAPHICS_PIPELINE_STATE = "Graphics pipeline state"; - -// The root compute pipeline state node. -static const char* STR_VULKAN_COMPUTE_PIPELINE_STATE = "Compute pipeline state"; - -// Vulkan flags member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_FLAGS = "flags"; - -// Vulkan Pipeline subpass member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_SUBPASS = "subpass"; - -// Vulkan Pipeline basePipelineIndex member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_BASE_INDEX = "basePipelineIndex"; - -// Vulkan Pipeline pVertexInputState member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_PVERTEX_INPUT_STATE = "pVertexInputState"; - -// Vulkan Pipeline vertexBindingDescriptionCount member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_VERTEX_BINDING_DESCRIPTION_COUNT = "vertexBindingDescriptionCount"; - -// Vulkan Pipeline pVertexBindingDescriptions member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_PVERTEX_BINDING_DESCRIPTIONS = "pVertexBindingDescriptions"; - -// Vulkan Vertex Input Binding Description struct type string. -static const char* STR_VULKAN_VERTEX_INPUT_BINDING_DESCRIPTION = "VkVertexInputBindingDescription"; - -// Vulkan Vertex Input Attribute Description struct type string. -static const char* STR_VULKAN_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION = "VkVertexInputAttributeDescription"; - -// Vulkan Pipeline vertexAttributeDescriptionCount member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_VERTEX_ATTRIBUTE_DESCRIPTION_COUNT = "vertexAttributeDescriptionCount"; - -// Vulkan Pipeline pVertexAttributeDescriptions member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_PVERTEX_ATTRIBUTE_DESCRIPTIONS = "pVertexAttributeDescriptions"; - -// Vulkan Pipeline binding member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_VERTEX_BINDING = "binding"; - -// Vulkan Pipeline stride member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_VERTEX_STRIDE = "stride"; - -// Vulkan Pipeline inputRate member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_VERTEX_INPUT_RATE = "inputRate"; - -// Vulkan Pipeline location member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_VERTEX_LOCATION = "location"; - -// Vulkan Pipeline format member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_VERTEX_FORMAT = "format"; - -// Vulkan Pipeline offset member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_OFFSET = "offset"; - -// Vulkan Pipeline extent member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_EXTENT = "extent"; - -// Vulkan Pipeline pInputAssemblyState member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_PINPUT_ASSEMBLY_STATE = "pInputAssemblyState"; - -// Vulkan Pipeline topology member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_TOPOLOGY = "topology"; - -// Vulkan Pipeline primitiveRestartEnable member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_PRIMITIVE_RESTART_ENABLE = "primitiveRestartEnable"; - -// Vulkan Pipeline pTessellationState member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_PTESSELLATION_STATE = "pTessellationState"; - -// Vulkan Pipeline patchControlPoints member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_PATCH_CONTROL_POINTS = "patchControlPoints"; - -// Vulkan Pipeline pViewportState member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_PVIEWPORT_STATE = "pViewportState"; - -// Vulkan Pipeline viewportCount member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_VIEWPORT_COUNT = "viewportCount"; - -// Vulkan Pipeline pViewports member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_PVIEWPORTS = "pViewports"; - -// Vulkan Pipeline scissorCount member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_SCISSOR_COUNT = "scissorCount"; - -// Vulkan Pipeline pScissors member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_PSCISSORS = "pScissors"; - -// Vulkan Pipeline VkViewport member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_VK_VIEWPORT = "VkViewport"; - -// Vulkan x member string. -static const char* STR_VULKAN_MEMBER_X = "x"; - -// Vulkan y member string. -static const char* STR_VULKAN_MEMBER_Y = "y"; - -// Vulkan width member string. -static const char* STR_VULKAN_MEMBER_WIDTH = "width"; - -// Vulkan height member string. -static const char* STR_VULKAN_MEMBER_HEIGHT = "height"; - -// Vulkan viewport minDepth member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_VIEWPORT_MIN_DEPTH = "minDepth"; - -// Vulkan viewport maxDepth member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_VIEWPORT_MAX_DEPTH = "maxDepth"; - -// Vulkan Pipeline VkRect2d member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_SCISSOR_RECT = "VkRect2D"; - -// Vulkan Pipeline pRasterizationState member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_PRASTERIZATION_STATE = "pRasterizationState"; - -// Vulkan Pipeline depthClampEnable member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_DEPTH_CLAMP_ENABLE = "depthClampEnable"; - -// Vulkan Pipeline rasterizerDiscardEnable member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_DISCARD_ENABLE = "rasterizerDiscardEnable"; - -// Vulkan Pipeline polygonMode member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_POLYGON_MODE = "polygonMode"; - -// Vulkan Pipeline cullMode member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_CULL_MODE = "cullMode"; - -// Vulkan Pipeline frontFace member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_FRONT_FACE = "frontFace"; - -// Vulkan Pipeline depthBiasEnable member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_DEPTH_BIAS_ENABLE = "depthBiasEnable"; - -// Vulkan Pipeline depthBiasConstantFactor member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_DEPTH_BIAS_CONSTANT_FACTOR = "depthBiasConstantFactor"; - -// Vulkan Pipeline depthBiasClamp member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_DEPTH_BIAS_CLAMP = "depthBiasClamp"; - -// Vulkan Pipeline depthBiasSlopeFactor member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_DEPTH_BIAS_SLOPE_FACTOR = "depthBiasSlopeFactor"; - -// Vulkan Pipeline lineWidth member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_LINE_WIDTH = "lineWidth"; - -// Vulkan Pipeline pMultisampleState member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_PMULTISAMPLE_STATE = "pMultisampleState"; - -// Vulkan Pipeline rasterizationSamples member string. -static const char* STR_VULKAN_MULTISAMPLE_RASTERIZATION_SAMPLES = "rasterizationSamples"; - -// Vulkan Pipeline multisample state pSampleMask type string. -static const char* STR_VULKAN_MULTISAMPLE_RASTERIZATION_SAMPLE_FLAGS_TYPE = "VkSampleMask"; - -// Vulkan Pipeline multisample state pSampleMask element type string. -static const char* STR_VULKAN_MULTISAMPLE_RASTERIZATION_SAMPLE_FLAGS_ELEMENT_TYPE = "uint32_t"; - -// Vulkan Pipeline sampleShadingEnable member string. -static const char* STR_VULKAN_MULTISAMPLE_SAMPLE_SHADING_ENABLE = "sampleShadingEnable"; - -// Vulkan Pipeline minSampleShading member string. -static const char* STR_VULKAN_MULTISAMPLE_MIN_SAMPLE_SHADING = "minSampleShading"; - -// Vulkan Pipeline pSampleMask member string. -static const char* STR_VULKAN_MULTISAMPLE_P_SAMPLE_MASK = "pSampleMask"; - -// Vulkan Pipeline alphaToCoverageEnable member string. -static const char* STR_VULKAN_MULTISAMPLE_ALPHA_TO_COVERAGE_ENABLE = "alphaToCoverageEnable"; - -// Vulkan Pipeline alphaToOneEnable member string. -static const char* STR_VULKAN_MULTISAMPLE_ALPHA_TO_ONE_ENABLE = "alphaToOneEnable"; - -// Vulkan Pipeline pDepthStencilState member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_PDEPTH_STENCIL_STATE = "pDepthStencilState"; - -// Vulkan depth stencil depthTestEnable member string. -static const char* STR_VULKAN_DEPTH_STENCIL_DEPTH_TEST_ENABLE = "depthTestEnable"; - -// Vulkan depth stencil depthWriteEnable member string. -static const char* STR_VULKAN_DEPTH_STENCIL_DEPTH_WRITE_ENABLE = "depthWriteEnable"; - -// Vulkan depth stencil depthCompareOp member string. -static const char* STR_VULKAN_DEPTH_STENCIL_DEPTH_COMPARE_OP = "depthCompareOp"; - -// Vulkan depth stencil depthBoundsTestEnable member string. -static const char* STR_VULKAN_DEPTH_STENCIL_DEPTH_BOUNDS_TEST_ENABLE = "depthBoundsTestEnable"; - -// Vulkan depth stencil stencilTestEnable member string. -static const char* STR_VULKAN_DEPTH_STENCIL_STENCIL_TEST_ENABLE = "stencilTestEnable"; - -// Vulkan depth stencil front member string. -static const char* STR_VULKAN_DEPTH_STENCIL_FRONT = "front"; - -// Vulkan depth stencil back member string. -static const char* STR_VULKAN_DEPTH_STENCIL_BACK = "back"; - -// Vulkan depth stencil minDepthBounds member string. -static const char* STR_VULKAN_DEPTH_STENCIL_MIN_DEPTH_BOUNDS = "minDepthBounds"; - -// Vulkan depth stencil maxDepthBounds member string. -static const char* STR_VULKAN_DEPTH_STENCIL_MAX_DEPTH_BOUNDS = "maxDepthBounds"; - -// Vulkan depth stencil op state failOp member string. -static const char* STR_VULKAN_DEPTH_STENCIL_STATE_FAIL_OP = "failOp"; - -// Vulkan depth stencil op state passOp member string. -static const char* STR_VULKAN_DEPTH_STENCIL_STATE_PASS_OP = "passOp"; - -// Vulkan depth stencil op state depthFailOp member string. -static const char* STR_VULKAN_DEPTH_STENCIL_STATE_DEPTH_FAIL_OP = "depthFailOp"; - -// Vulkan depth stencil op state compareOp member string. -static const char* STR_VULKAN_DEPTH_STENCIL_STATE_COMPARE_OP = "compareOp"; - -// Vulkan depth stencil op state compareMask member string. -static const char* STR_VULKAN_DEPTH_STENCIL_STATE_COMPARE_MASK = "compareMask"; - -// Vulkan depth stencil op state writeMask member string. -static const char* STR_VULKAN_DEPTH_STENCIL_STATE_WRITE_MASK = "writeMask"; - -// Vulkan depth stencil op state reference member string. -static const char* STR_VULKAN_DEPTH_STENCIL_STATE_REFERENCE = "reference"; - -// Vulkan color blend state logicOpEnable member string. -static const char* STR_VULKAN_COLOR_BLEND_STATE_LOGIC_OP_ENABLE = "logicOpEnable"; - -// Vulkan color blend state logicOp member string. -static const char* STR_VULKAN_COLOR_BLEND_STATE_LOGIC_OP = "logicOp"; - -// Vulkan color blend state attachmentCount member string. -static const char* STR_VULKAN_COLOR_BLEND_STATE_ATTACHMENT_COUNT = "attachmentCount"; - -// Vulkan color blend state pAttachments member string. -static const char* STR_VULKAN_COLOR_BLEND_STATE_P_ATTACHMENTS = "pAttachments"; - -// Vulkan color blend state blendConstants member string. -static const char* STR_VULKAN_COLOR_BLEND_STATE_BLEND_CONSTANTS = "blendConstants"; - -// Vulkan color blend attachment state type string. -static const char* STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE = "VkPipelineColorBlendAttachmentState"; - -// Vulkan color blend attachment state blendEnable member string. -static const char* STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE_BLEND_ENABLE = "blendEnable"; - -// Vulkan color blend attachment state srcColorBlendFactor member string. -static const char* STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE_SRC_COLOR_BLEND_FACTOR = "srcColorBlendFactor"; - -// Vulkan color blend attachment state dstColorBlendFactor member string. -static const char* STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE_DST_COLOR_BLEND_FACTOR = "dstColorBlendFactor"; - -// Vulkan color blend attachment state colorBlendOp member string. -static const char* STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE_COLOR_BLEND_OP = "colorBlendOp"; - -// Vulkan color blend attachment state srcAlphaBlendFactor member string. -static const char* STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE_SRC_ALPHA_BLEND_FACTOR = "srcAlphaBlendFactor"; - -// Vulkan color blend attachment state dstAlphaBlendFactor member string. -static const char* STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE_DST_ALPHA_BLEND_FACTOR = "dstAlphaBlendFactor"; - -// Vulkan color blend attachment state alphaBlendOp member string. -static const char* STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE_ALPHA_BLEND_OP = "alphaBlendOp"; - -// Vulkan color blend attachment state colorWriteMask member string. -static const char* STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE_COLOR_WRITE_MASK = "colorWriteMask"; - -// Vulkan Pipeline pColorBlendState member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_PCOLOR_BLEND_STATE = "pColorBlendState"; - -// Vulkan Pipeline pDynamicState member string. -static const char* STR_VULKAN_PIPELINE_MEMBER_PDYNAMIC_STATE = "pDynamicState"; - -// Vulkan Graphics Pipeline Create Info structure name. -static const char* STR_VULKAN_COMPUTE_PIPELINE_CREATE_INFO = "VkComputePipelineCreateInfo"; - -// Vulkan Render Pass attachmentCount member string. -static const char* STR_VULKAN_RENDER_PASS_ATTACHMENT_COUNT = "attachmentCount"; - -// Vulkan Render Pass pAttachments array member string. -static const char* STR_VULKAN_RENDER_PASS_P_ATTACHMENTS = "pAttachments"; - -// Vulkan Render Pass subpassCount member string. -static const char* STR_VULKAN_RENDER_PASS_SUBPASS_COUNT = "subpassCount"; - -// Vulkan Render Pass pSubpasses array member string. -static const char* STR_VULKAN_RENDER_PASS_P_SUBPASSES = "pSubpasses"; - -// Vulkan Render Pass pipelineBindPoint array member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_PIPELINE_BIND_POINT = "pipelineBindPoint"; - -// Vulkan Render Pass inputAttachmentCount array member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_INPUT_ATTACHMENT_COUNT = "inputAttachmentCount"; - -// Vulkan Render Pass pInputAttachments array member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_P_INPUT_ATTACHMENTS = "pInputAttachments"; - -// Vulkan Render Pass colorAttachmentCount array member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_COLOR_ATTACHMENT_COUNT = "colorAttachmentCount"; - -// Vulkan Render Pass pColorAttachments array member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_COLOR_ATTACHMENTS = "pColorAttachments"; - -// Vulkan Render Pass pResolveAttachments array member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_P_RESOLVE_ATTACHMENTS = "pResolveAttachments"; - -// Vulkan Render Pass pDepthStencilAttachment array member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_P_DEPTH_STENCIL_ATTACHMENT = "pDepthStencilAttachment"; - -// Vulkan Render Pass preserveAttachmentCount array member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_PRESERVE_ATTACHMENT_COUNT = "preserveAttachmentCount"; - -// Vulkan Render Pass pPreserveAttachments array member string. -static const char* STR_VULKAN_RENDER_PASS_P_PRESERVE_ATTACHMENTS = "pPreserveAttachments"; - -// Vulkan Render Pass preserveAttachment element member string. -static const char* STR_VULKAN_RENDER_PASS_PRESERVE_ATTACHMENT = "preserveAttachment"; - -// Vulkan Render Pass dependencyCount member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_COUNT = "dependencyCount"; - -// Vulkan Render Pass pDependencies array member string. -static const char* STR_VULKAN_RENDER_PASS_P_DEPENDENCIES = "pDependencies"; - -// Vulkan Render Pass dependency srcSubpass member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_SRC_SUBPASS = "srcSubpass"; - -// Vulkan Render Pass dependency dstSubpass member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_DST_SUBPASS = "dstSubpass"; - -// Vulkan Render Pass dependency srcStageMask member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_SRC_STAGE_MASK= "srcStageMask"; - -// Vulkan Render Pass dependency dstStageMask member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_DST_STAGE_MASK = "dstStageMask"; - -// Vulkan Render Pass dependency srcAccessMask member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_SRC_ACCESS_MASK = "srcAccessMask"; - -// Vulkan Render Pass dependency dstAccessMask member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_DST_ACCESS_MASK = "dstAccessMask"; - -// Vulkan Render Pass dependency dependencyFlags member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_DEPENDENCY_FLAGS = "dependencyFlags"; - -// Vulkan Render Pass attachment samples member string. -static const char* STR_VULKAN_RENDER_PASS_ATTACHMENT_SAMPLES = "samples"; - -// Vulkan Render Pass loadOp member string. -static const char* STR_VULKAN_RENDER_PASS_LOAD_OP = "loadOp"; - -// Vulkan Render Pass storeOp member string. -static const char* STR_VULKAN_RENDER_PASS_STORE_OP = "storeOp"; - -// Vulkan Render Pass stencilLoadOp member string. -static const char* STR_VULKAN_RENDER_PASS_STENCIL_LOAD_OP = "stencilLoadOp"; - -// Vulkan Render Pass stencilStoreOp member string. -static const char* STR_VULKAN_RENDER_PASS_STENCIL_STORE_OP = "stencilStoreOp"; - -// Vulkan Render Pass initialLayout member string. -static const char* STR_VULKAN_RENDER_PASS_INITIAL_LAYOUT = "initialLayout"; - -// Vulkan Render Pass finalLayout member string. -static const char* STR_VULKAN_RENDER_PASS_FINAL_LAYOUT = "finalLayout"; - -// Vulkan Render Pass attachment description type member string. -static const char* STR_VULKAN_RENDER_PASS_ATTACHMENT_DESCRIPTION = "VkAttachmentDescription"; - -// Vulkan Render Pass Subpass description type member string. -static const char* STR_VULKAN_RENDER_PASS_SUBPASS_DESCRIPTION = "VkSubpassDescription"; - -// Vulkan Render Pass dependency description type member string. -static const char* STR_VULKAN_RENDER_PASS_DEPENDENCY_DESCRIPTION = "VkSubpassDependency"; - -// Vulkan Render Pass Subpass pipelineBindPoint member string. -static const char* STR_VULKAN_RENDER_PASS_SUBPASS_PIPELINE_BIND_POINT = "pipelineBindPoint"; - -// Vulkan Render Pass Subpass inputAttachmentCount member string. -static const char* STR_VULKAN_RENDER_PASS_SUBPASS_INPUT_ATTACHMENT_COUNT = "inputAttachmentCount"; - -// Vulkan Render Pass Subpass pInputAttachments member string. -static const char* STR_VULKAN_RENDER_PASS_SUBPASS_P_INPUT_ATTACHMENTS = "pInputAttachments"; - -// Vulkan Render Pass Subpass attachment reference type member string. -static const char* STR_VULKAN_RENDER_SUBPASS_ATTACHMENT_REFERENCE = "VkAttachmentReference"; - -// Vulkan Render Pass Subpass preserve attachment type member string. -static const char* STR_VULKAN_RENDER_SUBPASS_PRESERVE_ATTACHMENT_ELEMENT_TYPE = "uint32_t"; - -// Vulkan Render Pass Subpass colorAttachmentCount member string. -static const char* STR_VULKAN_RENDER_PASS_SUBPASS_COLOR_ATTACHMENT_COUNT = "colorAttachmentCount"; - -// Vulkan Render Pass Subpass pColorAttachments member string. -static const char* STR_VULKAN_RENDER_PASS_SUBPASS_P_COLOR_ATTACHMENTS = "pColorAttachments"; - -// Vulkan Render Pass Subpass resolveAttachmentCount member string. -static const char* STR_VULKAN_RENDER_PASS_SUBPASS_RESOLVE_ATTACHMENT_COUNT = "resolveAttachmentCount"; - -// Vulkan Render Pass Subpass pResolveAttachments member string. -static const char* STR_VULKAN_RENDER_PASS_SUBPASS_P_RESOLVE_ATTACHMENTS = "pResolveAttachments"; - -// Vulkan Render Pass Subpass pDepthStencilAttachment member string. -static const char* STR_VULKAN_RENDER_PASS_SUBPASS_P_DEPTH_STENCIL_ATTACHMENT = "pDepthStencilAttachment"; - -// Vulkan Render Pass Subpass preserveAttachmentCount member string. -static const char* STR_VULKAN_RENDER_PASS_SUBPASS_PRESERVE_ATTACHMENT_COUNT = "preserveAttachmentCount"; - -// Vulkan Render Pass Subpass pPreserveAttachments member string. -static const char* STR_VULKAN_RENDER_PASS_SUBPASS_P_PRESERVE_ATTACHMENTS = "pPreserveAttachments"; - -// Vulkan Render Pass Subpass attachment member string. -static const char* STR_VULKAN_RENDER_PASS_SUBPASS_ATTACHMENT_INDEX = "attachment"; - -// Vulkan Render Pass Subpass layout member string. -static const char* STR_VULKAN_RENDER_PASS_SUBPASS_ATTACHMENT_LAYOUT = "layout"; - -// Vulkan Pipeline Layout descriptorSetCount member string. -static const char* STR_VULKAN_PIPELINE_LAYOUT_DESCRIPTOR_SET_LAYOUT_COUNT = "setLayoutCount"; - -// Vulkan Pipeline Layout pSetLayouts array member string. -static const char* STR_VULKAN_PIPELINE_LAYOUT_P_SET_LAYOUTS = "pSetLayouts"; - -// Vulkan Descriptor Set Layout handle type. -static const char* STR_VULKAN_DESCRIPTOR_SET_LAYOUT_HANDLE = "VkDescriptorSetLayout"; - -// Vulkan Descriptor Set Layouts header item title. -static const char* STR_VULKAN_DESCRIPTOR_SET_LAYOUTS_HEADER = "Descriptor Set Layouts"; - -// Vulkan Descriptor Set Layout count. -static const char* STR_VULKAN_DESCRIPTOR_SET_LAYOUT_COUNT = "Descriptor Set Layout count"; - -// Vulkan Pipeline Layout pushConstantRangeCount array member string. -static const char* STR_VULKAN_PIPELINE_LAYOUT_PUSH_CONSTANT_RANGE_COUNT = "pushConstantRangeCount"; - -// Vulkan Pipeline Layout pPushConstantRanges array member string. -static const char* STR_VULKAN_PIPELINE_LAYOUT_P_PUSH_CONSTANT_RANGES = "pPushConstantRanges"; - -// Vulkan Push Constant range type string. -static const char* STR_VULKAN_PUSH_CONSTANT_RANGE_TYPE = "VkPushConstantRange"; - -// Vulkan Pipeline Layout Stage Flags member string. -static const char* STR_VULKAN_PIPELINE_LAYOUT_STAGE_FLAGS = "stageFlags"; - -// Vulkan Push Constants offset member string. -static const char* STR_VULKAN_PIPELINE_LAYOUT_PUSH_CONSTANT_OFFSET = "offset"; - -// Vulkan Push Constants size member string. -static const char* STR_VULKAN_PIPELINE_LAYOUT_PUSH_CONSTANT_SIZE = "size"; - -// Vulkan Descriptor Set Layout bindingCount member string. -static const char* STR_VULKAN_PIPELINE_LAYOUT_DESCRIPTOR_SET_LAYOUT_BINDING_COUNT = "bindingCount"; - -// Vulkan Descriptor Set Layout pBindings member string. -static const char* STR_VULKAN_PIPELINE_LAYOUT_DESCRIPTOR_SET_LAYOUT_P_BINDINGS = "pBindings"; - -// Vulkan Descriptor Set Layout Binding type string. -static const char* STR_VULKAN_DESCRIPTOR_SET_LAYOUT_BINDING_TYPE = "VkDescriptorSetLayoutBinding"; - -// Vulkan Descriptor Set Layout binding member string. -static const char* STR_VULKAN_DESCRIPTOR_SET_LAYOUT_BINDING = "binding"; - -// Vulkan Descriptor Set Layout Binding descriptor type member string. -static const char* STR_VULKAN_DESCRIPTOR_SET_LAYOUT_BINDING_DESCRIPTOR_TYPE = "descriptorType"; - -// Vulkan Descriptor Set Layout Binding descriptor count member string. -static const char* STR_VULKAN_DESCRIPTOR_SET_LAYOUT_BINDING_DESCRIPTOR_COUNT = "descriptorCount"; - - -// *** VULKAN PIPELINE STATE EDITOR STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** VULKAN SHADER ABBREVIATION STAGE NAME STRINGS - START *** - -// The Vertex stage abbreviation string. -static const char* STR_VULKAN_STAGE_NAME_VERTEX_ABBREVIATION = "vert"; - -// The Vulkan Tessellation Control stage abbreviation string. -static const char* STR_VULKAN_STAGE_NAME_TESSELLATION_CONTROL_ABBREVIATION = "tesc"; - -// The Vulkan Tessellation Evaluation stage abbreviation string. -static const char* STR_VULKAN_STAGE_NAME_TESSELLATION_EVALUATION_ABBREVIATION = "tese"; - -// The geometry stage abbreviation string. -static const char* STR_VULKAN_STAGE_NAME_GEOMETRY_ABBREVIATION = "geom"; - -// The Vulkan Fragment stage abbreviation string. -static const char* STR_VULKAN_STAGE_NAME_FRAGMENT_ABBREVIATION = "frag"; - -// The Compute stage abbreviation string. -static const char* STR_VULKAN_STAGE_NAME_COMPUTE_ABBREVIATION = "comp"; - -// *** VULKAN SHADER ABBREVIATION STAGE NAME STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** VULKAN STAGE NAME STRINGS - START *** - -// The Vertex stage name string. -static const char* STR_VULKAN_STAGE_NAME_VERTEX = "Vertex"; - -// The Vulkan Tessellation Control stage name string. -static const char* STR_VULKAN_STAGE_NAME_TESSELLATION_CONTROL = "Tessellation Control"; - -// The Vulkan Tessellation Evaluation stage name string. -static const char* STR_VULKAN_STAGE_NAME_TESSELLATION_EVALUATION = "Tessellation Evaluation"; - -// The geometry stage name string. -static const char* STR_VULKAN_STAGE_NAME_GEOMETRY = "Geometry"; - -// The Vulkan Fragment stage name string. -static const char* STR_VULKAN_STAGE_NAME_FRAGMENT = "Fragment"; - -// The Compute stage name string. -static const char* STR_VULKAN_STAGE_NAME_COMPUTE = "Compute"; - -// *** VULKAN STAGE NAME STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** VULKAN SOURCE CODE STRINGS - START *** - -// The default source code for a Vulkan glsl vertex shader. -static const char* STR_NEW_FILE_TEMPLATE_CODE_VULKAN_GLSL_VERTEX_SHADER = - "/* Auto-generated with Radeon GPU Analyzer (RGA).*/\n" - "#version 450\n" - "\n" - "#extension GL_GOOGLE_include_directive : require\n" - "#extension GL_ARB_separate_shader_objects : enable\n" - "\n" - "out gl_PerVertex\n" - "{\n" - " vec4 gl_Position;\n" - "};\n" - "\n" - "layout(location = 0) out vec3 fragColor;\n" - "\n" - "void main()\n" - "{\n" - " float x = -1.0 + float((gl_VertexIndex & 1) << 2);\n" - " float y = -1.0 + float((gl_VertexIndex & 2) << 1);\n" - " gl_Position = vec4(x, y, 0, 1);\n" - "\n" - " fragColor = vec3(1.0f, 0.0f, 0.0f);\n" - "}"; - -// The default source code for a Vulkan glsl passthrough geometry shader. -static const char* STR_NEW_FILE_TEMPLATE_CODE_VULKAN_GLSL_GEOMETRY_SHADER = - "/* Auto-generated with Radeon GPU Analyzer (RGA).*/\n" - "#version 450\n" - "\n" - "#extension GL_GOOGLE_include_directive : require\n" - "#extension GL_ARB_separate_shader_objects : enable\n" - "\n" - "layout (triangles) in;\n" - "layout (triangle_strip, max_vertices=3) out;\n" - "layout (location = 0) out vec3 outColor;\n" - "\n" - "void main()\n" - "{\n" - " for(int vertexIndex = 0; vertexIndex < 3; vertexIndex++)\n" - " {\n" - " gl_Position = gl_in[vertexIndex].gl_Position;\n" - " EmitVertex();\n" - " }\n" - " EndPrimitive();\n" - "}"; - -// The default source code for a Vulkan glsl passthrough tessellation control shader. -static const char* STR_NEW_FILE_TEMPLATE_CODE_VULKAN_GLSL_TESSELLATION_CONTROL_SHADER = - "/* Auto-generated with Radeon GPU Analyzer (RGA).*/\n" - "#version 450\n" - "\n" - "#extension GL_GOOGLE_include_directive : require\n" - "#extension GL_ARB_separate_shader_objects : enable\n" - "\n" - "layout (vertices = 3) out;\n" - "\n" - "void main(void)\n" - "{\n" - " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" - "}"; - -// The default source code for a Vulkan glsl passthrough tessellation evaluation shader. -static const char* STR_NEW_FILE_TEMPLATE_CODE_VULKAN_GLSL_TESSELLATION_EVALUATION_SHADER = - "/* Auto-generated with Radeon GPU Analyzer (RGA).*/\n" - "#version 450\n" - "\n" - "#extension GL_GOOGLE_include_directive : require\n" - "#extension GL_ARB_separate_shader_objects : enable\n" - "\n" - "layout (triangles) in;\n" - "\n" - "void main(void)\n" - "{\n" - " gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) +\n" - " (gl_TessCoord.y * gl_in[1].gl_Position) +\n" - " (gl_TessCoord.z * gl_in[2].gl_Position);\n" - "}"; - -// The default source code for a Vulkan glsl fragment shader. -static const char* STR_NEW_FILE_TEMPLATE_CODE_VULKAN_GLSL_FRAGMENT_SHADER = - "/* Auto-generated with Radeon GPU Analyzer (RGA).*/\n" - "#version 450\n" - "\n" - "#extension GL_GOOGLE_include_directive : require\n" - "#extension GL_ARB_separate_shader_objects : enable\n" - "\n" - "layout(location = 0) in vec3 fragColor;\n" - "layout(location = 0) out vec4 outColor;\n" - "\n" - "void main()\n" - "{\n" - " outColor = vec4(fragColor, 1.0f);\n" - "}"; - -// The default source code for a Vulkan glsl compute shader. -static const char* STR_NEW_FILE_TEMPLATE_CODE_VULKAN_GLSL_COMPUTE_SHADER = - "/* Auto-generated with Radeon GPU Analyzer (RGA).*/\n" - "#version 450\n" - "\n" - "#extension GL_GOOGLE_include_directive : require\n" - "#extension GL_ARB_separate_shader_objects : enable\n" - "\n" - "void main()\n" - "{\n" - " uint index = gl_GlobalInvocationID.x;\n" - "}\n"; - -// *** VULKAN SOURCE CODE STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** VULKAN TYPE DECLARATIONS - START *** - -// Vulkan build settings. -struct rgBuildSettingsVulkan : public rgBuildSettings -{ - rgBuildSettingsVulkan() = default; - virtual ~rgBuildSettingsVulkan() = default; - - // Copy constructor used to initialize using another instance. - rgBuildSettingsVulkan(const rgBuildSettingsVulkan& other) : - rgBuildSettings(other), - m_isGenerateDebugInfoChecked(other.m_isGenerateDebugInfoChecked), - m_isNoExplicitBindingsChecked(other.m_isNoExplicitBindingsChecked), - m_isUseHlslBlockOffsetsChecked(other.m_isUseHlslBlockOffsetsChecked), - m_isUseHlslIoMappingChecked(other.m_isUseHlslIoMappingChecked), - m_isEnableValidationLayersChecked(other.m_isEnableValidationLayersChecked), - m_ICDLocation(other.m_ICDLocation), - m_glslangOptions(other.m_glslangOptions), - m_binaryFileName(other.m_binaryFileName) - {} - - virtual bool HasSameSettings(const rgBuildSettingsVulkan& other) const - { - bool isSame = rgBuildSettings::HasSameSettings(other) && - (m_isGenerateDebugInfoChecked == other.m_isGenerateDebugInfoChecked) && - (m_isNoExplicitBindingsChecked == other.m_isNoExplicitBindingsChecked) && - (m_isUseHlslBlockOffsetsChecked == other.m_isUseHlslBlockOffsetsChecked) && - (m_isUseHlslIoMappingChecked == other.m_isUseHlslIoMappingChecked) && - (m_isEnableValidationLayersChecked == other.m_isEnableValidationLayersChecked) && - (m_ICDLocation == other.m_ICDLocation) && - (m_glslangOptions == other.m_glslangOptions) && - (m_binaryFileName == other.m_binaryFileName); - - return isSame; - } - - bool m_isGenerateDebugInfoChecked = false; - bool m_isNoExplicitBindingsChecked = false; - bool m_isUseHlslBlockOffsetsChecked = false; - bool m_isUseHlslIoMappingChecked = false; - bool m_isEnableValidationLayersChecked = false; - std::string m_ICDLocation; - std::string m_glslangOptions; - std::string m_binaryFileName; -}; - -// A clone of an Vulkan project. -struct rgProjectCloneVulkan : public rgGraphicsProjectClone -{ - // CTOR #1. - rgProjectCloneVulkan() - { - // Instantiate a Vulkan build settings instance by default. - m_pBuildSettings = std::make_shared(); - } - - // CTOR #2. - rgProjectCloneVulkan(const std::string& cloneName, std::shared_ptr pBuildSettings) : - rgGraphicsProjectClone(cloneName, pBuildSettings) {} - - // Paths to original SPIR-V binary files. - rgPipelineShaders m_spvBackup; -}; - -// An Vulkan project. -struct rgProjectVulkan : public rgProject -{ - // CTOR #1. - rgProjectVulkan() : rgProject("", "", rgProjectAPI::Vulkan) {} - - // CTOR #2. - rgProjectVulkan(const std::string& projectName, const std::string& projectFileFullPath) : rgProject(projectName, - projectFileFullPath, rgProjectAPI::Vulkan) {} - - // CTOR #3. - rgProjectVulkan(const std::string& projectName, const std::string& projectFileFullPath, - const std::vector>& clones) : - rgProject(projectName, projectFileFullPath, rgProjectAPI::Vulkan, clones) {} -}; - -// *** VULKAN TYPE DECLARATIONS - END *** diff --git a/RadeonGPUAnalyzerGUI/Include/rgDefinitions.h b/RadeonGPUAnalyzerGUI/Include/rgDefinitions.h deleted file mode 100644 index ae18483..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgDefinitions.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -// The mode string used for OpenCL mode. -static const char* STR_MODE_STRING_OPENCL = "rocm-cl"; - -// The mode string used for Vulkan mode. -static const char* STR_MODE_STRING_VULKAN = "vulkan"; - -// The default entry point name for Vulkan GLSL shaders. -static const char* STR_DEFAULT_VULKAN_GLSL_ENTRYPOINT_NAME = "main"; - -// Standard truncation lengths. -static const int gs_TEXT_TRUNCATE_LENGTH_FRONT = 10; -static const int gs_TEXT_TRUNCATE_LENGTH_BACK = 10; -static const int gs_TEXT_TRUNCATE_LENGTH_BACK_OPENCL = 10; -static const int gs_TEXT_TRUNCATE_LENGTH_BACK_VULKAN = 2; - -// The constant used when the selected line in the source file doesn't have any correlated disassembly lines. -static const int kInvalidCorrelationLineIndex = -1; - -// The duration, in milliseconds, of how long that the status bar text will remain before being cleared. -const int gs_STATUS_BAR_NOTIFICATION_TIMEOUT_MS = 3000; - -// The font size in point for various RGA buttons. -const int gs_BUTTON_POINT_FONT_SIZE = 8; - -// The font size for build view. -static const int gs_BUILD_VIEW_FONT_SIZE = 10; - -// The property name used to block recursive style repolishing. -static const char* gs_IS_REPOLISHING_BLOCKED = "isRepolishingBlocked"; - -// Home page definitions. -static const char* gs_ACTION_HOTKEY_OPEN_PROJECT = "Ctrl+Alt+O"; -static const char* gs_ACTION_HOTKEY_BACK_TO_HOME = "Ctrl+Alt+H"; -static const char* gs_ACTION_HOTKEY_EXIT = "Alt+F4"; -static const char* gs_ACTION_HOTKEY_ABOUT = "Ctrl+F1"; -static const char* gs_ACTION_HOTKEY_HELP_MANUAL = "F1"; - -// Focus navigation hotkey definitions. -static const char* gs_ACTION_HOTKEY_NEXT_VIEW = "Ctrl+Tab"; -static const char* gs_ACTION_HOTKEY_PREVIOUS_VIEW = "Shift+Ctrl+Tab"; - -// File menu hotkey definitions. -static const char* gs_ACTION_HOTKEY_FILE_MENU_NEXT_ITEM = "Down"; -static const char* gs_ACTION_HOTKEY_FILE_MENU_PREV_ITEM = "Up"; -static const char* gs_ACTION_HOTKEY_FILE_MENU_ACTIVATE_SPACE = "Space"; -static const char* gs_ACTION_HOTKEY_FILE_MENU_CONTEXT_MENU = "Shift+F10"; -static const char* gs_ACTION_HOTKEY_FILE_MENU_ACTIVATE_RETURN = "Return"; -static const char* gs_ACTION_HOTKEY_FILE_MENU_ACTIVATE_ENTER = "Enter"; -static const char* gs_ACTION_HOTKEY_FILE_MENU_RENAME = "F2"; -static const char* gs_ACTION_HOTKEY_FILE_MENU_ACTIVATE_TAB = "Tab"; -static const char* gs_ACTION_HOTKEY_FILE_MENU_ACTIVATE_SHIFT_TAB = "Shift+Tab"; - -// Edit menu hotkey definitions. -static const char* gs_ACTION_HOTKEY_GO_TO_LINE = "Ctrl+G"; -static const char* gs_ACTION_HOTKEY_FIND = "Ctrl+F"; -static const char* gs_ACTION_HOTKEY_FIND_NEXT = "F3"; -static const char* gs_ACTION_HOTKEY_FIND_PREVIOUS = "Shift+F3"; - -// Build menu hotkey definitions. -static const char* gs_ACTION_HOTKEY_BUILD_PROJECT = "Ctrl+Shift+B"; -static const char* gs_ACTION_HOTKEY_BUILD_SETTINGS = "F8"; -static const char* gs_ACTION_HOTKEY_PIPELINE_STATE = "F9"; -static const char* gs_ACTION_HOTKEY_BUILD_CANCEL = "Ctrl+Shift+C"; - -// Source view hotkey definitions. -static const char* gs_SOURCE_EDITOR_HOTKEY_CONTEXT_MENU_CUT = "Ctrl+X"; -static const char* gs_SOURCE_EDITOR_HOTKEY_CONTEXT_MENU_COPY = "Ctrl+C"; -static const char* gs_SOURCE_EDITOR_HOTKEY_CONTEXT_MENU_PASTE = "Ctrl+V"; -static const char* gs_SOURCE_EDITOR_HOTKEY_CONTEXT_MENU_SELECT_ALL = "Ctrl+A"; - -// Disassembly view hot key definitions. -static const char* gs_DISASSEMBLY_VIEW_HOTKEY_GPU_SELECTION = "Ctrl+T"; - -// View container hot key definitions. -static const char* gs_SWITCH_CONTAINER_SIZE = "Ctrl+R"; - -// Restore default settings hot key. -static const char* gs_RESTORE_DEFAULT_SETTINGS = "Ctrl+R"; - -// Icon resource paths. -static const char* gs_ICON_RESOURCE_RGA_LOGO = ":/icons/rgaIcon.png"; -static const char* gs_ICON_RESOURCE_FIND_MAGNIFYING_GLASS = ":/icons/magnifyingGlassIcon.svg"; -static const char* gs_ICON_RESOURCE_EXPANDED_ROW = ":/icons/expandFileItem.svg"; -static const char* gs_ICON_RESOURCE_COLLAPSED_ROW = ":/icons/collapsedArrow.svg"; -static const char* gs_ICON_RESOURCE_REMOVE_NOTIFICATION = ":/icons/correlationWarningIcon.svg"; - -// Build settings options list delimiter. -static const char* s_OPTIONS_LIST_DELIMITER = ";"; - -// Macros. -#define RG_SAFE_DELETE(ptr) { delete ptr; ptr = nullptr;} - -#ifdef WIN32 - #define STRCPY(dst, size, src) strcpy_s(dst, size, src) -#else - #define STRCPY(dst, size, src) strncpy(dst, src, size) -#endif \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/rgFactory.h b/RadeonGPUAnalyzerGUI/Include/rgFactory.h deleted file mode 100644 index 5543381..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgFactory.h +++ /dev/null @@ -1,75 +0,0 @@ -#pragma once - -// Qt. -#include - -// Local. -#include - -// Forward declares. -class QWidget; -class rgAppState; -class rgBuildSettingsView; -class rgBuildView; -class rgIsaDisassemblyView; -class rgMenu; -class rgMainWindow; -class rgRenameProjectDialog; -class rgSettingsTab; -class rgStartTab; -class rgStatusBar; - -// Base factory used to create API-specific object instances. -class rgFactory -{ -public: - virtual ~rgFactory() = default; - - // Get a factory instance based on the given API. - static std::shared_ptr CreateFactory(rgProjectAPI api); - - // Create a new application state. - virtual std::shared_ptr CreateAppState() = 0; - - // Create a project instance. - virtual std::shared_ptr CreateProject(const std::string& projectName, const std::string& projectFileFullPath) = 0; - - // Create a project clone instance. - virtual std::shared_ptr CreateProjectClone(const std::string& cloneName) = 0; - - // Create a build settings instance. - // pInitialBuildSettings is an optional pointer to an existing build settings instance to create a copy of. - // If pInitialBuildSettings is not provided, the API's default build settings will be used. - virtual std::shared_ptr CreateBuildSettings(std::shared_ptr pInitialBuildSettings) = 0; - - // *** Views - BEGIN *** - - // Create an API-specific build settings view instance. - virtual rgBuildSettingsView* CreateBuildSettingsView(QWidget* pParent, std::shared_ptr pBuildSettings, bool isGlobalSettings) = 0; - - // Create an API-specific build view. - virtual rgBuildView* CreateBuildView(QWidget* pParent) = 0; - - // Create an API-specific disassembly view. - virtual rgIsaDisassemblyView* CreateDisassemblyView(QWidget* pParent) = 0; - - // Create an API-specific file menu. - virtual rgMenu* CreateFileMenu(QWidget* pParent) = 0; - - // Create an API-specific start tab. - virtual rgStartTab* CreateStartTab(QWidget* pParent) = 0; - - // Create an API-specific rename project dialog box. - virtual rgRenameProjectDialog* CreateRenameProjectDialog(std::string& projectName, QWidget* pParent) = 0; - - // Create an API-specific settings tab. - virtual rgSettingsTab* CreateSettingsTab(QWidget* pParent) = 0; - - // Create an API-specific status bar. - virtual rgStatusBar* CreateStatusBar(QStatusBar* pStatusBar, QWidget* pParent) = 0; - - // *** Views - END *** - -protected: - rgStylesheetPackage m_stylesheetPackage; -}; diff --git a/RadeonGPUAnalyzerGUI/Include/rgFactoryGraphics.h b/RadeonGPUAnalyzerGUI/Include/rgFactoryGraphics.h deleted file mode 100644 index e23a87b..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgFactoryGraphics.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -// Local. -#include - -// Forward declarations. -class rgPipelineStateModel; -class rgPipelineStateView; - -class rgFactoryGraphics : public rgFactory -{ -public: - rgFactoryGraphics() = default; - virtual ~rgFactoryGraphics() = default; - - // Create an API-specific Pipeline State model instance. - virtual rgPipelineStateModel* CreatePipelineStateModel(QWidget* pParent) = 0; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/rgFactoryOpenCL.h b/RadeonGPUAnalyzerGUI/Include/rgFactoryOpenCL.h deleted file mode 100644 index 3232f22..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgFactoryOpenCL.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -// C++. -#include - -// Local. -#include - -// Forward declares. -class QWidget; -class rgBuildView; -class rgIsaDisassemblyView; - -// Base factory used to create API-specific object instances. -class rgFactoryOpenCL : public rgFactory -{ -public: - // Create a new OpenCL application state. - virtual std::shared_ptr CreateAppState() override; - - // Create a project instance. - virtual std::shared_ptr CreateProject(const std::string& projectName, const std::string& projectFileFullPath) override; - - // Create a project clone instance. - virtual std::shared_ptr CreateProjectClone(const std::string& cloneName) override; - - // Create a build settings instance. - virtual std::shared_ptr CreateBuildSettings(std::shared_ptr pInitialBuildSettings) override; - - // *** Views - BEGIN *** - - // Create an OpenCL-specific build settings view instance. - virtual rgBuildSettingsView* CreateBuildSettingsView(QWidget* pParent, std::shared_ptr pBuildSettings, bool isGlobalSettings) override; - - // Create an OpenCL build view. - virtual rgBuildView* CreateBuildView(QWidget* pParent) override; - - // Create an OpenCL disassembly view. - virtual rgIsaDisassemblyView* CreateDisassemblyView(QWidget* pParent) override; - - // Create an OpenCL file menu. - virtual rgMenu* CreateFileMenu(QWidget* pParent) override; - - // Create an OpenCL-specific start tab. - virtual rgStartTab* CreateStartTab(QWidget* pParent) override; - - // Create an OpenCL-specific project rename dialog box. - rgRenameProjectDialog* CreateRenameProjectDialog(std::string& projectName, QWidget* pParent) override; - - // Create an API-specific settings tab. - virtual rgSettingsTab* CreateSettingsTab(QWidget* pParent) override; - - // Create an OpenCL-specific status bar. - virtual rgStatusBar* CreateStatusBar(QStatusBar* pStatusBar, QWidget* pParent) override; - - // *** Views - END *** -}; diff --git a/RadeonGPUAnalyzerGUI/Include/rgFactoryVulkan.h b/RadeonGPUAnalyzerGUI/Include/rgFactoryVulkan.h deleted file mode 100644 index f179cb3..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgFactoryVulkan.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -// Local. -#include - -class rgFactoryVulkan : public rgFactoryGraphics -{ -public: - // Create a new Vulkan application state. - virtual std::shared_ptr CreateAppState() override; - - // Create a project instance. - virtual std::shared_ptr CreateProject(const std::string& projectName, const std::string& projectFileFullPath) override; - - // Create a project clone instance. - virtual std::shared_ptr CreateProjectClone(const std::string& cloneName) override; - - // Create a build settings instance. - virtual std::shared_ptr CreateBuildSettings(std::shared_ptr pInitialBuildSettings) override; - - // *** Views - BEGIN *** - - // Create a Vulkan-specific build settings view instance. - virtual rgBuildSettingsView* CreateBuildSettingsView(QWidget* pParent, std::shared_ptr pBuildSettings, bool isGlobalSettings) override; - - // Create a Vulkan-specific build view. - virtual rgBuildView* CreateBuildView(QWidget* pParent) override; - - // Create a Vulkan disassembly view. - virtual rgIsaDisassemblyView* CreateDisassemblyView(QWidget* pParent) override; - - // Create a Vulkan-specific file menu. - virtual rgMenu* CreateFileMenu(QWidget* pParent) override; - - // Create a Vulkan-specific start tab. - virtual rgStartTab* CreateStartTab(QWidget* pParent) override; - - // Create a Vulkan-specific project rename dialog box. - rgRenameProjectDialog* CreateRenameProjectDialog(std::string& projectName, QWidget* pParent) override; - - // Create an API-specific settings tab. - virtual rgSettingsTab* CreateSettingsTab(QWidget* pParent) override; - - // Create a Vulkan-specific status bar. - virtual rgStatusBar* CreateStatusBar(QStatusBar* pStatusBar, QWidget* pParent) override; - - // Create a Vulkan-specific Pipeline State model instance. - virtual rgPipelineStateModel* CreatePipelineStateModel(QWidget* pParent) override; - - // *** Views - END *** -}; diff --git a/RadeonGPUAnalyzerGUI/Include/rgObjectNames.h b/RadeonGPUAnalyzerGUI/Include/rgObjectNames.h deleted file mode 100644 index 1eb0269..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgObjectNames.h +++ /dev/null @@ -1,143 +0,0 @@ -#pragma once - -// Object names for PSO editor objects (rgPipelineStateModelVulkan.cpp) - START -// String constants. -static const char* STR_ALPHA_BLEND_OP_NODE = "pAlphaBlendOpNode"; -static const char* STR_ALPHA_BLEND_TO_COVERAGE_NODE = "pAlphaToCoverageNode"; -static const char* STR_ALPHA_TO_ONE_NODE = "pAlphaToOneNode"; -static const char* STR_ARRAY_ELEMENT = "pArrayElement"; -static const char* STR_ATTACHMENT_COUNT_ITEM = "pAttachmentCountItem"; -static const char* STR_ATTACHMENT_NODE = "pAttachmentNode"; -static const char* STR_ATTACHMENTS_ROOT_ITEM = "pAttachmentsRootItem"; -static const char* STR_BACK_STENCIL_OP_STATE_NODE = "pBackStencilOpStateNode"; -static const char* STR_BASE_PIPELINE_INDEX_CREATE_INFO = "pBasePipelineIndexCreateInfo"; -static const char* STR_BINDING_ELEMENT = "pBindingElement"; -static const char* STR_BLEND_CONSTANT_NODE = "pBlendConstantNode"; -static const char* STR_BLEND_CONSTANTS_ROOT_NODE = "pBlendConstantsRootNode"; -static const char* STR_BLEND_ENABLE_NODE = "pBlendEnableNode"; -static const char* STR_COLOR_ATTACHMENT_COUNT_NODE = "pColorAttachmentCountNode"; -static const char* STR_COLOR_ATTACHMENTS_ROOT_ITEM = "pColorAttachmentsRootItem"; -static const char* STR_COLOR_BLEND_ATTACHEMENT_STATE_COUNT_ITEM = "pColorBlendAttachmentStateCountItem"; -static const char* STR_COLOR_BLEND_OP_NODE = "pColorBlendOpNode"; -static const char* STR_COLOR_BLEND_STATE_ROOT = "pColorBlendStateRoot"; -static const char* STR_COMPARE_MASK_NODE = "pCompareMaskNode"; -static const char* STR_COMPARE_OP_NODE = "pCompareOpNode"; -static const char* STR_COLOR_COMPONENT_WRITE_MASK = "pColorComponentWriteMask"; -static const char* STR_CREATE_INFO_ROOT_NODE = "pCreateInfoRootNode"; -static const char* STR_CULL_MODE_NODE = "pCullModeNode"; -static const char* STR_DEPENDENCIES_ROOT_ITEM = "pDependenciesRootItem"; -static const char* STR_DEPENDENCY_DESCRIPTION_COUNT_ITEM = "pDependencyDescriptionCountItem"; -static const char* STR_DEPENDENCY_FLAGS = "pDependencyFlags"; -static const char* STR_DEPTH_BIAS_CLAMP_NODE = "pDepthBiasClampNode"; -static const char* STR_DEPTH_BIAS_CONSTANT_FACTOR_NODE = "pDepthBiasConstantFactorNode"; -static const char* STR_DEPTH_BIAS_ENABLE_NODE = "pDepthBiasEnableNode"; -static const char* STR_DEPTH_BIAS_SLOPE_FACTOR_NODE = "pDepthBiasSlopeFactorNode"; -static const char* STR_DEPTH_BOUNDS_TEST_ENABLE_NODE = "pDepthBoundsTestEnableNode"; -static const char* STR_DEPTH_CLAMP_ENABLE_ITEM = "pDepthClampEnableItem"; -static const char* STR_DEPTH_COMPARE_OP_NODE = "pDepthCompareOpNode"; -static const char* STR_DEPTH_FAIL_OP = "pDepthFailOp"; -static const char* STR_DEPTH_STENCIL_ATTACHMENTS_ROOT_ITEM = "pDepthStencilAttachmentsRootItem"; -static const char* STR_DEPTH_STENCIL_STATE_ROOT = "pDepthStencilStateRoot"; -static const char* STR_DEPTH_TEST_ENABLE_NODE = "pDepthTestEnableNode"; -static const char* STR_DEPTH_WRITE_ENABLE_NODE = "pDepthWriteEnableNode"; -static const char* STR_DESCRIPTOR_SET_BINDING_COUNT_ITEM = "pDescriptorSetBindingCountItem"; -static const char* STR_DESCRIPTION_SET_LAYOUT_BINDING_COUNT_NODE = "pDescriptorSetLayoutBindingCountNode"; -static const char* STR_DESCRIPTOR_SET_LAYOUT_BINDING_INDEX_NODE = "pDescriptorSetLayoutBindingIndexNode"; -static const char* STR_DESCRIPTOR_SET_LAYOUT_BINDINGS_ROOT_ITEM = "pDescriptorSetLayoutBindingsRootItem"; -static const char* STR_DESCRIPTOR_SET_LAYOUT_COUNT_ITEM = "pDescriptorSetLayoutCountItem"; -static const char* STR_DESCRIPTOR_SET_LAYOUT_FLAGS_NODE = "pDescriptorSetLayoutFlagsNode"; -static const char* STR_DESCRIPTOR_SET_LAYOUT_HANDLE_NODE = "pDescriptorSetLayoutHandleNode"; -static const char* STR_DESCRIPTOR_SET_LAYOUTS_ITEM = "pDescriptorSetLayoutsItem"; -static const char* STR_DESCRIPTOR_SET_LAYOUTS_ROOT = "pDescriptorSetLayoutsRoot"; -static const char* STR_DESCRIPTOR_SET_LAYOUTS_ROOT_ITEM = "pDescriptorSetLayoutsRootItem"; -static const char* STR_DESCRIPTOR_TYPE_NODE = "pDescriptorTypeNode"; -static const char* STR_DST_ACCESS_MASK = "pDstAccessMask"; -static const char* STR_DST_ALPHA_BLEND_FACTOR_NODE= "pDstAlphaBlendFactorNode"; -static const char* STR_DST_COLOR_BLEND_FACTOR_NODE = "pDstColorBlendFactorNode"; -static const char* STR_DST_STAGE_MASK = "pDstStageMask"; -static const char* STR_DST_SUBPASS = "pDstSubpass"; -static const char* STR_EXTENT_ROOT= "pExtentRoot"; -static const char* STR_FAIL_OP_NODE = "pFailOpNode"; -static const char* STR_FINAL_LAYOUT_ITEM = "pFinalLayoutItem"; -static const char* STR_FLAGS = "pFlags"; -static const char* STR_FLAGS_ELEMENT = "pFlagsElement"; -static const char* STR_FLAGS_ITEM = "pFlagsItem"; -static const char* STR_FORMAT_ELEMENT = "pFormatElement"; -static const char* STR_FRONT_FACE_NODE = "pFrontFaceNode"; -static const char* STR_FRONT_STENCIL_OP_STATE_NODE = "pFrontStencilOpStateNode"; -static const char* STR_GRAPHICS_PIPELINE_CREATE_INFO_ROOT = "pGraphicsPipelineCreateInfoRoot"; -static const char* STR_HEIGHT_ITEM = "pHeightItem"; -static const char* STR_INITIAL_LAYOUT_ITEM = "pIinitialLayoutItem"; -static const char* STR_IMAGE_LAYOUT_NODE = "pImageLayoutNode"; -static const char* STR_INPUT_ASSEMBLY_STATE_ROOT = "pInputAssemblyStateRoot"; -static const char* STR_INPUT_ATTACHMENT_COUNT_NODE = "pInputAttachmentCountNode"; -static const char* STR_INPUT_ATTACHMENTS_ROOT_ITEM = "pInputAttachmentsRootItem"; -static const char* STR_INPUT_RATE_ELEMENT = "pInputRateElement"; -static const char* STR_LINE_WIDTH_NODE = "pLineWidthNode"; -static const char* STR_LOAD_OP_ITEM = "pLoadOpItem"; -static const char* STR_LOCATION_ELEMENT = "pLocationElement"; -static const char* STR_LOGIC_OP_ENABLE_NODE = "pLogicOpEnableNode"; -static const char* STR_LOGIC_OP_NODE = "pLogicOpNode"; -static const char* STR_MAX_DEPTH_BOUNDS_NODE= "pMaxDepthBoundsNode"; -static const char* STR_MAX_DEPTH_ITEM = "pMaxDepthItem"; -static const char* STR_MIN_DEPTH_BOUNDS_NODE = "pMinDepthBoundsNode"; -static const char* STR_MIN_DEPTH_ITEM = "pMinDepthItem"; -static const char* STR_MIN_SAMPLE_SHADING_NODE = "pMinSampleShadingNode"; -static const char* STR_MULTISAMPLE_STATE_ROOT = "pMultisampleStateRoot"; -static const char* STR_OFFSET_ELEMENT = "pOffsetElement"; -static const char* STR_OFFSET_NODE = "pOffsetNode"; -static const char* STR_PASS_OP_NODE = "pPassOpNode"; -static const char* STR_PATCH_CONTROL_POINTS_ITEM = "pPatchControlPointsItem"; -static const char* STR_PIPELINE_BIND_POINT_NODE = "pPipelineBindPointNode"; -static const char* STR_PIPELINE_LAYOUT_CREATE_INFO_ROOT = "pPipelineLayoutCreateInfoRoot"; -static const char* STR_POLYGON_MODE_NODE = "pPolygonModeNode"; -static const char* STR_PRESERVE_ATTACHMENT_COUNT_NODE = "pPreserveAttachmentCountNode"; -static const char* STR_PRESERVE_ATTACHMENT_NODE = "pPreserveAttachmentNode"; -static const char* STR_PRESERVE_INPUT_ATTACHMENT_ROOT_ITEM = "pPreserveInputAttachmentsRootItem"; -static const char* STR_PRIMITIVE_RESTART_ENABLE_ITEM = "pPrimitiveRestartEnableItem"; -static const char* STR_PUSH_CONSTANT_ARRAY_ROOT_ITEM = "pPushConstantsArrayRootItem"; -static const char* STR_PUSH_CONSTANTS_COUNT_ITEM = "pPushConstantsCountItem"; -static const char* STR_RASTERIZATION_SAMPLES = "pRasterizationSamples"; -static const char* STR_RASTERIZATION_STATE_ROOT= "pRasterizationStateRoot"; -static const char* STR_RASTERIZER_DISCARD_ENABLE = "pRasterizerDiscardEnable"; -static const char* STR_REFERENCE_NODE = "pReferenceNode"; -static const char* STR_RENDER_PASS_CREATE_INFO_ROOT = "pRenderPassCreateInfoRoot"; -static const char* STR_RESOLVE_ATTACHMENT_COUNT_NODE = "pResolveAttachmentCountNode"; -static const char* STR_RESOLVE_ATTACHMENTS_ROOT_ITEM = "pResolveAttachmentsRootItem"; -static const char* STR_SAMPLE_MASK_COUNT_NODE = "pSampleMaskCountNode"; -static const char* STR_SAMPLE_MASK_ELEMENT_NODE = "pSampleMaskElementNode"; -static const char* STR_SAMPLE_MASK_ROOT_ITEM = "pSampleMaskRootItem"; -static const char* STR_SAMPLE_SHADING_ENABLE = "pSampleShadingEnable"; -static const char* STR_SAMPLES_ITEM = "pSamplesItem"; -static const char* STR_SCISSOR_COUNT_ITEM = "pScissorCountItem"; -static const char* STR_SCISSORS_ROOT_ITEM = "pScissorsRootItem"; -static const char* STR_SIZE_NODE = "pSizeNode"; -static const char* STR_SRC_ACCESS_MASK = "pSrcAccessMask"; -static const char* STR_SRC_ALPHA_BLEND_FACTOR_NODE = "pSrcAlphaBlendFactorNode"; -static const char* STR_SRC_COLOR_BLEND_FACTOR_NODE = "pSrcColorBlendFactorNode"; -static const char* STR_SRC_STAGE_MASK = "pSrcStageMask"; -static const char* STR_SRC_SUBPASS = "pSrcSubpass"; -static const char* STR_STAGE_FLAGS_NODE = "pStageFlagsNode"; -static const char* STR_STENCIL_LOAD_OP_ITEM = "pStencilLoadOpItem"; -static const char* STR_STENCIL_STORE_OP_ITEM = "pStencilStoreOpItem"; -static const char* STR_STENCIL_TEST_ENABLE_NODE = "pStencilTestEnableNode"; -static const char* STR_STORE_OP_ITEM = "pStoreOpItem"; -static const char* STR_STRIDE_ELEMENT = "pStrideElement"; -static const char* STR_SUBPASS_DESCRIPTION_COUNT_ITEM = "pSubpassDescriptionCountItem"; -static const char* STR_SUBPASS_ROOT_ITEM = "pSubpassRootItem"; -static const char* STR_TESSELLATION_STATE_ROOT = "pTessellationStateRoot"; -static const char* STR_TOPOLOGY_ITEM= "pTopologyItem"; -static const char* STR_VERTEX_ATTRIBUTE_DESCRIPTION_COUNT_ITEM = "pVertexAttributeDescriptionCountItem"; -static const char* STR_VERTEX_ATTRIBUTE_DESCRIPTIONS_ITEM = "pVertexAttributeDescriptionsItem"; -static const char* STR_VERTEX_BINDING_DESCRIPTION_COUNT_ITEM = "pVertexBindingDescriptionCountItem"; -static const char* STR_VERTEX_BINDING_DESCRIPTIONS_ITEM = "pVertexBindingDescriptionsItem"; -static const char* STR_VERTEX_INPUT_STATE_ROOT = "pVertexInputStateRoot"; -static const char* STR_VIEWPORT_COUNT_ITEM = "pViewportCountItem"; -static const char* STR_VIEWPORT_STATE_ROOT_ITEM = "pViewportStateRoot"; -static const char* STR_VIEWPORTS_ROOT_ITEM = "pViewportsRootItem"; -static const char* STR_VK_COMPUTE_PIPELINE_CREATE_INFO_ROOT = "pVkComputePipelineCreateInfoRoot"; -static const char* STR_WIDTH_ITEM = "pWidthItem"; -static const char* STR_WRITE_MASK_NODE = "pWriteMaskNode"; -static const char* STR_X_ITEM = "pXItem"; -static const char* STR_Y_ITEM = "pYItem"; -// Object names for PSO editor objects (rgPipelineStateModelVulkan.cpp) - END \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/rgResourceUsageCsvFileParser.h b/RadeonGPUAnalyzerGUI/Include/rgResourceUsageCsvFileParser.h deleted file mode 100644 index 5181e22..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgResourceUsageCsvFileParser.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -// C++. -#include - -// Local. -#include -#include - -// A file parser used to process Resource Usage CSV files. -class rgResourceUsageCsvFileParser : public rgCsvFileParser -{ -public: - // A constructor that accepts a full path to the CSV file to be parsed. - rgResourceUsageCsvFileParser(const std::string& csvFilePath) : rgCsvFileParser(csvFilePath) {} - - // Get the resource usage data parsed from the CSV file. - const rgResourceUsageData& GetData() const { return m_resourceUsageData; } - -protected: - // Parse the given line from the CSV file - virtual bool ProcessLineTokens(const std::vector& tokens) override; - -private: - // The variable used to store resource usage parsed from the CSV file. - rgResourceUsageData m_resourceUsageData; - - // An enumeration specifying each column we expect to find in the Resource Usage CSV file. - enum rgResourceUsageCsvFileColumns - { - Device, - ScratchMemory, - ThreadsPerWorkgroup, - WavefrontSize, - AvailableLdsBytes, - UsedLdsBytes, - AvailableSgprs, - UsedSgprs, - SgprSpills, - AvailableVgprs, - UsedVgprs, - VgprSpills, - ClWorkgroupXDimension, - ClWorkgroupYDimension, - ClWorkgroupZDimension, - IsaSize, - Count - }; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/rgStringConstants.h b/RadeonGPUAnalyzerGUI/Include/rgStringConstants.h deleted file mode 100644 index 350eabd..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgStringConstants.h +++ /dev/null @@ -1,620 +0,0 @@ -#pragma once - -// Application name. -static const char* STR_APP_NAME = "Radeon GPU Analyzer"; - -// Global configuration file name. -static const char* STR_GLOBAL_CONFIG_FILE_NAME_PREFIX = "RGAConfig"; -static const char* STR_GLOBAL_CONFIG_FILE_EXTENSION = "xml"; - -// CLI version-info cache file name. -static const char* STR_VERSION_INFO_FILE_NAME = "VersionInfo.xml"; - -// Application folder name. -static const char* STR_APP_FOLDER_NAME = "RadeonGPUAnalyzer"; - -// Application executable name. -#ifdef __linux -static const char* STR_EXECUTABLE_NAME = "./rga"; -#else -static const char* STR_EXECUTABLE_NAME = "rga.exe"; -#endif - -// Projects folder name. -#ifdef __linux -static const char* STR_PROJECTS_FOLDER_NAME = "projects"; -#else -static const char* STR_PROJECTS_FOLDER_NAME = "Projects"; -#endif // __linux - -// String used to build the window title text. -static const char* STR_TITLE_PROJECT = "Project"; - -// Sub-folder of project folder for temporary files. -static const char* STR_PROJECT_SUBFOLDER_TEMP = "temp"; - -// Sub-folder of project folder for backup files. -static const char* STR_PROJECT_SUBFOLDER_GENERATED = "generated"; - -// Clone folder prefix. -static const char* STR_CLONE_FOLDER_NAME = "Clone"; - -// The project build artifacts output folder. -static const char* STR_OUTPUT_FOLDER_NAME = "Output"; - -// The filename suffix used in each session metadata file dumped for a target GPU compilation. -static const char* STR_SESSION_METADATA_FILENAME = "cliInvocation.xml"; - -// The name used for the resource usage analysis CSV file that's dumped when a program is built. -static const char* STR_RESOURCE_USAGE_CSV_FILENAME = "resourceUsage.csv"; - -// Project file extension. -static const char* STR_PROJECT_FILE_EXTENSION = ".rga"; - -// Default source filename for new files. -static const char* STR_DEFAULT_SOURCE_FILENAME = "src"; - -// Suffix for unsaved files. -static const char* STR_UNSAVED_FILE_SUFFIX = "*"; - -// String truncation delimeter. -static const char* STR_TRUNCATED_STRING_DELIMETER = "..."; - -// Default extensions for different Vulkan input files. -static const char STR_VK_FILE_EXT_DELIMITER = ';'; -static const char* STR_VK_FILE_EXT_SPIRV_TXT = "spvas"; -static const char* STR_VK_FILE_EXT_SPIRV_BIN = "spv"; -static const char* STR_VK_FILE_EXT_GLSL = "vert;frag;tesc;tese;geom;comp"; -static const char* STR_VK_FILE_EXT_HLSL = "hlsl"; - -// *** LOG FILE MESSAGES - START *** -static const char* STR_LOG_RGA_GUI_STARTED = "RGA GUI started."; -static const char* STR_LOG_FAILED_LOAD_VERSION_INFO_FILE = "Failed to load version info file: "; -static const char* STR_LOG_FAILED_INIT_CONFIG = "Initialization of Config Manager failed."; -static const char* STR_LOG_CLOSING_RGA_GUI = "Closing RGA GUI."; -static const char* STR_LOG_BUILDING_PROJECT_CLONE_1 = "Building Project: "; -static const char* STR_LOG_BUILDING_PROJECT_CLONE_2 = ", clone: "; -static const char* STR_LOG_LAUNCHING_CLI = "Launching RGA CLI with command line: "; -static const char* STR_LOG_EXTRACT_SETTINGS_ERROR = "Error reading settings file."; - -// *** LOG FILE MESSAGES - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** ERROR STRINGS - START *** - -static const char* STR_ERR_FATAL_PREFIX = "Fatal error: "; -static const char* STR_ERR_CANNOT_READ_CONFIG_FILE_A = "RGA is unable to read the global configuration file: "; -static const char* STR_ERR_DELETE_FILE_AND_RERUN = "Please delete the file, and re-run the application."; -static const char* STR_ERR_RGA_WILL_NOW_EXIT = "RGA will now exit."; -static const char* STR_ERR_CANNOT_RESTORE_DEFAULT_SETTINGS = "Cannot restore default settings."; -static const char* STR_ERR_CANNOT_ADD_FILE_A = "Cannot add the file: "; -static const char* STR_ERR_CANNOT_ADD_FILE_B = ", since a file with that name already exists."; -static const char* STR_ERR_CANNOT_WRITE_TO_FILE = "Cannot write to file: "; -static const char* STR_ERR_CANNOT_RENAME_FILE_A = "Cannot rename file to "; -static const char* STR_ERR_CANNOT_RENAME_FILE_B_ALREADY_EXISTS = " since a file with that name already exists."; -static const char* STR_ERR_CANNOT_RENAME_FILE_B_ILLEGAL_FILENAME = " since the given file name is illegal."; -static const char* STR_ERR_CANNOT_RENAME_FILE_BLANK_FILENAME = "File name cannot be empty."; -static const char* STR_ERR_CANNOT_LOAD_PROJECT_FILE = "Failed to load project"; -static const char* STR_ERR_CANNOT_LOAD_PROJECT_FILE_NO_VALID_SOURCES = "No valid source files exist in project."; -static const char* STR_ERR_CANNOT_LOAD_SOURCE_FILE_MSG = "Failed to find file "; -static const char* STR_ERR_CANNOT_LOAD_BUILD_OUTPUT = "Failed to load project build output."; -static const char* STR_ERR_CANNOT_LOAD_VERSION_INFO_FILE = "RGA Failed to load version the info file: "; -static const char* STR_ERR_CANNOT_LOAD_SUPPORTED_GPUS_LIST_FOR_MODE_A = "Failed to load list of supported GPUs for '"; -static const char* STR_ERR_CANNOT_LOAD_SUPPORTED_GPUS_LIST_FOR_MODE_B = "' mode."; -static const char* STR_ERR_CANNOT_LOAD_DISASSEMBLY_CSV_FILE = "Failed to load disassembly output file at "; -static const char* STR_ERR_ILLEGAL_PROJECT_NAME = "Project name is not a legal file name or exceeds 50 characters: "; -static const char* STR_ERR_FAILED_TO_OPEN_FILE_BROWSER = "Failed to open the system's file explorer."; -static const char* STR_ERR_CSV_PARSING_FAILED_A = "Failed to parse "; -static const char* STR_ERR_CSV_PARSING_FAILED_B = " at line "; -static const char* STR_ERR_FAILED_TO_GET_ENTRYPOINT_LINE_NUMBERS = "Failed to query entry point names and line numbers."; -static const char* STR_ERR_INVALID_FOLDER = "Invalid folder specified."; -static const char* STR_NEW_PROJECT_ALREADY_EXISTS = "A project with that name has already been created. Please choose a different project name."; -static const char* STR_ERR_FAILED_TO_GENERATE_BUILD_COMMAND = "Failed to generate command line used for project build."; -static const char* STR_ERR_CANNOT_OPEN_LOG_FILE = "Failed to create a log file."; -static const char* STR_ERR_CANNOT_SAVE_PIPELINE_STATE_FILE = "Failed to save pipeline state file: "; -static const char* STR_ERR_CANNOT_LOAD_PIPELINE_STATE_FILE = "Failed to load pipeline state file:"; -static const char* STR_ERR_CANNOT_INITIALIZE_PIPELINE_STATE_FILE = "Failed to initialize pipeline state file:"; -static const char* STR_ERR_CANNOT_DETERMINE_PIPELINE_TYPE = "The pipeline type was not graphics or compute."; -static const char* STR_ERR_CANNOT_FAILED_TO_LOAD_PIPELINE_STATE_FILE = "Failed to read pipeline state from file: file might be corrupted."; -static const char* STR_ERR_FAILED_TO_SAVE_PIPELINE_STATE_FILE = "Failed to save pipeline state file."; -static const char* STR_ERR_COULD_NOT_LOCATE_HEADER_FILE = "Could not locate header file. Check 'Additional include directories' under build settings."; -static const char* STR_ERR_COULD_NOT_OPEN_HEADER_FILE_VIEWER = "Could not launch include file viewer:"; -static const char* STR_ERR_FAILED_TO_VALIDATE = "Invalid pipeline state."; -static const char* STR_ERROR_RESOLVE_ATTACHMENTS_INVALID_A = "RenderPass pSubpass["; -static const char* STR_ERROR_RESOLVE_ATTACHMENTS_INVALID_B = "]->pResolveAttachments is non-null, but array dimension does not match colorAttachmentCount."; -static const char* STR_ERROR_RESOLVE_ATTACHMENTS_INVALID_C = "Please adjust as required by the Vulkan spec."; -static const char* STR_ERROR_MULTISAMPLING_SAMPLE_MASK_INVALID_A = "The multisampling state 'rasterizationSamples' field is incompatible with the value of 'pSampleMask'."; -static const char* STR_ERROR_MULTISAMPLING_SAMPLE_MASK_INVALID_B = "Please adjust the 'rasterizationSamples' field or alter the dimension of 'pSampleMask' as required by the Vulkan spec."; - -// *** ERROR STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** MENUS STRINGS - START *** - -// File menu. -static const char* STR_ADD_EXISTING_FILE = "Add existing GLSL/SPIR-V file"; -static const char* STR_CREATE_NEW_FILE = "Create template GLSL file"; - -// File menu item. -static const char* STR_MENU_BAR_FILE = "&File"; - -// File menu item entry point label text list. -static const char* STR_MENU_BAR_FILE_ITEM_ENTRYPOINT_HEADER_OPENCL = "Kernels"; -static const char* STR_MENU_BAR_FILE_ITEM_ENTRYPOINT_HEADER_DEFAULT = "Entrypoints"; - -// The tooltip shown for a file item's entry point list item. -static const char* STR_MENU_ITEM_ENTRYPOINT_TOOLTIP_TEXT = "Click to see analysis results for "; - -// Find strings. -static const char* STR_MENU_BAR_EDIT_QUICK_FIND = "Find..."; -static const char* STR_MENU_BAR_EDIT_QUICK_FIND_TOOLTIP = "Find a string in the current source file (Ctrl+F)."; -static const char* STR_EDIT_FIND_NEXT = "Find next."; -static const char* STR_EDIT_FIND_NEXT_TOOLTIP = "Find next search result (F3)."; -static const char* STR_EDIT_FIND_PREVIOUS = "Find previous"; -static const char* STR_EDIT_FIND_PREVIOUS_TOOLTIP = "Find previous search result (Shift+F3)."; -static const char* STR_EDIT_FIND_CLOSE_TOOLTIP = "Close."; - -// Open Project menu item. -static const char* STR_MENU_BAR_OPEN_PROJECT = "&Open existing RGA project..."; -static const char* STR_MENU_BAR_OPEN_PROJECT_TOOLTIP = "Open an existing RGA project (.rga file) (Ctrl+Alt+O)."; - -// Edit menu item. -static const char* STR_MENU_BAR_EDIT = "&Edit"; - -// Go to line menu item. -static const char* STR_MENU_BAR_GO_TO_LINE = "&Go to..."; -static const char* STR_MENU_BAR_GO_TO_LINE_TOOLTIP = "Go to line (Ctrl+G)."; - -// Build menu items. -static const char* STR_MENU_BAR_BUILD = "&Build"; -static const char* STR_MENU_BAR_BUILD_PROJECT = "Build project"; -static const char* STR_MENU_BAR_BUILD_PROJECT_TOOLTIP = "Build the current project (Ctrl+Shift+B)."; -static const char* STR_MENU_BAR_BUILD_SETTINGS_TOOLTIP = "View the current project's build settings (F8)."; -static const char* STR_MENU_BAR_BUILD_CANCEL_TOOLTIP = "Cancel the build process (Ctrl+Shift+C)."; -static const char* STR_MENU_BUILD_SETTINGS = "Build settings"; -static const char* STR_MENU_PIPELINE_STATE_EDITOR = "Pipeline state"; -static const char* STR_MENU_BAR_PIPELINE_STATE_TOOLTIP = "View and edit the current project's pipeline state (F9)."; -static const char* STR_MENU_BUILD_SETTINGS_LOWER = "build settings"; -static const char* STR_MENU_CANCEL_BUILD = "Cancel build"; - -// Graphics menu item strings. -static const char* STR_GRAPHICS_MENU_PIPELINE_STATE_TOOLTIP = "View/Edit the current pipeline's state (F9)."; -static const char* STR_GRAPHICS_MENU_SHADER_STAGE_ADD_BUTTON_TOOLTIP_A = "Add/Create a "; -static const char* STR_GRAPHICS_MENU_SHADER_STAGE_ADD_BUTTON_TOOLTIP_B = " shader file."; -static const char* STR_GRAPHICS_MENU_SHADER_STAGE_CREATE_BUTTON_TOOLTIP_A = "Create a new "; -static const char* STR_GRAPHICS_MENU_SHADER_STAGE_CREATE_BUTTON_TOOLTIP_B = " shader file."; -static const char* STR_GRAPHICS_MENU_SHADER_STAGE_CLOSE_BUTTON_TOOLTIP = "Remove this file from this stage."; -static const char* STR_GRAPHICS_MENU_SHADER_STAGE_TOOLTIP = " stage."; - -// Help menu items. -static const char* STR_MENU_BAR_HELP = "&Help"; -static const char* STR_MENU_BAR_HELP_ABOUT = "About"; -static const char* STR_MENU_BAR_HELP_ABOUT_TOOLTIP = "Display the details of this Radeon GPU Analyzer version (Ctrl+F1)."; -static const char* STR_MENU_BAR_HELP_GETTING_STARTED_GUIDE = "Getting started guide"; -static const char* STR_MENU_BAR_HELP_GETTING_STARTED_GUIDE_TOOLTIP = "Open the RGA quickstart guide."; -static const char* STR_MENU_BAR_HELP_MANUAL = "Help manual"; -static const char* STR_MENU_BAR_HELP_MANUAL_TOOLTIP = "Open the RGA help manual (F1)."; - -// Save File menu item. -static const char* STR_MENU_BAR_SAVE_FILE = "&Save file"; -static const char* STR_MENU_BAR_SAVE_FILE_TOOLTIP = "Save the current file (Ctrl+S)."; -static const char* STR_MENU_BAR_SAVE_SETTINGS = "&Save settings"; -static const char* STR_MENU_BAR_SAVE_SETTINGS_TOOLTIP = "Save the current project build settings (Ctrl+S)."; - -// Back to home menu item. -static const char* STR_MENU_BAR_BACK_TO_HOME = "&Back to home page"; -static const char* STR_MENU_BAR_BACK_TO_HOME_TOOLTIP = "Close the existing project and go back to the home page (Ctrl+Alt+H)."; - -// Exit menu item. -static const char* STR_MENU_BAR_EXIT = "&Exit"; -static const char* STR_MENU_BAR_EXIT_TOOLTIP = "Exit the application (Alt+F4)."; - -// Settings view Restore default settings action. -static const char* STR_RESTORE_DEFAULT_SETTINGS = "Restore default settings."; - -// *** MENUS STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** STATUS BAR STRINGS - START *** - -static const char* STR_STATUS_BAR_FILE_MODIFIED_OUTSIDE_ENV = "The current file has been changed outside the environment."; -static const char* STR_STATUS_BAR_BUILD_STARTED = "Build started..."; -static const char* STR_STATUS_BAR_BUILD_FAILED = "Build failed"; -static const char* STR_STATUS_BAR_BUILD_CANCELED = "Build canceled"; -static const char* STR_STATUS_BAR_BUILD_SUCCEEDED = "Build succeeded"; - -// *** STATUS BAR STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** FILE CONTEXT MENU STRINGS - START *** - -// File item context menu's "Open containing folder" action text. -#ifdef __linux -static const char* STR_FILE_CONTEXT_MENU_OPEN_CONTAINING_FOLDER = "Show in file browser"; -#else -static const char* STR_FILE_CONTEXT_MENU_OPEN_CONTAINING_FOLDER = "Show in explorer"; -#endif -static const char* STR_FILE_CONTEXT_MENU_RENAME_FILE = "Rename"; -static const char* STR_FILE_CONTEXT_MENU_REMOVE_FILE = "Remove"; -static const char* STR_FILE_CONTEXT_MENU_COPY_FILE_NAME = "Copy"; -static const char* STR_FILE_CONTEXT_MENU_RESTORE_SPV = "Revert to original SPIR-V binary"; - -// Tooltip for the remove button on the file menu item. -static const char* STR_FILE_MENU_REMOVE_FILE_TOOLTIP_PREFIX = "Remove "; -static const char* STR_FILE_MENU_REMOVE_FILE_TOOLTIP_SUFFIX = " from this project."; - -// Tooltip for the project title at the top of the file menu. -static const char* STR_FILE_MENU_PROJECT_TITLE_TOOLTIP_A = "Project name: "; -static const char* STR_FILE_MENU_PROJECT_TITLE_TOOLTIP_B = " (double-click to rename)."; - -// *** FILE CONTEXT MENU STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** MAIN WINDOW CONTEXT MENU STRINGS - START *** - -static const char* STR_MAIN_WINDOW_LOAD_PROJECT = "Load project"; -static const char* STR_MAIN_WINDOW_LOADING_PROJECT = "Loading project..."; -static const char* STR_MAIN_WINDOW_PROJECT_LOAD_SUCCESS = "Project loaded successfully."; - -// *** MAIN WINDOW CONTEXT MENU STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** FILE DIALOG STRINGS - START *** - -static const char* STR_FILE_DIALOG_CAPTION = "Open existing file"; -static const char* STR_FILE_DIALOG_RGA_CAPTION = "Open existing project"; -static const char* STR_FILE_DIALOG_RGA_FILTER = "RGA files (*.rga)"; -static const char* STR_FILE_DIALOG_SAVE_NEW_FILE = "Save new file"; -static const char* STR_FILE_DIALOG_FILTER_OPENCL = "OpenCL files (*.cl)"; -static const char* STR_FILE_DIALOG_FILTER_SPIRV = "SPIR-V files (*.spv)"; -static const char* STR_FILE_DIALOG_FILTER_SPIRV_BINARY_EXT = "*.spv"; -static const char* STR_FILE_DIALOG_FILTER_GLSL = "GLSL files"; -static const char* STR_FILE_DIALOG_FILTER_GLSL_SPIRV = "GLSL | SPIR-V files"; -static const char* STR_FILE_DIALOG_FILTER_SPV_TXT = "SPIR-V text files"; -static const char* STR_FILE_DIALOG_FILTER_ALL = "All files (*.*)"; -static const char* STR_FILE_DIALOG_FILTER_INCLUDE_VIEWER = "Select an executable to be used for opening include files"; - -// The title used for the unsaved file dialog. -static const char* STR_UNSAVED_ITEMS_DIALOG_TITLE = "Unsaved changes"; - -// The title used for the browse missing source files dialog. -static const char* STR_BROWSE_MISSING_FILE_DIALOG_TITLE = "Failed to load project"; - -// Confirm that the user really wants to remove the file from the project. -static const char* STR_MENU_BAR_CONFIRM_REMOVE_FILE_DIALOG_TITLE = "Remove file"; -static const char* STR_MENU_BAR_CONFIRM_REMOVE_FILE_DIALOG_WARNING = " will be removed from the project. Are you sure?"; - -// Check if the user wants to reload an externally modified file. -static const char* STR_RELOAD_FILE_DIALOG_TITLE = "Reload"; -static const char* STR_RELOAD_FILE_DIALOG_TEXT = "This file has been modified by another project.\nDo you want to reload it?"; - -// Confirm that the user wants to revert to original SPIR-V binary shader file. -static const char* STR_MENU_BAR_VULKAN_CONFIRM_REVERT_TO_ORIG_SPV_A = "This will revert all SPIR-V assembly edits and restore the original SPIR-V binary from: "; -static const char* STR_MENU_BAR_VULKAN_CONFIRM_REVERT_TO_ORIG_SPV_B = "Are you sure?"; - -// *** FILE DIALOG STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** BUILD SETTINGS STRINGS - START *** - -// General section. -static const char* STR_BUILD_SETTINGS_GENERAL_TOOLTIP = "General build settings."; -static const char* STR_BUILD_SETTINGS_CMD_LINE_TOOLTIP = "The command line options that are going to be passed to the rga command line tool based on the values on this page."; -static const char* STR_BUILD_SETTINGS_VULKAN_RUNTIME_TOOLTIP = "Settings that impact the Vulkan runtime."; - -// Target GPU dialog strings. -static const char* STR_TARGET_GPU_ARCHITECTURE = "Architecture"; -static const char* STR_TARGET_GPU_PRODUCT_NAME = "Product name"; -static const char* STR_TARGET_GPU_COMPUTE_CAPABILITY = "Compute capability"; -static const char* STR_TABLE_TOOLTIP_COLUMN_ARCHITECTURE = "Name of the GPU HW architecture."; -static const char* STR_TABLE_TOOLTIP_COLUMN_COMPUTE_CAPABILITY = "Name of the architecture variant. From the compiler's point of view, GPUs with the same compute capability are identical."; -static const char* STR_TABLE_TOOLTIP_COLUMN_PRODUCT_NAME = "Public name of the GPU."; - -// Build settings view strings. -static const char* STR_BUILD_SETTINGS_DEFAULT_TITLE = "Default"; -static const char* STR_BUILD_SETTINGS_PROJECT_TITLE = "Project"; -static const char* STR_BUILD_SETTINGS_DEFAULT_TITLE_B = " build settings"; -static const char* STR_BUILD_SETTINGS_GLOBAL_TITLE_END = "Build Settings"; -static const char* STR_BUILD_SETTINGS_GLOBAL_TOOLTIP_A = "The default "; -static const char* STR_BUILD_SETTINGS_GLOBAL_TOOLTIP_B = " settings that will be used for any newly created project."; -static const char* STR_BUILD_SETTINGS_PROJECT_TOOLTIP_A = "The "; -static const char* STR_BUILD_SETTINGS_PROJECT_TOOLTIP_B = " settings that will be used for this project."; -static const char* STR_BUILD_SETTINGS_PREDEFINED_MACROS_TOOLTIP = "Predefined macros should be separated by ';'. If a macro definition includes a space, surround it with parentheses."; -static const char* STR_BUILD_SETTINGS_ADDITIONAL_INC_DIRECTORY_TOOLTIP = "Additional include directories should be separated by ';'. If a path includes a space, surround it with parentheses."; -static const char* STR_BUILD_SETTINGS_DEFAULT_SETTINGS_CONFIRMATION_TITLE = "Restore default values"; -static const char* STR_BUILD_SETTINGS_DEFAULT_SETTINGS_CONFIRMATION = "Are you sure you want to restore default values?"; -static const char* STR_BUILD_SETTINGS_TARGET_GPUS_TOOLTIP = "The target architectures to build the code for."; -static const char* STR_BUILD_SETTINGS_OPTIMIZATION_LEVEL = "The compiler optimization level that will be applied."; -static const char* STR_BUILD_SETTINGS_ALTERNATIVE_COMPILER_GLSLANG_TOOLTIP = "Settings for the front-end compiler (glslang), as well as tools such as disassembler and assembler."; -static const char* STR_BUILD_SETTINGS_ALTERNATIVE_COMPILER_TOOLTIP_GENERIC = "To use an alternative compiler, provide the following paths.\nOtherwise, the default compiler, which is bundled with RGA, will be used."; -static const char* STR_BUILD_SETTINGS_SETTINGS_CMDLINE_TOOLTIP = "The command string which will be passed to the RGA backend when it is invoked. This command is generated according to the above selected settings."; -static const char* STR_BUILD_SETTINGS_CLANG_OPTIONS_TOOLTIP = "Additional options for the clang compiler. For example, use -Weverything to enable all diagnostics."; - -// Build settings error strings. -static const char* STR_ERR_INVALID_PENDING_SETTING = "The following issues must be resolved before saving build settings:"; -static const char* STR_ERR_TARGET_GPUS_CANNOT_BE_EMPTY = "The Target GPUs field cannot be empty."; -static const char* STR_ERR_INVALID_GPUS_SPECIFIED = "The following are not valid target GPUs: "; - -// Select include directories strings. -static const char* STR_INCLUDE_DIR_DIALOG_BROWSE_BUTTON = "&Browse..."; -static const char* STR_INCLUDE_DIR_DIALOG_SELECT_INCLUDE_DIRS = "Add include directories"; -static const char* STR_INCLUDE_DIR_DIALOG_DELETE_BOX_TITLE = "Delete confirmation"; -static const char* STR_INCLUDE_DIR_DIALOG_DELETE_BOX_MESSAGE = "Are you sure you want to delete this entry?"; -static const char* STR_INCLUDE_DIR_DIALOG_DIR_DOES_NOT_EXIST = "This directory does not exist."; -static const char* STR_INCLUDE_DIR_DIALOG_DIR_ALREADY_SELECTED = "This directory is already selected."; -static const char* STR_INCLUDE_DIR_DIALOG_SELECT_DIR_TITLE = "Select a directory"; -static const char* STR_ICD_LOCATION_DIALOG_SELECT_FILE_TITLE = "Browse for Vulkan ICD file"; - -// Predefined macros editor dialog strings. -static const char* STR_PREPROCESSOR_DIRECTIVES_DIALOG_TITLE = "Add preprocessor directives"; -static const char* STR_PREPROCESSOR_DIRECTIVES_DIALOG_DIRECTIVE_IS_DUPLICATE = "Definition already defined: "; -static const char* STR_PREPROCESSOR_DIRECTIVES_DIALOG_DIRECTIVE_CONTAINS_WHITESPACE = "Definition contains whitespace: "; - -// Default binary output file name. -static const char* STR_BUILD_SETTINGS_OUTPUT_BINARY_FILE_NAME = "codeobj.bin"; - -// *** BUILD SETTINGS STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** GLOBAL SETTINGS STRINGS - START *** - -// Global settings view strings. -static const char* STR_GLOBAL_SETTINGS_TITLE = "Global settings"; -static const char* STR_GLOBAL_SETTINGS_CHECKBOX_TOOLTIP = "If checked, RGA will always use the auto-generated project name, without prompting for a rename when creating a new project."; -static const char* STR_GLOBAL_SETTINGS_LOG_FILE_LOCATION = "The directory where RGA will save log files. RGA will delete log files that are older than 3 days upon startup."; -static const char* STR_GLOBAL_SETTINGS_DISASSEMBLY_SECTION_TOOLTIP = "Settings for the GCN ISA disassembly view."; -static const char* STR_GLOBAL_SETTINGS_DISASSEMBLY_COLUMNS_TOOLTIP = "The columns which will be visible by default in the disassembly view."; -static const char* STR_GLOBAL_SETTINGS_SRC_VIEW_SECTION_TOOLTIP = "Settings for the source code editor."; -static const char* STR_GLOBAL_SETTINGS_SRC_VIEW_FONT_TYPE_TOOLTIP = "The font type which would be used in the source code editor."; -static const char* STR_GLOBAL_SETTINGS_SRC_VIEW_FONT_SIZE_TOOLTIP = "The font size which would be used in the source code editor."; -static const char* STR_GLOBAL_SETTINGS_SRC_VIEW_INCLUDE_VIEWER_DEFAULT = ""; -static const char* STR_GLOBAL_SETTINGS_SRC_VIEW_INCLUDE_FILES_VIEWER_TOOLTIP = "When trying to open header files from the source code viewer, RGA would use the system's default app. To override this behavior, use this setting to provide a full path to an alternative viewer."; -static const char* STR_GLOBAL_SETTNIGS_FILE_EXT_GLSL_TOOLTIP = "Treat files with these extensions as GLSL source files. By default, RGA would treat files with unknown extensions as SPIR-V binary files."; -static const char* STR_GLOBAL_SETTNIGS_FILE_EXT_HLSL_TOOLTIP = "Treat files with these extensions as HLSL source files. By default, RGA would treat files with unknown extensions as SPIR-V binary files."; -static const char* STR_GLOBAL_SETTNIGS_FILE_EXT_SPV_TXT_TOOLTIP = "Treat files with these extensions as SPIR-V text files. By default, RGA would treat files with unknown extensions as SPIR-V binary files."; -static const char* STR_GLOBAL_SETTINGS_DEFAULT_SRC_LANG_TOOLTIP = "Use this language when creating a new source file."; -static const char* STR_GLOBAL_SETTINGS_GENERAL_SECTION_TOOLTIP = "General application-level settings."; -static const char* STR_GLOBAL_SETTINGS_DEFAULT_STARTUP_API_TOOLTIP = "If this setting is set, RGA will automatically start in the specified mode, without showing the startup dialog where the desired mode can be selected."; -static const char* STR_GLOBAL_SETTINGS_INPUT_FILES_SECTION_TOOLTIP = "Settings that configure how RGA interprets different input files."; -static const char* STR_GLOBAL_SETTINGS_SPV_EXTENSIONS_TOOLTIP = "Since RGA assumes SPIR-V binary as an input by default, use this option to specify file filters for SPIR-V binary files. When showing the Add Existing File dialog, RGA would dynamically use these file filters."; - -// Default input file extensions. -static const char* STR_GLOBAL_SETTINGS_FILE_EXT_GLSL = "vert;tesc;tese;frag;geom;comp;glsl"; -static const char* STR_GLOBAL_SETTINGS_FILE_EXT_HLSL = "hlsl;fx;hs;ds;ps"; -static const char* STR_GLOBAL_SETTINGS_FILE_EXT_SPVAS = "spvas"; -static const char* STR_GLOBAL_SETTINGS_FILE_EXT_SPV = "spv"; - -// Default binary output file name. -static const char* STR_GLOBAL_SETTINGS_OUTPUT_BINARY_FILE_NAME = "codeobj.bin"; - -// *** GLOBAL SETTINGS STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** PIPELINE STATE EDITOR STRINGS - START *** - -// The default name for a new pipeline. -static const char* STR_DEFAULT_PIPELINE_NAME = "Pipeline"; - -// The caption string used when browsing to an existing pipeline state file. -static const char* STR_PIPELINE_STATE_FILE_DIALOG_CAPTION = "Open existing pipeline state file"; - -// The default file extension for graphics pipeline state files. -static const char* STR_DEFAULT_PIPELINE_FILE_EXTENSION_GRAPHICS = ".gpso"; -static const char* STR_DEFAULT_PIPELINE_FILE_EXTENSION_NAME_GRAPHICS = "gpso"; - -// The default file extension for compute pipeline state files. -static const char* STR_DEFAULT_PIPELINE_FILE_EXTENSION_COMPUTE = ".cpso"; -static const char* STR_DEFAULT_PIPELINE_FILE_EXTENSION_NAME_COMPUTE = "cpso"; - -// File extension delimiter. -static const char* STR_FILE_EXTENSION_DELIMITER = "."; - -// The file extension filter string used for graphics pipeline state files. -static const char* STR_DEFAULT_PIPELINE_FILE_EXTENSION_FILTER_GRAPHICS = "Graphics PSO files (*.gpso)"; - -// The file extension filter string used for compute pipeline state files. -static const char* STR_DEFAULT_PIPELINE_FILE_EXTENSION_FILTER_COMPUTE = "Compute PSO files (*.cpso)"; - -// The PSO TreeView's header for the column used to display the member name. -static const char* STR_PIPELINE_STATE_EDITOR_MEMBER_NAME = "Member"; - -// The PSO TreeView's header for the column used to display the member value. -static const char* STR_PIPELINE_STATE_EDITOR_MEMBER_VALUE = "Value"; - -// Status bar strings for the PSO editor. -static const char* STR_PIPELINE_STATE_EDITOR_FILE_LOADED_SUCCESSFULLY = "Pipeline state file loaded successfully."; -static const char* STR_PIPELINE_STATE_EDITOR_FILE_FAILED_LOADING = "Pipeline state file failed to load."; - -// Confirm that the user wants to delete the element. -static const char* STR_PIPELINE_STATE_EDITOR_DELETE_ELEMENT_CONFIRMATION_TITLE = "Delete confirmation"; - -// Pipeline state editor information strings. -static const char* STR_PIPELINE_STATE_EDITOR_LABEL_GRAPHICS = "The Vulkan graphics state for the current pipeline."; -static const char* STR_PIPELINE_STATE_EDITOR_LABEL_COMPUTE = "The Vulkan compute state for the current pipeline."; -static const char* STR_PIPELINE_STATE_EDITOR_LABEL_HELP = " State can be edited manually or intercepted from a Vulkan app using the RGA layer."; - -// *** PIPELINE STATE EDITOR STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** SOURCE EDITOR STRINGS - START *** - -// Source editor titlebar text. -static const char* STR_SOURCE_EDITOR_TITLEBAR_CORRELATION_DISABLED_A = "Correlation disabled: "; -static const char* STR_SOURCE_EDITOR_TITLEBAR_CORRELATION_DISABLED_B = "Source no longer matches disassembly. Build to re-enable correlation."; -static const char* STR_SOURCE_EDITOR_TITLEBAR_SPIRV_DISASM_SAVED_A = "generated. Right-click on the left menu item and select"; -static const char* STR_SOURCE_EDITOR_TITLEBAR_SPIRV_DISASM_SAVED_B = "to revert all edits."; -static const char* STR_SOURCE_EDITOR_TITLEBAR_DISMISS_MESSAGE_BUTTON_TOOLTIP = "Click to dismiss the message."; - -// Context menu. -static const char* STR_SOURCE_EDITOR_CONTEXT_MENU_OPEN_HEADER = "Open header file..."; -static const char* STR_SOURCE_EDITOR_CONTEXT_MENU_CUT = "Cut"; -static const char* STR_SOURCE_EDITOR_CONTEXT_MENU_COPY = "Copy"; -static const char* STR_SOURCE_EDITOR_CONTEXT_MENU_PASTE = "Paste"; -static const char* STR_SOURCE_EDITOR_CONTEXT_MENU_SELECT_ALL = "Select all"; - -// *** SOURCE EDITOR STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** DISASSEMBLY VIEW STRINGS - START *** - -// Disassembly table column names. -static const char* STR_DISASSEMBLY_TABLE_COLUMN_ALL = "All"; -static const char* STR_DISASSEMBLY_TABLE_COLUMN_ADDRESS = "Address"; -static const char* STR_DISASSEMBLY_TABLE_COLUMN_OPCODE = "Opcode"; -static const char* STR_DISASSEMBLY_TABLE_COLUMN_OPERANDS = "Operands"; -static const char* STR_DISASSEMBLY_TABLE_COLUMN_CYCLES = "Cycles"; -static const char* STR_DISASSEMBLY_TABLE_COLUMN_FUNCTIONAL_UNIT = "Functional unit"; -static const char* STR_DISASSEMBLY_TABLE_COLUMN_BINARY_ENCODING = "Binary encoding"; - -// Context menu strings -static const char* STR_DISASSEMBLY_TABLE_CONTEXT_MENU_COPY = "Copy selected disassembly"; -#ifdef __linux -static const char* STR_DISASSEMBLY_TABLE_CONTEXT_MENU_OPEN_IN_FILE_BROWSER = "Show disassembly file in file browser"; -#else -static const char* STR_DISASSEMBLY_TABLE_CONTEXT_MENU_OPEN_IN_FILE_BROWSER = "Show disassembly file in explorer"; -#endif - -// *** DISASSEMBLY VIEW STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** RESOURCE USAGE STRINGS - START *** - -// Titlebar text strings. -static const char* STR_GPU_RESOURCE_USAGE = "Resource usage"; -static const char* STR_RESOURCE_USAGE_VGPRS = "VGPRs"; -static const char* STR_RESOURCE_USAGE_SGPRS = "SGPRs"; -static const char* STR_RESOURCE_USAGE_LDS = "LDS"; -static const char* STR_RESOURCE_USAGE_SPILLS = "spills"; -static const char* STR_RESOURCE_USAGE_SCRATCH = "Scratch memory"; -static const char* STR_RESOURCE_USAGE_ICACHE = "Instruction cache"; -static const char* STR_RESOURCE_USAGE_WAVES_PER_SIMD = "Waves/SIMD"; - -// *** RESOURCE USAGE STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** OUTPUT WINDOW STRINGS - START *** - -static const char* STR_OUTPUT_WINDOW_BUILDING_PROJECT_HEADER_A = "Building "; -static const char* STR_OUTPUT_WINDOW_BUILDING_PROJECT_HEADER_B = " project \""; -static const char* STR_OUTPUT_WINDOW_BUILDING_PROJECT_HEADER_C = "\" for "; -static const char* STR_OUTPUT_WINDOW_BUILDING_PROJECT_FAILED_TEXT = "Build Failed "; -static const char* STR_OUTPUT_WINDOW_BUILDING_PROJECT_FAILED_INVALID_CLONE = "due to invalid clone."; -static const char* STR_OUTPUT_WINDOW_CLEAR_BUTTON_TOOLTIP = "Clear the output window."; -static const char* STR_OUTPUT_WINDOW_CLEAR_BUTTON_STATUSTIP = "Clear the contents of the output window."; - -// *** OUTPUT WINDOW STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** STYLESHEET STRINGS - START *** - -// Stylesheet directory (relative to resource folder). -static const char* STR_STYLESHEET_RESOURCE_PATH = ":/stylesheets/"; - -// Stylesheet files. -static const char* STR_FILE_MENU_STYLESHEET_FILE = "rgFileMenuStyle.qss"; -static const char* STR_FILE_MENU_STYLESHEET_FILE_OPENCL = "OpenCL/rgFileMenuStyleOpenCL.qss"; -static const char* STR_FILE_MENU_STYLESHEET_FILE_VULKAN = "Vulkan/rgFileMenuStyleVulkan.qss"; -static const char* STR_APPLICATION_STYLESHEET_FILE = "rgApplicationStyle.qss"; -static const char* STR_APPLICATION_STYLESHEET_FILE_OPENCL = "OpenCL/rgApplicationStyleOpenCL.qss"; -static const char* STR_APPLICATION_STYLESHEET_FILE_VULKAN = "Vulkan/rgApplicationStyleVulkan.qss"; -static const char* STR_MAIN_WINDOW_STYLESHEET_FILE = "rgMainWindowStyle.qss"; -static const char* STR_MAIN_WINDOW_STYLESHEET_FILE_OPENCL = "OpenCL/rgMainWindowStyleOpenCL.qss"; -static const char* STR_MAIN_WINDOW_STYLESHEET_FILE_VULKAN = "Vulkan/rgMainWindowStyleVulkan.qss"; - -// The "current" property of file menu items. -static const char* STR_FILE_MENU_PROPERTY_CURRENT = "current"; - -// The "hovered" property of file menu items. -static const char* STR_FILE_MENU_PROPERTY_HOVERED = "hovered"; - -// The "occupied" property of file menu items. -static const char* STR_FILE_MENU_PROPERTY_OCCUPIED = "occupied"; - -// *** STYLESHEET STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** CONFIG FILE STRINGS - START *** - -static const char* STR_SPLITTER_NAME_BUILD_OUTPUT = "BuildOutput"; -static const char* STR_SPLITTER_NAME_SOURCE_DISASSEMBLY = "SourceAssembly"; - -// *** CONFIG FILE STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** VIEW CONTAINER NAME STRINGS - START *** - -static const char* STR_RG_FILE_MENU_VIEW_CONTAINER = "FileMenuViewContainer"; -static const char* STR_RG_SOURCE_VIEW_CONTAINER = "SourceViewContainer"; -static const char* STR_RG_ISA_DISASSEMBLY_VIEW_CONTAINER = "DisassemblyViewContainer"; -static const char* STR_RG_BUILD_OUTPUT_VIEW_CONTAINER = "BuildOutputViewContainer"; - -// *** VIEW CONTAINER NAME STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** GO TO LINE DIALOG STRINGS - START *** - -// The title used for the go to line dialog. -static const char* STR_GO_TO_LINE_DIALOG_TITLE = "Go to line"; - -// *** GO TO LINE DIALOG STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** SETTINGS CONFIRMATION DIALOG STRINGS - START *** - -static const char* STR_SETTINGS_CONFIRMATION_APPLICATION_SETTINGS = "Application settings"; - -// *** SETTINGS CONFIRMATION DIALOG STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** BUILD VIEW FONT FAMILY - START *** - -#ifdef __linux -static const char* STR_BUILD_VIEW_FONT_FAMILY = "DejaVu Sans Mono"; -#else -static const char* STR_BUILD_VIEW_FONT_FAMILY = "Consolas"; -#endif -static const char* STR_BUILD_VIEW_SETTINGS_SCROLLAREA = "settingsScrollArea"; -static const char* STR_BUILD_VIEW_SETTINGS_SCROLLAREA_STYLESHEET = "QScrollArea#settingsScrollArea { background-color: transparent; }"; -static const char* STR_BUILD_VIEW_BUILD_SETTINGS_WIDGET_STYLESHEET_GREEN = "#buildSettingsWidget { border: 1px solid rgb(18, 152, 0) }"; -static const char* STR_BUILD_VIEW_BUILD_SETTINGS_WIDGET_STYLESHEET_RED = "#buildSettingsWidget { border: 1px solid rgb(224, 30, 55); }"; -static const char* STR_BUILD_VIEW_BUILD_SETTINGS_WIDGET_STYLESHEET_BLACK = "#buildSettingsWidget { border: 1px solid black; }"; - -// *** BUILD VIEW FONT FAMILY - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** STARTUP DIALOG STRINGS - START *** - -static const char* STR_STARTUP_DIALOG_OPENCL_DESCRIPTION = "Compile and analyze OpenCL source code, using AMD's LLVM-based Lightning Compiler."; -static const char* STR_STARTUP_DIALOG_VULKAN_DESCRIPTION = "Compile and analyze graphics and compute Vulkan pipelines, from SPIR-V or GLSL files."; - -// *** STARTUP DIALOG STRINGS - END *** - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// *** CHECK FOR UPDATES DIALOG STRINGS - START *** - -static const char* STR_UPDATES_CHECKING_FOR_UPDATES = "Checking for updates..."; -static const char* STR_UPDATES_NO_UPDATES_AVAILABLE = "Checking for updates... done.\n\nNo updates available."; -static const char* STR_UPDATES_RESULTS_WINDOW_TITLE = "Available updates"; - -// *** CHECK FOR UPDATES DIALOG STRINGS - END *** \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/rgUtilsGraphics.h b/RadeonGPUAnalyzerGUI/Include/rgUtilsGraphics.h deleted file mode 100644 index cc925cc..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgUtilsGraphics.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -// C++. -#include -#include -#include - -// Local. -#include - -// A utilities class that can be implemented per graphics API. -class rgUtilsGraphics -{ -public: - virtual ~rgUtilsGraphics() = default; - - // Get a utility factory instance based on the given API. - static std::shared_ptr CreateUtility(rgProjectAPI api); - - // Get the abbreviated stage name string for the given pipeline stage. - virtual std::string PipelineStageToAbbreviation(rgPipelineStage pipelineStage) = 0; - - // Get the API-specific name for the given pipeline stage. - virtual std::string PipelineStageToString(rgPipelineStage pipelineStage) = 0; - - // Get the default source code for the given stage. - virtual std::string GetDefaultShaderCode(rgPipelineStage pipelineStage) = 0; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/rgUtilsVulkan.h b/RadeonGPUAnalyzerGUI/Include/rgUtilsVulkan.h deleted file mode 100644 index 5bc996c..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgUtilsVulkan.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -// Local. -#include - -class rgUtilsVulkan : public rgUtilsGraphics -{ -public: - virtual ~rgUtilsVulkan() = default; - - // Get the Vulkan glsl abbreviation string for the given pipeline stage. - virtual std::string PipelineStageToAbbreviation(rgPipelineStage pipelineStage) override; - - // Get the API-specific name for the given pipeline stage. - virtual std::string PipelineStageToString(rgPipelineStage pipelineStage) override; - - // Get the default source code for the given stage. - virtual std::string GetDefaultShaderCode(rgPipelineStage pipelineStage) override; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/rgXMLCliVersionInfo.h b/RadeonGPUAnalyzerGUI/Include/rgXMLCliVersionInfo.h deleted file mode 100644 index a725667..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgXMLCliVersionInfo.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -// C++. -#include - -// Local. -#include - -// A class responsible for parsing the CLI's version-info results. -class rgXMLCliVersionInfo -{ -public: - // Read the version info from file. - static bool ReadVersionInfo(const std::string& versionInfoFilePath, std::shared_ptr& pVersionInfo); -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/rgXMLSessionConfig.h b/RadeonGPUAnalyzerGUI/Include/rgXMLSessionConfig.h deleted file mode 100644 index 0d45948..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgXMLSessionConfig.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -// C++. -#include - -// Local. -#include - -// Forward declarations. -namespace tinyxml2 -{ - class XMLNode; -} - -// A class responsible for parsing session metadata. -class rgXMLSessionConfig -{ -public: - // Read the OpenCL project session metadata XML at the given file path. - static bool ReadSessionMetadataOpenCL(const std::string& sessionMetadataFilePath, std::shared_ptr& pCliOutput); - - // Read the Vulkan Pipeline session metadata XML at the given file path. - static bool ReadSessionMetadataVulkan(const std::string& sessionMetadataFilePath, std::shared_ptr& pCliOutput); - -private: - // Read the outputs node into an rgOutputItem array. - static bool ReadBuildOutputs(tinyxml2::XMLNode* pOutputsNode, std::vector& output); - - // Read an entry's output fields. - static bool ReadEntryOutputs(tinyxml2::XMLNode* pOutputEntryNode, rgFileOutputs& pOutputs); - - // Read each input file node's outputs. - static bool ReadInputFiles(tinyxml2::XMLNode* pInputFileNode, std::shared_ptr& pCliOutput); - - // Read a pipeline stage's output file paths. - static bool ReadPipelineStageOutputs(tinyxml2::XMLNode* pOutputsNode, rgEntryOutput& stageOutput); -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Include/rgXMLUtils.h b/RadeonGPUAnalyzerGUI/Include/rgXMLUtils.h deleted file mode 100644 index dce8c17..0000000 --- a/RadeonGPUAnalyzerGUI/Include/rgXMLUtils.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -// A set of utility functions to simplify processing XML. -class rgXMLUtils -{ -public: - // Returns the text value of a given node. - static bool ReadNodeTextString(tinyxml2::XMLNode* pNode, std::string& str); - - // Reads a node's text as an unsigned number. - static bool ReadNodeTextUnsigned(tinyxml2::XMLNode* pNode, unsigned& val); - - // Reads a node's text as a boolean value. - static bool ReadNodeTextBool(tinyxml2::XMLNode* pNode, bool& val); - - // The RGA data model version that this build uses. - static std::string GetRGADataModelVersion(); - - // Append a new XML element to the given parent node. - template - static void AppendXMLElement(tinyxml2::XMLDocument &xmlDoc, tinyxml2::XMLElement* pParentElement, const char* pElemName, T elemValue) - { - if (pParentElement != nullptr && pElemName != nullptr) - { - tinyxml2::XMLElement* pElem = xmlDoc.NewElement(pElemName); - if (pElem != nullptr) - { - pElem->SetText(elemValue); - pParentElement->InsertEndChild(pElem); - } - } - } - -private: - rgXMLUtils() = default; - ~rgXMLUtils() = default; -}; \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Res/RadeonGPUAnalyzerGUI.qrc b/RadeonGPUAnalyzerGUI/Res/RadeonGPUAnalyzerGUI.qrc deleted file mode 100644 index 3386737..0000000 --- a/RadeonGPUAnalyzerGUI/Res/RadeonGPUAnalyzerGUI.qrc +++ /dev/null @@ -1,44 +0,0 @@ - - - stylesheets/rgFileMenuStyle.qss - stylesheets/rgMainWindowStyle.qss - stylesheets/rgApplicationStyle.qss - icons/addElementIcon.svg - icons/addFileIcon.svg - icons/arrowDown.svg - icons/arrowLeft.svg - icons/arrowRight.svg - icons/arrowUp.svg - icons/newFileIcon.svg - icons/closeIcon.svg - icons/clearIcon.svg - icons/collapsedArrow.svg - icons/contractFileItem.svg - icons/expandFileItem.svg - icons/filterRowsIcon.svg - icons/trashCan.svg - icons/viewMinimizeIcon.svg - icons/viewMinimizeIconHover.svg - icons/viewMaximizeIcon.svg - icons/viewMaximizeIconHover.svg - icons/gearIcon.svg - icons/rgaIcon.png - icons/findPreviousIcon.svg - icons/findNextIcon.svg - icons/magnifyingGlassIcon.svg - icons/correlationWarningIcon.svg - icons/ApiLogos/openCLIconWide.png - icons/ApiLogos/vulkanIcon.png - stylesheets/OpenCL/rgApplicationStyleOpenCL.qss - stylesheets/OpenCL/rgMainWindowStyleOpenCL.qss - stylesheets/OpenCL/rgFileMenuStyleOpenCL.qss - stylesheets/Vulkan/rgApplicationStyleVulkan.qss - stylesheets/Vulkan/rgMainWindowStyleVulkan.qss - icons/gearIconWhite.svg - icons/checkedDisabledIcon.svg - icons/stateSettingsCube.svg - stylesheets/Vulkan/rgFileMenuStyleVulkan.qss - icons/deleteIcon.svg - icons/notificationIcon.svg - - diff --git a/RadeonGPUAnalyzerGUI/Res/stylesheets/OpenCL/rgApplicationStyleOpenCL.qss b/RadeonGPUAnalyzerGUI/Res/stylesheets/OpenCL/rgApplicationStyleOpenCL.qss deleted file mode 100644 index 8563ee7..0000000 --- a/RadeonGPUAnalyzerGUI/Res/stylesheets/OpenCL/rgApplicationStyleOpenCL.qss +++ /dev/null @@ -1,77 +0,0 @@ -/********************************************************************/ -/* Line Edit and Checkbox focus border -/********************************************************************/ -QLineEdit:focus, -QCheckBox:focus -{ - border: 1px solid lightGreen; -} - -/********************************************************************/ -/* OpenCL File Menu border color -/********************************************************************/ -rgMenuOpenCL -{ - border: 1px solid black; -} - -/********************************************************************/ -/* Frame focus border -/********************************************************************/ -QFrame:focus -{ - border: 1px solid black; -} - -rgBuildSettingsViewOpenCL #addTargetGPUsButton:focus, -rgBuildSettingsViewOpenCL #includeDirsBrowseButton:focus, -rgBuildSettingsViewOpenCL #predefinedMacrosBrowseButton:focus, -rgBuildSettingsViewOpenCL #compilerBinariesBrowseButton:focus, -rgBuildSettingsViewOpenCL #compilerIncludesBrowseButton:focus, -rgBuildSettingsViewOpenCL #compilerLibrariesBrowseButton:focus, -rgBuildSettingsViewOpenCL #optimizationLevelComboBox:focus, -rgBuildSettingsViewOpenCL #addTargetGPUsButton:hover, -rgBuildSettingsViewOpenCL #includeDirsBrowseButton:hover, -rgBuildSettingsViewOpenCL #predefinedMacrosBrowseButton:hover, -rgBuildSettingsViewOpenCL #compilerBinariesBrowseButton:hover, -rgBuildSettingsViewOpenCL #compilerIncludesBrowseButton:hover, -rgBuildSettingsViewOpenCL #compilerLibrariesBrowseButton:hover, -rgBuildSettingsViewOpenCL #optimizationLevelComboBox:hover -{ - border: 1px solid lightGreen; - background: rgb(240, 240, 240); -} - -rgViewContainer[viewHovered="true"][viewFocused="false"] rgMenuTitlebar #itemBackground, -rgViewContainer[viewHovered="true"][viewFocused="false"] rgFileMenuTitlebar #itemBackground, -rgViewContainer[viewHovered="true"][viewFocused="false"] rgStandardTitlebar, -rgViewContainer[viewHovered="true"][viewFocused="false"] rgSourceEditorTitlebar, -rgViewContainer[viewHovered="true"][viewFocused="false"] #viewTitlebar -{ - border-bottom: 3px solid rgb(18, 95, 0); -} - -rgViewContainer[viewFocused="true"] rgMenuTitlebar #itemBackground, -rgViewContainer[viewFocused="true"] rgFileMenuTitlebar #itemBackground, -rgViewContainer[viewFocused="true"] rgStandardTitlebar, -rgViewContainer[viewFocused="true"] rgSourceEditorTitlebar, -rgViewContainer[viewFocused="true"] #viewTitlebar -{ - border-bottom: 3px solid rgb(18, 152, 0); -} - -/********************************************************************/ -/* Target GPUs line edit background -/********************************************************************/ -rgBuildSettingsViewOpenCL #targetGPUsLineEdit -{ - background-color: rgb(240, 240, 240); -} - -/********************************************************************/ -/* Line edit border color -/********************************************************************/ -QLineEdit -{ - border: 1px solid black; -} diff --git a/RadeonGPUAnalyzerGUI/Res/stylesheets/Vulkan/rgFileMenuStyleVulkan.qss b/RadeonGPUAnalyzerGUI/Res/stylesheets/Vulkan/rgFileMenuStyleVulkan.qss deleted file mode 100644 index 3f6e4b1..0000000 --- a/RadeonGPUAnalyzerGUI/Res/stylesheets/Vulkan/rgFileMenuStyleVulkan.qss +++ /dev/null @@ -1,17 +0,0 @@ -/********************************************************************/ -/* Build settings menu item (rgMenuBuildSettingsItem) -/********************************************************************/ - -rgMenuBuildSettingsItem QPushButton -{ - background-color: rgb(214, 214, 214); - text-align: left; - padding-left: 11px; -} - -rgMenuBuildSettingsItem QPushButton:hover -{ - border-style: solid; - border-width: 2px; - border-color: rgb(135,20,16); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/main.cpp b/RadeonGPUAnalyzerGUI/Src/main.cpp deleted file mode 100644 index 84d9a5c..0000000 --- a/RadeonGPUAnalyzerGUI/Src/main.cpp +++ /dev/null @@ -1,163 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include - -// Infra. -#include -#include -#ifdef RGA_GUI_AUTOMATION -#include -#endif - -// Local. -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char *argv[]) -{ - int result = -1; - static const int s_TOP_MARGIN = 8; - const int EXPLICIT_MIN_WIDTH = 700; - const int EXPLICIT_MIN_HEIGHT = 700; - -#ifdef RGA_GUI_AUTOMATION - // Parse the command line and start Testing Thread. - rgTestConfig testConfig = rgTestClientThread::ParseCmdLine(argc, argv); - rgTestClientThread tester(testConfig); - if (testConfig.list_tests_ || testConfig.test_gui_) - { - if (testConfig.test_gui_ && testConfig.iteration_ == 1) - { - // Delete old config & project files. - rgTestClientThread::DeleteOldFiles(); - } - - // Start the testing thread. - tester.start(); - } - - // Don't start GUI if test list is requested. - if (testConfig.list_tests_) - { - tester.wait(); - return 0; - } -#endif - - // Initialize the configuration manager. - bool isInitialized = rgConfigManager::Instance().Init(); - assert(isInitialized); - - // Get the global settings from the config manager. - std::shared_ptr pGlobalSettings = rgConfigManager::Instance().GetGlobalConfig(); - assert(pGlobalSettings != nullptr); - - // Start the Qt application. - QApplication applicationInstance(argc, argv); - - if (pGlobalSettings != nullptr) - { - rgProjectAPI selectedApi = pGlobalSettings->m_defaultAPI; - if (pGlobalSettings->m_shouldPromptForAPI || selectedApi == rgProjectAPI::Unknown) - { - rgStartupDialog startupDialog; - -#ifdef RGA_GUI_AUTOMATION - tester.StartupDlgCreated(&startupDialog); -#endif - int result = startupDialog.exec(); - - if (result == QDialog::Rejected) - { - // exit RGA. - exit(0); - } - else - { - // Use the API that the user selected. - selectedApi = startupDialog.SelectedApi(); - - // If the user doesn't want to be asked again, then set NOT to prompt at startup. - rgConfigManager::Instance().SetPromptForAPIAtStartup(!startupDialog.ShouldNotAskAgain()); - - if (startupDialog.ShouldNotAskAgain()) - { - // Save the selected API as the new default. - rgConfigManager::Instance().SetDefaultAPI(selectedApi); - - // Save the fact that they don't want to be prompted again. - rgConfigManager::Instance().SaveGlobalConfigFile(); - } - } - } - - rgConfigManager::Instance().SetCurrentAPI(selectedApi); - } - - // Get the window geometry from config manager. - rgWindowConfig windowConfig = {}; - rgConfigManager::Instance().GetWindowGeometry(windowConfig); - - // Create the main window instance. - rgMainWindow mainWindow; - -#ifdef RGA_GUI_AUTOMATION - tester.MainWndCreated(&mainWindow); -#endif - - // Initialize the main window. - mainWindow.InitMainWindow(); - - // Update the Y position. - if (windowConfig.m_windowYPos <= 0) - { - windowConfig.m_windowYPos = mainWindow.statusBar()->height() + s_TOP_MARGIN; - } - - // Force an explicit minimum size. - mainWindow.setMinimumSize(EXPLICIT_MIN_WIDTH, EXPLICIT_MIN_HEIGHT); - - // Initialize the scaling manager. - ScalingManager& scalingManager = ScalingManager::Get(); - scalingManager.Initialize(&mainWindow); - scalingManager.RegisterAll(); - - // Show maximized if either geometry value is zero, or if the window was closed maximized. - if (windowConfig.m_windowWidth == 0 || windowConfig.m_windowHeight == 0 || windowConfig.m_windowState & Qt::WindowMaximized || windowConfig.m_windowState & Qt::WindowFullScreen) - { - mainWindow.showMaximized(); - } - else - { - // Set the window geometry and size policy. - QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - mainWindow.setSizePolicy(sizePolicy); - mainWindow.setGeometry(windowConfig.m_windowXPos, windowConfig.m_windowYPos, windowConfig.m_windowWidth, windowConfig.m_windowHeight); - - // Show main window. - mainWindow.show(); - } - - // Before starting the app, check if there is any queued fatal initialization error. - std::string fatalErrorMsg = rgConfigManager::Instance().GetFatalErrorMessage(); - if (!fatalErrorMsg.empty()) - { - // Display the fatal error to the user and exit after the user confirms. - rgUtils::ShowErrorMessageBox(fatalErrorMsg.c_str()); - rgLog::file << fatalErrorMsg << std::endl; - exit(-1); - } - - result = applicationInstance.exec(); - rgConfigManager::Instance().Close(); - - return result; -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgAboutDialog.cpp b/RadeonGPUAnalyzerGUI/Src/rgAboutDialog.cpp deleted file mode 100644 index 4ac65d5..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgAboutDialog.cpp +++ /dev/null @@ -1,232 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include - -// Infra. -#include -#include -#include - -// Local. -#include -#include -#include -#include - -// Shared between CLI and GUI. -#include -#include - -rgAboutDialog::rgAboutDialog(QWidget* pParent) : - QDialog(pParent), - m_pCheckForUpdatesDialog(nullptr), - m_pCheckForUpdatesDialogButtonBox(nullptr), - m_pCheckForUpdatesDialogLabel(nullptr), - m_pCheckForUpdatesThread(nullptr) -{ - ui.setupUi(this); - - // Set the size to fixed. - QSize size; - size.setWidth(300 * ScalingManager::Get().GetScaleFactor()); - size.setHeight(125 * ScalingManager::Get().GetScaleFactor()); - setFixedSize(size); - - // 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); - - // Get the CLI version info. - std::shared_ptr pCliVersion = rgConfigManager::Instance().GetVersionInfo(); - - // Build the version strings for the CLI. - if(pCliVersion != nullptr) - { - std::stringstream cliVersionString; - cliVersionString << ui.CliVersionLabel->text().toStdString() << " " << - pCliVersion->m_version << " (" << pCliVersion->m_buildDate << ")"; - ui.CliVersionLabel->setText(cliVersionString.str().c_str()); - } - - // Build the version string for the GUI. - std::stringstream guiVersionString; - - // Convert the date string. - std::string guiDateString(STR_RGA_BUILD_DATE); - bool isConverted = rgaSharedUtils::ConvertDateString(guiDateString); - assert(isConverted); - - guiVersionString << ui.ApplicationVersionLabel->text().toStdString() << " " << - STR_RGA_VERSION << "." << STR_RGA_BUILD_NUM << " (" << guiDateString << ")"; - ui.ApplicationVersionLabel->setText(guiVersionString.str().c_str()); - - // Set the about dialog OK button to have a pointing hand cursor. - QPushButton* pButton = ui.buttonBox->button(QDialogButtonBox::Ok); - assert(pButton != nullptr); - if (pButton != nullptr) - { - pButton->setCursor(Qt::PointingHandCursor); - } - - ui.checkForUpdatesButton->setCursor(Qt::PointingHandCursor); - - // Connect the check for updates push button to the handler. - bool isButtonConnected = connect(ui.checkForUpdatesButton, &QPushButton::clicked, this, &rgAboutDialog::HandleCheckForUpdatesClicked); - assert(isButtonConnected); - if (!isButtonConnected) - { - // Disable the button if the slot cannot be connected. - ui.checkForUpdatesButton->setEnabled(false); - } -} - -void rgAboutDialog::HandleCheckForUpdatesClicked() -{ - // Don't allow checking for updates if there is already one in progress. - if (m_pCheckForUpdatesThread == nullptr) - { - // Create the check for updates thread - m_pCheckForUpdatesThread = new UpdateCheck::ThreadController(this, RGA_VERSION_MAJOR, RGA_VERSION_MINOR, RGA_VERSION_UPDATE, RGA_BUILD_NUMBER); - - // Build dialog to display and allow user to cancel the check if desired. - if (m_pCheckForUpdatesDialog == nullptr) - { - m_pCheckForUpdatesDialog = new QDialog(this); - m_pCheckForUpdatesDialog->setWindowTitle(STR_APP_NAME); - m_pCheckForUpdatesDialog->setWindowFlags(m_pCheckForUpdatesDialog->windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint); - m_pCheckForUpdatesDialog->setFixedWidth(250 * ScalingManager::Get().GetScaleFactor()); - m_pCheckForUpdatesDialog->setFixedHeight(100 * ScalingManager::Get().GetScaleFactor()); - - // Set background to white. - rgUtils::SetBackgroundColor(m_pCheckForUpdatesDialog, Qt::white); - - QVBoxLayout* pLayout = new QVBoxLayout(); - m_pCheckForUpdatesDialog->setLayout(pLayout); - m_pCheckForUpdatesDialogLabel = new QLabel(STR_UPDATES_CHECKING_FOR_UPDATES); - m_pCheckForUpdatesDialog->layout()->addWidget(m_pCheckForUpdatesDialogLabel); - m_pCheckForUpdatesDialog->layout()->addItem(new QSpacerItem(5, 10, QSizePolicy::Minimum, QSizePolicy::Expanding)); - - // Add Cancel button to cancel the check for updates. - m_pCheckForUpdatesDialogButtonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, m_pCheckForUpdatesDialog); - m_pCheckForUpdatesDialogButtonBox->button(QDialogButtonBox::Cancel)->setCursor(Qt::PointingHandCursor); - m_pCheckForUpdatesDialogButtonBox->button(QDialogButtonBox::Ok)->setCursor(Qt::PointingHandCursor); - m_pCheckForUpdatesDialogButtonBox->button(QDialogButtonBox::Ok)->setVisible(false); - m_pCheckForUpdatesDialog->layout()->addWidget(m_pCheckForUpdatesDialogButtonBox); - - // If the cancel button is pressed, signal the dialog to reject, which is similar to closing it. - bool isRejectedConnected = connect(m_pCheckForUpdatesDialogButtonBox, &QDialogButtonBox::rejected, m_pCheckForUpdatesDialog, &QDialog::reject); - assert(isRejectedConnected); - - bool isOkConnected = connect(m_pCheckForUpdatesDialogButtonBox, &QDialogButtonBox::accepted, m_pCheckForUpdatesDialog, &QDialog::accept); - assert(isRejectedConnected); - } - else - { - // The dialog already exists, but may have the wrong text and button on it. Fix it up before displaying again. - m_pCheckForUpdatesDialogLabel->setText(STR_UPDATES_CHECKING_FOR_UPDATES); - m_pCheckForUpdatesDialogButtonBox->button(QDialogButtonBox::Cancel)->setVisible(true); - m_pCheckForUpdatesDialogButtonBox->button(QDialogButtonBox::Ok)->setVisible(false); - } - - // Cancel the check for updates if the dialog is closed. - bool isCancelDialogConnected = connect(m_pCheckForUpdatesDialog, &QDialog::rejected, m_pCheckForUpdatesThread, &UpdateCheck::ThreadController::CancelCheckForUpdates); - assert(isCancelDialogConnected); - - // Get notified when the check for updates has completed or was cancelled. - bool isCompletedConnected = connect(m_pCheckForUpdatesThread, &UpdateCheck::ThreadController::CheckForUpdatesComplete, this, &rgAboutDialog::HandleCheckForUpdatesCompleted); - assert(isCompletedConnected); - bool isCancelledConnected = connect(m_pCheckForUpdatesThread, &UpdateCheck::ThreadController::CheckForUpdatesCancelled, this, &rgAboutDialog::HandleCheckForUpdatesCancelled); - assert(isCancelledConnected); - - m_pCheckForUpdatesThread->StartCheckForUpdates(STR_RGA_UPDATECHECK_URL, STR_RGA_UPDATECHECK_ASSET_NAME); - - ui.checkForUpdatesButton->setCursor(Qt::WaitCursor); - - m_pCheckForUpdatesDialog->show(); - } -} - -void rgAboutDialog::HandleCheckForUpdatesCancelled(UpdateCheck::ThreadController* pThread) -{ - // Restore pointing hand cursor. - ui.checkForUpdatesButton->setCursor(Qt::PointingHandCursor); - - // Delete the previous thread since it is no longer useful. - if (m_pCheckForUpdatesThread == pThread) - { - if (m_pCheckForUpdatesThread != nullptr) - { - delete m_pCheckForUpdatesThread; - m_pCheckForUpdatesThread = nullptr; - } - } -} - -void rgAboutDialog::HandleCheckForUpdatesCompleted(UpdateCheck::ThreadController* pThread, const UpdateCheck::Results& updateCheckResults) -{ - if (updateCheckResults.wasCheckSuccessful && !updateCheckResults.updateInfo.m_isUpdateAvailable) - { - // Update the existing dialog to report that there are no updates available, and switch to the Ok button. - m_pCheckForUpdatesDialogLabel->setText(STR_UPDATES_NO_UPDATES_AVAILABLE); - m_pCheckForUpdatesDialogButtonBox->button(QDialogButtonBox::Cancel)->setVisible(false); - m_pCheckForUpdatesDialogButtonBox->button(QDialogButtonBox::Ok)->setVisible(true); - m_pCheckForUpdatesDialog->update(); - } - else - { - // Close the pending dialog. - m_pCheckForUpdatesDialog->close(); - - UpdateCheckResultsDialog* pResultsDialog = new UpdateCheckResultsDialog(this); - if (pResultsDialog != nullptr) - { - // Hide the tag label. - pResultsDialog->SetShowTags(false); - - // Change from default title. - pResultsDialog->setWindowTitle(STR_UPDATES_RESULTS_WINDOW_TITLE); - - // Set background to white. - rgUtils::SetBackgroundColor(pResultsDialog, Qt::white); - - // Set this dialog to get deleted when it is closed. - pResultsDialog->setAttribute(Qt::WA_DeleteOnClose, true); - pResultsDialog->setWindowFlags(pResultsDialog->windowFlags() & ~Qt::WindowContextHelpButtonHint); - pResultsDialog->setFixedSize(400 * ScalingManager::Get().GetScaleFactor(), - 300 * ScalingManager::Get().GetScaleFactor()); - QDialogButtonBox* pButtonBox = pResultsDialog->findChild("buttonBox"); - if (pButtonBox != nullptr) - { - QPushButton* pCloseButton = pButtonBox->button(QDialogButtonBox::Close); - if (pCloseButton != nullptr) - { - pCloseButton->setCursor(Qt::PointingHandCursor); - } - } - - // Set the results. - pResultsDialog->SetResults(updateCheckResults); - - // Display it as a modal dialog. - pResultsDialog->exec(); - } - } - - // Delete the thread so that it no longer exists in the background. - if (m_pCheckForUpdatesThread == pThread) - { - if (m_pCheckForUpdatesThread != nullptr) - { - delete m_pCheckForUpdatesThread; - m_pCheckForUpdatesThread = nullptr; - } - } - - // Restore pointing hand cursor. - ui.checkForUpdatesButton->setCursor(Qt::PointingHandCursor); -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgAddCreateMenuItem.cpp b/RadeonGPUAnalyzerGUI/Src/rgAddCreateMenuItem.cpp deleted file mode 100644 index a08fb60..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgAddCreateMenuItem.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "rgAddCreateMenuItem.h" - -#include -#include - -rgAddCreateMenuItem::rgAddCreateMenuItem(rgMenu* pParent) : - rgMenuItem(pParent) -{ - ui.setupUi(this); - ui.addButton->setContentsMargins(0, 0, 0, 0); - ui.createButton->setContentsMargins(0, 0, 0, 0); - - // Set button tooltips and status tips. - rgUtils::SetToolAndStatusTip(STR_MENU_BAR_OPEN_EXISTING_FILE_TOOLTIP_OPENCL, ui.addButton); - rgUtils::SetToolAndStatusTip(STR_MENU_BAR_CREATE_NEW_FILE_TOOLTIP_OPENCL, ui.createButton); - - // Set mouse pointer to pointing hand cursor. - SetCursor(); -} - -QPushButton* rgAddCreateMenuItem::GetAddButton() const -{ - return ui.addButton; -} - -QPushButton* rgAddCreateMenuItem::GetCreateButton() const -{ - return ui.createButton; -} - -void rgAddCreateMenuItem::SetCursor() -{ - // Set mouse pointer to pointing hand cursor. - ui.addButton->setCursor(Qt::PointingHandCursor); - ui.createButton->setCursor(Qt::PointingHandCursor); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgAppState.cpp b/RadeonGPUAnalyzerGUI/Src/rgAppState.cpp deleted file mode 100644 index 8d259a1..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgAppState.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// C++. -#include - -// Local. -#include -#include -#include -#include -#include - -void rgAppState::CreateFileActions(QMenu* pMenubar) -{ - // Create API-specific file menu actions. - CreateApiSpecificFileActions(pMenubar); - - // Connect file menu actions. - ConnectFileMenuActions(); -} - -void rgAppState::SetMainWindow(rgMainWindow* pMainWindow) -{ - m_pMainWindow = pMainWindow; -} - -void rgAppState::SetSettingsTab(rgSettingsTab* pSettingsTab) -{ - m_pSettingsTab = pSettingsTab; -} - -bool rgAppState::ShowProjectSaveDialog() -{ - bool shouldActionContinue = true; - rgBuildView* pBuildView = GetBuildView(); - if (pBuildView != nullptr) - { - shouldActionContinue = pBuildView->ShowSaveDialog(); - } - - return shouldActionContinue; -} - -bool rgAppState::IsGraphics() const -{ - return m_isGraphics; -} - -rgAppStateGraphics::rgAppStateGraphics() -{ - // Set the graphics flag to true. - m_isGraphics = true; -} - -bool rgAppState::IsInputFileNameBlank() const -{ - bool result = false; - - // Handle blank input file in global settings view. - rgGlobalSettingsView* pGlobalSettings = m_pSettingsTab->GetGlobalSettingsView(); - if (pGlobalSettings != nullptr) - { - bool isInputFileNameBlank = pGlobalSettings->IsInputFileBlank(); - if (isInputFileNameBlank) - { - pGlobalSettings->ProcessInputFileBlank(); - result = true; - } - } - - return result; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgAppStateOpenCL.cpp b/RadeonGPUAnalyzerGUI/Src/rgAppStateOpenCL.cpp deleted file mode 100644 index b29b460..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgAppStateOpenCL.cpp +++ /dev/null @@ -1,368 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -void rgAppStateOpenCL::ResetBuildView() -{ - // Destroy the rgBuildView instance. Subsequent project creation or load operations will - // re-initialize a new rgBuildView. - RG_SAFE_DELETE(m_pBuildView); - - // Re-create an empty rgBuildView. - CreateBuildView(); -} - -void rgAppStateOpenCL::ConnectBuildViewSignals(rgBuildView* pBuildView) -{ - rgBuildViewOpenCL* pOpenCLBuildView = static_cast(pBuildView); - assert(pOpenCLBuildView != nullptr); - if (pOpenCLBuildView != nullptr) - { - // Connect the rgBuildViewOpenCL default menu item's Create button. - bool isConnected = connect(pOpenCLBuildView, &rgBuildViewOpenCL::CreateFileButtonClicked, this, &rgAppStateOpenCL::HandleCreateNewCLFile); - assert(isConnected); - - // Connect the rgBuildViewOpenCL default menu item's Open button. - isConnected = connect(pOpenCLBuildView, &rgBuildViewOpenCL::OpenFileButtonClicked, this, &rgAppStateOpenCL::HandleOpenExistingCLFile); - assert(isConnected); - } -} - -rgStartTab* rgAppStateOpenCL::GetStartTab() -{ - return m_pStartTab; -} - -rgBuildView* rgAppStateOpenCL::GetBuildView() -{ - return m_pBuildView; -} - -void rgAppStateOpenCL::SetStartTab(rgStartTab* pStartTab) -{ - m_pStartTab = static_cast(pStartTab); -} - -void rgAppStateOpenCL::Cleanup(QMenu* pMenubar) -{ - assert(m_pNewFileAction != nullptr); - assert(pMenubar != nullptr); - if (m_pNewFileAction != nullptr && pMenubar != nullptr) - { - // Remove the OpenCL-specific actions from the file menu. - pMenubar->removeAction(m_pNewFileAction); - } -} - -void rgAppStateOpenCL::HandleProjectBuildStarted() -{ - // Do not allow creating/adding files. - m_pNewFileAction->setEnabled(false); - m_pOpenFileAction->setEnabled(false); -} - -void rgAppStateOpenCL::ResetViewStateAfterBuild() -{ - m_pNewFileAction->setEnabled(true); - m_pOpenFileAction->setEnabled(true); -} - -void rgAppStateOpenCL::HandleCreateNewCLFile() -{ - assert(m_pMainWindow != nullptr); - if (m_pMainWindow != nullptr) - { - // Ask user to save pending settings. - bool userCanceledAction = false; - if (m_pSettingsTab != nullptr) - { - userCanceledAction = !m_pSettingsTab->PromptToSavePendingChanges(); - } - - if (!userCanceledAction) - { - if (m_pBuildView != nullptr) - { - // Prompt to save items in the build view if needed; including the project build settings. - userCanceledAction = !m_pBuildView->ShowSaveDialog(); - } - - if (!userCanceledAction) - { - // Track if a project was actually created. - bool wasProjectCreated = false; - - assert(m_pBuildView != nullptr); - if (m_pBuildView != nullptr) - { - m_pMainWindow->setAcceptDrops(false); - wasProjectCreated = m_pBuildView->CreateNewSourceFileInProject(); - m_pMainWindow->setAcceptDrops(true); - if (wasProjectCreated) - { - // Show the build view as the central widget. - m_pMainWindow->SwitchToView(rgMainWindow::MainWindowView::BuildView); - - // Adjust the menu button focus. - rgMenu* pMenu = m_pBuildView->GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - pMenu->SetButtonsNoFocus(); - } - } - else - { - // The project was not created successfully, so clean up the build view. - m_pMainWindow->DestroyBuildView(); - } - - - // Restore the layout if no project was created. - if (!wasProjectCreated) - { - // Reset the actions to the default state. - m_pMainWindow->ResetActionsState(); - } - } - } - } - } -} - -void rgAppStateOpenCL::HandleOpenExistingCLFile() -{ - assert(m_pMainWindow != nullptr); - if (m_pMainWindow != nullptr) - { - // Ask user to save pending settings. - bool userCanceledAction = false; - if (m_pSettingsTab != nullptr) - { - userCanceledAction = !m_pSettingsTab->PromptToSavePendingChanges(); - } - - if (!userCanceledAction) - { - if (m_pBuildView != nullptr) - { - // Prompt to save items in the build view if needed; including the project build settings. - userCanceledAction = !m_pBuildView->ShowSaveDialog(); - } - - if (!userCanceledAction) - { - // Retrieve the current API from the configuration manager. - rgProjectAPI currentAPI = rgConfigManager::Instance().GetCurrentAPI(); - - QStringList selectedFiles; - bool isOk = rgUtils::OpenFileDialogForMultipleFiles(m_pMainWindow, currentAPI, selectedFiles); - if (isOk && !selectedFiles.empty()) - { - m_pMainWindow->setAcceptDrops(false); - OpenFilesInBuildView(selectedFiles); - m_pMainWindow->setAcceptDrops(true); - } - } - } - } -} - -void rgAppStateOpenCL::CreateApiSpecificFileActions(QMenu* pMenubar) -{ - m_pNewFileAction = new QAction(tr(STR_MENU_BAR_CREATE_NEW_FILE_OPENCL), this); - m_pNewFileAction->setShortcuts(QKeySequence::New); - m_pNewFileAction->setStatusTip(tr(STR_MENU_BAR_CREATE_NEW_FILE_TOOLTIP_OPENCL)); - bool isConnected = connect(m_pNewFileAction, &QAction::triggered, this, &rgAppStateOpenCL::HandleCreateNewCLFile); - assert(isConnected); - if (isConnected) - { - pMenubar->addAction(m_pNewFileAction); - } - - m_pOpenFileAction = new QAction(tr(STR_MENU_BAR_OPEN_EXISTING_FILE_OPENCL), this); - m_pOpenFileAction->setShortcuts(QKeySequence::Open); - m_pOpenFileAction->setStatusTip(tr(STR_MENU_BAR_OPEN_EXISTING_FILE_TOOLTIP_OPENCL)); - isConnected = connect(m_pOpenFileAction, &QAction::triggered, this, &rgAppStateOpenCL::HandleOpenExistingCLFile); - assert(isConnected); - if (isConnected) - { - pMenubar->addAction(m_pOpenFileAction); - } -} - -void rgAppStateOpenCL::CreateBuildView() -{ - // Create a factory matching the new API mode to switch to. - std::shared_ptr pFactory = rgFactory::CreateFactory(rgProjectAPI::OpenCL); - assert(pFactory != nullptr); - if (pFactory != nullptr) - { - // Instantiate the rgBuildView. - m_pBuildView = static_cast(pFactory->CreateBuildView(m_pMainWindow)); - - // Connect the project created handler so the rgMainWindow can - // add the new rgBuildView instance to the widget hierarchy. - bool isConnected = connect(m_pBuildView, &rgBuildView::ProjectCreated, m_pMainWindow, &rgMainWindow::HandleProjectCreated); - assert(isConnected); - } -} - -void rgAppStateOpenCL::ConnectFileMenuActions() -{ - assert(m_pStartTab != nullptr); - if (m_pStartTab != nullptr) - { - // Connect the "Create new CL file" button in the start page. - bool isConnected = connect(m_pStartTab, &rgStartTabOpenCL::CreateNewCLFileEvent, this, &rgAppStateOpenCL::HandleCreateNewCLFile); - assert(isConnected); - - // Connect the "Open existing CL file" button in the start page. - isConnected = connect(m_pStartTab, &rgStartTabOpenCL::OpenExistingFileEvent, this, &rgAppStateOpenCL::HandleOpenExistingCLFile); - assert(isConnected); - } -} - -void rgAppStateOpenCL::OpenFilesInBuildView(const QStringList& filePaths) -{ - if (!filePaths.empty()) - { - assert(m_pBuildView != nullptr); - if (m_pBuildView != nullptr) - { - for (const QString& selectedFile : filePaths) - { - // Update the project to reference to selected source file. - bool result = m_pBuildView->AddExistingSourcefileToProject(selectedFile.toStdString()); - - // Break out of the for loop if the operation failed. - if (!result) - { - break; - } - } - - // Switch to the build view if there's at least one file being edited. - if (!m_pBuildView->HasSourceCodeEditors()) - { - // Show the build view as the central widget. - m_pMainWindow->SwitchToView(rgMainWindow::MainWindowView::BuildView); - } - else - { - // The project was not created successfully, so clean up the build view. - m_pMainWindow->DestroyBuildView(); - } - } - } -} - -void rgAppStateOpenCL::GetApplicationStylesheet(std::vector& stylesheetFileNames) -{ - stylesheetFileNames.push_back(STR_APPLICATION_STYLESHEET_FILE_OPENCL); - stylesheetFileNames.push_back(STR_APPLICATION_STYLESHEET_FILE); -} - -void rgAppStateOpenCL::GetMainWindowStylesheet(std::vector& stylesheetFileNames) -{ - stylesheetFileNames.push_back(STR_MAIN_WINDOW_STYLESHEET_FILE_OPENCL); - stylesheetFileNames.push_back(STR_MAIN_WINDOW_STYLESHEET_FILE); -} - -std::string rgAppStateOpenCL::GetGlobalSettingsViewStylesheet() const -{ - const char* STR_OPENCL_APP_SETTINGS_STYLESHEET = - "rgGlobalSettingsView #projectNameCheckBox:focus," - "rgGlobalSettingsView #projectNameCheckBox:hover," - "rgGlobalSettingsView #logFileLocationFolderOpenButton:focus," - "rgGlobalSettingsView #logFileLocationFolderOpenButton:hover," - "rgGlobalSettingsView #defaultApiOnStartupComboBox:focus," - "rgGlobalSettingsView #defaultApiOnStartupComboBox:hover," - "rgGlobalSettingsView #columnVisibilityArrowPushButton:focus," - "rgGlobalSettingsView #columnVisibilityArrowPushButton:hover," - "rgGlobalSettingsView #fontFamilyComboBox:focus," - "rgGlobalSettingsView #fontFamilyComboBox:hover," - "rgGlobalSettingsView #fontSizeComboBox:focus," - "rgGlobalSettingsView #fontSizeComboBox:hover," - "rgGlobalSettingsView #logFileLocationLineEdit:focus," - "rgGlobalSettingsView #logFileLocationLineEdit:hover," - "rgGlobalSettingsView #includeFilesViewerLineEdit:focus," - "rgGlobalSettingsView #includeFilesViewerLineEdit:hover," - "rgGlobalSettingsView #includeFilesViewerBrowseButton:focus," - "rgGlobalSettingsView #includeFilesViewerBrowseButton:hover," - "rgGlobalSettingsView #assocExtGlslLineEdit:focus," - "rgGlobalSettingsView #assocExtGlslLineEdit:hover," - "rgGlobalSettingsView #assocExtSpvasLineEdit:focus," - "rgGlobalSettingsView #assocExtSpvasLineEdit:hover," - "rgGlobalSettingsView #assocExtSpvBinaryLineEdit:focus," - "rgGlobalSettingsView #assocExtSpvBinaryLineEdit:hover," - "rgGlobalSettingsView #assocExtSpvasLabel:focus," - "rgGlobalSettingsView #assocExtSpvasLabel:hover," - "rgGlobalSettingsView #defaultLangComboBox:focus," - "rgGlobalSettingsView #defaultLangComboBox:hover" - "{" - "border: 1px solid lightGreen;" - "background: rgb(240, 240, 240);" - "}"; - return STR_OPENCL_APP_SETTINGS_STYLESHEET; -} - -std::string rgAppStateOpenCL::GetBuildSettingsViewStylesheet() const -{ - const char* STR_OPENCL_BUILD_SETTINGS_STYLESHEET = - "rgBuildSettingsView #doubleAsSingleCheckBox:focus," - "rgBuildSettingsView #doubleAsSingleCheckBox:hover," - "rgBuildSettingsView #flushDenormalizedCheckBox:focus," - "rgBuildSettingsView #flushDenormalizedCheckBox:hover," - "rgBuildSettingsView #strictAliasingCheckBox:focus," - "rgBuildSettingsView #strictAliasingCheckBox:hover," - "rgBuildSettingsView #enableMADCheckBox:focus," - "rgBuildSettingsView #enableMADCheckBox:hover," - "rgBuildSettingsView #ignoreZeroSignednessCheckBox:focus," - "rgBuildSettingsView #ignoreZeroSignednessCheckBox:hover," - "rgBuildSettingsView #allowUnsafeOptimizationsCheckBox:focus," - "rgBuildSettingsView #allowUnsafeOptimizationsCheckBox:hover," - "rgBuildSettingsView #assumeNoNanNorInfiniteCheckBox:focus," - "rgBuildSettingsView #assumeNoNanNorInfiniteCheckBox:hover," - "rgBuildSettingsView #aggressiveMathOptimizationsCheckBox:focus," - "rgBuildSettingsView #aggressiveMathOptimizationsCheckBox:hover," - "rgBuildSettingsView #correctlyRoundSinglePrecisionCheckBox:focus," - "rgBuildSettingsView #correctlyRoundSinglePrecisionCheckBox:hover," - "rgBuildSettingsView #predefinedMacrosLineEdit:focus," - "rgBuildSettingsView #predefinedMacrosLineEdit:hover," - "rgBuildSettingsView #includeDirectoriesLineEdit:focus," - "rgBuildSettingsView #includeDirectoriesLineEdit:hover," - "rgBuildSettingsView #compilerBinariesLineEdit:focus," - "rgBuildSettingsView #compilerBinariesLineEdit:hover," - "rgBuildSettingsView #compilerIncludesLineEdit:focus," - "rgBuildSettingsView #compilerIncludesLineEdit:hover," - "rgBuildSettingsView #additionalOptionsTextEdit:focus," - "rgBuildSettingsView #additionalOptionsTextEdit:hover," - "rgBuildSettingsView #allOptionsTextEdit:focus," - "rgBuildSettingsView #allOptionsTextEdit:hover," - "rgBuildSettingsView #compilerLibrariesLineEdit:focus," - "rgBuildSettingsView #compilerLibrariesLineEdit:hover" - "{" - "border: 1px solid lightGreen;" - "background: rgb(240, 240, 240);" - "}"; - return STR_OPENCL_BUILD_SETTINGS_STYLESHEET; -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgAppStateVulkan.cpp b/RadeonGPUAnalyzerGUI/Src/rgAppStateVulkan.cpp deleted file mode 100644 index de501c0..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgAppStateVulkan.cpp +++ /dev/null @@ -1,340 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void rgAppStateVulkan::ResetBuildView() -{ - // Destroy the existing rgBuildView instance. Subsequent project creation or load operations will - // re-initialize a new rgBuildView. - RG_SAFE_DELETE(m_pBuildView); - - // Enable the "Create pipeline" actions in the app menu. - if (m_pNewGraphicsPipelineAction != nullptr && m_pNewComputePipelineAction != nullptr) - { - m_pNewGraphicsPipelineAction->setEnabled(true); - m_pNewComputePipelineAction->setEnabled(true); - } - - // Re-create an empty rgBuildView. - CreateBuildView(); -} - -void rgAppStateVulkan::ConnectBuildViewSignals(rgBuildView* pBuildView) -{ - bool isConnected = connect(pBuildView, &rgBuildView::ProjectLoaded, this, &rgAppStateVulkan::HandleProjectLoaded); - assert(isConnected); -} - -rgStartTab* rgAppStateVulkan::GetStartTab() -{ - return m_pStartTab; -} - -rgBuildView* rgAppStateVulkan::GetBuildView() -{ - return m_pBuildView; -} - -void rgAppStateVulkan::SetStartTab(rgStartTab* pStartTab) -{ - m_pStartTab = static_cast(pStartTab); -} - -void rgAppStateVulkan::Cleanup(QMenu* pMenubar) -{ - assert(m_pNewGraphicsPipelineAction != nullptr); - assert(m_pNewComputePipelineAction != nullptr); - assert(pMenubar != nullptr); - if (m_pNewGraphicsPipelineAction != nullptr && m_pNewComputePipelineAction != nullptr && pMenubar != nullptr) - { - // Remove the Vulkan-specific actions from the file menu. - pMenubar->removeAction(m_pNewGraphicsPipelineAction); - pMenubar->removeAction(m_pNewComputePipelineAction); - } -} - -void rgAppStateVulkan::HandleCreateNewGraphicsPipeline() -{ - assert(m_pMainWindow != nullptr); - if (m_pMainWindow != nullptr) - { - // Ask user to save pending settings. - bool userCanceledAction = false; - - if (!IsInputFileNameBlank()) - { - if (m_pSettingsTab != nullptr) - { - userCanceledAction = !m_pSettingsTab->PromptToSavePendingChanges(); - } - - if (!userCanceledAction) - { - // Track if a project was actually created. - bool wasProjectCreated = false; - - assert(m_pBuildView != nullptr); - if (m_pBuildView != nullptr) - { - m_pMainWindow->setAcceptDrops(false); - wasProjectCreated = m_pBuildView->CreateDefaultGraphicsPipeline(); - m_pMainWindow->setAcceptDrops(true); - - if (wasProjectCreated) - { - // Show the build view as the central widget. - m_pMainWindow->SwitchToView(rgMainWindow::MainWindowView::BuildView); - } - else - { - // The project was not created successfully, so clean up the build view. - m_pMainWindow->DestroyBuildView(); - } - } - - // Restore the layout if no project was created. - if (!wasProjectCreated) - { - // Reset the actions to the default state. - m_pMainWindow->ResetActionsState(); - } - } - } - } -} - -void rgAppStateVulkan::HandleCreateNewComputePipeline() -{ - assert(m_pMainWindow != nullptr); - if (m_pMainWindow != nullptr) - { - // Ask user to save pending settings. - bool userCanceledAction = false; - if (!IsInputFileNameBlank()) - { - if (m_pSettingsTab != nullptr) - { - userCanceledAction = !m_pSettingsTab->PromptToSavePendingChanges(); - } - - if (!userCanceledAction) - { - // Track if a project was actually created. - bool wasProjectCreated = false; - - assert(m_pBuildView != nullptr); - if (m_pBuildView != nullptr) - { - m_pMainWindow->setAcceptDrops(false); - wasProjectCreated = m_pBuildView->CreateDefaultComputePipeline(); - m_pMainWindow->setAcceptDrops(true); - - if (wasProjectCreated) - { - // Show the build view as the central widget. - m_pMainWindow->SwitchToView(rgMainWindow::MainWindowView::BuildView); - } - else - { - // The project was not created successfully, so clean up the build view. - m_pMainWindow->DestroyBuildView(); - } - } - - // Restore the layout if no project was created. - if (!wasProjectCreated) - { - // Reset the actions to the default state. - m_pMainWindow->ResetActionsState(); - } - } - } - } -} - -void rgAppStateVulkan::HandleProjectBuildStarted() -{ -} - -void rgAppStateVulkan::HandleProjectLoaded(std::shared_ptr) -{ - m_pNewGraphicsPipelineAction->setEnabled(false); - m_pNewComputePipelineAction->setEnabled(false); -} - -void rgAppStateVulkan::CreateApiSpecificFileActions(QMenu* pMenubar) -{ - // Create new Graphics PSO action. - m_pNewGraphicsPipelineAction = new QAction(tr(STR_MENU_BAR_CREATE_NEW_GRAPHICS_PSO_VULKAN), this); - m_pNewGraphicsPipelineAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_NEW_VULKAN_GRAPHICS_PROJECT)); - m_pNewGraphicsPipelineAction->setStatusTip(tr(STR_MENU_BAR_CREATE_NEW_GRAPHICS_PSO_TOOLTIP_VULKAN)); - bool isConnected = connect(m_pNewGraphicsPipelineAction, &QAction::triggered, this, &rgAppStateVulkan::HandleCreateNewGraphicsPipeline); - assert(isConnected); - if (isConnected) - { - pMenubar->addAction(m_pNewGraphicsPipelineAction); - } - - // Create new Compute PSO action. - m_pNewComputePipelineAction = new QAction(tr(STR_MENU_BAR_CREATE_NEW_COMPUTE_PSO_VULKAN), this); - m_pNewComputePipelineAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_NEW_VULKAN_COMPUTE_PROJECT)); - m_pNewComputePipelineAction->setStatusTip(tr(STR_MENU_BAR_CREATE_NEW_COMPUTE_PSO_TOOLTIP_VULKAN)); - isConnected = connect(m_pNewComputePipelineAction, &QAction::triggered, this, &rgAppStateVulkan::HandleCreateNewComputePipeline); - assert(isConnected); - if (isConnected) - { - pMenubar->addAction(m_pNewComputePipelineAction); - } - - m_pNewGraphicsPipelineAction->setEnabled(true); - m_pNewComputePipelineAction->setEnabled(true); -} - -void rgAppStateVulkan::CreateBuildView() -{ - // Create a factory matching the new API mode to switch to. - std::shared_ptr pFactory = rgFactory::CreateFactory(rgProjectAPI::Vulkan); - assert(pFactory != nullptr); - if (pFactory != nullptr) - { - // Instantiate the rgBuildView. - m_pBuildView = static_cast(pFactory->CreateBuildView(m_pMainWindow)); - - // Connect the project created handler so the rgMainWindow can - // add the new rgBuildView instance to the widget hierarchy. - bool isConnected = connect(m_pBuildView, &rgBuildView::ProjectCreated, m_pMainWindow, &rgMainWindow::HandleProjectCreated); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(m_pMainWindow, &rgMainWindow::HotKeyPressedSignal, m_pBuildView, &rgBuildView::HotKeyPressedSignal); - assert(isConnected); - } -} - -void rgAppStateVulkan::ConnectFileMenuActions() -{ - assert(m_pStartTab != nullptr); - if (m_pStartTab != nullptr) - { - // Connect the "Create new graphics pipeline" button in the start page. - bool isConnected = connect(m_pStartTab, &rgStartTabVulkan::CreateGraphicsPipelineEvent, this, &rgAppStateVulkan::HandleCreateNewGraphicsPipeline); - assert(isConnected); - - // Connect the "Create new compute pipeline" button in the start page. - isConnected = connect(m_pStartTab, &rgStartTabVulkan::CreateComputePipelineEvent, this, &rgAppStateVulkan::HandleCreateNewComputePipeline); - assert(isConnected); - } -} - -void rgAppStateVulkan::GetApplicationStylesheet(std::vector& stylesheetFileNames) -{ - stylesheetFileNames.push_back(STR_APPLICATION_STYLESHEET_FILE); - stylesheetFileNames.push_back(STR_APPLICATION_STYLESHEET_FILE_VULKAN); -} - -void rgAppStateVulkan::GetMainWindowStylesheet(std::vector& stylesheetFileNames) -{ - stylesheetFileNames.push_back(STR_MAIN_WINDOW_STYLESHEET_FILE_VULKAN); - stylesheetFileNames.push_back(STR_MAIN_WINDOW_STYLESHEET_FILE); -} - -void rgAppStateVulkan::HandlePipelineStateEvent() -{ - // Switch to the pipeline state view. - rgMenuGraphics* pMenu = m_pBuildView->GetGraphicsFileMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - rgMenuPipelineStateItem* pPsoItem = pMenu->GetPipelineStateItem(); - m_pBuildView->HandlePipelineStateMenuItemClicked(pPsoItem); - } -} - -std::string rgAppStateVulkan::GetGlobalSettingsViewStylesheet() const -{ - const char* STR_VULKAN_APP_SETTINGS_STYLESHEET = - "rgGlobalSettingsView #projectNameCheckBox:focus," - "rgGlobalSettingsView #projectNameCheckBox:hover," - "rgGlobalSettingsView #logFileLocationFolderOpenButton:focus," - "rgGlobalSettingsView #logFileLocationFolderOpenButton:hover," - "rgGlobalSettingsView #defaultApiOnStartupComboBox:focus," - "rgGlobalSettingsView #defaultApiOnStartupComboBox:hover," - "rgGlobalSettingsView #columnVisibilityArrowPushButton:focus," - "rgGlobalSettingsView #columnVisibilityArrowPushButton:hover," - "rgGlobalSettingsView #fontFamilyComboBox:focus," - "rgGlobalSettingsView #fontFamilyComboBox:hover," - "rgGlobalSettingsView #fontSizeComboBox:focus," - "rgGlobalSettingsView #fontSizeComboBox:hover," - "rgGlobalSettingsView #logFileLocationLineEdit:focus," - "rgGlobalSettingsView #logFileLocationLineEdit:hover," - "rgGlobalSettingsView #includeFilesViewerLineEdit:focus," - "rgGlobalSettingsView #includeFilesViewerLineEdit:hover," - "rgGlobalSettingsView #includeFilesViewerBrowseButton:focus," - "rgGlobalSettingsView #includeFilesViewerBrowseButton:hover," - "rgGlobalSettingsView #assocExtGlslLineEdit:focus," - "rgGlobalSettingsView #assocExtGlslLineEdit:hover," - "rgGlobalSettingsView #assocExtSpvBinaryLineEdit:focus," - "rgGlobalSettingsView #assocExtSpvBinaryLineEdit:hover," - "rgGlobalSettingsView #assocExtSpvasLineEdit:focus," - "rgGlobalSettingsView #assocExtSpvasLineEdit:hover," - "rgGlobalSettingsView #assocExtSpvasLabel:focus," - "rgGlobalSettingsView #assocExtSpvasLabel:hover," - "rgGlobalSettingsView #defaultLangComboBox:focus," - "rgGlobalSettingsView #defaultLangComboBox:hover" - "{" - "border: 1px solid rgb(224, 30, 55);" - "background: rgb(240, 240, 240);" - "}"; - return STR_VULKAN_APP_SETTINGS_STYLESHEET; -} - -std::string rgAppStateVulkan::GetBuildSettingsViewStylesheet() const -{ - const char* STR_VULKAN_BUILD_SETTINGS_STYLESHEET = - "rgBuildSettingsView #predefinedMacrosLineEdit:focus," - "rgBuildSettingsView #predefinedMacrosLineEdit:hover," - "rgBuildSettingsView #includeDirectoriesLineEdit:focus," - "rgBuildSettingsView #includeDirectoriesLineEdit:hover," - "rgBuildSettingsView #ICDLocationLineEdit:focus," - "rgBuildSettingsView #ICDLocationLineEdit:hover," - "rgBuildSettingsView #glslangOptionsLineEdit:focus," - "rgBuildSettingsView #glslangOptionsLineEdit:hover," - "rgBuildSettingsView #compilerBinariesLineEdit:focus," - "rgBuildSettingsView #compilerBinariesLineEdit:hover," - "rgBuildSettingsView #compilerIncludesLineEdit:focus," - "rgBuildSettingsView #compilerIncludesLineEdit:hover," - "rgBuildSettingsView #compilerLibrariesLineEdit:focus," - "rgBuildSettingsView #compilerLibrariesLineEdit:hover," - "rgBuildSettingsView #enableValidationLayersCheckBox:focus," - "rgBuildSettingsView #enableValidationLayersCheckBox:hover," - "rgBuildSettingsView #allOptionsTextEdit:focus," - "rgBuildSettingsView #allOptionsTextEdit:hover," - "rgBuildSettingsView #outputFileBinaryNameLineEdit:focus," - "rgBuildSettingsView #outputFileBinaryNameLineEdit:hover" - "{" - "border: 1px solid rgb(224, 30, 55);" - "background: rgb(240, 240, 240);" - "}"; - return STR_VULKAN_BUILD_SETTINGS_STYLESHEET; -} - -void rgAppStateVulkan::OpenFilesInBuildView(const QStringList& filePaths) -{ - // @TODO: Need to implement this method. -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgBrowseButton.cpp b/RadeonGPUAnalyzerGUI/Src/rgBrowseButton.cpp deleted file mode 100644 index 40c3e60..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgBrowseButton.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// Local. -#include - -rgBrowseButton::rgBrowseButton(QWidget* pParent) : QPushButton(pParent) -{ -} - -void rgBrowseButton::focusInEvent(QFocusEvent* pEvent) -{ - emit BrowseButtonFocusInEvent(); - - // Pass the event onto the base class. - QPushButton::focusInEvent(pEvent); -} - -void rgBrowseButton::focusOutEvent(QFocusEvent* pEvent) -{ - emit BrowseButtonFocusOutEvent(); - - // Pass the event onto the base class. - QPushButton::focusOutEvent(pEvent); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgBrowseMissingFileDialog.cpp b/RadeonGPUAnalyzerGUI/Src/rgBrowseMissingFileDialog.cpp deleted file mode 100644 index 303d476..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgBrowseMissingFileDialog.cpp +++ /dev/null @@ -1,198 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include -#include -#include - -// Local. -#include -#include -#include - -rgBrowseMissingFileDialog::rgBrowseMissingFileDialog(rgProjectAPI api, QWidget* pParent) - : QDialog(pParent) - , m_projectAPI(api) -{ - // Setup the UI. - ui.setupUi(this); - - // Workaround to avoid browsing. - ui.browsePushButton->setVisible(false); - ui.cancelPushButton->setVisible(false); - - // Connect the signals. - ConnectSignals(); - - // Create item delegate for the list widget. - m_pItemDelegate = new rgMissingFileItemDelegate(); - bool isDelegateValid = (m_pItemDelegate != nullptr); - assert(isDelegateValid); - - if (isDelegateValid) - { - // Set custom delegate for the list widget. - ui.fileListWidget->setItemDelegate(m_pItemDelegate); - } - - // Disable selection of items. - ui.fileListWidget->setSelectionMode(QAbstractItemView::SingleSelection); - - // Disable the browse button until the user selects a row to update. - ToggleBrowseButtonEnabled(false); - - // Disable the help button in the title bar. - setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); -} - -rgBrowseMissingFileDialog::~rgBrowseMissingFileDialog() -{ - delete m_pItemDelegate; -} - -void rgBrowseMissingFileDialog::ConnectSignals() -{ - // File list's selected row changed handler. - QItemSelectionModel* pFileListSelectionModel = ui.fileListWidget->selectionModel(); - bool isConnected = connect(pFileListSelectionModel, &QItemSelectionModel::selectionChanged, this, &rgBrowseMissingFileDialog::HandleSelectedFilePathChanged); - assert(isConnected); - - // Browse button. - isConnected = connect(ui.browsePushButton, &QPushButton::clicked, this, &rgBrowseMissingFileDialog::HandleBrowseButtonClicked); - assert(isConnected); - - // OK button. - isConnected = connect(ui.okPushButton, &QPushButton::clicked, [=] { done(MissingFileDialogResult::OK); }); - assert(isConnected); - - // Cancel button. - isConnected = connect(ui.cancelPushButton, &QPushButton::clicked, [=] { done(MissingFileDialogResult::Cancel); }); - assert(isConnected); - - isConnected = connect(this, &QDialog::rejected, this, &rgBrowseMissingFileDialog::HandleRejected); - assert(isConnected); -} - -void rgBrowseMissingFileDialog::ToggleBrowseButtonEnabled(bool isEnabled) -{ - ui.browsePushButton->setEnabled(isEnabled); -} - -void rgBrowseMissingFileDialog::AddFile(const std::string filename) -{ - ui.fileListWidget->addItem(filename.c_str()); -} - -const std::map& rgBrowseMissingFileDialog::GetUpdateFilePathsMap() const -{ - return m_updatedPathMap; -} - -void rgBrowseMissingFileDialog::HandleBrowseButtonClicked() -{ - // Use the selection model to determine which path the user wants to update. - QItemSelectionModel* pSelectionModel = ui.fileListWidget->selectionModel(); - assert(pSelectionModel != nullptr); - if (pSelectionModel != nullptr) - { - QModelIndex selectedRowIndex = pSelectionModel->currentIndex(); - int rowIndex = selectedRowIndex.row(); - - BrowseFilePathForRow(rowIndex); - } -} - -void rgBrowseMissingFileDialog::BrowseFilePathForRow(int rowIndex) -{ - QModelIndex selectedRowIndex = ui.fileListWidget->model()->index(rowIndex, 0); - bool isIndexValid = selectedRowIndex.isValid(); - assert(isIndexValid); - - if (isIndexValid) - { - QVariant rowData = selectedRowIndex.data(Qt::DisplayRole); - - // Extract the existing path to the missing file. - const std::string originalFilePath = rowData.toString().toStdString(); - std::string updatedFilePath = originalFilePath; - - // Show a file browser dialog so the user can update the path to the missing file. - bool filePathUpdated = rgUtils::OpenFileDialog(this, m_projectAPI, updatedFilePath); - - // Did the user provide a valid path to replace the missing file's path? - if (filePathUpdated) - { - bool updatedFileExists = rgUtils::IsFileExists(updatedFilePath); - assert(updatedFileExists); - - if (updatedFileExists) - { - // Update the map with the new file paths. - m_updatedPathMap[originalFilePath] = updatedFilePath; - - // Update the list row to display the new updated file path. - ui.fileListWidget->model()->setData(selectedRowIndex, updatedFilePath.c_str()); - } - } - } -} - -void rgBrowseMissingFileDialog::HandleSelectedFilePathChanged(const QItemSelection &selected, const QItemSelection &deselected) -{ - // Toggle the enabledness of the Browse button if necessary. - bool enableBrowse = false; - if (!selected.empty()) - { - QModelIndexList selectedIndices = selected.indexes(); - if (!selectedIndices.empty()) - { - QModelIndex selectedRowIndex = selectedIndices[0]; - if (selectedRowIndex.isValid()) - { - // The browse button should be clickable if the user has selected a valid row. - enableBrowse = true; - } - } - } - - ToggleBrowseButtonEnabled(enableBrowse); -} - -void rgBrowseMissingFileDialog::HandleSelectedRowDoubleClicked(QListWidgetItem* pItem) -{ - int rowIndex = ui.fileListWidget->row(pItem); - - BrowseFilePathForRow(rowIndex); -} - -void rgBrowseMissingFileDialog::HandleRejected() -{ - setResult(MissingFileDialogResult::Cancel); -} - -void rgMissingFileItemDelegate::drawDisplay(QPainter* pPainter, const QStyleOptionViewItem& option, const QRect &rect, const QString& text) const -{ - bool isPainterValid = (pPainter != nullptr); - assert(isPainterValid); - - if (isPainterValid) - { - // Truncate string so it fits within rect. - QString truncatedString = rgUtils::TruncateString(text.toStdString(), gs_TEXT_TRUNCATE_LENGTH_FRONT, - gs_TEXT_TRUNCATE_LENGTH_BACK, rect.width(), pPainter->font(), rgUtils::EXPAND_BACK).c_str(); - - // Draw text within rect. - pPainter->drawText(rect, Qt::AlignVCenter, truncatedString); - } -} - -QSize rgMissingFileItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const -{ - // Use standard size hint implementation, but with a fixed width of 0 (width will be determined by view width). - QSize adjustedHint = QItemDelegate::sizeHint(option, index); - adjustedHint.setWidth(0); - - return adjustedHint; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgBuildSettingsView.cpp b/RadeonGPUAnalyzerGUI/Src/rgBuildSettingsView.cpp deleted file mode 100644 index 42f4479..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgBuildSettingsView.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// C++. -#include - -// Local. -#include -#include - -rgBuildSettingsView::rgBuildSettingsView(QWidget* pParent, bool isGlobalSettings) : - rgSettingsView(pParent), - m_isGlobalSettings(isGlobalSettings) -{ -} - -void rgBuildSettingsView::SetHasPendingChanges(bool hasPendingChanges) -{ - // Only emit the signal if the state of the pending changes is different - // than it was before. - if (m_hasPendingChanges != hasPendingChanges) - { - m_hasPendingChanges = hasPendingChanges; - - emit PendingChangesStateChanged(m_hasPendingChanges); - } -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgBuildSettingsViewOpenCL.cpp b/RadeonGPUAnalyzerGUI/Src/rgBuildSettingsViewOpenCL.cpp deleted file mode 100644 index 1bb4545..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgBuildSettingsViewOpenCL.cpp +++ /dev/null @@ -1,941 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include -#include -#include -#include - -// Infra. -#include -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Checkbox tool tip stylesheets. -static const char* s_STR_FILEMENU_TITLE_BAR_TOOLTIP_WIDTH = "min-width: %1px; width: %2px;"; -static const char* s_STR_FILEMENU_TITLE_BAR_TOOLTIP_HEIGHT = "min-height: %1px; height: %2px; max-height: %3px;"; - -// The delimiter to use to join and split a string of option items. -static const char* s_OPTIONS_LIST_DELIMITER = ";"; - -rgBuildSettingsViewOpenCL::rgBuildSettingsViewOpenCL(QWidget* pParent, const rgBuildSettingsOpenCL& buildSettings, bool isGlobalSettings) : - rgBuildSettingsView(pParent, isGlobalSettings), - m_initialSettings(buildSettings) -{ - // Setup the UI. - ui.setupUi(this); - - // Set the background to white. - QPalette pal = palette(); - pal.setColor(QPalette::Background, Qt::white); - this->setAutoFillBackground(true); - this->setPalette(pal); - - // Create the include directories editor view. - m_pIncludeDirectoriesView = new rgIncludeDirectoriesView(s_OPTIONS_LIST_DELIMITER, this); - - // Create the preprocessor directives editor dialog. - m_pPreprocessorDirectivesDialog = new rgPreprocessorDirectivesDialog(s_OPTIONS_LIST_DELIMITER, this); - - // Connect the signals. - ConnectSignals(); - - // Connect focus in/out events for all of the line edits. - ConnectLineEditFocusEvents(); - - // Connect focus in/out events for all of the checkboxes. - ConnectCheckBoxClickedEvents(); - - // Connect focus in event for the combobox. - ConnectComboboxClickEvent(); - - // Initialize the UI based on the incoming build settings. - PushToWidgets(buildSettings); - - // Initialize the command line preview text. - UpdateCommandLineText(); - - // Set tooltips for general items. - ui.targetGPUsLabel->setToolTip(STR_BUILD_SETTINGS_TARGET_GPUS_TOOLTIP); - ui.predefinedMacrosLabel->setToolTip(STR_BUILD_SETTINGS_PREDEFINED_MACROS_TOOLTIP); - ui.includeDirectoriesLabel->setToolTip(STR_BUILD_SETTINGS_ADDITIONAL_INC_DIRECTORY_TOOLTIP); - - // Set tooltips for alternative compiler components. - ui.alternativeCompilerLabel->setToolTip(STR_BUILD_SETTINGS_ALTERNATIVE_COMPILER_TOOLTIP_GENERIC); - ui.compilerBinariesLabel->setToolTip(CLI_DESC_ALTERNATIVE_ROCM_BIN_FOLDER); - ui.compilerIncludesLabel->setToolTip(CLI_DESC_ALTERNATIVE_ROCM_INC_FOLDER); - ui.compilerLibrariesLabel->setToolTip(CLI_DESC_ALTERNATIVE_ROCM_LIB_FOLDER); - - // Set tooltip for the optimization level item. - ui.optimizationLevelLabel->setToolTip(STR_BUILD_SETTINGS_OPTIMIZATION_LEVEL); - - // Set tooltips for the Settings command line section. - ui.settingsCommandLineHeaderLabel->setToolTip(STR_BUILD_SETTINGS_SETTINGS_CMDLINE_TOOLTIP); - - // Set tooltips for the Additional options line section. - ui.additionalOptionsHeaderLabel->setToolTip(STR_BUILD_SETTINGS_CLANG_OPTIONS_TOOLTIP); - - // Set the tooltip for the General section of the build settings. - ui.generalHeaderLabel->setToolTip(STR_BUILD_SETTINGS_GENERAL_TOOLTIP); - - // Set the tooltip for the command line section of the build settings. - ui.settingsCommandLineHeaderLabel->setToolTip(STR_BUILD_SETTINGS_CMD_LINE_TOOLTIP); - - // Set the mouse cursor to the pointing hand cursor for various widgets. - SetCursor(); - - // Set the geometry of tool tip boxes. - SetToolTipGeometry(); - - // Set the event filter for "Additional Options" and "All Options" text edits. - ui.additionalOptionsTextEdit->installEventFilter(this); - ui.allOptionsTextEdit->installEventFilter(this); - - // Disable tabbing in additional options text edit, so tabbing moves focus to the next widget. - this->ui.additionalOptionsTextEdit->setTabChangesFocus(true); -} - -void rgBuildSettingsViewOpenCL::PushToWidgets(const rgBuildSettingsOpenCL& buildSettings) -{ - // The items below are common build settings for all API types. - QString targetGpusList(rgUtils::BuildSemicolonSeparatedStringList(buildSettings.m_targetGpus).c_str()); - ui.targetGPUsLineEdit->setText(targetGpusList); - - QString predefinedMacros(rgUtils::BuildSemicolonSeparatedStringList(buildSettings.m_predefinedMacros).c_str()); - ui.predefinedMacrosLineEdit->setText(predefinedMacros); - - QString additionalIncludeDirs(rgUtils::BuildSemicolonSeparatedStringList(buildSettings.m_additionalIncludeDirectories).c_str()); - ui.includeDirectoriesLineEdit->setText(additionalIncludeDirs); - - // Items below are OpenCL-specific build settings only. - ui.optimizationLevelComboBox->setCurrentText(buildSettings.m_optimizationLevel.c_str()); - ui.doubleAsSingleCheckBox->setChecked(buildSettings.m_isTreatDoubleAsSingle); - ui.flushDenormalizedCheckBox->setChecked(buildSettings.m_isDenormsAsZeros); - ui.strictAliasingCheckBox->setChecked(buildSettings.m_isStrictAliasing); - ui.enableMADCheckBox->setChecked(buildSettings.m_isEnableMAD); - ui.ignoreZeroSignednessCheckBox->setChecked(buildSettings.m_isIgnoreZeroSignedness); - ui.allowUnsafeOptimizationsCheckBox->setChecked(buildSettings.m_isUnsafeOptimizations); - ui.assumeNoNanNorInfiniteCheckBox->setChecked(buildSettings.m_isNoNanNorInfinite); - ui.aggressiveMathOptimizationsCheckBox->setChecked(buildSettings.m_isAggressiveMathOptimizations); - ui.correctlyRoundSinglePrecisionCheckBox->setChecked(buildSettings.m_isCorrectlyRoundDivSqrt); - ui.additionalOptionsTextEdit->document()->setPlainText(buildSettings.m_additionalOptions.c_str()); - ui.compilerBinariesLineEdit->setText(std::get(buildSettings.m_compilerPaths).c_str()); - ui.compilerIncludesLineEdit->setText(std::get(buildSettings.m_compilerPaths).c_str()); - ui.compilerLibrariesLineEdit->setText(std::get(buildSettings.m_compilerPaths).c_str()); -} - -rgBuildSettingsOpenCL rgBuildSettingsViewOpenCL::PullFromWidgets() const -{ - rgBuildSettingsOpenCL settings; - - // Target GPUs - std::vector targetGPUsVector; - const std::string& commaSeparatedTargetGPUs = ui.targetGPUsLineEdit->text().toStdString(); - rgUtils::splitString(commaSeparatedTargetGPUs, rgConfigManager::RGA_LIST_DELIMITER, targetGPUsVector); - settings.m_targetGpus = targetGPUsVector; - - // Predefined Macros - std::vector predefinedMacrosVector; - const std::string& commaSeparatedPredefinedMacros = ui.predefinedMacrosLineEdit->text().toStdString(); - rgUtils::splitString(commaSeparatedPredefinedMacros, rgConfigManager::RGA_LIST_DELIMITER, predefinedMacrosVector); - settings.m_predefinedMacros = predefinedMacrosVector; - - // Additional Include Directories - std::vector additionalIncludeDirectoriesVector; - const std::string& commaSeparatedAdditionalIncludeDirectories = ui.includeDirectoriesLineEdit->text().toStdString(); - rgUtils::splitString(commaSeparatedAdditionalIncludeDirectories, rgConfigManager::RGA_LIST_DELIMITER, additionalIncludeDirectoriesVector); - settings.m_additionalIncludeDirectories = additionalIncludeDirectoriesVector; - - // AdditionalOptions: - settings.m_additionalOptions = ui.additionalOptionsTextEdit->document()->toPlainText().toStdString(); - - // AlternativeCompilerBinDir: - std::get(settings.m_compilerPaths) = ui.compilerBinariesLineEdit->text().toStdString(); - - // AlternativeCompilerIncDir: - std::get(settings.m_compilerPaths) = ui.compilerIncludesLineEdit->text().toStdString(); - - // AlternativeCompilerLibDir: - std::get(settings.m_compilerPaths) = ui.compilerLibrariesLineEdit->text().toStdString(); - - - // OpenCL Specific Settings - - // OptimizationLevel: - settings.m_optimizationLevel = ui.optimizationLevelComboBox->currentText().toStdString(); - - // TreatDoubleFloatingPointAsSingle: - settings.m_isTreatDoubleAsSingle = ui.doubleAsSingleCheckBox->isChecked(); - - // FlushDenormalizedFloatsAsZero: - settings.m_isDenormsAsZeros = ui.flushDenormalizedCheckBox->isChecked(); - - // AssumeStrictAliasingRules: - settings.m_isStrictAliasing = ui.strictAliasingCheckBox->isChecked(); - - // EnableMADInstructions: - settings.m_isEnableMAD = ui.enableMADCheckBox->isChecked(); - - //IgnoreSignednessOfZeros: - settings.m_isIgnoreZeroSignedness = ui.ignoreZeroSignednessCheckBox->isChecked(); - - // AllowUnsafeOptimizations: - settings.m_isUnsafeOptimizations = ui.allowUnsafeOptimizationsCheckBox->isChecked(); - - // AssumeNoNaNNorInfinite: - settings.m_isNoNanNorInfinite = ui.assumeNoNanNorInfiniteCheckBox->isChecked(); - - // AgressiveMathOptimizations: - settings.m_isAggressiveMathOptimizations = ui.aggressiveMathOptimizationsCheckBox->isChecked(); - - // CorrectlyRoundSingleDivideAndSqrt: - settings.m_isCorrectlyRoundDivSqrt = ui.correctlyRoundSinglePrecisionCheckBox->isChecked(); - - return settings; -} - -void rgBuildSettingsViewOpenCL::ConnectSignals() -{ - // Add target GPU button. - bool isConnected = connect(this->ui.addTargetGPUsButton, &QPushButton::clicked, this, &rgBuildSettingsViewOpenCL::HandleAddTargetGpusButtonClick); - assert(isConnected); - - // Add include directories editor dialog button. - isConnected = connect(this->ui.includeDirsBrowseButton, &QPushButton::clicked, this, &rgBuildSettingsViewOpenCL::HandleIncludeDirsBrowseButtonClick); - assert(isConnected); - - // Add preprocessor directives editor dialog button. - isConnected = connect(this->ui.predefinedMacrosBrowseButton, &QPushButton::clicked, this, &rgBuildSettingsViewOpenCL::HandlePreprocessorDirectivesBrowseButtonClick); - assert(isConnected); - - // Connect all textboxes within the view. - isConnected = connect(this->ui.targetGPUsLineEdit, &QLineEdit::textChanged, this, &rgBuildSettingsViewOpenCL::HandleTextEditChanged); - assert(isConnected); - - isConnected = connect(this->ui.predefinedMacrosLineEdit, &QLineEdit::textChanged, this, &rgBuildSettingsViewOpenCL::HandleTextEditChanged); - assert(isConnected); - - isConnected = connect(this->ui.includeDirectoriesLineEdit, &QLineEdit::textChanged, this, &rgBuildSettingsViewOpenCL::HandleTextEditChanged); - assert(isConnected); - - isConnected = connect(this->ui.optimizationLevelComboBox, static_cast(&QComboBox::currentIndexChanged), this, &rgBuildSettingsViewOpenCL::HandleComboboxIndexChanged); - assert(isConnected); - - isConnected = connect(this->ui.doubleAsSingleCheckBox, &rgCheckBox::stateChanged, this, &rgBuildSettingsViewOpenCL::HandleCheckboxStateChanged); - assert(isConnected); - - isConnected = connect(this->ui.flushDenormalizedCheckBox, &rgCheckBox::stateChanged, this, &rgBuildSettingsViewOpenCL::HandleCheckboxStateChanged); - assert(isConnected); - - isConnected = connect(this->ui.strictAliasingCheckBox, &rgCheckBox::stateChanged, this, &rgBuildSettingsViewOpenCL::HandleCheckboxStateChanged); - assert(isConnected); - - isConnected = connect(this->ui.enableMADCheckBox, &rgCheckBox::stateChanged, this, &rgBuildSettingsViewOpenCL::HandleCheckboxStateChanged); - assert(isConnected); - - isConnected = connect(this->ui.ignoreZeroSignednessCheckBox, &rgCheckBox::stateChanged, this, &rgBuildSettingsViewOpenCL::HandleCheckboxStateChanged); - assert(isConnected); - - isConnected = connect(this->ui.allowUnsafeOptimizationsCheckBox, &rgCheckBox::stateChanged, this, &rgBuildSettingsViewOpenCL::HandleCheckboxStateChanged); - assert(isConnected); - - isConnected = connect(this->ui.assumeNoNanNorInfiniteCheckBox, &rgCheckBox::stateChanged, this, &rgBuildSettingsViewOpenCL::HandleCheckboxStateChanged); - assert(isConnected); - - isConnected = connect(this->ui.aggressiveMathOptimizationsCheckBox, &rgCheckBox::stateChanged, this, &rgBuildSettingsViewOpenCL::HandleCheckboxStateChanged); - assert(isConnected); - - isConnected = connect(this->ui.correctlyRoundSinglePrecisionCheckBox, &rgCheckBox::stateChanged, this, &rgBuildSettingsViewOpenCL::HandleCheckboxStateChanged); - assert(isConnected); - - // Connect "Additional Options" text box. - isConnected = connect(this->ui.additionalOptionsTextEdit, &QPlainTextEdit::textChanged, this, &rgBuildSettingsViewOpenCL::HandleAdditionalOptionsTextChanged); - assert(isConnected); - - // Connect Alternative Compiler folders browse buttons. - isConnected = connect(this->ui.compilerBinariesBrowseButton, &QPushButton::clicked, this, [&]() { HandleCompilerFolderBrowseButtonClick(CompilerFolderType::Bin); }); - assert(isConnected); - isConnected = connect(this->ui.compilerIncludesBrowseButton, &QPushButton::clicked, this, [&]() { HandleCompilerFolderBrowseButtonClick(CompilerFolderType::Include); }); - assert(isConnected); - isConnected = connect(this->ui.compilerLibrariesBrowseButton, &QPushButton::clicked, this, [&]() { HandleCompilerFolderBrowseButtonClick(CompilerFolderType::Lib); }); - assert(isConnected); - - // Connect Alternative Compiler folders text edits. - isConnected = connect(this->ui.compilerBinariesLineEdit, &QLineEdit::textChanged, this, [&]() { HandleCompilerFolderEditChanged(CompilerFolderType::Bin); }); - assert(isConnected); - isConnected = connect(this->ui.compilerIncludesLineEdit, &QLineEdit::textChanged, this, [&]() { HandleCompilerFolderEditChanged(CompilerFolderType::Include); }); - assert(isConnected); - isConnected = connect(this->ui.compilerLibrariesLineEdit, &QLineEdit::textChanged, this, [&]() { HandleCompilerFolderEditChanged(CompilerFolderType::Lib); }); - assert(isConnected); - - // Connect the include directory editor dialog's "OK" button click. - isConnected = connect(m_pIncludeDirectoriesView, &rgIncludeDirectoriesView::OKButtonClicked, this, &rgBuildSettingsViewOpenCL::HandleIncludeDirsUpdated); - assert(isConnected); - - // Connect the preprocessor directives editor dialog's "OK" button click. - isConnected = connect(m_pPreprocessorDirectivesDialog, &rgPreprocessorDirectivesDialog::OKButtonClicked, this, &rgBuildSettingsViewOpenCL::HandlePreprocessorDirectivesUpdated); - assert(isConnected); -} - -void rgBuildSettingsViewOpenCL::ConnectLineEditFocusEvents() -{ - bool isConnected = false; - - isConnected = connect(this->ui.includeDirectoriesLineEdit, &rgLineEdit::LineEditFocusInEvent, this, &rgBuildSettingsViewOpenCL::HandleLineEditFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.includeDirectoriesLineEdit, &rgLineEdit::LineEditFocusOutEvent, this, &rgBuildSettingsViewOpenCL::HandleLineEditFocusOutEvent); - assert(isConnected); - - isConnected = connect(this->ui.predefinedMacrosLineEdit, &rgLineEdit::LineEditFocusInEvent, this, &rgBuildSettingsViewOpenCL::HandleLineEditFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.predefinedMacrosLineEdit, &rgLineEdit::LineEditFocusOutEvent, this, &rgBuildSettingsViewOpenCL::HandleLineEditFocusOutEvent); - assert(isConnected); - - isConnected = connect(this->ui.targetGPUsLineEdit, &rgLineEdit::LineEditFocusInEvent, this, &rgBuildSettingsViewOpenCL::HandleLineEditFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.targetGPUsLineEdit, &rgLineEdit::LineEditFocusOutEvent, this, &rgBuildSettingsViewOpenCL::HandleLineEditFocusOutEvent); - assert(isConnected); - - isConnected = connect(this->ui.compilerBinariesLineEdit, &rgLineEdit::LineEditFocusInEvent, this, &rgBuildSettingsViewOpenCL::HandleLineEditFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.compilerBinariesLineEdit, &rgLineEdit::LineEditFocusOutEvent, this, &rgBuildSettingsViewOpenCL::HandleLineEditFocusOutEvent); - assert(isConnected); - - isConnected = connect(this->ui.compilerIncludesLineEdit, &rgLineEdit::LineEditFocusInEvent, this, &rgBuildSettingsViewOpenCL::HandleLineEditFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.compilerIncludesLineEdit, &rgLineEdit::LineEditFocusOutEvent, this, &rgBuildSettingsViewOpenCL::HandleLineEditFocusOutEvent); - assert(isConnected); - - isConnected = connect(this->ui.compilerLibrariesLineEdit, &rgLineEdit::LineEditFocusInEvent, this, &rgBuildSettingsViewOpenCL::HandleLineEditFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.compilerLibrariesLineEdit, &rgLineEdit::LineEditFocusOutEvent, this, &rgBuildSettingsViewOpenCL::HandleLineEditFocusOutEvent); - assert(isConnected); -} - -void rgBuildSettingsViewOpenCL::ConnectCheckBoxClickedEvents() -{ - bool isConnected = false; - - isConnected = connect(this->ui.aggressiveMathOptimizationsCheckBox, &rgCheckBox::clicked, this, &rgBuildSettingsViewOpenCL::HandleCheckBoxClickedEvent); - assert(isConnected); - - isConnected = connect(this->ui.allowUnsafeOptimizationsCheckBox, &rgCheckBox::clicked, this, &rgBuildSettingsViewOpenCL::HandleCheckBoxClickedEvent); - assert(isConnected); - - isConnected = connect(this->ui.assumeNoNanNorInfiniteCheckBox, &rgCheckBox::clicked, this, &rgBuildSettingsViewOpenCL::HandleCheckBoxClickedEvent); - assert(isConnected); - - isConnected = connect(this->ui.correctlyRoundSinglePrecisionCheckBox, &rgCheckBox::clicked, this, &rgBuildSettingsViewOpenCL::HandleCheckBoxClickedEvent); - assert(isConnected); - - isConnected = connect(this->ui.doubleAsSingleCheckBox, &rgCheckBox::clicked, this, &rgBuildSettingsViewOpenCL::HandleCheckBoxClickedEvent); - assert(isConnected); - - isConnected = connect(this->ui.enableMADCheckBox, &rgCheckBox::clicked, this, &rgBuildSettingsViewOpenCL::HandleCheckBoxClickedEvent); - assert(isConnected); - - isConnected = connect(this->ui.flushDenormalizedCheckBox, &rgCheckBox::clicked, this, &rgBuildSettingsViewOpenCL::HandleCheckBoxClickedEvent); - assert(isConnected); - - isConnected = connect(this->ui.ignoreZeroSignednessCheckBox, &rgCheckBox::clicked, this, &rgBuildSettingsViewOpenCL::HandleCheckBoxClickedEvent); - assert(isConnected); - - isConnected = connect(this->ui.strictAliasingCheckBox, &rgCheckBox::clicked, this, &rgBuildSettingsViewOpenCL::HandleCheckBoxClickedEvent); - assert(isConnected); -} - -void rgBuildSettingsViewOpenCL::ConnectComboboxClickEvent() -{ - bool isConnected = connect(this->ui.optimizationLevelComboBox, &rgComboBox::ComboBoxFocusInEvent, this, &rgBuildSettingsViewOpenCL::HandleComboBoxFocusInEvent); - assert(isConnected); -} - -bool rgBuildSettingsViewOpenCL::eventFilter(QObject* pObject, QEvent* pEvent) -{ - // Intercept events for "Additional "Options" widget. - if (pEvent != nullptr) - { - if (pEvent->type() == QEvent::FocusIn) - { - HandleLineEditFocusInEvent(); - } - else if (pEvent->type() == QEvent::FocusOut) - { - HandleLineEditFocusOutEvent(); - } - } - - // Continue default processing. - return QObject::eventFilter(pObject, pEvent); -} - -void rgBuildSettingsViewOpenCL::HandleAddTargetGpusButtonClick() -{ - // Trim out any spaces within the target GPUs string. - QString selectedGPUs = this->ui.targetGPUsLineEdit->text(); - - // Create a new Target GPU Selection dialog instance. - m_pTargetGpusDialog = new rgTargetGpusDialog(selectedGPUs, this); - - // Register the target gpu dialog box with the scaling manager. - ScalingManager::Get().RegisterObject(m_pTargetGpusDialog); - - // Center the dialog on the view (registering with the scaling manager - // shifts it out of the center so we need to manually center it). - rgUtils::CenterOnWidget(m_pTargetGpusDialog, this); - - // Present the dialog to the user. - m_pTargetGpusDialog->setModal(true); - int dialogResult = m_pTargetGpusDialog->exec(); - - // If the user clicked "OK", extract the Checked items into a comma-separated string, - // and put the string in the Target GPUs textbox. - if (dialogResult == 1) - { - // After the dialog is hidden, extract the list of families selected by the user. - std::vector selectedFamilies = m_pTargetGpusDialog->GetSelectedCapabilityGroups(); - - // Remove gfx notation if needed. - std::transform(selectedFamilies.begin(), selectedFamilies.end(), selectedFamilies.begin(), - [&](std::string& family) - { - return rgUtils::RemoveGfxNotation(family); - }); - - // Create a comma-separated list of GPU families that the user selected. - std::stringstream familyListString; - size_t numFamilies = selectedFamilies.size(); - for (size_t familyIndex = 0; familyIndex < numFamilies; ++familyIndex) - { - // Append the family name to the string. - familyListString << selectedFamilies[familyIndex]; - - // Append a comma between each family name, until the last one. - if ((familyIndex + 1) < numFamilies) - { - familyListString << rgConfigManager::RGA_LIST_DELIMITER; - } - } - - // Set the target GPUs text. - ui.targetGPUsLineEdit->setText(familyListString.str().c_str()); - - // Inform the UI of a possible change to the pending state. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - } -} - -void rgBuildSettingsViewOpenCL::HandleTextEditChanged() -{ - // Determine which control's text has been updated. - QLineEdit* pLineEdit = static_cast(QObject::sender()); - assert(pLineEdit != nullptr); - if (pLineEdit != nullptr) - { - // Inform the UI of a possible change to the pending state. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - - // Update the command line preview text. - UpdateCommandLineText(); - } -} - -void rgBuildSettingsViewOpenCL::HandleComboboxIndexChanged(int index) -{ - // Determine which control's text has been updated. - QComboBox *pComboBox = static_cast(QObject::sender()); - assert(pComboBox != nullptr); - if (pComboBox != nullptr) - { - // Inform the UI of a possible change to the pending state. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - - // Update the command line preview text. - UpdateCommandLineText(); - } -} - -void rgBuildSettingsViewOpenCL::HandleCheckboxStateChanged() -{ - // Determine which control's text has been updated. - QCheckBox* pCheckBox = static_cast(QObject::sender()); - assert(pCheckBox != nullptr); - if (pCheckBox != nullptr) - { - // Inform the UI of a possible change to the pending state. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - - // Update the command line preview text. - UpdateCommandLineText(); - } -} - -std::string rgBuildSettingsViewOpenCL::GetTitleString() -{ - std::stringstream titleString; - - // Build the title string. - if (m_isGlobalSettings) - { - // For the global settings. - titleString << STR_BUILD_SETTINGS_DEFAULT_TITLE; - titleString << " "; - titleString << STR_API_NAME_OPENCL; - titleString << " "; - } - else - { - // For project-specific settings. - titleString << STR_BUILD_SETTINGS_PROJECT_TITLE; - titleString << " "; - } - titleString << STR_MENU_BUILD_SETTINGS_LOWER; - - return titleString.str(); -} - -const std::string rgBuildSettingsViewOpenCL::GetTitleTooltipString() const -{ - std::stringstream tooltipString; - - if (m_isGlobalSettings) - { - tooltipString << STR_BUILD_SETTINGS_GLOBAL_TOOLTIP_A; - tooltipString << STR_API_NAME_OPENCL; - tooltipString << STR_BUILD_SETTINGS_GLOBAL_TOOLTIP_B; - } - else - { - tooltipString << STR_BUILD_SETTINGS_PROJECT_TOOLTIP_A; - tooltipString << STR_API_NAME_OPENCL; - tooltipString << STR_BUILD_SETTINGS_PROJECT_TOOLTIP_B; - } - - return tooltipString.str(); -} - -void rgBuildSettingsViewOpenCL::HandlePendingChangesStateChanged(bool hasPendingChanges) -{ - // Let the base class determine if there is a need to signal listeners - // about the pending changes state. - rgBuildSettingsView::SetHasPendingChanges(hasPendingChanges); -} - -void rgBuildSettingsViewOpenCL::UpdateCommandLineText() -{ - rgBuildSettingsOpenCL apiBuildSetting = PullFromWidgets(); - - // Generate a command line string from the build settings structure. - std::string buildSettings; - bool ret = rgCliUtils::GenerateOpenClBuildSettingsString(apiBuildSetting, buildSettings, false); - assert(ret); - if (ret) - { - ui.allOptionsTextEdit->setPlainText(buildSettings.c_str()); - } -} - -bool rgBuildSettingsViewOpenCL::IsTargetGpusStringValid(std::vector& errors) const -{ - bool isValid = true; - - // The target GPUs string must be non-empty. - std::string targetGpusString = ui.targetGPUsLineEdit->text().toStdString(); - if (targetGpusString.empty()) - { - // The Target GPUs field is invalid since it is empty. - errors.push_back(STR_ERR_TARGET_GPUS_CANNOT_BE_EMPTY); - isValid = false; - } - else - { - // Split the comma-separated GPUs string. - std::vector targetGPUsVector; - rgUtils::splitString(targetGpusString, rgConfigManager::RGA_LIST_DELIMITER, targetGPUsVector); - - // Use the Config Manager to verify that the specified GPUs are valid. - std::vector invalidGpus; - rgConfigManager& configManager = rgConfigManager::Instance(); - for (const std::string& targetGpuFamilyName : targetGPUsVector) - { - std::string trimmedName; - rgUtils::TrimLeadingAndTrailingWhitespace(targetGpuFamilyName, trimmedName); - - // Is the given target GPU family name supported? - if (!configManager.IsGpuFamilySupported(trimmedName)) - { - // Add the GPU to a list of invalid names if it's not supported. - invalidGpus.push_back(trimmedName); - } - } - - if (!invalidGpus.empty()) - { - // Build an error string indicating the invalid GPUs. - std::stringstream errorStream; - errorStream << STR_ERR_INVALID_GPUS_SPECIFIED; - - int numInvalid = static_cast(invalidGpus.size()); - for (int gpuIndex = 0; gpuIndex < numInvalid; ++gpuIndex) - { - errorStream << invalidGpus[gpuIndex]; - - if (gpuIndex != (numInvalid - 1)) - { - errorStream << ", "; - } - } - - // Add an error field indicating that the GPU name is invalid. - errors.push_back(errorStream.str()); - isValid = false; - } - } - - return isValid; -} - -bool rgBuildSettingsViewOpenCL::ValidatePendingSettings() -{ - std::vector errors; - bool isValid = IsTargetGpusStringValid(errors); - if (!isValid) - { - std::stringstream errorStream; - errorStream << STR_ERR_INVALID_PENDING_SETTING; - errorStream << std::endl; - - // Loop through all errors and append them to the stream. - for (const std::string errorString : errors) - { - errorStream << errorString; - errorStream << std::endl; - } - - // Display an error message box to the user telling them what to fix. - rgUtils::ShowErrorMessageBox(errorStream.str().c_str(), this); - } - - return isValid; -} - -void rgBuildSettingsViewOpenCL::SetCursor() -{ - // Set the cursor to pointing hand cursor. - ui.addTargetGPUsButton->setCursor(Qt::PointingHandCursor); - ui.aggressiveMathOptimizationsCheckBox->setCursor(Qt::PointingHandCursor); - ui.allowUnsafeOptimizationsCheckBox->setCursor(Qt::PointingHandCursor); - ui.assumeNoNanNorInfiniteCheckBox->setCursor(Qt::PointingHandCursor); - ui.correctlyRoundSinglePrecisionCheckBox->setCursor(Qt::PointingHandCursor); - ui.doubleAsSingleCheckBox->setCursor(Qt::PointingHandCursor); - ui.enableMADCheckBox->setCursor(Qt::PointingHandCursor); - ui.flushDenormalizedCheckBox->setCursor(Qt::PointingHandCursor); - ui.ignoreZeroSignednessCheckBox->setCursor(Qt::PointingHandCursor); - ui.strictAliasingCheckBox->setCursor(Qt::PointingHandCursor); - ui.optimizationLevelComboBox->setCursor(Qt::PointingHandCursor); - ui.includeDirsBrowseButton->setCursor(Qt::PointingHandCursor); - ui.predefinedMacrosBrowseButton->setCursor(Qt::PointingHandCursor); - - // Set the cursor for alternative compiler buttons. - ui.compilerBinariesBrowseButton->setCursor(Qt::PointingHandCursor); - ui.compilerIncludesBrowseButton->setCursor(Qt::PointingHandCursor); - ui.compilerLibrariesBrowseButton->setCursor(Qt::PointingHandCursor); -} - -void rgBuildSettingsViewOpenCL::HandleIncludeDirsBrowseButtonClick() -{ - // Position the window in the middle of the screen. - m_pIncludeDirectoriesView->setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, m_pIncludeDirectoriesView->size(), qApp->desktop()->availableGeometry())); - - // Set the current include dirs. - m_pIncludeDirectoriesView->SetListItems(ui.includeDirectoriesLineEdit->text()); - - // Show the window. - m_pIncludeDirectoriesView->exec(); -} - -void rgBuildSettingsViewOpenCL::HandleIncludeDirsUpdated(QStringList includeDirs) -{ - QString includeDirsText; - - // Create a delimiter-separated string. - if (!includeDirs.isEmpty()) - { - includeDirsText = includeDirs.join(s_OPTIONS_LIST_DELIMITER); - } - - // Update the text box. - ui.includeDirectoriesLineEdit->setText(includeDirsText); -} - -void rgBuildSettingsViewOpenCL::HandlePreprocessorDirectivesBrowseButtonClick() -{ - // Position the window in the middle of the screen. - m_pPreprocessorDirectivesDialog->setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, m_pPreprocessorDirectivesDialog->size(), qApp->desktop()->availableGeometry())); - - // Set the current preprocessor directives in the dialog. - m_pPreprocessorDirectivesDialog->SetListItems(ui.predefinedMacrosLineEdit->text()); - - // Show the dialog. - m_pPreprocessorDirectivesDialog->exec(); -} - -void rgBuildSettingsViewOpenCL::HandlePreprocessorDirectivesUpdated(QStringList preprocessorDirectives) -{ - QString preprocessorDirectivesText; - - // Create a delimiter-separated string. - if (!preprocessorDirectives.isEmpty()) - { - preprocessorDirectivesText = preprocessorDirectives.join(s_OPTIONS_LIST_DELIMITER); - } - - // Update the text box. - ui.predefinedMacrosLineEdit->setText(preprocessorDirectivesText); -} - -void rgBuildSettingsViewOpenCL::HandleAdditionalOptionsTextChanged() -{ - // Inform the UI of a possible change to the pending state. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - - // Update the command line preview text. - UpdateCommandLineText(); -} - -void rgBuildSettingsViewOpenCL::SetToolTipGeometry() -{ - // Get the font metrics. - QFontMetrics fontMetrics(ui.doubleAsSingleCheckBox->font()); - - // Use the width of an edit box as width of the tooltip string. - const int width = ui.includeDirectoriesLineEdit->width(); - - // Calculate the height of the tooltip string. - const int height = fontMetrics.height() * ScalingManager::Get().GetScaleFactor(); - - // Create a width and a height string. - const QString widthString = QString(s_STR_FILEMENU_TITLE_BAR_TOOLTIP_WIDTH).arg(width).arg(width); - const QString heightString = QString(s_STR_FILEMENU_TITLE_BAR_TOOLTIP_HEIGHT).arg(height).arg(height).arg(height); - - // Set the stylesheet. - ui.doubleAsSingleCheckBox->setStyleSheet("QToolTip {" + widthString + heightString + "}"); - ui.flushDenormalizedCheckBox->setStyleSheet("QToolTip {" + widthString + "}"); - ui.aggressiveMathOptimizationsCheckBox->setStyleSheet("QToolTip {" + widthString + "}"); - ui.allowUnsafeOptimizationsCheckBox->setStyleSheet("QToolTip {" + widthString + "}"); - ui.assumeNoNanNorInfiniteCheckBox->setStyleSheet("QToolTip {" + widthString + "}"); - ui.correctlyRoundSinglePrecisionCheckBox->setStyleSheet("QToolTip {" + widthString + "}"); - ui.doubleAsSingleCheckBox->setStyleSheet("QToolTip {" + widthString + "}"); - ui.enableMADCheckBox->setStyleSheet("QToolTip {" + widthString + "}"); - ui.ignoreZeroSignednessCheckBox->setStyleSheet("QToolTip {" + widthString + "}"); - ui.strictAliasingCheckBox->setStyleSheet("QToolTip {" + widthString + "}"); - ui.additionalOptionsHeaderLabel->setStyleSheet("QToolTip {" + widthString + "}"); -} - -void rgBuildSettingsViewOpenCL::HandleLineEditFocusInEvent() -{ - emit SetFrameBorderGreenSignal(); -} - -void rgBuildSettingsViewOpenCL::HandleLineEditFocusOutEvent() -{ - emit SetFrameBorderBlackSignal(); -} - -void rgBuildSettingsViewOpenCL::HandleCheckBoxClickedEvent() -{ - emit SetFrameBorderGreenSignal(); -} - -void rgBuildSettingsViewOpenCL::HandleComboBoxFocusInEvent() -{ - emit SetFrameBorderGreenSignal(); -} - -void rgBuildSettingsViewOpenCL::HandleCompilerFolderBrowseButtonClick(CompilerFolderType folderType) -{ - QFileDialog fileDialog; - - // If existing text in the line edit is not empty, pass it to the File Dialog. - // Otherwise, get the latest entry from the directories list and open the dialog there. - QLineEdit* pLineEdit = (folderType == CompilerFolderType::Bin ? ui.compilerBinariesLineEdit : - (folderType == CompilerFolderType::Include ? ui.compilerIncludesLineEdit : ui.compilerLibrariesLineEdit)); - assert(pLineEdit != nullptr); - if (pLineEdit != nullptr) - { - QString currentDir = (pLineEdit->text().isEmpty() ? QString::fromStdString(rgConfigManager::Instance().GetLastSelectedFolder()) : pLineEdit->text()); - - QString selectedDirectory = QFileDialog::getExistingDirectory(this, tr(STR_INCLUDE_DIR_DIALOG_SELECT_DIR_TITLE), - currentDir, QFileDialog::ShowDirsOnly); - if (!selectedDirectory.isEmpty()) - { - switch (folderType) - { - case CompilerFolderType::Bin: ui.compilerBinariesLineEdit->setText(selectedDirectory); break; - case CompilerFolderType::Include: ui.compilerIncludesLineEdit->setText(selectedDirectory); break; - case CompilerFolderType::Lib: ui.compilerLibrariesLineEdit->setText(selectedDirectory); break; - default: assert(false); - } - } - } -} - -void rgBuildSettingsViewOpenCL::HandleCompilerFolderEditChanged(CompilerFolderType folderType) -{ - auto pTextEdit = qobject_cast(QObject::sender()); - assert(pTextEdit != nullptr); - if (pTextEdit != nullptr) - { - // Inform the UI of a possible change to the pending state. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - } - - // Update the command line preview text. - UpdateCommandLineText(); -} - -bool rgBuildSettingsViewOpenCL::GetHasPendingChanges() const -{ - bool ret = false; - - rgBuildSettingsOpenCL apiBuildSettings = PullFromWidgets(); - - ret = !m_initialSettings.HasSameSettings(apiBuildSettings); - - return ret; -} - -bool rgBuildSettingsViewOpenCL::RevertPendingChanges() -{ - PushToWidgets(m_initialSettings); - - // Inform the UI of a possible change to the pending state. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - - return false; -} - -void rgBuildSettingsViewOpenCL::RestoreDefaultSettings() -{ - bool isRestored = false; - - if (m_isGlobalSettings) - { - // If this is for the global settings, then restore to the hard-coded defaults. - - // Get the hard-coded default build settings. - std::shared_ptr pDefaultBuildSettings = rgConfigManager::GetDefaultBuildSettings(rgProjectAPI::OpenCL); - - std::shared_ptr pApiBuildSettings = std::dynamic_pointer_cast(pDefaultBuildSettings); - assert(pApiBuildSettings != nullptr); - if (pApiBuildSettings != nullptr) - { - // Reset our initial settings back to the defaults. - m_initialSettings = *pApiBuildSettings; - - // Update the UI to reflect the new initial settings. - PushToWidgets(m_initialSettings); - - // Update the ConfigManager to use the new settings. - rgConfigManager::Instance().SetApiBuildSettings(STR_API_NAME_OPENCL, &m_initialSettings); - - // Save the settings file - isRestored = rgConfigManager::Instance().SaveGlobalConfigFile(); - - // Inform the rest of the UI that the settings have been changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - } - } - else - { - // This view is showing project-specific settings, so restore back to the stored settings in the project. - std::shared_ptr pDefaultSettings = rgConfigManager::Instance().GetUserGlobalBuildSettings(rgProjectAPI::OpenCL); - auto pCLDefaultSettings = std::dynamic_pointer_cast(pDefaultSettings); - - m_initialSettings = *pCLDefaultSettings; - - PushToWidgets(m_initialSettings); - - // Inform the rest of the UI that the settings have been changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - - // Let the rgBuildView know that the build settings have been updated. - emit ProjectBuildSettingsSaved(pCLDefaultSettings); - isRestored = true; - } - - // Show an error dialog if the settings failed to be reset. - if (!isRestored) - { - rgUtils::ShowErrorMessageBox(STR_ERR_CANNOT_RESTORE_DEFAULT_SETTINGS, this); - } -} - -bool rgBuildSettingsViewOpenCL::SaveSettings() -{ - bool isValid = ValidatePendingSettings(); - if (isValid) - { - // Reset the initial settings to match what the UI shows. - m_initialSettings = PullFromWidgets(); - - if (m_isGlobalSettings) - { - // Update the config manager to use these new settings. - rgConfigManager& configManager = rgConfigManager::Instance(); - configManager.SetApiBuildSettings(STR_API_NAME_OPENCL, &m_initialSettings); - - // Save the global config settings. - isValid = configManager.SaveGlobalConfigFile(); - } - else - { - // Save the project settings. - std::shared_ptr pTmpPtr = std::make_shared(m_initialSettings); - emit ProjectBuildSettingsSaved(pTmpPtr); - } - - if (isValid) - { - // Make sure the rest of the UI knows that the settings have been saved. - HandlePendingChangesStateChanged(false); - } - } - - // Set focus to target GPUs browse button. - ui.addTargetGPUsButton->setFocus(); - - return isValid; -} - -void rgBuildSettingsViewOpenCL::mousePressEvent(QMouseEvent* pEvent) -{ - Q_UNUSED(pEvent); - - emit SetFrameBorderGreenSignal(); -} - -void rgBuildSettingsViewOpenCL::SetInitialWidgetFocus() -{ - ui.addTargetGPUsButton->setFocus(); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgBuildSettingsViewVulkan.cpp b/RadeonGPUAnalyzerGUI/Src/rgBuildSettingsViewVulkan.cpp deleted file mode 100644 index d9da8c8..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgBuildSettingsViewVulkan.cpp +++ /dev/null @@ -1,997 +0,0 @@ -// C++. -#include -#include -#include - -// Qt. -#include -#include -#include -#include - -// Infra. -#include -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Checkbox tool tip stylesheets. -static const char* s_STR_FILEMENU_TITLE_BAR_TOOLTIP_WIDTH = "min-width: %1px; width: %2px;"; -static const char* s_STR_FILEMENU_TITLE_BAR_TOOLTIP_HEIGHT = "min-height: %1px; height: %2px; max-height: %3px;"; - -// The delimiter to use to join and split a string of option items. -static const char* s_OPTIONS_LIST_DELIMITER = ";"; - -rgBuildSettingsViewVulkan::rgBuildSettingsViewVulkan(QWidget* pParent, const rgBuildSettingsVulkan& buildSettings, bool isGlobalSettings) : - rgBuildSettingsView(pParent, isGlobalSettings), - m_initialSettings(buildSettings) -{ - // Setup the UI. - ui.setupUi(this); - - // Set the background to white. - QPalette pal = palette(); - pal.setColor(QPalette::Background, Qt::white); - this->setAutoFillBackground(true); - this->setPalette(pal); - - // Create the include directories editor view. - m_pIncludeDirectoriesView = new rgIncludeDirectoriesView(s_OPTIONS_LIST_DELIMITER, this); - - // Create the preprocessor directives editor dialog. - m_pPreprocessorDirectivesDialog = new rgPreprocessorDirectivesDialog(s_OPTIONS_LIST_DELIMITER, this); - - // Connect the signals. - ConnectSignals(); - - // Connect focus in/out events for all of the line edits. - ConnectLineEditFocusEvents(); - - // Connect clicked events for check boxes. - ConnectCheckBoxClickedEvents(); - - // Initialize the UI based on the incoming build settings. - PushToWidgets(buildSettings); - - // Initialize the command line preview text. - UpdateCommandLineText(); - - // Set tooltips for general items. - ui.targetGPUsLabel->setToolTip(STR_BUILD_SETTINGS_TARGET_GPUS_TOOLTIP); - ui.predefinedMacrosLabel->setToolTip(STR_BUILD_SETTINGS_PREDEFINED_MACROS_TOOLTIP); - ui.includeDirectoriesLabel->setToolTip(STR_BUILD_SETTINGS_ADDITIONAL_INC_DIRECTORY_TOOLTIP); - - // Set tooltip for Vulkan runtime section. - ui.vulkanOptionsHeaderLabel->setToolTip(STR_BUILD_SETTINGS_VULKAN_RUNTIME_TOOLTIP); - - // Set tooltip for ICD location item. - ui.ICDLocationLabel->setToolTip(CLI_OPT_ICD_DESCRIPTION); - - // Set tooltips for alternative compiler (glslang) component. - // Use the same tooltip for both the title and the item purposely. - ui.alternativeCompilerHeaderLabel->setToolTip(STR_BUILD_SETTINGS_ALTERNATIVE_COMPILER_GLSLANG_TOOLTIP); - ui.glslangOptionsLabel->setToolTip(CLI_OPT_GLSLANG_OPT_DESCRIPTION_A); - ui.compilerBinariesLabel->setToolTip(CLI_DESC_ALTERNATIVE_VK_BIN_FOLDER); - - // Set tooltip for the General section. - ui.generalHeaderLabel->setToolTip(STR_BUILD_SETTINGS_GENERAL_TOOLTIP); - - // Set the tooltip for the command line section of the build settings. - ui.settingsCommandLineHeaderLabel->setToolTip(STR_BUILD_SETTINGS_CMD_LINE_TOOLTIP); - - // Set the mouse cursor to the pointing hand cursor for various widgets. - SetCursor(); - - // Set the event filter for "All Options" text edit. - ui.allOptionsTextEdit->installEventFilter(this); - - // Hide HLSL options for now. - HideHLSLOptions(); -} - -void rgBuildSettingsViewVulkan::HideHLSLOptions() -{ - // Hide HLSL options for now. - ui.vulkanOptionsHeaderLabel->hide(); - ui.generateDebugInfoCheckBox->hide(); - ui.generateDebugInfoLabel->hide(); - ui.noExplicitBindingsCheckBox->hide(); - ui.noExplicitBindingsLabel->hide(); - ui.useHLSLBlockOffsetsCheckBox->hide(); - ui.useHLSLBlockOffsetsLabel->hide(); - ui.useHLSLIOMappingCheckBox->hide(); - ui.useHLSLIOMappingLabel->hide(); -} - -void rgBuildSettingsViewVulkan::ConnectCheckBoxClickedEvents() -{ - bool isConnected = false; - - isConnected = connect(ui.generateDebugInfoCheckBox, &rgCheckBox::clicked, this, &rgBuildSettingsViewVulkan::HandleCheckBoxClickedEvent); - assert(isConnected); - - isConnected = connect(ui.noExplicitBindingsCheckBox, &rgCheckBox::clicked, this, &rgBuildSettingsViewVulkan::HandleCheckBoxClickedEvent); - assert(isConnected); - - isConnected = connect(ui.useHLSLBlockOffsetsCheckBox, &rgCheckBox::clicked, this, &rgBuildSettingsViewVulkan::HandleCheckBoxClickedEvent); - assert(isConnected); - - isConnected = connect(ui.useHLSLIOMappingCheckBox, &rgCheckBox::clicked, this, &rgBuildSettingsViewVulkan::HandleCheckBoxClickedEvent); - assert(isConnected); - - isConnected = connect(ui.enableValidationLayersCheckBox, &rgCheckBox::clicked, this, &rgBuildSettingsViewVulkan::HandleCheckBoxClickedEvent); - assert(isConnected); -} - -// Make the UI reflect the values in the supplied settings struct. -void rgBuildSettingsViewVulkan::PushToWidgets(const rgBuildSettingsVulkan& settings) -{ - // Disable any signals from the widgets while they're being populated. - QSignalBlocker signalBlockerTargetGPUsLineEdit(ui.targetGPUsLineEdit); - QSignalBlocker signalBlockerPredefinedMacrosLineEdit(ui.predefinedMacrosLineEdit); - QSignalBlocker signalBlockerIncludeDirectoriesLineEdit(ui.includeDirectoriesLineEdit); - QSignalBlocker signalBlockerGenerateDebugInfoCheckBox(ui.generateDebugInfoCheckBox); - QSignalBlocker signalBlockerNoExplicitBindingsCheckBox(ui.noExplicitBindingsCheckBox); - QSignalBlocker signalBlockerUseHLSLBlockOffsetsCheckBox(ui.useHLSLBlockOffsetsCheckBox); - QSignalBlocker signalBlockerUseHLSLIOMappingCheckBox(ui.useHLSLIOMappingCheckBox); - QSignalBlocker signalBlockerEnableValidationLayersCheckBox(ui.enableValidationLayersCheckBox); - QSignalBlocker signalBlockerICDLocationLineEdit(ui.ICDLocationLineEdit); - QSignalBlocker signalBlockerGlslangOptionsLineEdit(ui.glslangOptionsLineEdit); - QSignalBlocker signalBlockerCompilerBinariesLineEdit(ui.compilerBinariesLineEdit); - QSignalBlocker signalBlockerOutputFileBinaryNameLineEdit(ui.outputFileBinaryNameLineEdit); - - // The items below are common build settings for all API types. - QString targetGpusList(rgUtils::BuildSemicolonSeparatedStringList(settings.m_targetGpus).c_str()); - ui.targetGPUsLineEdit->setText(targetGpusList); - - QString predefinedMacros(rgUtils::BuildSemicolonSeparatedStringList(settings.m_predefinedMacros).c_str()); - ui.predefinedMacrosLineEdit->setText(predefinedMacros); - - QString additionalIncludeDirs(rgUtils::BuildSemicolonSeparatedStringList(settings.m_additionalIncludeDirectories).c_str()); - ui.includeDirectoriesLineEdit->setText(additionalIncludeDirs); - - // Items below are Vulkan-specific build settings only. - ui.generateDebugInfoCheckBox->setChecked(settings.m_isGenerateDebugInfoChecked); - ui.noExplicitBindingsCheckBox->setChecked(settings.m_isNoExplicitBindingsChecked); - ui.useHLSLBlockOffsetsCheckBox->setChecked(settings.m_isUseHlslBlockOffsetsChecked); - ui.useHLSLIOMappingCheckBox->setChecked(settings.m_isUseHlslIoMappingChecked); - ui.enableValidationLayersCheckBox->setChecked(settings.m_isEnableValidationLayersChecked); - ui.ICDLocationLineEdit->setText(QString::fromStdString(settings.m_ICDLocation)); - ui.glslangOptionsLineEdit->setText(QString::fromStdString(settings.m_glslangOptions)); - ui.compilerBinariesLineEdit->setText(QString::fromStdString(std::get(settings.m_compilerPaths))); - - // Output binary file name. - ui.outputFileBinaryNameLineEdit->setText(settings.m_binaryFileName.c_str()); -} - -rgBuildSettingsVulkan rgBuildSettingsViewVulkan::PullFromWidgets() const -{ - rgBuildSettingsVulkan settings; - - // Target GPUs. - std::vector targetGPUsVector; - const std::string& commaSeparatedTargetGPUs = ui.targetGPUsLineEdit->text().toStdString(); - rgUtils::splitString(commaSeparatedTargetGPUs, rgConfigManager::RGA_LIST_DELIMITER, targetGPUsVector); - settings.m_targetGpus = targetGPUsVector; - - // Predefined Macros. - std::vector predefinedMacrosVector; - const std::string& commaSeparatedPredefinedMacros = ui.predefinedMacrosLineEdit->text().toStdString(); - rgUtils::splitString(commaSeparatedPredefinedMacros, rgConfigManager::RGA_LIST_DELIMITER, predefinedMacrosVector); - settings.m_predefinedMacros = predefinedMacrosVector; - - // Additional Include Directories. - std::vector additionalIncludeDirectoriesVector; - const std::string& commaSeparatedAdditionalIncludeDirectories = ui.includeDirectoriesLineEdit->text().toStdString(); - rgUtils::splitString(commaSeparatedAdditionalIncludeDirectories, rgConfigManager::RGA_LIST_DELIMITER, additionalIncludeDirectoriesVector); - settings.m_additionalIncludeDirectories = additionalIncludeDirectoriesVector; - - // Vulkan-specific settings. - settings.m_isGenerateDebugInfoChecked = ui.generateDebugInfoCheckBox->isChecked(); - settings.m_isNoExplicitBindingsChecked = ui.noExplicitBindingsCheckBox->isChecked(); - settings.m_isUseHlslBlockOffsetsChecked = ui.useHLSLBlockOffsetsCheckBox->isChecked(); - settings.m_isUseHlslIoMappingChecked = ui.useHLSLIOMappingCheckBox->isChecked(); - settings.m_isEnableValidationLayersChecked = ui.enableValidationLayersCheckBox->isChecked(); - settings.m_ICDLocation = ui.ICDLocationLineEdit->text().toStdString(); - settings.m_glslangOptions = ui.glslangOptionsLineEdit->text().toStdString(); - std::get(settings.m_compilerPaths) = ui.compilerBinariesLineEdit->text().toStdString(); - - // Binary output file name. - settings.m_binaryFileName = ui.outputFileBinaryNameLineEdit->text().toStdString(); - - return settings; -} - -void rgBuildSettingsViewVulkan::ConnectSignals() -{ - // Add target GPU button. - bool isConnected = connect(this->ui.addTargetGPUsButton, &QPushButton::clicked, this, &rgBuildSettingsViewVulkan::HandleAddTargetGpusButtonClick); - assert(isConnected); - - // Add include directories editor dialog button. - isConnected = connect(this->ui.includeDirsBrowseButton, &QPushButton::clicked, this, &rgBuildSettingsViewVulkan::HandleIncludeDirsBrowseButtonClick); - assert(isConnected); - - // Add preprocessor directives editor dialog button. - isConnected = connect(this->ui.predefinedMacrosBrowseButton, &QPushButton::clicked, this, &rgBuildSettingsViewVulkan::HandlePreprocessorDirectivesBrowseButtonClick); - assert(isConnected); - - // Connect all textboxes within the view. - isConnected = connect(this->ui.targetGPUsLineEdit, &QLineEdit::textChanged, this, &rgBuildSettingsViewVulkan::HandleTextEditChanged); - assert(isConnected); - - // Handle changes to the Predefined Macros setting. - isConnected = connect(this->ui.predefinedMacrosLineEdit, &QLineEdit::textChanged, this, &rgBuildSettingsViewVulkan::HandleTextEditChanged); - assert(isConnected); - - // Handle changes to the Include Directories setting. - isConnected = connect(this->ui.includeDirectoriesLineEdit, &QLineEdit::textChanged, this, &rgBuildSettingsViewVulkan::HandleTextEditChanged); - assert(isConnected); - - // Connect the include directory editor dialog's "OK" button click. - isConnected = connect(m_pIncludeDirectoriesView, &rgIncludeDirectoriesView::OKButtonClicked, this, &rgBuildSettingsViewVulkan::HandleIncludeDirsUpdated); - assert(isConnected); - - // Connect the preprocessor directives editor dialog's "OK" button click. - isConnected = connect(m_pPreprocessorDirectivesDialog, &rgPreprocessorDirectivesDialog::OKButtonClicked, this, &rgBuildSettingsViewVulkan::HandlePreprocessorDirectivesUpdated); - assert(isConnected); - - // Handle changes to the Generate Debug Info checkbox. - isConnected = connect(this->ui.generateDebugInfoCheckBox, &rgCheckBox::stateChanged, this, &rgBuildSettingsViewVulkan::HandleCheckboxStateChanged); - assert(isConnected); - - // Handle changes to the No Explicit Bindings checkbox. - isConnected = connect(this->ui.noExplicitBindingsCheckBox, &rgCheckBox::stateChanged, this, &rgBuildSettingsViewVulkan::HandleCheckboxStateChanged); - assert(isConnected); - - // Handle changes to the Use HLSL Block Offsets checkbox. - isConnected = connect(this->ui.useHLSLBlockOffsetsCheckBox, &rgCheckBox::stateChanged, this, &rgBuildSettingsViewVulkan::HandleCheckboxStateChanged); - assert(isConnected); - - // Handle changes to the Use HLSL IO Mapping checkbox. - isConnected = connect(this->ui.useHLSLIOMappingCheckBox, &rgCheckBox::stateChanged, this, &rgBuildSettingsViewVulkan::HandleCheckboxStateChanged); - assert(isConnected); - - // Handle changes to the Enable Validation Layers checkbox. - isConnected = connect(this->ui.enableValidationLayersCheckBox, &rgCheckBox::stateChanged, this, &rgBuildSettingsViewVulkan::HandleCheckboxStateChanged); - assert(isConnected); - - // Handle clicking of ICD location browse button. - isConnected = connect(this->ui.ICDLocationBrowseButton, &QPushButton::clicked, this, &rgBuildSettingsViewVulkan::HandleICDLocationBrowseButtonClick); - assert(isConnected); - - // Handle changes to the ICD location line edit. - isConnected = connect(this->ui.ICDLocationLineEdit, &QLineEdit::textChanged, this, &rgBuildSettingsViewVulkan::HandleICDLocationLineEditChanged); - assert(isConnected); - - // Handle changes to the glslang options line edit. - isConnected = connect(this->ui.glslangOptionsLineEdit, &QLineEdit::textChanged, this, &rgBuildSettingsViewVulkan::HandleGlslangOptionsLineEditChanged); - assert(isConnected); - - // Handle clicking of the Alternative Compiler path browse button. - isConnected = connect(this->ui.compilerBrowseButton, &QPushButton::clicked, this, &rgBuildSettingsViewVulkan::HandleAlternativeCompilerBrowseButtonClicked); - assert(isConnected); - - // Handle changes to the Alternative Compiler path line edit. - isConnected = connect(this->ui.compilerBinariesLineEdit, &QLineEdit::textChanged, this, &rgBuildSettingsViewVulkan::HandleAlternativeCompilerLineEditChanged); - assert(isConnected); - - // Binary Output File name textChanged signal. - isConnected = connect(this->ui.outputFileBinaryNameLineEdit, &QLineEdit::textChanged, this, &rgBuildSettingsViewVulkan::HandleOutputBinaryEditBoxChanged); - assert(isConnected); - - // Binary Output File name editingFinished signal. - isConnected = connect(this->ui.outputFileBinaryNameLineEdit, &QLineEdit::editingFinished, this, &rgBuildSettingsViewVulkan::HandleOutputBinaryFileEditingFinished); - assert(isConnected); -} - -void rgBuildSettingsViewVulkan::HandleOutputBinaryFileEditingFinished() -{ - // Verify that the output binary file text is not empty before losing the focus. - if (this->ui.outputFileBinaryNameLineEdit->text().trimmed().isEmpty() || !rgUtils::IsValidFileName(ui.outputFileBinaryNameLineEdit->text().toStdString())) - { - // Initialize the binary output file name edit line. - std::shared_ptr pDefaultSettings = rgConfigManager::Instance().GetUserGlobalBuildSettings(rgProjectAPI::Vulkan); - auto pVkDefaultSettings = std::dynamic_pointer_cast(pDefaultSettings); - - assert(pVkDefaultSettings != nullptr); - if (pVkDefaultSettings != nullptr) - { - this->ui.outputFileBinaryNameLineEdit->setText(pVkDefaultSettings->m_binaryFileName.c_str()); - } - this->ui.outputFileBinaryNameLineEdit->setFocus(); - } - - // Signal to any listeners that the values in the UI have changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - - // Update the command line preview text. - UpdateCommandLineText(); -} - -void rgBuildSettingsViewVulkan::HandleOutputBinaryEditBoxChanged(const QString& text) -{ - // Update the tooltip. - ui.outputFileBinaryNameLineEdit->setToolTip(text); - - // Restore the cursor to the original position when the text has changed. - QtCommon::QtUtil::RestoreCursorPosition cursorPosition(ui.outputFileBinaryNameLineEdit); - - // Signal to any listeners that the values in the UI have changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - - // Update the command line preview text. - UpdateCommandLineText(); -} - -void rgBuildSettingsViewVulkan::HandleICDLocationBrowseButtonClick(bool /* checked */) -{ - QString selectedFile = QFileDialog::getOpenFileName(this, tr(STR_ICD_LOCATION_DIALOG_SELECT_FILE_TITLE), - ui.ICDLocationLineEdit->text(), - tr(STR_DIALOG_FILTER_ICD)); - if (!selectedFile.isEmpty()) - { - ui.ICDLocationLineEdit->setText(selectedFile); - - // Inform the UI of a possible change to the pending state. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - - // Update the command line preview text. - UpdateCommandLineText(); - } -} - -void rgBuildSettingsViewVulkan::HandleICDLocationLineEditChanged(const QString& text) -{ - // Restore the cursor to the original position when the text has changed. - QtCommon::QtUtil::RestoreCursorPosition cursorPosition(ui.ICDLocationLineEdit); - - // Set the text value. - ui.ICDLocationLineEdit->setText(text); - - // Inform the UI of a possible change to the pending state. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - - // Update the command line preview text. - UpdateCommandLineText(); -} - -void rgBuildSettingsViewVulkan::HandleGlslangOptionsLineEditChanged(const QString& text) -{ - // Restore the cursor to the original position when the text has changed. - QtCommon::QtUtil::RestoreCursorPosition cursorPosition(ui.glslangOptionsLineEdit); - - // Set the text value. - ui.glslangOptionsLineEdit->setText(text); - - // Inform the UI of a possible change to the pending state. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - - // Update the command line preview text. - UpdateCommandLineText(); -} - -void rgBuildSettingsViewVulkan::HandleAlternativeCompilerBrowseButtonClicked() -{ - QFileDialog fileDialog; - QLineEdit* pLineEdit = ui.compilerBinariesLineEdit; - assert(pLineEdit != nullptr); - if (pLineEdit != nullptr) - { - QString currentDir = (pLineEdit->text().isEmpty() ? - QString::fromStdString(rgConfigManager::Instance().GetLastSelectedFolder()) : pLineEdit->text()); - - QString selectedDirectory = QFileDialog::getExistingDirectory(this, tr(STR_INCLUDE_DIR_DIALOG_SELECT_DIR_TITLE), - currentDir, QFileDialog::ShowDirsOnly); - if (!selectedDirectory.isEmpty()) - { - ui.compilerBinariesLineEdit->setText(selectedDirectory); - - // Inform the UI of a possible change to the pending state. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - - // Update the command line preview text. - UpdateCommandLineText(); - } - } -} - -void rgBuildSettingsViewVulkan::HandleAlternativeCompilerLineEditChanged(const QString& text) -{ - // Restore the cursor to the original position when the text has changed. - QtCommon::QtUtil::RestoreCursorPosition cursorPosition(ui.compilerBinariesLineEdit); - - // Set the text value. - ui.compilerBinariesLineEdit->setText(text); - - // Inform the UI of a possible change to the pending state. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - - // Update the command line preview text. - UpdateCommandLineText(); -} - -void rgBuildSettingsViewVulkan::ConnectLineEditFocusEvents() -{ - bool isConnected = false; - - isConnected = connect(this->ui.includeDirectoriesLineEdit, &rgLineEdit::LineEditFocusInEvent, this, &rgBuildSettingsViewVulkan::HandleLineEditFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.includeDirectoriesLineEdit, &rgLineEdit::LineEditFocusOutEvent, this, &rgBuildSettingsViewVulkan::HandleLineEditFocusOutEvent); - assert(isConnected); - - isConnected = connect(this->ui.predefinedMacrosLineEdit, &rgLineEdit::LineEditFocusInEvent, this, &rgBuildSettingsViewVulkan::HandleLineEditFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.predefinedMacrosLineEdit, &rgLineEdit::LineEditFocusOutEvent, this, &rgBuildSettingsViewVulkan::HandleLineEditFocusOutEvent); - assert(isConnected); - - isConnected = connect(this->ui.targetGPUsLineEdit, &rgLineEdit::LineEditFocusInEvent, this, &rgBuildSettingsViewVulkan::HandleLineEditFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.targetGPUsLineEdit, &rgLineEdit::LineEditFocusOutEvent, this, &rgBuildSettingsViewVulkan::HandleLineEditFocusOutEvent); - assert(isConnected); - - isConnected = connect(this->ui.ICDLocationLineEdit, &rgLineEdit::LineEditFocusInEvent, this, &rgBuildSettingsViewVulkan::HandleLineEditFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.ICDLocationLineEdit, &rgLineEdit::LineEditFocusOutEvent, this, &rgBuildSettingsViewVulkan::HandleLineEditFocusOutEvent); - assert(isConnected); - - isConnected = connect(this->ui.glslangOptionsLineEdit, &rgLineEdit::LineEditFocusInEvent, this, &rgBuildSettingsViewVulkan::HandleLineEditFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.glslangOptionsLineEdit, &rgLineEdit::LineEditFocusOutEvent, this, &rgBuildSettingsViewVulkan::HandleLineEditFocusOutEvent); - assert(isConnected); - - isConnected = connect(this->ui.compilerBinariesLineEdit, &rgLineEdit::LineEditFocusInEvent, this, &rgBuildSettingsViewVulkan::HandleLineEditFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.compilerBinariesLineEdit, &rgLineEdit::LineEditFocusOutEvent, this, &rgBuildSettingsViewVulkan::HandleLineEditFocusOutEvent); - assert(isConnected); - - isConnected = connect(this->ui.addTargetGPUsButton, &rgBrowseButton::BrowseButtonFocusInEvent, this, &rgBuildSettingsViewVulkan::HandleBrowseButtonFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.addTargetGPUsButton, &rgBrowseButton::BrowseButtonFocusOutEvent, this, &rgBuildSettingsViewVulkan::HandleBrowseButtonFocusOutEvent); - assert(isConnected); - - isConnected = connect(this->ui.predefinedMacrosBrowseButton, &rgBrowseButton::BrowseButtonFocusInEvent, this, &rgBuildSettingsViewVulkan::HandleBrowseButtonFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.predefinedMacrosBrowseButton, &rgBrowseButton::BrowseButtonFocusOutEvent, this, &rgBuildSettingsViewVulkan::HandleBrowseButtonFocusOutEvent); - assert(isConnected); - - isConnected = connect(this->ui.includeDirsBrowseButton, &rgBrowseButton::BrowseButtonFocusInEvent, this, &rgBuildSettingsViewVulkan::HandleBrowseButtonFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.includeDirsBrowseButton, &rgBrowseButton::BrowseButtonFocusOutEvent, this, &rgBuildSettingsViewVulkan::HandleBrowseButtonFocusOutEvent); - assert(isConnected); - - isConnected = connect(this->ui.ICDLocationBrowseButton, &rgBrowseButton::BrowseButtonFocusInEvent, this, &rgBuildSettingsViewVulkan::HandleBrowseButtonFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.ICDLocationBrowseButton, &rgBrowseButton::BrowseButtonFocusOutEvent, this, &rgBuildSettingsViewVulkan::HandleBrowseButtonFocusOutEvent); - assert(isConnected); - - isConnected = connect(this->ui.compilerBrowseButton, &rgBrowseButton::BrowseButtonFocusInEvent, this, &rgBuildSettingsViewVulkan::HandleBrowseButtonFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.compilerBrowseButton, &rgBrowseButton::BrowseButtonFocusOutEvent, this, &rgBuildSettingsViewVulkan::HandleBrowseButtonFocusOutEvent); - assert(isConnected); - - isConnected = connect(this->ui.enableValidationLayersCheckBox, &rgCheckBox::CheckBoxFocusInEvent, this, &rgBuildSettingsViewVulkan::HandleCheckBoxFocusInEvent); - assert(isConnected); - - isConnected = connect(this->ui.enableValidationLayersCheckBox, &rgCheckBox::CheckBoxFocusOutEvent, this, &rgBuildSettingsViewVulkan::HandleCheckBoxFocusOutEvent); - assert(isConnected); -} - -void rgBuildSettingsViewVulkan::HandleAddTargetGpusButtonClick() -{ - // Set the frame border color to red. - emit SetFrameBorderRedSignal(); - - // Trim out any spaces within the target GPUs string. - QString selectedGPUs = this->ui.targetGPUsLineEdit->text(); - - // Create a new Target GPU Selection dialog instance. - m_pTargetGpusDialog = new rgTargetGpusDialog(selectedGPUs, this); - - // Register the target gpu dialog box with the scaling manager. - ScalingManager::Get().RegisterObject(m_pTargetGpusDialog); - - // Center the dialog on the view (registering with the scaling manager - // shifts it out of the center so we need to manually center it). - rgUtils::CenterOnWidget(m_pTargetGpusDialog, this); - - // Present the dialog to the user. - m_pTargetGpusDialog->setModal(true); - int dialogResult = m_pTargetGpusDialog->exec(); - - // If the user clicked "OK", extract the Checked items into a comma-separated string, - // and put the string in the Target GPUs textbox. - if (dialogResult == 1) - { - // After the dialog is hidden, extract the list of families selected by the user. - std::vector selectedFamilies = m_pTargetGpusDialog->GetSelectedCapabilityGroups(); - - // Remove gfx notation if needed. - std::transform(selectedFamilies.begin(), selectedFamilies.end(), selectedFamilies.begin(), - [&](std::string& family) - { - return rgUtils::RemoveGfxNotation(family); - }); - - // Create a comma-separated list of GPU families that the user selected. - std::stringstream familyListString; - size_t numFamilies = selectedFamilies.size(); - for (size_t familyIndex = 0; familyIndex < numFamilies; ++familyIndex) - { - // Append the family name to the string. - familyListString << selectedFamilies[familyIndex]; - - // Append a comma between each family name, until the last one. - if ((familyIndex + 1) < numFamilies) - { - familyListString << rgConfigManager::RGA_LIST_DELIMITER; - } - } - - // Set the target GPUs text. - ui.targetGPUsLineEdit->setText(familyListString.str().c_str()); - - // Inform the UI of a possible change to the pending state. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - } -} - -void rgBuildSettingsViewVulkan::HandleTextEditChanged() -{ - // Determine which control's text has been updated. - QLineEdit* pLineEdit = static_cast(QObject::sender()); - assert(pLineEdit != nullptr); - if (pLineEdit != nullptr) - { - // Inform the UI of a possible change to the pending state. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - - // Update the command line preview text. - UpdateCommandLineText(); - } -} - -std::string rgBuildSettingsViewVulkan::GetTitleString() -{ - std::stringstream titleString; - - // Build the title string. - if (m_isGlobalSettings) - { - // For the global settings. - titleString << STR_BUILD_SETTINGS_DEFAULT_TITLE; - titleString << " "; - titleString << STR_API_NAME_VULKAN; - titleString << " "; - } - else - { - // For project-specific settings. - titleString << STR_BUILD_SETTINGS_PROJECT_TITLE; - titleString << " "; - } - titleString << STR_MENU_BUILD_SETTINGS_LOWER; - - return titleString.str(); -} - -const std::string rgBuildSettingsViewVulkan::GetTitleTooltipString() const -{ - std::stringstream tooltipString; - - if (m_isGlobalSettings) - { - tooltipString << STR_BUILD_SETTINGS_GLOBAL_TOOLTIP_A; - tooltipString << STR_API_NAME_VULKAN; - tooltipString << STR_BUILD_SETTINGS_GLOBAL_TOOLTIP_B; - } - else - { - tooltipString << STR_BUILD_SETTINGS_PROJECT_TOOLTIP_A; - tooltipString << STR_API_NAME_VULKAN; - tooltipString << STR_BUILD_SETTINGS_PROJECT_TOOLTIP_B; - } - - return tooltipString.str(); -} - -void rgBuildSettingsViewVulkan::UpdateCommandLineText() -{ - rgBuildSettingsVulkan apiBuildSetting = PullFromWidgets(); - - // Generate a command line string from the build settings structure. - std::string buildSettings; - bool ret = rgCliUtils::GenerateVulkanBuildSettingsString(apiBuildSetting, buildSettings); - assert(ret); - if (ret) - { - ui.allOptionsTextEdit->setPlainText(buildSettings.c_str()); - } -} - -void rgBuildSettingsViewVulkan::HandlePendingChangesStateChanged(bool hasPendingChanges) -{ - // Let the base class determine if there is a need to signal listeners - // about the pending changes state. - rgBuildSettingsView::SetHasPendingChanges(hasPendingChanges); -} - -bool rgBuildSettingsViewVulkan::IsTargetGpusStringValid(std::vector& errors) const -{ - bool isValid = true; - - // The target GPUs string must be non-empty. - std::string targetGpusString = ui.targetGPUsLineEdit->text().toStdString(); - if (targetGpusString.empty()) - { - // The Target GPUs field is invalid since it is empty. - errors.push_back(STR_ERR_TARGET_GPUS_CANNOT_BE_EMPTY); - isValid = false; - } - else - { - // Split the comma-separated GPUs string. - std::vector targetGPUsVector; - rgUtils::splitString(targetGpusString, rgConfigManager::RGA_LIST_DELIMITER, targetGPUsVector); - - // Use the Config Manager to verify that the specified GPUs are valid. - std::vector invalidGpus; - rgConfigManager& configManager = rgConfigManager::Instance(); - for (const std::string& targetGpuFamilyName : targetGPUsVector) - { - std::string trimmedName; - rgUtils::TrimLeadingAndTrailingWhitespace(targetGpuFamilyName, trimmedName); - - // Is the given target GPU family name supported? - if (!configManager.IsGpuFamilySupported(trimmedName)) - { - // Add the GPU to a list of invalid names if it's not supported. - invalidGpus.push_back(trimmedName); - } - } - - if (!invalidGpus.empty()) - { - // Build an error string indicating the invalid GPUs. - std::stringstream errorStream; - errorStream << STR_ERR_INVALID_GPUS_SPECIFIED; - - int numInvalid = static_cast(invalidGpus.size()); - for (int gpuIndex = 0; gpuIndex < numInvalid; ++gpuIndex) - { - errorStream << invalidGpus[gpuIndex]; - - if (gpuIndex != (numInvalid - 1)) - { - errorStream << ", "; - } - } - - // Add an error indicating that the GPU name is invalid. - errors.push_back(errorStream.str()); - isValid = false; - } - } - - return isValid; -} - -bool rgBuildSettingsViewVulkan::ValidatePendingSettings() -{ - std::vector errorFields; - bool isValid = IsTargetGpusStringValid(errorFields); - if (!isValid) - { - std::stringstream errorStream; - errorStream << STR_ERR_INVALID_PENDING_SETTING; - errorStream << std::endl; - - // Loop through all errors and append them to the stream. - for (const std::string error : errorFields) - { - errorStream << error; - errorStream << std::endl; - } - - // Display an error message box to the user telling them what to fix. - rgUtils::ShowErrorMessageBox(errorStream.str().c_str(), this); - } - - return isValid; -} - -void rgBuildSettingsViewVulkan::SetCursor() -{ - // Set the cursor for buttons to pointing hand cursor. - ui.addTargetGPUsButton->setCursor(Qt::PointingHandCursor); - ui.includeDirsBrowseButton->setCursor(Qt::PointingHandCursor); - ui.predefinedMacrosBrowseButton->setCursor(Qt::PointingHandCursor); - ui.ICDLocationBrowseButton->setCursor(Qt::PointingHandCursor); - ui.compilerBrowseButton->setCursor(Qt::PointingHandCursor); - - // Set the cursor for check boxes to pointing hand cursor. - ui.generateDebugInfoCheckBox->setCursor(Qt::PointingHandCursor); - ui.noExplicitBindingsCheckBox->setCursor(Qt::PointingHandCursor); - ui.useHLSLBlockOffsetsCheckBox->setCursor(Qt::PointingHandCursor); - ui.useHLSLIOMappingCheckBox->setCursor(Qt::PointingHandCursor); - ui.enableValidationLayersCheckBox->setCursor(Qt::PointingHandCursor); -} - -void rgBuildSettingsViewVulkan::HandleIncludeDirsBrowseButtonClick() -{ - // Set the frame border color to red. - emit SetFrameBorderRedSignal(); - - // Position the window in the middle of the screen. - m_pIncludeDirectoriesView->setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, m_pIncludeDirectoriesView->size(), qApp->desktop()->availableGeometry())); - - // Set the current include dirs. - m_pIncludeDirectoriesView->SetListItems(ui.includeDirectoriesLineEdit->text()); - - // Show the window. - m_pIncludeDirectoriesView->exec(); -} - -void rgBuildSettingsViewVulkan::HandleIncludeDirsUpdated(QStringList includeDirs) -{ - QString includeDirsText; - - // Create a delimiter-separated string. - if (!includeDirs.isEmpty()) - { - includeDirsText = includeDirs.join(s_OPTIONS_LIST_DELIMITER); - } - - // Update the text box. - ui.includeDirectoriesLineEdit->setText(includeDirsText); - - // Inform the rest of the UI that the settings have been changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); -} - -void rgBuildSettingsViewVulkan::HandlePreprocessorDirectivesBrowseButtonClick() -{ - // Set the frame border color to red. - emit SetFrameBorderRedSignal(); - - // Position the window in the middle of the screen. - m_pPreprocessorDirectivesDialog->setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, m_pPreprocessorDirectivesDialog->size(), qApp->desktop()->availableGeometry())); - - // Set the current preprocessor directives in the dialog. - m_pPreprocessorDirectivesDialog->SetListItems(ui.predefinedMacrosLineEdit->text()); - - // Show the dialog. - m_pPreprocessorDirectivesDialog->exec(); -} - -void rgBuildSettingsViewVulkan::HandlePreprocessorDirectivesUpdated(QStringList preprocessorDirectives) -{ - QString preprocessorDirectivesText; - - // Create a delimiter-separated string. - if (!preprocessorDirectives.isEmpty()) - { - preprocessorDirectivesText = preprocessorDirectives.join(s_OPTIONS_LIST_DELIMITER); - } - - // Update the text box. - ui.predefinedMacrosLineEdit->setText(preprocessorDirectivesText); - - // Inform the rest of the UI that the settings have been changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); -} - -void rgBuildSettingsViewVulkan::HandleLineEditFocusInEvent() -{ - emit SetFrameBorderRedSignal(); -} - -void rgBuildSettingsViewVulkan::HandleLineEditFocusOutEvent() -{ - emit SetFrameBorderBlackSignal(); -} - -void rgBuildSettingsViewVulkan::HandleBrowseButtonFocusInEvent() -{ - emit SetFrameBorderRedSignal(); -} - -void rgBuildSettingsViewVulkan::HandleBrowseButtonFocusOutEvent() -{ - emit SetFrameBorderBlackSignal(); -} - -void rgBuildSettingsViewVulkan::HandleCheckBoxFocusInEvent() -{ - emit SetFrameBorderRedSignal(); -} - -void rgBuildSettingsViewVulkan::HandleCheckBoxFocusOutEvent() -{ - emit SetFrameBorderBlackSignal(); -} - -void rgBuildSettingsViewVulkan::HandleCheckBoxClickedEvent() -{ - emit SetFrameBorderRedSignal(); -} - -void rgBuildSettingsViewVulkan::HandleCheckboxStateChanged() -{ - // Make sure it was a checkbox that caused this state change (just to be sure). - QCheckBox* pCheckBox = static_cast(QObject::sender()); - assert(pCheckBox != nullptr); - if (pCheckBox != nullptr) - { - // Inform the UI of a possible change to the pending state. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - - // Update the command line preview text. - UpdateCommandLineText(); - } -} - -bool rgBuildSettingsViewVulkan::GetHasPendingChanges() const -{ - rgBuildSettingsVulkan currentSettings = PullFromWidgets(); - - bool hasChanges = !m_initialSettings.HasSameSettings(currentSettings); - - return hasChanges; -} - -bool rgBuildSettingsViewVulkan::RevertPendingChanges() -{ - PushToWidgets(m_initialSettings); - - // Make sure the rest of the UI knows that the settings don't need to be saved. - HandlePendingChangesStateChanged(false); - - return false; -} - -void rgBuildSettingsViewVulkan::RestoreDefaultSettings() -{ - bool isRestored = false; - - if (m_isGlobalSettings) - { - // If this is for the global settings, then restore to the hard-coded defaults. - - // Get the hardcoded default build settings. - std::shared_ptr pDefaultBuildSettings = rgConfigManager::GetDefaultBuildSettings(rgProjectAPI::Vulkan); - - std::shared_ptr pApiBuildSettings = std::dynamic_pointer_cast(pDefaultBuildSettings); - assert(pApiBuildSettings != nullptr); - if (pApiBuildSettings != nullptr) - { - // Reset our initial settings back to the defaults. - m_initialSettings = *pApiBuildSettings; - - // Update the UI to reflect the new initial settings. - PushToWidgets(m_initialSettings); - - // Update the ConfigManager to use the new settings. - rgConfigManager::Instance().SetApiBuildSettings(STR_API_NAME_VULKAN, &m_initialSettings); - - // Save the settings file. - isRestored = rgConfigManager::Instance().SaveGlobalConfigFile(); - - // Inform the rest of the UI that the settings have been changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - } - } - else - { - // This view is showing project-specific settings, so restore back to the stored settings in the project. - std::shared_ptr pDefaultSettings = rgConfigManager::Instance().GetUserGlobalBuildSettings(rgProjectAPI::Vulkan); - auto pVkDefaultSettings = std::dynamic_pointer_cast(pDefaultSettings); - - m_initialSettings = *pVkDefaultSettings; - - PushToWidgets(m_initialSettings); - - // Inform the rest of the UI that the settings have been changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - - // Let the rgBuildView know that the build settings have been updated. - emit ProjectBuildSettingsSaved(pVkDefaultSettings); - isRestored = true; - } - - // Show an error dialog if the settings failed to be reset. - if (!isRestored) - { - rgUtils::ShowErrorMessageBox(STR_ERR_CANNOT_RESTORE_DEFAULT_SETTINGS, this); - } -} - -bool rgBuildSettingsViewVulkan::SaveSettings() -{ - bool canBeSaved = ValidatePendingSettings(); - if (canBeSaved) - { - // Reset the initial settings to match what the UI shows. - m_initialSettings = PullFromWidgets(); - - if (m_isGlobalSettings) - { - // Update the config manager to use these new settings. - rgConfigManager& configManager = rgConfigManager::Instance(); - configManager.SetApiBuildSettings(STR_API_NAME_VULKAN, &m_initialSettings); - - // Save the global config settings. - canBeSaved = configManager.SaveGlobalConfigFile(); - } - else - { - // Save the project settings. - std::shared_ptr pTmpPtr = std::make_shared(m_initialSettings); - emit ProjectBuildSettingsSaved(pTmpPtr); - } - - if (canBeSaved) - { - // Make sure the rest of the UI knows that the settings have been saved. - HandlePendingChangesStateChanged(false); - } - } - - // Set focus to target GPUs browse button. - ui.addTargetGPUsButton->setFocus(); - - return canBeSaved; -} - -void rgBuildSettingsViewVulkan::mousePressEvent(QMouseEvent* pEvent) -{ - Q_UNUSED(pEvent); - - emit SetFrameBorderRedSignal(); -} - -bool rgBuildSettingsViewVulkan::eventFilter(QObject* pObject, QEvent* pEvent) -{ - // Intercept events for "All Options" widget. - if (pEvent != nullptr) - { - if (pEvent->type() == QEvent::FocusIn) - { - HandleLineEditFocusInEvent(); - } - else if (pEvent->type() == QEvent::FocusOut) - { - HandleLineEditFocusOutEvent(); - } - } - - // Continue default processing. - return QObject::eventFilter(pObject, pEvent); -} - -void rgBuildSettingsViewVulkan::SetInitialWidgetFocus() -{ - ui.addTargetGPUsButton->setFocus(); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgBuildSettingsWidget.cpp b/RadeonGPUAnalyzerGUI/Src/rgBuildSettingsWidget.cpp deleted file mode 100644 index 93c0b27..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgBuildSettingsWidget.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// C++. -#include -#include - -// Local. -#include - -rgBuildSettingsWidget::rgBuildSettingsWidget(QWidget* pParent) : QFrame(pParent) -{ - setObjectName("buildSettingsWidget"); -} - -void rgBuildSettingsWidget::focusInEvent(QFocusEvent* pEvent) -{ - emit FrameFocusInEventSignal(); - - // Pass the event onto the base class. - QFrame::focusInEvent(pEvent); -} - -void rgBuildSettingsWidget::focusOutEvent(QFocusEvent* pEvent) -{ - emit FrameFocusOutEventSignal(); - - // Pass the event onto the base class. - QFrame::focusOutEvent(pEvent); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgBuildView.cpp b/RadeonGPUAnalyzerGUI/Src/rgBuildView.cpp deleted file mode 100644 index 72166cd..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgBuildView.cpp +++ /dev/null @@ -1,3201 +0,0 @@ -// C++. -#include -#include -#include - -// Qt. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Infra. -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const int s_FILE_MENU_VIEW_CONTAINER_WIDTH = 200; -static const int s_FIND_TEXT_WIDGET_HORIZONTAL_MARGIN = 10; -static const int s_FIND_TEXT_WIDGET_VERTICAL_MARGIN = 10; - -rgBuildView::rgBuildView(rgProjectAPI api, QWidget* pParent) : - QWidget(pParent), - m_cloneIndex(0), - m_pParent(pParent) -{ - // Setup the UI. - ui.setupUi(this); - - // Create the factory used to create API specific objects within the rgBuildView. - m_pFactory = rgFactory::CreateFactory(api); - - // Create the find widget. - CreateFindWidget(); -} - -bool rgBuildView::CheckSourcesModifiedSinceLastBuild(rgSourceCodeEditor* pCodeEditor) -{ - bool isModifiedAfterBuild = false; - - assert(pCodeEditor != nullptr); - if (pCodeEditor != nullptr) - { - auto fileModificationTimeMapIter = m_fileModifiedTimeMap.find(pCodeEditor); - if (fileModificationTimeMapIter != m_fileModifiedTimeMap.end()) - { - // If the source file was modified after the last build, line correlation data has become invalid. - const QDateTime& lastSavedTime = fileModificationTimeMapIter->second; - if (lastSavedTime > m_lastSuccessfulBuildTime) - { - isModifiedAfterBuild = true; - } - } - } - - return isModifiedAfterBuild; -} - -void rgBuildView::ClearBuildView() -{ - rgMenu* pMenu = GetMenu(); - if (pMenu != nullptr) - { - pMenu->ClearFiles(); - } - - // Clean up source editor instances. - ClearEditors(); - - // Clear the output window. - if (m_pCliOutputWindow != nullptr) - { - m_pCliOutputWindow->ClearText(); - } -} - -void rgBuildView::ClearEditors() -{ - std::vector filePaths; - for (auto editorIter = m_sourceCodeEditors.begin(); editorIter != m_sourceCodeEditors.end(); ++editorIter) - { - filePaths.push_back(editorIter->first); - } - - for (const std::string& fullFilePath : filePaths) - { - RemoveEditor(fullFilePath); - } -} - -void rgBuildView::ConnectFileSignals() -{ - rgMenu* pMenu = GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - // Connect the file menu to the build view, so that the view knows when the current file is switched. - bool isConnected = connect(pMenu, &rgMenu::SelectedFileChanged, this, &rgBuildView::HandleSelectedFileChanged); - assert(isConnected); - - // Connect the file menu's MenuItemCloseButtonClicked signal with the menu item closed handler. - isConnected = connect(pMenu, &rgMenu::MenuItemCloseButtonClicked, this, &rgBuildView::HandleMenuItemCloseButtonClicked); - assert(isConnected); - - // Connect the file menu default item's "Add new file" button. - isConnected = connect(pMenu, &rgMenu::CreateFileButtonClicked, this, &rgBuildView::CreateFileButtonClicked); - assert(isConnected); - - // Connect the file menu default item's "Open existing file" button. - isConnected = connect(pMenu, &rgMenu::OpenFileButtonClicked, this, &rgBuildView::OpenFileButtonClicked); - assert(isConnected); - - // Connect the file menu's rename signal. - isConnected = connect(pMenu, &rgMenu::FileRenamed, this, &rgBuildView::HandleFileRenamed); - assert(isConnected); - - // Connect the file menu's project renamed signal. - isConnected = connect(m_pFileMenuTitlebar, &rgMenuTitlebar::TitleChanged, this, &rgBuildView::HandleProjectRenamed); - assert(isConnected); - - // Connect the file menu's item count change signal. - isConnected = connect(pMenu, &rgMenu::FileMenuItemCountChanged, this, &rgBuildView::ProjectFileCountChanged); - assert(isConnected); - - // Connect the file menu's file build settings button click signal to the rgBuildView's handler. - isConnected = connect(pMenu, &rgMenu::BuildSettingsButtonClicked, this, &rgBuildView::HandleFindWidgetVisibilityToggled); - assert(isConnected); - - // Connect the file menu's next focus change signal. - isConnected = connect(pMenu, &rgMenu::FocusNextView, this, &rgBuildView::HandleFocusNextView); - assert(isConnected); - - // Connect the error location reported by CLI output window to the rgBuildView's handlers. - isConnected = connect(m_pCliOutputWindow, &rgCliOutputView::SwitchToFile, pMenu, &rgMenu::HandleSwitchToFile); - assert(isConnected); - - // Connect the focus file menu signal to the build view's handlers. - isConnected = connect(m_pCliOutputWindow, &rgCliOutputView::FocusNextView, this, &rgBuildView::HandleFocusNextView); - assert(isConnected); - - // Connect the focus output window signal to the build view's handlers. - isConnected = connect(m_pCliOutputWindow, &rgCliOutputView::FocusOutputWindow, this, &rgBuildView::HandleSetOutputWindowFocus); - assert(isConnected); - - // Connect the source editor's scroll-to-line signal. - isConnected = connect(pMenu, &rgMenu::ScrollCodeEditorToLine, this, &rgBuildView::HandleScrollCodeEditorToLine); - assert(isConnected); - - // Connect the "Build Settings" button in the file menu. - rgMenuBuildSettingsItem* pBuildSettingsItem = pMenu->GetBuildSettingsItem(); - const QPushButton* pBuildSettingsFileMenuButton = pBuildSettingsItem->GetBuildSettingsButton(); - isConnected = connect(pBuildSettingsFileMenuButton, &QPushButton::clicked, this, &rgBuildView::HandleBuildSettingsMenuButtonClicked); - assert(isConnected); - - // Connect to the file menu container's mouse click event. - isConnected = connect(m_pFileMenuViewContainer, &rgViewContainer::ViewContainerMouseClickEventSignal, this, &rgBuildView::HandleSetFrameBorderBlack); - assert(isConnected); - - // Connect menu signals. - isConnected = ConnectMenuSignals(); - assert(isConnected); - } -} - -void rgBuildView::HandleFocusPrevView() -{ - assert(m_pViewManager != nullptr); - if (m_pViewManager != nullptr) - { - m_pViewManager->FocusPrevView(); - } -} - -void rgBuildView::HandleSetOutputWindowFocus() -{ - assert(m_pViewManager != nullptr); - if (m_pViewManager != nullptr) - { - m_pViewManager->SetOutputWindowFocus(); - } -} - -void rgBuildView::HandleSetDisassemblyViewFocus() -{ - assert(m_pViewManager != nullptr); - if (m_pViewManager != nullptr) - { - m_pViewManager->SetDisassemblyViewFocus(); - } -} - -void rgBuildView::ConnectBuildSettingsSignals() -{ - // "Save" button. - bool isConnected = connect(m_pSettingsButtonsView, &rgSettingsButtonsView::SaveSettingsButtonClickedSignal, this, &rgBuildView::HandleSaveSettingsButtonClicked); - assert(isConnected); - - // "Restore defaults" button. - isConnected = connect(m_pSettingsButtonsView, &rgSettingsButtonsView::RestoreDefaultSettingsButtonClickedSignal, this, &rgBuildView::HandleRestoreDefaultsSettingsClicked); - assert(isConnected); - - // Connect the save settings view clicked signal. - isConnected = connect(m_pSettingsButtonsView, &rgSettingsButtonsView::SettingsButtonsViewClickedSignal, this, &rgBuildView::SetAPISpecificBorderColor); - assert(isConnected); -} - -void rgBuildView::ConnectFindSignals() -{ - // Connect the find widget's close toggle handler. - bool isConnected = connect(m_pFindWidget, &rgFindTextWidget::CloseWidgetSignal, this, &rgBuildView::HandleFindWidgetVisibilityToggled); - assert(isConnected); -} - -void rgBuildView::ConnectBuildViewSignals() -{ - bool isConnected = connect(this, &rgBuildView::LineCorrelationEnabledStateChanged, this, &rgBuildView::HandleIsLineCorrelationEnabled); - assert(isConnected); - - isConnected = connect(this, &rgBuildView::ProjectBuildSuccess, this, &rgBuildView::HandleProjectBuildSuccess); - assert(isConnected); - - isConnected = connect(qGuiApp, &QGuiApplication::applicationStateChanged, this, &rgBuildView::HandleApplicationStateChanged); - assert(isConnected); - - isConnected = connect(m_pViewManager, &rgViewManager::BuildSettingsWidgetFocusInSignal, this, &rgBuildView::SetAPISpecificBorderColor); - assert(isConnected); - - isConnected = connect(m_pViewManager, &rgViewManager::BuildSettingsWidgetFocusInSignal, this, &rgBuildView::SetDefaultFocusWidget); - assert(isConnected); - - isConnected = connect(m_pViewManager, &rgViewManager::BuildSettingsWidgetFocusOutSignal, this, &rgBuildView::HandleSetFrameBorderBlack); - assert(isConnected); -} - -void rgBuildView::ConnectOutputWindowSignals() -{ - bool isConnected = connect(this, &rgBuildView::ProjectBuildStarted, m_pCliOutputWindow, &rgCliOutputView::HandleBuildStarted); - assert(isConnected); - - isConnected = connect(this, &rgBuildView::ProjectBuildFailure, m_pCliOutputWindow, &rgCliOutputView::HandleBuildEnded); - assert(isConnected); - - isConnected = connect(this, &rgBuildView::ProjectBuildSuccess, m_pCliOutputWindow, &rgCliOutputView::HandleBuildEnded); - assert(isConnected); - - isConnected = connect(this, &rgBuildView::ProjectBuildCanceled, m_pCliOutputWindow, &rgCliOutputView::HandleBuildEnded); - assert(isConnected); - - assert(m_pOutputSplitter != nullptr); - if (m_pOutputSplitter != nullptr) - { - // Connect the handler invoked when the output window splitter is resized. - isConnected = connect(m_pOutputSplitter, &rgMaximizeSplitter::splitterMoved, this, &rgBuildView::HandleSplitterMoved); - assert(isConnected); - } -} - -bool rgBuildView::ConnectDisassemblyViewSignals() -{ - bool isConnected = false; - - assert(m_pDisassemblyView != nullptr); - if (m_pDisassemblyView != nullptr) - { - // Connect the handler invoked when the highlighted correlation line in the input source file should be updated. - isConnected = connect(m_pDisassemblyView, &rgIsaDisassemblyView::InputSourceHighlightedLineChanged, - this, &rgBuildView::HandleHighlightedCorrelationLineUpdated); - assert(isConnected); - - // Connect the rgIsaDisassemblyView's table resized handler. - isConnected = connect(m_pDisassemblyView, &rgIsaDisassemblyView::DisassemblyTableWidthResizeRequested, - this, &rgBuildView::HandleDisassemblyTableWidthResizeRequested); - assert(isConnected); - - // Connect the rgIsaDisassemblyView's Target GPU changed handler. - isConnected = connect(m_pDisassemblyView, &rgIsaDisassemblyView::SelectedTargetGpuChanged, - this, &rgBuildView::HandleSelectedTargetGpuChanged); - assert(isConnected); - - // Connect the rgIsaDisassemblyView's clicked handler. - isConnected = connect(m_pDisassemblyView, &rgIsaDisassemblyView::DisassemblyViewClicked, - this, &rgBuildView::HandleDisassemblyViewClicked); - assert(isConnected); - - // Connect the rgIsaDisassemblyViewTitlebar's double click handler. - m_pDisassemblyView->ConnectTitleBarDoubleClick(m_pDisassemblyViewContainer); - - // Connect the focus disassembly view signal to the build view's handlers. - isConnected = connect(m_pDisassemblyView, &rgIsaDisassemblyView::FocusDisassemblyView, this, &rgBuildView::HandleSetDisassemblyViewFocus); - assert(isConnected); - - // Connect the handler invoked when cli output window should be highlighted. - isConnected = connect(m_pDisassemblyView, &rgIsaDisassemblyView::FocusCliOutputWindow, - this, &rgBuildView::HandleSetOutputWindowFocus); - assert(isConnected); - - // Connect the splitter's frame in focus signal. - if (m_pDisassemblyViewSplitter != nullptr) - { - isConnected = connect(m_pDisassemblyViewSplitter, &rgMaximizeSplitter::FrameInFocusSignal, - m_pDisassemblyView, &rgIsaDisassemblyView::HandleDisassemblyTabViewClicked); - assert(isConnected); - } - - // Connect the source code editor focus in signal. - assert(m_pCurrentCodeEditor != nullptr); - if (m_pCurrentCodeEditor != nullptr) - { - // Connect the source editor's focus in handler. - isConnected = connect(m_pCurrentCodeEditor, &rgSourceCodeEditor::SourceCodeEditorFocusInEvent, - m_pDisassemblyView, &rgIsaDisassemblyView::HandleFocusOutEvent); - assert(isConnected); - - // Connect the source editor's scrollbar disabling signal. - isConnected = connect(m_pCurrentCodeEditor, &rgSourceCodeEditor::DisableScrollbarSignals, - m_pDisassemblyView, &rgIsaDisassemblyView::DisableScrollbarSignals); - assert(isConnected); - - // Connect the source editor's scrollbar enabling signal. - isConnected = connect(m_pCurrentCodeEditor, &rgSourceCodeEditor::EnableScrollbarSignals, - m_pDisassemblyView, &rgIsaDisassemblyView::EnableScrollbarSignals); - assert(isConnected); - } - - rgMenu* pMenu = GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - // Connect the file menu focus in signal. - isConnected = connect(pMenu, &rgMenu::FileMenuFocusInEvent, m_pDisassemblyView, &rgIsaDisassemblyView::HandleFocusOutEvent); - assert(isConnected); - - // Connect the file menu focus in signal to set the current view focus value. - isConnected = connect(pMenu, &rgMenu::FileMenuFocusInEvent, this, &rgBuildView::HandleFileMenuFocusInEvent); - assert(isConnected); - } - - // Connect the view manager focus in signals. - assert(m_pViewManager != nullptr); - if (m_pViewManager != nullptr) - { - isConnected = connect(m_pViewManager, &rgViewManager::FrameFocusInSignal, m_pDisassemblyView, &rgIsaDisassemblyView::HandleDisassemblyTabViewClicked); - assert(isConnected); - - isConnected = connect(m_pViewManager, &rgViewManager::FrameFocusOutSignal, m_pDisassemblyView, &rgIsaDisassemblyView::HandleFocusOutEvent); - assert(isConnected); - } - - // Connect the focus column push button signal to the disassembly view's handlers. - isConnected = connect(m_pCliOutputWindow, &rgCliOutputView::FocusColumnPushButton, m_pDisassemblyView, &rgIsaDisassemblyView::HandleFocusColumnsPushButton); - assert(isConnected); - - // Connect the focus source window signal to the disassembly view's handlers. - isConnected = connect(m_pDisassemblyView, &rgIsaDisassemblyView::FocusSourceWindow, this, &rgBuildView::HandleFocusPreviousView); - assert(isConnected); - - // Connect the switch container size signal from the disassembly view. - isConnected = connect(m_pDisassemblyView, &rgIsaDisassemblyView::SwitchDisassemblyContainerSize, this, &rgBuildView::HandleSwitchContainerSize); - assert(isConnected); - - // Connect API-specific rgBuildView signals to the disassembly view. - ConnectDisassemblyViewApiSpecificSignals(); - } - - assert(m_pDisassemblyViewSplitter != nullptr); - if (m_pDisassemblyViewSplitter != nullptr) - { - // Connect the handler invoked when the disassembly container has been maximized. - isConnected = connect(m_pDisassemblyViewSplitter, &rgMaximizeSplitter::ViewMaximized, - this, &rgBuildView::HandleDisassemblyViewSizeMaximize); - assert(isConnected); - - // Connect the handler invoked when the disassembly container has been restored to normal size. - isConnected = connect(m_pDisassemblyViewSplitter, &rgMaximizeSplitter::ViewRestored, - this, &rgBuildView::HandleDisassemblyViewSizeRestore); - assert(isConnected); - - // Connect the handler invoked when the disassembly splitter is resized. - isConnected = connect(m_pDisassemblyViewSplitter, &rgMaximizeSplitter::splitterMoved, - this, &rgBuildView::HandleSplitterMoved); - assert(isConnected); - } - - return isConnected; -} - -void rgBuildView::HandleSwitchContainerSize() -{ - assert(m_pViewManager != nullptr); - if (m_pViewManager != nullptr) - { - m_pViewManager->SwitchContainerSize(); - } -} - -void rgBuildView::HandleFocusCliOutputWindow() -{ - assert(m_pViewManager != nullptr); - if (m_pViewManager != nullptr) - { - m_pViewManager->FocusNextView(); - } -} - -void rgBuildView::HandleFocusPreviousView() -{ - assert(m_pViewManager != nullptr); - if (m_pViewManager != nullptr) - { - m_pViewManager->FocusPrevView(); - } -} - -void rgBuildView::HandleFileMenuFocusInEvent() -{ - assert(m_pViewManager != nullptr); - if (m_pViewManager != nullptr) - { - m_pViewManager->SetCurrentFocusedView(rgViewManager::rgCurrentFocusedIndex::FileMenuCurrent); - } -} - -void rgBuildView::ConnectSourcecodeEditorSignals(rgSourceCodeEditor* pEditor) -{ - // Connect the file modified handler. - bool isConnected = connect(pEditor, &QPlainTextEdit::modificationChanged, this, &rgBuildView::HandleEditorModificationStateChanged); - assert(isConnected); - - // Connect the source editor's selected line changed handler. - isConnected = connect(pEditor, &rgSourceCodeEditor::SelectedLineChanged, this, &rgBuildView::HandleSourceFileSelectedLineChanged); - assert(isConnected); - - // Connect the source editor's resized handler. - isConnected = connect(pEditor, &rgSourceCodeEditor::EditorResized, this, &rgBuildView::HandleSourceEditorResized); - assert(isConnected); - - // Connect the source editor's hidden handler. - isConnected = connect(pEditor, &rgSourceCodeEditor::EditorHidden, this, &rgBuildView::HandleSourceEditorHidden); - assert(isConnected); - - // Connect the editor titlebar's "Dismiss Message" handler. - isConnected = connect(m_pSourceEditorTitlebar, &rgSourceEditorTitlebar::DismissMsgButtonClicked, - this, &rgBuildView::HandleCodeEditorTitlebarDismissMsgPressed); - assert(isConnected); -} - -void rgBuildView::OpenBuildSettings() -{ - SwitchEditMode(EditMode::BuildSettings); -} - -bool rgBuildView::PopulateBuildView() -{ - bool ret = false; - - // Clear the rgBuildView's file menu and source editor before repopulating it. - ClearBuildView(); - - // Verify that each source file path referenced by the project is valid. - // Allow the user to fix any invalid paths that are found. - bool isProjectSourcesValid = rgUtils::IsProjectSourcePathsValid(m_pProject, m_cloneIndex, this); - - // If the project source paths are valid, proceed. - if (isProjectSourcesValid) - { - bool isPopulated = PopulateMenu(); - rgMenu* pMenu = GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - // Does the menu contain any files after attempting to populate it? - if (pMenu->IsEmpty()) - { - // There are no files to display. Open the rgBuildView in an empty state, and return true. - SwitchEditMode(EditMode::Empty); - } - ret = true; - } - } - - return ret; -} - -void rgBuildView::CreateProjectClone() -{ - if (m_pProject != nullptr) - { - // Create Clone 0, and add it into the new project. - std::string cloneName = rgUtils::GenerateCloneName(m_cloneIndex); - std::shared_ptr pClone0 = m_pFactory->CreateProjectClone(cloneName); - assert(pClone0 != nullptr); - if (pClone0 != nullptr) - { - m_pProject->m_clones.push_back(pClone0); - - // Save the project file. - rgConfigManager& configManager = rgConfigManager::Instance(); - configManager.SaveProjectFile(m_pProject); - - if (m_pFileMenuTitlebar != nullptr) - { - // Set project name title in file menu. - std::stringstream title; - title << rgUtils::GetProjectTitlePrefix(m_pProject->m_api) << m_pProject->m_projectName; - m_pFileMenuTitlebar->SetTitle(title.str().c_str()); - } - - // Indicate that a new project has been loaded. - emit ProjectLoaded(m_pProject); - - // Create a new build settings view after a new project has been created. - CreateBuildSettingsView(); - } - } -} - -void rgBuildView::BuildCurrentProject() -{ - // Destroy outputs from previous builds. - DestroyProjectBuildArtifacts(); - - // Clear the output window. - m_pCliOutputWindow->ClearText(); - - // Set the "is currently building" flag. - HandleIsBuildInProgressChanged(true); - - // Notify the system that a build has started. - emit ProjectBuildStarted(); - - // The function that will be invoked by the build thread. - auto backgroundTask = [&] - { - // Build an output path where all of the build artifacts will be dumped to. - std::string outputPath = CreateProjectBuildOutputPath(); - - // Create the output directory if it doesn't already exist. - bool isOk = rgUtils::IsDirExists(outputPath); - if (!isOk) - { - isOk = rgUtils::CreateFolder(outputPath); - assert(isOk); - } - - if (isOk) - { - // Create a new output folder specific to the current clone's build artifacts. - std::stringstream cloneFolderName; - cloneFolderName << STR_CLONE_FOLDER_NAME; - cloneFolderName << m_cloneIndex; - - // Append the clone folder to the output folder. - isOk = rgUtils::AppendFolderToPath(outputPath, cloneFolderName.str(), outputPath); - if (isOk) - { - // Append a path separator to the new output path. - isOk = rgUtils::AppendPathSeparator(outputPath, outputPath); - assert(isOk); - - // Create the output folder if it does not exist. - if (!rgUtils::IsDirExists(outputPath)) - { - isOk = rgUtils::CreateFolder(outputPath); - assert(isOk); - } - } - } - - // If the correct build output paths exist, proceed with building the project. - if (isOk) - { - // Set up the function pointer responsible for handling new output from the CLI invocation. - using std::placeholders::_1; - std::function appendBuildOutput = std::bind(&rgBuildView::HandleNewCLIOutputString, this, _1); - - // Build the current project clone. - m_cancelBuildSignal = false; - - // Verify that the clone index is valid. - int numClones = static_cast(m_pProject->m_clones.size()); - bool isCloneIndexValid = (m_cloneIndex >= 0 && m_cloneIndex < numClones); - assert(isCloneIndexValid); - if (isCloneIndexValid) - { - // Attempt to build the clone. - bool isProjectBuilt = false; - std::vector gpusWithBuildOutputs; - rgProjectAPI currentApi = rgConfigManager::Instance().GetCurrentAPI(); - - // Get the binary output file name and create a project. - assert(m_pProject->m_clones[m_cloneIndex]->m_pBuildSettings != nullptr); - if (currentApi == rgProjectAPI::OpenCL) - { - std::shared_ptr pProjectSettings = m_pProject->m_clones[m_cloneIndex]->m_pBuildSettings; - std::string binaryName = STR_BUILD_SETTINGS_OUTPUT_BINARY_FILE_NAME; - isProjectBuilt = rgCliLauncher::BuildProjectCloneOpenCL(m_pProject, m_cloneIndex, outputPath, binaryName, appendBuildOutput, gpusWithBuildOutputs, m_cancelBuildSignal); - } - else if (currentApi == rgProjectAPI::Vulkan) - { - std::shared_ptr pProjectSettings = m_pProject->m_clones[m_cloneIndex]->m_pBuildSettings; - std::string binaryName = STR_BUILD_SETTINGS_OUTPUT_BINARY_FILE_NAME; - assert(pProjectSettings != nullptr); - if (pProjectSettings != nullptr) - { - binaryName = pProjectSettings->m_binaryFileName; - } - isProjectBuilt = rgCliLauncher::BuildProjectCloneVulkan(m_pProject, m_cloneIndex, outputPath, binaryName, appendBuildOutput, gpusWithBuildOutputs, m_cancelBuildSignal); - } - - // Verify that the build was not canceled. - if (!m_cancelBuildSignal) - { - // If the project was built successfully, parse the session metadata file and populate an rgCliOutput structure. - if (isProjectBuilt) - { - // Load the build outputs in the project's directory. - std::string projectDirectory; - bool isOk = rgUtils::ExtractFileDirectory(m_pProject->m_projectFileFullPath, projectDirectory); - if (isOk) - { - bool isOutputLoaded = LoadBuildOutput(projectDirectory, &gpusWithBuildOutputs); - assert(isOutputLoaded); - if (isOutputLoaded) - { - // Trigger the build success signal. - emit ProjectBuildSuccess(); - } - else - { - // Trigger the build failure signal. - emit ProjectBuildFailure(); - } - } - } - } - else - { - // Trigger the build cancellation signal. - emit ProjectBuildCanceled(); - - // Notify the user that the build was canceled. - HandleNewCLIOutputString(STR_STATUS_BAR_BUILD_CANCELED); - } - } - } - }; - - // Launch the build thread. - std::thread buildThread(backgroundTask); - buildThread.detach(); -} - -bool rgBuildView::CreateFileMenu() -{ - // Create the API-specific file menu. - bool isOk = CreateMenu(this); - if (isOk) - { - // Retrieve a pointer to the file menu. - rgMenu* pMenu = GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - assert(m_pProject != nullptr); - if (m_pProject != nullptr) - { - // Ensure that the incoming clone index is valid for the current project. - bool isValidRange = (m_cloneIndex >= 0 && m_cloneIndex < m_pProject->m_clones.size()); - assert(isValidRange); - - if (isValidRange) - { - std::shared_ptr pProjectClone = m_pProject->m_clones[m_cloneIndex]; - - // Initialize the menu with default items. - pMenu->InitializeDefaultMenuItems(pProjectClone); - } - } - } - - // Create the menu title bar where the program name is displayed. - m_pFileMenuTitlebar = new rgMenuTitlebar(); - - // Register the menu title bar with scaling manager. - ScalingManager::Get().RegisterObject(m_pFileMenuTitlebar); - - // Wrap the file menu in a view container with its title bar. - m_pFileMenuViewContainer->SetMainWidget(pMenu); - m_pFileMenuViewContainer->SetTitlebarWidget(m_pFileMenuTitlebar); - m_pFileMenuViewContainer->setObjectName(STR_RG_FILE_MENU_VIEW_CONTAINER); - - // Connect signals for the file menu. - ConnectFileSignals(); - } - - return isOk; -} - -bool rgBuildView::CreateNewEmptyProject() -{ - bool ret = false; - std::string projectName; - - // Get the global configuration. - rgConfigManager& configManager = rgConfigManager::Instance(); - std::shared_ptr pGlobalSettings = configManager.GetGlobalConfig(); - - if (pGlobalSettings->m_useDefaultProjectName == true) - { - // Generate a default project name. - projectName = rgUtils::GenerateDefaultProjectName(); - - // Create a project instance with the given name. - m_pProject = m_pFactory->CreateProject(projectName, rgConfigManager::GenerateProjectFilepath(projectName)); - assert(m_pProject != nullptr); - - // Create the clone - CreateProjectClone(); - - // We're done. - ret = true; - } - else - { - // Repeatedly ask the user for a project name when their provided name is invalid. - bool isValidProjectPath = false; - do - { - rgRenameProjectDialog* pRenameProjectDialog = m_pFactory->CreateRenameProjectDialog(projectName, m_pParent); - - // Prompt the user for the project name. - int rc = pRenameProjectDialog->exec(); - if (rc == QDialog::Accepted) - { - // Generate the path to where the new project's project file would live. - std::string projectFilePath = rgConfigManager::GenerateProjectFilepath(projectName); - - // The path for the new project is valid only if it doesn't already exist. - isValidProjectPath = !rgUtils::IsFileExists(projectFilePath); - if (isValidProjectPath) - { - // Create a project instance with the given name. - m_pProject = m_pFactory->CreateProject(projectName, projectFilePath); - assert(m_pProject != nullptr); - - // Create the clone. - CreateProjectClone(); - - // We're done. - ret = true; - } - else - { - // Let the user know that the project name they have provided has already been used. - rgUtils::ShowErrorMessageBox(STR_NEW_PROJECT_ALREADY_EXISTS, this); - } - } - else - { - break; - } - - // Free memory. - RG_SAFE_DELETE(pRenameProjectDialog); - - } while (!isValidProjectPath); - } - - return ret; -} - -void rgBuildView::InitializeView() -{ - // Create an empty panel to insert alongside the file menu when no files are open. - m_pEmptyPanel = new QWidget(this); - - // Create container for source view widgets. - m_pSourceViewStack = new QWidget(); - QVBoxLayout* pLayout = new QVBoxLayout(); - pLayout->setContentsMargins(0, 0, 0, 0); - m_pSourceViewStack->setLayout(pLayout); - - // Wrap the source code stack in a view container and a source editor titlebar. - m_pSourceViewContainer = new rgViewContainer(); - m_pSourceViewContainer->SetMainWidget(m_pSourceViewStack); - m_pSourceEditorTitlebar = new rgSourceEditorTitlebar(m_pSourceViewContainer); - m_pSourceViewContainer->SetTitlebarWidget(m_pSourceEditorTitlebar); - m_pSourceViewContainer->setObjectName(STR_RG_SOURCE_VIEW_CONTAINER); - - // Create the disassembly view splitter. - m_pDisassemblyViewSplitter = new rgMaximizeSplitter(this); - m_pDisassemblyViewSplitter->setOrientation(Qt::Orientation::Horizontal); - m_pDisassemblyViewSplitter->setChildrenCollapsible(false); - - // Add the source view container to the disassembly view splitter. - m_pDisassemblyViewSplitter->AddMaximizableWidget(m_pSourceViewContainer); - - // Set up the splitter between the file menu and the rest of the views. - m_pFileMenuSplitter = new QSplitter(Qt::Orientation::Horizontal, this); - - // Create the file menu's container. - m_pFileMenuViewContainer = new rgViewContainer(); - - // Set the fixed width of file menu container. - m_pFileMenuViewContainer->setFixedWidth(s_FILE_MENU_VIEW_CONTAINER_WIDTH); - - // Add the file menu and the disassembly view splitter to the file menu splitter. - m_pFileMenuSplitter->addWidget(m_pFileMenuViewContainer); - m_pFileMenuSplitter->addWidget(m_pDisassemblyViewSplitter); - - // The file menu should not grow with the window, while the source code view should. - m_pFileMenuSplitter->setStretchFactor(0, 0); - m_pFileMenuSplitter->setStretchFactor(1, 1); - - // Disable the file menu splitter. - m_pFileMenuSplitter->handle(1)->setDisabled(true); - - // Create the output window. - m_pCliOutputWindow = new rgCliOutputView(this); - - // Wrap the build output view in a view container with an embedded titlebar. - m_pBuildOutputViewContainer = new rgViewContainer(); - m_pBuildOutputViewContainer->SetMainWidget(m_pCliOutputWindow); - m_pBuildOutputViewContainer->setObjectName(STR_RG_BUILD_OUTPUT_VIEW_CONTAINER); - - // Create a vertical splitter to divide the rgBuildView's FileMenu/SourceEditors and the Output Window. - m_pOutputSplitter = new rgMaximizeSplitter(this); - m_pOutputSplitter->setOrientation(Qt::Orientation::Vertical); - - // Connect the build output window signals. - ConnectOutputWindowSignals(); - - // Add the file menu's splitter and the output window to the splitter. - m_pOutputSplitter->addWidget(m_pFileMenuSplitter); - m_pOutputSplitter->AddMaximizableWidget(m_pBuildOutputViewContainer); - - // Let the file menu and code editor resize, and the output window will stay vertically squished. - m_pOutputSplitter->setStretchFactor(0, 6); - m_pOutputSplitter->setStretchFactor(1, 1); - m_pOutputSplitter->setCollapsible(1, false); - - // Create a main window layout, and add the root-level splitter widget. - QVBoxLayout* pMainLayout = new QVBoxLayout(this); - pMainLayout->addWidget(m_pOutputSplitter); - this->setLayout(pMainLayout); - - // Restore the previous session rgBuildView layout. - RestoreViewLayout(); - - // Setup view manager. - m_pViewManager = new rgViewManager(this); - m_pViewManager->AddView(m_pFileMenuViewContainer, true); - m_pViewManager->AddView(m_pSourceViewContainer, true); - m_pViewManager->AddView(m_pBuildOutputViewContainer, true); - - // Connect signals for the Build View. - ConnectBuildViewSignals(); - - // Declare EditMode as a meta type so it can be used with slots/signals. - int id = qRegisterMetaType(); - Q_UNUSED(id); - - // Create the file menu. - CreateFileMenu(); - - // Update the menu's title bar to display the Project name. - assert(m_pFileMenuTitlebar != nullptr); - assert(m_pProject != nullptr); - if (m_pFileMenuTitlebar != nullptr && m_pProject != nullptr) - { - // Set project name title in file menu. - std::stringstream title; - title << rgUtils::GetProjectTitlePrefix(m_pProject->m_api) << m_pProject->m_projectName; - m_pFileMenuTitlebar->SetTitle(title.str().c_str()); - } - - // Create a new build settings view after a new project has been created. - CreateBuildSettingsView(); - - // Create and initialize views specific to the current mode only. - InitializeModeSpecificViews(); - - // Apply the stylesheets for the build settings. - rgProjectAPI currentApi = rgConfigManager::Instance().GetCurrentAPI(); - std::shared_ptr pFactory = rgFactory::CreateFactory(currentApi); - assert(pFactory != nullptr); - if (pFactory != nullptr) - { - std::shared_ptr pAppState = pFactory->CreateAppState(); - assert(pAppState != nullptr); - if (pAppState != nullptr) - { - SetBuildSettingsStylesheet(pAppState->GetBuildSettingsViewStylesheet()); - } - } -} - -void rgBuildView::SetBuildSettingsStylesheet(const std::string& stylesheet) -{ - assert(m_pBuildSettingsView != nullptr); - if (m_pBuildSettingsView != nullptr) - { - m_pBuildSettingsView->setStyleSheet(stylesheet.c_str()); - } -} - -bool rgBuildView::HasSourceCodeEditors() const -{ - return m_sourceCodeEditors.empty(); -} - -bool rgBuildView::HasProject() const -{ - return (m_pProject != nullptr); -} - -bool rgBuildView::LoadBuildOutput(const std::string& projectFolder, const std::vector* pTargetGpus) -{ - bool isLoaded = false; - - std::vector targetGpuFamilyResultsToLoad; - - // Build a list of possible target GPUs to attempt to load results for, based on the supported GPUs for the current mode. - std::shared_ptr pVersionInfo = rgConfigManager::Instance().GetVersionInfo(); - assert(pVersionInfo != nullptr); - if (pVersionInfo != nullptr) - { - // Determine which GPU architectures and families are supported in the current mode. - const std::string& currentMode = rgConfigManager::Instance().GetCurrentModeString(); - auto modeArchitecturesIter = pVersionInfo->m_gpuArchitectures.find(currentMode); - if (modeArchitecturesIter != pVersionInfo->m_gpuArchitectures.end()) - { - const std::vector& modeArchitectures = modeArchitecturesIter->second; - - // Step through each architecture. - for (auto architectureIter = modeArchitectures.begin(); architectureIter != modeArchitectures.end(); ++architectureIter) - { - // Step through each family within the architecture. - for (auto familyIter = architectureIter->m_gpuFamilies.begin(); familyIter != architectureIter->m_gpuFamilies.end(); ++familyIter) - { - // Add the family name to the list of targets to attempt to load results for. - targetGpuFamilyResultsToLoad.push_back(familyIter->m_familyName); - } - } - } - } - - // Build a path to the project's output directory. - std::string buildOutputPath = CreateProjectBuildOutputPath(); - - // Generate a clone name string based on the current clone index. - std::string outputFolderPath; - - bool isOk = rgUtils::AppendFolderToPath(projectFolder, STR_OUTPUT_FOLDER_NAME, outputFolderPath); - assert(isOk); - if (isOk) - { - // Append the clone folder to the build output path. - std::string cloneNameString = rgUtils::GenerateCloneName(m_cloneIndex); - bool isOk = rgUtils::AppendFolderToPath(outputFolderPath, cloneNameString, outputFolderPath); - assert(isOk); - if (isOk) - { - const std::vector* pGpusToLoad = nullptr; - if (pTargetGpus != nullptr) - { - // If a list of GPUs was provided, attempt to load output for each. - pGpusToLoad = pTargetGpus; - } - else - { - // When no target GPUs to load are provided, fall back to attempting to load results for all possible target GPUs. - // If the session metadata for the target GPU doesn't exist, there's no disassembly to load. - pGpusToLoad = &targetGpuFamilyResultsToLoad; - } - - assert(pGpusToLoad != nullptr); - if (pGpusToLoad != nullptr) - { - // Attempt to load outputs for each GPU that was targeted. - for (const std::string& currentGpu : *pGpusToLoad) - { - std::stringstream metadataFilenameStream; - metadataFilenameStream << currentGpu; - metadataFilenameStream << "_"; - metadataFilenameStream << STR_SESSION_METADATA_FILENAME; - bool isLoadedForGpu = false; - - std::string fullMetadataFilePath; - isOk = rgUtils::AppendFileNameToPath(outputFolderPath, metadataFilenameStream.str(), fullMetadataFilePath); - assert(isOk); - if (isOk) - { - // Does the session metadata file exist? - bool isMetadataExists = rgUtils::IsFileExists(fullMetadataFilePath); - if (isMetadataExists) - { - // Emit a signal so the file coloring in the file menu is updated. - emit UpdateFileColoring(); - - std::shared_ptr pGpuOutput = nullptr; - isLoadedForGpu = LoadSessionMetadata(fullMetadataFilePath, pGpuOutput); - - if (isLoadedForGpu && pGpuOutput != nullptr) - { - // Add the outputs to the map to store per-GPU results. - m_buildOutputs[currentGpu] = pGpuOutput; - isLoaded = true; - } - } - } - } - } - } - } - - return isLoaded; -} - -bool rgBuildView::LoadProjectFile(const std::string& projectFilePath) -{ - bool ret = false; - - rgConfigManager& configManager = rgConfigManager::Instance(); - - // Reset the view state before loading the project file. - ResetView(); - - // Get the configuration manager to load a project file. - m_pProject = configManager.LoadProjectFile(projectFilePath); - - // Update the window title if the project loaded correctly. - assert(m_pProject != nullptr); - if (m_pProject != nullptr) - { - // Signal that a new project has been loaded into the rgBuildView. - emit ProjectLoaded(m_pProject); - - ret = true; - } - else - { - // Tell the user that the project file failed to load. - std::stringstream errorStream; - errorStream << STR_ERR_CANNOT_LOAD_PROJECT_FILE << " "; - errorStream << projectFilePath; - rgUtils::ShowErrorMessageBox(errorStream.str().c_str(), this); - } - - return ret; -} - -void rgBuildView::ReloadFile(const std::string& filePath) -{ - SetSourceCodeText(filePath); -} - -void rgBuildView::SaveCurrentFile() -{ - bool isSourceCodeEditorValid = (m_pCurrentCodeEditor != nullptr); - assert(isSourceCodeEditorValid); - if (isSourceCodeEditorValid) - { - rgMenu* pMenu = GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr && pMenu->GetSelectedFileItem() != nullptr) - { - std::string currentFilename = pMenu->GetSelectedFilePath(); - - // Ask the user for a filename if none exists so far. - if (currentFilename.empty()) - { - std::string filter = std::string(STR_FILE_DIALOG_FILTER_OPENCL) + ";;" + STR_FILE_DIALOG_FILTER_ALL; - currentFilename = QFileDialog::getSaveFileName(this, STR_FILE_DIALOG_SAVE_NEW_FILE, - rgConfigManager::Instance().GetLastSelectedFolder().c_str(), filter.c_str()).toStdString(); - - // Extract directory from full path. - std::string fileDirectory; - bool isOk = rgUtils::ExtractFileDirectory(currentFilename, fileDirectory); - assert(isOk); - - if (isOk) - { - // Update last selected directory in global config. - std::shared_ptr pGlobalConfig = rgConfigManager::Instance().GetGlobalConfig(); - pGlobalConfig->m_lastSelectedDirectory = fileDirectory; - } - } - - // Write the editor text to file if the file path is valid. - if (!currentFilename.empty()) - { - SaveEditorTextToFile(m_pCurrentCodeEditor, currentFilename); - } - } - } -} - -rgUnsavedItemsDialog::UnsavedFileDialogResult rgBuildView::RequestSaveFile(const std::string& fullPath) -{ - QStringList unsavedFiles; - - // Get editor that corresponds to this filepath. - rgSourceCodeEditor* pEditor = GetEditorForFilepath(fullPath); - - bool isEditorValid = (pEditor != nullptr); - assert(isEditorValid); - - // Add file to the list if it is unsaved (modified). - if (isEditorValid && pEditor->document()->isModified()) - { - unsavedFiles << fullPath.c_str(); - } - - // Ask the user to save edited files. - rgUnsavedItemsDialog::UnsavedFileDialogResult userResponse = RequestSaveFiles(unsavedFiles); - return userResponse; -} - -bool rgBuildView::ShowSaveDialog(rgFilesToSave filesToSave /* = rgFilesToSave::All */, bool shouldSaveSourceFiles /* = false */) -{ - bool ret = false; - QStringList unsavedFiles; - - // This flag would be set to true if the user chose to cancel the operation. - // In that case, we should return false from this function and the subsequent - // logic would make sure to cancel the entire operation (as part of which showing - // the save dialog was required). - bool isCanceled = false; - - if (shouldSaveSourceFiles && (filesToSave == rgFilesToSave::SourceFiles || filesToSave == rgFilesToSave::All)) - { - // Add unsaved source files to the list of files that must be saved. - GetUnsavedSourceFiles(unsavedFiles); - } - - // Does the user have pending Build Settings changes to save? - bool pendingBuildSettingsChanges = false; - - // If the build settings have been modified but the changes are still pending, add the build settings file to the list. - if (m_pBuildSettingsView != nullptr) - { - if (filesToSave == rgFilesToSave::BuildSettings || filesToSave == rgFilesToSave::All) - { - pendingBuildSettingsChanges = m_pBuildSettingsView->GetHasPendingChanges(); - if (pendingBuildSettingsChanges) - { - // Add a build settings item to the unsaved files list. - unsavedFiles << STR_MENU_BUILD_SETTINGS; - } - } - - // File changes are ignored unless it is: - // Project close. - // App exit. - if (pendingBuildSettingsChanges || shouldSaveSourceFiles) - { - // Ask the user if they want to save files with modifications. - rgUnsavedItemsDialog::UnsavedFileDialogResult saveResult = rgUnsavedItemsDialog::Yes; - if (!unsavedFiles.empty()) - { - saveResult = RequestSaveFiles(unsavedFiles); - switch (saveResult) - { - case rgUnsavedItemsDialog::No: - { - if (pendingBuildSettingsChanges) - { - // If the user clicks "No," they don't care about the pending changes. Revert them before moving on. - m_pBuildSettingsView->RevertPendingChanges(); - } - else - { - // Discard the changes from all editors. - for (const QString& unsavedFilePath : unsavedFiles) - { - rgSourceCodeEditor* pEditor = GetEditorForFilepath(unsavedFilePath.toStdString()); - DiscardEditorChanges(pEditor); - } - } - } - break; - case rgUnsavedItemsDialog::Cancel: - isCanceled = true; - break; - default: - break; - } - } - - // If "Yes", proceed with the build. If "No", proceed with the build since the pending settings have been reverted. - // If "Cancel," stop the attempt to build and continue where the user left off. - ret = (saveResult == rgUnsavedItemsDialog::Yes || saveResult == rgUnsavedItemsDialog::No); - } - - ret = (ret || (!pendingBuildSettingsChanges)) && !isCanceled; - } - else - { - // Return true if the build settings view was not created yet. - // This happens when the user has not created or opened a project, - // and attempts to quit the application. - ret = true; - } - - return ret; -} - -rgUnsavedItemsDialog::UnsavedFileDialogResult rgBuildView::RequestSaveFiles(const QStringList& unsavedFiles) -{ - rgUnsavedItemsDialog::UnsavedFileDialogResult result = rgUnsavedItemsDialog::Cancel; - - // Don't display the dialog if there are no files, just return. - if (unsavedFiles.size() > 0) - { - // Create a modal unsaved file dialog. - rgUnsavedItemsDialog* pUnsavedFileDialog = new rgUnsavedItemsDialog(this); - pUnsavedFileDialog->setModal(true); - pUnsavedFileDialog->setWindowTitle(STR_UNSAVED_ITEMS_DIALOG_TITLE); - - // Add unsaved files to the dialog list. - pUnsavedFileDialog->AddFiles(unsavedFiles); - - // Register the dialog with the scaling manager. - pUnsavedFileDialog->show(); - ScalingManager::Get().RegisterObject(pUnsavedFileDialog); - - // Center the dialog on the view (registering with the scaling manager - // shifts it out of the center so we need to manually center it). - rgUtils::CenterOnWidget(pUnsavedFileDialog, this); - - // Execute the dialog and get the result. - result = static_cast(pUnsavedFileDialog->exec()); - - switch (result) - { - case rgUnsavedItemsDialog::Yes: - // Save all files and indicated dialog accepted. - if (!SaveFiles(unsavedFiles)) - { - // The files weren't saved, so the action in-flight should be cancelled. - result = rgUnsavedItemsDialog::Cancel; - } - break; - // If the user chooses No or Cancel, nothing needs to happen except for making the dialog disappear. - case rgUnsavedItemsDialog::No: - case rgUnsavedItemsDialog::Cancel: - break; - default: - // Shouldn't get here. - assert(false); - } - - // Free memory. - RG_SAFE_DELETE(pUnsavedFileDialog); - } - else - { - // No files need to be saved because none have been modified. - result = rgUnsavedItemsDialog::Yes; - } - - return result; -} - -bool rgBuildView::SaveFiles(const QStringList& unsavedFiles) -{ - bool isSaved = true; - - // Step through each of the files with pending changes. - auto stringListIter = unsavedFiles.begin(); - while (stringListIter != unsavedFiles.end()) - { - // If the file isn't the Build Settings item, it's a path to an input source file. - const std::string& filePath = stringListIter->toStdString(); - if (filePath.compare(STR_MENU_BUILD_SETTINGS) == 0) - { - // Submit all pending changes and save the build settings file. - if (m_pBuildSettingsView != nullptr) - { - isSaved = m_pBuildSettingsView->SaveSettings(); - } - } - else - { - SaveSourceFile(stringListIter->toStdString().c_str()); - } - - stringListIter++; - - if (!isSaved) - { - break; - } - } - - return isSaved; -} - -void rgBuildView::SaveSourceFile(const std::string& sourceFilePath) -{ - rgSourceCodeEditor* pEditor = GetEditorForFilepath(sourceFilePath); - - bool isEditorValid = (pEditor != nullptr); - assert(isEditorValid); - - if (isEditorValid) - { - SaveEditorTextToFile(pEditor, sourceFilePath); - } -} - -bool rgBuildView::SaveCurrentState() -{ - // Save all source files when a new build is started. - QStringList unsavedSources; - GetUnsavedSourceFiles(unsavedSources); - if (!unsavedSources.empty()) - { - for (const QString& sourceFilePath : unsavedSources) - { - SaveSourceFile(sourceFilePath.toStdString().c_str()); - } - } - - // Save the current project first. - SaveCurrentFile(); - - // The build settings must be saved in order to proceed with a build. - bool shouldProceedWithBuild = ShowSaveDialog(rgFilesToSave::BuildSettings); - - return shouldProceedWithBuild; -} - -bool rgBuildView::RequestRemoveAllFiles() -{ - bool isSaveAccepted = ShowSaveDialog(rgBuildView::rgFilesToSave::All, true); - if (isSaveAccepted) - { - rgMenu* pMenu = GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - // Remove all file menu items. - auto editorIter = m_sourceCodeEditors.begin(); - while (editorIter != m_sourceCodeEditors.end()) - { - std::string fullPath = editorIter->first; - pMenu->RemoveItem(fullPath); - RemoveEditor(fullPath); - - // Keep getting first item until all are removed. - editorIter = m_sourceCodeEditors.begin(); - } - } - } - - return isSaveAccepted; -} - -void rgBuildView::SetSourceCodeText(const std::string& fileFullPath) -{ - QString srcCode; - - if (m_pCurrentCodeEditor != nullptr) - { - if (!fileFullPath.empty()) - { - bool isOk = rgUtils::ReadTextFile(fileFullPath, srcCode); - if (isOk) - { - // Save the current line number and vertical scroll position. - int currentLineNumber = m_pCurrentCodeEditor->GetSelectedLineNumber(); - const int vScrollPosition = m_pCurrentCodeEditor->verticalScrollBar()->value(); - - // Set the text. - m_pCurrentCodeEditor->setText(srcCode); - - // Remember most recent time file was modified. - QFileInfo fileInfo(fileFullPath.c_str()); - m_fileModifiedTimeMap[m_pCurrentCodeEditor] = fileInfo.lastModified(); - - // Indicate that a freshly loaded file is considered unmodified. - m_pCurrentCodeEditor->document()->setModified(false); - - // Set the highlighted line. - QList lineNumbers; - lineNumbers << currentLineNumber; - m_pCurrentCodeEditor->SetHighlightedLines(lineNumbers); - - // Restore the cursor position after reloading the file. - QTextCursor cursor(m_pCurrentCodeEditor->document()->findBlockByLineNumber(currentLineNumber - 1)); - m_pCurrentCodeEditor->setTextCursor(cursor); - if (currentLineNumber <= m_pCurrentCodeEditor->document()->blockCount()) - { - m_pCurrentCodeEditor->verticalScrollBar()->setValue(vScrollPosition); - } - } - } - else - { - m_pCurrentCodeEditor->setText(""); - m_pCurrentCodeEditor->document()->setModified(false); - } - } -} - -void rgBuildView::ToggleDisassemblyViewVisibility(bool isVisible) -{ - bool isViewCreated = m_pDisassemblyViewContainer != nullptr && m_pDisassemblyView != nullptr; - - // If the disassembly view is being hidden, the splitter may have to be restored before hiding the view. - if (!isVisible) - { - assert(m_pDisassemblyViewSplitter != nullptr); - if (m_pDisassemblyViewSplitter != nullptr) - { - // Is there a container that's currently maximized in the splitter? - QWidget* pMaximizedWidget = m_pDisassemblyViewSplitter->GetMaximizedWidget(); - if (pMaximizedWidget == m_pDisassemblyViewContainer) - { - // Restore the maximized view before switching to the build settings. - m_pDisassemblyViewSplitter->Restore(); - } - } - } - - if (isVisible) - { - // The view needs to exist if we try to make it visible. - assert(isViewCreated); - } - - if (isViewCreated) - { - // Show the disassembly view container to display the tables within. - m_pDisassemblyViewContainer->setVisible(isVisible); - m_pDisassemblyViewContainer->SetHiddenState(!isVisible); - } - - assert(m_pSourceViewContainer != nullptr); - if (m_pSourceViewContainer != nullptr) - { - // Only allow the source editor container to be maximized/restored when the disassembly view is available. - m_pSourceViewContainer->SetIsMaximizable(isVisible); - } -} - -void rgBuildView::HandleSourceEditorHidden() -{ - // Hide the find widget. - ToggleFindWidgetVisibility(false); -} - -void rgBuildView::HandleSourceEditorResized() -{ - if (m_pFindWidget != nullptr) - { - UpdateFindWidgetGeometry(); - } -} - -void rgBuildView::HandleSourceEditorOpenHeaderRequest(const QString& path) -{ - // Check if the file exists. - assert(m_pProject != nullptr); - assert(m_cloneIndex < m_pProject->m_clones.size()); - assert(m_pProject->m_clones[m_cloneIndex] != nullptr); - assert(m_pProject->m_clones[m_cloneIndex]->m_pBuildSettings != nullptr); - if (m_pProject != nullptr && m_cloneIndex < m_pProject->m_clones.size() && - m_pProject->m_clones[m_cloneIndex] != nullptr) - { - const std::vector& includePaths = - m_pProject->m_clones[m_cloneIndex]->m_pBuildSettings->m_additionalIncludeDirectories; - - // The path to the file that we would like to open. - std::string pathToOpen; - - // Try to find if any file with that full path exists on the system. - bool isExist = rgUtils::IsFileExists(path.toStdString()); - if (!isExist) - { - // Try the local directory. - assert(m_pCurrentCodeEditor != nullptr); - if (m_pCurrentCodeEditor != nullptr) - { - // Get the directory of the currently edited file. - std::string fileDirectory; - std::string filePath = GetFilepathForEditor(m_pCurrentCodeEditor); - bool isDirExtracted = rgUtils::ExtractFileDirectory(filePath, fileDirectory); - if (isDirExtracted) - { - // Search for the user's file in the directory - // where the currently edited file is located. - std::stringstream fullPath; - fullPath << fileDirectory << "/" << path.toStdString(); - if (rgUtils::IsFileExists(fullPath.str())) - { - // We found it. - pathToOpen = fullPath.str(); - isExist = true; - } - } - } - - if (!isExist) - { - // Try to create the path for each of the Additional Include paths. - for (const std::string includePath : includePaths) - { - std::stringstream fullPath; - fullPath << includePath; - fullPath << "/" << path.toStdString(); - if (rgUtils::IsFileExists(fullPath.str())) - { - pathToOpen = fullPath.str(); - isExist = true; - break; - } - } - } - } - else - { - pathToOpen = path.toStdString(); - } - - if (isExist) - { - // Open the include file. - bool isLaunched = OpenIncludeFile(pathToOpen); - if (!isLaunched) - { - // Notify the user that the viewer app could not be launched. - std::stringstream errMsg; - errMsg << STR_ERR_COULD_NOT_OPEN_HEADER_FILE_VIEWER << - rgConfigManager::Instance().GetIncludeFileViewer(); - emit SetStatusBarText(errMsg.str()); - } - } - else - { - // Notify the user that the header could not be located. - emit SetStatusBarText(STR_ERR_COULD_NOT_LOCATE_HEADER_FILE); - } - } -} - -void rgBuildView::HandleCodeEditorTitlebarDismissMsgPressed() -{ - assert(m_pCurrentCodeEditor != nullptr); - if (m_pCurrentCodeEditor != nullptr) - { - m_pCurrentCodeEditor->SetTitleBarText(""); - } -} - -void rgBuildView::HandleHighlightedCorrelationLineUpdated(int lineNumber) -{ - // A list that gets filled with correlated line numbers to highlight in the source editor. - QList highlightedLines; - - // Only fill up the list with valid correlated lines if possible. Otherwise, nothing will get highlighted. - bool isCorrelationEnabled = IsLineCorrelationEnabled(m_pCurrentCodeEditor); - if (isCorrelationEnabled) - { - // Only scroll to the highlighted line if it's a valid line number. - if (lineNumber != kInvalidCorrelationLineIndex) - { - highlightedLines.push_back(lineNumber); - - // Scroll the source editor to show the highlighted line. - m_pCurrentCodeEditor->ScrollToLine(lineNumber); - } - } - - // Add the correlated input source line number to the editor's highlight list. - m_pCurrentCodeEditor->SetHighlightedLines(highlightedLines); -} - -void rgBuildView::HandleIsLineCorrelationEnabled(rgSourceCodeEditor* pEditor, bool isEnabled) -{ - // Update the correlation state flag. - std::string filePath = GetFilepathForEditor(pEditor); - UpdateSourceFileCorrelationState(filePath, isEnabled); - - if (!isEnabled) - { - // Invalidate the highlighted correlation lines within the source editor and disassembly views. - HandleSourceFileSelectedLineChanged(pEditor, kInvalidCorrelationLineIndex); - HandleHighlightedCorrelationLineUpdated(kInvalidCorrelationLineIndex); - } - else - { - // Use the currently-selected line in the source editor to highlight correlated lines in the disassembly table. - assert(pEditor != nullptr); - if (pEditor != nullptr) - { - // Trigger a line correlation update by re-selecting the current line in the source editor. - int selectedLineNumber = pEditor->GetSelectedLineNumber(); - HandleSourceFileSelectedLineChanged(pEditor, selectedLineNumber); - } - } - - // Update the editor's titlebar text. - if (m_pCurrentCodeEditor == pEditor) - { - UpdateSourceEditorTitlebar(pEditor); - } -} - -void rgBuildView::HandleBuildSettingsPendingChangesStateChanged(bool hasPendingChanges) -{ - // Pull the build settings menu item out of the file menu. - rgMenu* pMenu = GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - rgMenuBuildSettingsItem* pBuildSettingsMenuItem = pMenu->GetBuildSettingsItem(); - assert(pBuildSettingsMenuItem != nullptr); - - // Toggle the pending changed flag. - if (pBuildSettingsMenuItem != nullptr) - { - pBuildSettingsMenuItem->SetHasPendingChanges(hasPendingChanges); - - // Update the file menu save build settings item visibility. - emit CurrentEditorModificationStateChanged(hasPendingChanges); - } - - // Set the enabledness of the "Save" button. - assert(m_pSettingsButtonsView != nullptr); - if (m_pSettingsButtonsView != nullptr) - { - m_pSettingsButtonsView->EnableSaveButton(hasPendingChanges); - } - } -} - -void rgBuildView::HandleBuildSettingsSaved(std::shared_ptr pBuildSettings) -{ - assert(m_pProject != nullptr); - if (m_pProject != nullptr) - { - bool projectHasClones = !m_pProject->m_clones.empty(); - assert(projectHasClones); - - if (projectHasClones) - { - // Replace the clone's build settings with the latest updated settings. - m_pProject->m_clones[m_cloneIndex]->m_pBuildSettings = pBuildSettings; - - // Save the project after adding a source file. - rgConfigManager::Instance().SaveProjectFile(m_pProject); - } - } - - // Signal that the build settings have changed and should be saved. - emit ProjectBuildSettingsSaved(pBuildSettings); -} - -void rgBuildView::HandleSelectedTargetGpuChanged(const std::string& targetGpu) -{ - // Look for build output for the target GPU being switched to. - auto targetGpuBuildOutputs = m_buildOutputs.find(targetGpu); - - // Find the build outputs for the given GPU. - bool isValidTargetGpu = targetGpuBuildOutputs != m_buildOutputs.end(); - assert(isValidTargetGpu); - if (isValidTargetGpu) - { - // Switch the target GPU. - m_currentTargetGpu = targetGpu; - - InputFileToBuildOutputsMap outputsMap; - bool gotOutputs = GetInputFileOutputs(targetGpuBuildOutputs->second, outputsMap); - - assert(gotOutputs); - if (gotOutputs) - { - assert(m_pCurrentCodeEditor != nullptr); - if (m_pCurrentCodeEditor != nullptr) - { - std::string currentFilePath = GetFilepathForEditor(m_pCurrentCodeEditor); - - // Does the currently-selected source file have build output for the new Target GPU? - auto sourceFileOutputsIter = outputsMap.find(currentFilePath); - - // Trigger an update to handle highlighting the correlated disassembly - // lines associated with the selected line in the current file. - bool isFileBuiltForTarget = sourceFileOutputsIter != outputsMap.end(); - if (isFileBuiltForTarget) - { - // Use the currently-selected line in the source editor to highlight correlated lines in the disassembly table. - int selectedLineNumber = m_pCurrentCodeEditor->GetSelectedLineNumber(); - HandleSourceFileSelectedLineChanged(m_pCurrentCodeEditor, selectedLineNumber); - } - } - } - } -} - -void rgBuildView::HandleFileRenamed(const std::string& oldFilepath, const std::string& newFilepath) -{ - // Update references to the old file path within the BuildView. - RenameFile(oldFilepath, newFilepath); - - // Emit a signal to trigger the file rename within the project file. - emit FileRenamed(oldFilepath, newFilepath); - - // If the paths match, the file just finished being renamed from the file menu. - if (oldFilepath.compare(newFilepath) == 0) - { - // Switch the focus from the file menu item to the source editor. - if (m_pCurrentCodeEditor != nullptr) - { - m_pCurrentCodeEditor->setFocus(); - } - } -} - -void rgBuildView::HandleFocusNextView() -{ - assert(m_pViewManager != nullptr); - if (m_pViewManager != nullptr) - { - // Manually advance to the next view within the rgViewManager. - m_pViewManager->FocusNextView(); - } -} - -void rgBuildView::HandleFindWidgetVisibilityToggled() -{ - if (m_pFindWidget != nullptr) - { - bool isVisible = m_pFindWidget->isVisible(); - ToggleFindWidgetVisibility(!isVisible); - } -} - -void rgBuildView::HandleProjectRenamed(const std::string& projectName) -{ - // Get current project directory. - std::string directory; - rgUtils::ExtractFileDirectory(m_pProject->m_projectFileFullPath, directory); - - // Create full path by appending new name to directory. - char separator = static_cast(QDir::separator().unicode()); - std::string fullPath = directory + separator + projectName + STR_PROJECT_FILE_EXTENSION; - - // Rename the project. - RenameProject(fullPath); -} - -void rgBuildView::HandleEditorModificationStateChanged(bool isModified) -{ - // Get the sender of the signal. - rgSourceCodeEditor* pEditor = static_cast(sender()); - - // Get the file path for the given editor instance. - std::string fullFilePath = GetFilepathForEditor(pEditor); - - rgMenu* pMenu = GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - // Set menu item saved state. - pMenu->SetItemIsSaved(fullFilePath, !isModified); - } - - // If the editor being modified is the current one, emit the modification signal. - if (pEditor == m_pCurrentCodeEditor) - { - emit CurrentEditorModificationStateChanged(isModified); - } - - // Was a source file modified and saved after the last build time? - bool filesModifiedAfterBuild = CheckSourcesModifiedSinceLastBuild(pEditor); - if (filesModifiedAfterBuild) - { - emit LineCorrelationEnabledStateChanged(pEditor, false); - } - else - { - emit LineCorrelationEnabledStateChanged(pEditor, !isModified); - } -} - -void rgBuildView::HandleMenuItemCloseButtonClicked(const std::string& fullPath) -{ - std::stringstream msg; - msg << fullPath << STR_MENU_BAR_CONFIRM_REMOVE_FILE_DIALOG_WARNING; - - if (ShowRemoveFileConfirmation(msg.str(), fullPath)) - { - // Remove the input file from the rgBuildView. - RemoveInputFile(fullPath); - } -} - -void rgBuildView::SetViewContentsWidget(QWidget* pNewContents) -{ - assert(m_pSourceViewStack != nullptr); - if (m_pSourceViewStack != nullptr) - { - // Hide all existing views before replacing with the new one. - QLayout* pLayout = m_pSourceViewStack->layout(); - - assert(pLayout != nullptr); - if (pLayout != nullptr) - { - for (int childIndex = 0; childIndex < pLayout->count(); ++childIndex) - { - QLayoutItem* pItemLayout = pLayout->itemAt(childIndex); - assert(pItemLayout != nullptr); - if (pItemLayout != nullptr) - { - QWidget* pItem = pItemLayout->widget(); - assert(pItem != nullptr); - if (pItem != nullptr) - { - pItem->hide(); - } - } - } - } - - // Verify that the new contents are valid. - assert(pNewContents != nullptr); - if (pNewContents != nullptr) - { - // Add the new contents, and make it visible. - m_pSourceViewStack->layout()->addWidget(pNewContents); - pNewContents->show(); - - // Use the active view as the focus proxy for the source view stack. - m_pSourceViewStack->setFocusProxy(pNewContents); - - // Set focus to the new contents. - pNewContents->setFocus(); - } - } -} - -bool rgBuildView::ShowRemoveFileConfirmation(const std::string& messageString, const std::string& fullPath) -{ - bool isRemoved = false; - - if (!fullPath.empty()) - { - // Ask the user if they're sure they want to remove the file. - isRemoved = rgUtils::ShowConfirmationMessageBox(STR_MENU_BAR_CONFIRM_REMOVE_FILE_DIALOG_TITLE, messageString.c_str(), this); - - // Ask the user if we should save the changes. Continue only if the user did not ask to cancel the operation. - isRemoved = isRemoved && (RequestSaveFile(fullPath) != rgUnsavedItemsDialog::Cancel); - } - - return isRemoved; -} - -void rgBuildView::HandleFindTriggered() -{ - // Toggle to show the find widget. - ToggleFindWidgetVisibility(true); -} - -void rgBuildView::HandleIsBuildInProgressChanged(bool isBuilding) -{ - m_isBuildInProgress = isBuilding; -} - -void rgBuildView::HandleProjectBuildSuccess() -{ - // Reset the project building flag. - HandleIsBuildInProgressChanged(false); - - // Update the last successful build time to now. - m_lastSuccessfulBuildTime = QDateTime::currentDateTime(); - - rgMenu* pMenu = GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - CurrentBuildSucceeded(); - } - - // The current project was built successfully. Open the disassembly view with the results. - bool isDisassemblyLoaded = LoadDisassemblyFromBuildOutput(); - assert(isDisassemblyLoaded); - if (isDisassemblyLoaded) - { - // Switch to the Source Code view and show the disassembly view. - if (pMenu != nullptr) - { - pMenu->DeselectItems(); - pMenu->SwitchToLastSelectedItem(); - } - ShowCurrentFileDisassembly(); - } - - assert(m_pCurrentCodeEditor != nullptr); - if (m_pCurrentCodeEditor != nullptr) - { - // Use the currently-selected line in the source editor to highlight correlated lines in the disassembly table. - int selectedLineNumber = m_pCurrentCodeEditor->GetSelectedLineNumber(); - HandleSourceFileSelectedLineChanged(m_pCurrentCodeEditor, selectedLineNumber); - } - - // Resize the disassembly view. - HandleDisassemblyTableWidthResizeRequested(0); - - // Update the notification message if needed. - UpdateApplicationNotificationMessage(); -} - -void rgBuildView::HandleApplicationStateChanged(Qt::ApplicationState state) -{ - // When the application becomes active, check for external file modifications. - if (state == Qt::ApplicationActive) - { - CheckExternalFileModification(); - } -} - -void rgBuildView::HandleDisassemblyTableWidthResizeRequested(int minimumWidth) -{ - assert(m_pDisassemblyView != nullptr); - assert(m_pDisassemblyViewContainer != nullptr); - assert(m_pDisassemblyViewSplitter != nullptr); - - // Before resizing the disassembly table, make sure that it is not in maximized state. - if (m_pDisassemblyView != nullptr && m_pDisassemblyViewContainer != nullptr - && m_pDisassemblyViewSplitter != nullptr && !m_pDisassemblyViewContainer->IsInMaximizedState()) - { - // Add a small portion of extra buffer space to the right side of the table. - static const float RESIZE_EXTRA_MARGIN = 1.5f; - minimumWidth = static_cast(minimumWidth * RESIZE_EXTRA_MARGIN); - - QRect resourceUsageTextBounds; - m_pDisassemblyView->GetResourceUsageTextBounds(resourceUsageTextBounds); - - // Set maximum width for the widgets containing the ISA disassembly table. - const int resourceUsageStringWidth = resourceUsageTextBounds.width(); - const int maximumWidth = resourceUsageStringWidth > minimumWidth ? resourceUsageStringWidth : minimumWidth; - - int splitterWidth = m_pDisassemblyViewSplitter->size().width(); - QList splitterWidths; - splitterWidths.push_back(splitterWidth - maximumWidth); - splitterWidths.push_back(maximumWidth); - - // Set the ideal width for both sides of the splitter. - m_pDisassemblyViewSplitter->setSizes(splitterWidths); - - // Save the new sizes. - SetConfigSplitterPositions(); - } -} - -void rgBuildView::HandleBuildSettingsMenuButtonClicked() -{ - OpenBuildSettings(); -} - -void rgBuildView::ResetView() -{ - // Nullify any previous project object. - if (m_pProject != nullptr) - { - m_pProject = nullptr; - } - - // Clear the view. - ClearBuildView(); -} - -void rgBuildView::DestroyBuildOutputsForFile(const std::string& inputFileFullPath) -{ - bool isProjectEmpty = false; - - // Iterate through build output for all target GPUs. - auto firstTargetGpu = m_buildOutputs.begin(); - auto lastTargetGpu = m_buildOutputs.end(); - for (auto targetGpuIter = firstTargetGpu; targetGpuIter != lastTargetGpu; ++targetGpuIter) - { - std::shared_ptr pBuildOutput = targetGpuIter->second; - - // Search for outputs for the given source file. - assert(pBuildOutput != nullptr); - if (pBuildOutput != nullptr) - { - auto inputFileOutputsIter = pBuildOutput->m_perFileOutput.find(inputFileFullPath); - if (inputFileOutputsIter != pBuildOutput->m_perFileOutput.end()) - { - // Step through all outputs associated with the given input source file. - rgFileOutputs& fileOutputs = inputFileOutputsIter->second; - for (const rgEntryOutput& entryOutput : fileOutputs.m_outputs) - { - for (const rgOutputItem& outputItem : entryOutput.m_outputs) - { - // Destroy the output file. - QFile::remove(outputItem.m_filePath.c_str()); - } - } - - // Erase the source file's outputs from the existing build output structure. - pBuildOutput->m_perFileOutput.erase(inputFileOutputsIter); - } - - // Is this the last file being removed from the build output structure? - if (pBuildOutput->m_perFileOutput.empty()) - { - isProjectEmpty = true; - } - } - } - - // Destroy all remnants of previous builds of the project. - if (isProjectEmpty) - { - DestroyProjectBuildArtifacts(); - } -} - -void rgBuildView::RemoveEditor(const std::string& filename, bool switchToNextFile) -{ - // Attempt to find the editor instance used to display the given file. - rgSourceCodeEditor* pEditor = nullptr; - auto editorIter = m_sourceCodeEditors.find(filename); - if (editorIter != m_sourceCodeEditors.end()) - { - pEditor = editorIter->second; - } - - assert(pEditor != nullptr); - - // Remove the editor from the map, and hide it from the interface. - QWidget* pTitleBar = m_pSourceViewContainer->GetTitleBar(); - rgSourceEditorTitlebar* pSourceViewTitleBar = qobject_cast(pTitleBar); - if (pSourceViewTitleBar != nullptr) - { - pSourceViewTitleBar->SetTitlebarContentsVisibility(false); - } - - m_sourceCodeEditors.erase(editorIter); - - if (pEditor == m_pCurrentCodeEditor) - { - // There is no more "Current Editor," because it is being closed. - m_pCurrentCodeEditor->hide(); - m_pCurrentCodeEditor = nullptr; - } - - // Destroy the editor associated with the file that was closed. - pEditor->deleteLater(); - - if (switchToNextFile) - { - SwitchToFirstRemainingFile(); - } -} - -void rgBuildView::RemoveInputFile(const std::string& inputFileFullPath) -{ - rgConfigManager& configManager = rgConfigManager::Instance(); - - // Remove the file from the project. - configManager.RemoveSourceFilePath(m_pProject, m_cloneIndex, inputFileFullPath); - configManager.SaveProjectFile(m_pProject); - - rgMenu* pMenu = GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - // Remove the file from the file menu. - pMenu->RemoveItem(inputFileFullPath); - } - - // Remove the associated file editor. - RemoveEditor(inputFileFullPath); - - // Clean up outputs from previous builds associated with this file. - DestroyBuildOutputsForFile(inputFileFullPath); - - // Remove the file's build outputs from the disassembly view. - if (m_pDisassemblyView != nullptr) - { - m_pDisassemblyView->RemoveInputFileEntries(inputFileFullPath); - - // Hide the disassembly view when there's no data in it. - if (m_pDisassemblyView->IsEmpty()) - { - // Minimize the disassembly view before hiding it to preserve correct rgBuildView layout. - m_pDisassemblyViewSplitter->Restore(); - - // Hide the disassembly view now that it's empty. - ToggleDisassemblyViewVisibility(false); - } - else - { - // Trigger a correlation update after the source file has been removed. - HandleSelectedTargetGpuChanged(m_currentTargetGpu); - } - } -} - -bool rgBuildView::LoadDisassemblyFromBuildOutput() -{ - bool result = false; - - if (m_pDisassemblyViewContainer == nullptr || m_pDisassemblyView == nullptr) - { - // Create the ISA disassembly view. - CreateIsaDisassemblyView(); - - // Connect the disassembly view signals. - result = ConnectDisassemblyViewSignals(); - } - - assert(m_pDisassemblyView != nullptr); - if (m_pDisassemblyView != nullptr) - { - // Clear all previously loaded build output. - m_pDisassemblyView->ClearBuildOutput(); - - assert(m_pProject != nullptr); - if (m_pProject != nullptr) - { - // Ensure that the incoming clone index is valid for the current project. - bool isValidRange = (m_cloneIndex >= 0 && m_cloneIndex < m_pProject->m_clones.size()); - assert(isValidRange); - - if (isValidRange) - { - // Ensure that the clone is valid before creating the rgBuildSettingsView. - std::shared_ptr pClone = m_pProject->m_clones[m_cloneIndex]; - - // Verify that the clone exists. - assert(pClone != nullptr); - if (pClone != nullptr) - { - // Populate the disassembly view with the build output. - result = m_pDisassemblyView->PopulateBuildOutput(pClone, m_buildOutputs); - } - } - } - } - - return result; -} - -void rgBuildView::DestroyProjectBuildArtifacts() -{ - // Navigate to the current clone's build output and destroy all artifacts. - std::string projectBuildOutputPath = CreateProjectBuildOutputPath(); - - // Destroy all build artifacts in the project's output directory. - QDir outputDir(projectBuildOutputPath.c_str()); - outputDir.removeRecursively(); - - // Clear references to outputs from previous project compilations. - m_buildOutputs.clear(); - - if (m_pDisassemblyView != nullptr) - { - // Clear any disassembly tables already loaded into the view. - m_pDisassemblyView->ClearBuildOutput(); - - // Hide the disassembly view. - ToggleDisassemblyViewVisibility(false); - } -} - -std::string rgBuildView::GetFilepathForEditor(const rgSourceCodeEditor* pEditor) -{ - // Return an empty string by default. - std::string ret = ""; - - auto editorIter = m_sourceCodeEditors.begin(); - while (editorIter != m_sourceCodeEditors.end()) - { - // Return the filename if a match is found. - if (editorIter->second == pEditor) - { - ret = editorIter->first; - break; - } - - editorIter++; - } - - return ret; -} - -void rgBuildView::HandleNewCLIOutputString(const std::string& cliOutputString) -{ - // Send the CLI's output text to the output window. - m_pCliOutputWindow->EmitSetText(cliOutputString.c_str()); -} - -bool rgBuildView::IsLineCorrelationEnabled(rgSourceCodeEditor* pSourceEditor) -{ - bool isCorrelationEnabled = false; - - assert(m_pProject != nullptr); - if (m_pProject != nullptr) - { - // Ensure that the clone index is valid. - bool isValidCloneIndex = m_cloneIndex >= 0 && m_cloneIndex < m_pProject->m_clones.size(); - assert(isValidCloneIndex); - if (isValidCloneIndex) - { - auto firstFile = m_pProject->m_clones[m_cloneIndex]->m_sourceFiles.begin(); - auto lastFile = m_pProject->m_clones[m_cloneIndex]->m_sourceFiles.end(); - - // Search the list of source file info for the one that matches the given editor. - std::string filePath = GetFilepathForEditor(pSourceEditor); - rgSourceFilePathSearcher pathSearcher(filePath); - auto fileIter = std::find_if(firstFile, lastFile, pathSearcher); - assert(fileIter != lastFile); - if (fileIter != lastFile) - { - // Update the correlation state for the file. - isCorrelationEnabled = fileIter->m_isCorrelated; - } - } - } - - return isCorrelationEnabled; -} - -std::string rgBuildView::CreateProjectBuildOutputPath() const -{ - std::string resultPath; - - // Build an output path where all of the build artifacts will be dumped to. - std::string projectDirectory; - bool isOk = rgUtils::ExtractFileDirectory(m_pProject->m_projectFileFullPath, projectDirectory); - assert(isOk); - if (isOk) - { - std::string outputFolderPath; - isOk = rgUtils::AppendFolderToPath(projectDirectory, STR_OUTPUT_FOLDER_NAME, outputFolderPath); - assert(isOk); - if (isOk) - { - resultPath = outputFolderPath; - } - } - - return resultPath; -} - -bool rgBuildView::SwitchToEditor(rgSourceCodeEditor* pEditor) -{ - bool ret = false; - - assert(pEditor != nullptr); - if (pEditor != nullptr) - { - // Verify if the user is allowed to switch to source editing mode. - bool isSwitchingAllowed = CanSwitchEditMode(); - if (isSwitchingAllowed) - { - // Switch to the new editor. - SetViewContentsWidget(pEditor); - - if (m_pCurrentCodeEditor != nullptr) - { - bool oldEditorIsModified = m_pCurrentCodeEditor->document()->isModified(); - bool newEditorIsModified = pEditor->document()->isModified(); - - // Check if the new editor has a different modification state then the old one - if (oldEditorIsModified != newEditorIsModified) - { - emit CurrentEditorModificationStateChanged(newEditorIsModified); - } - } - - // The editor being switched to is now the current editor. - m_pCurrentCodeEditor = pEditor; - - // Update the editor context. - UpdateSourceEditorSearchContext(); - - // Update the title bar text. - const std::string& titleBarText = pEditor->GetTitleBarText(); - if (!titleBarText.empty()) - { - m_pSourceEditorTitlebar->ShowMessage(titleBarText); - } - else - { - m_pSourceEditorTitlebar->SetTitlebarContentsVisibility(false); - } - - // The editor isn't empty, and will switch to displaying source code. - SwitchEditMode(EditMode::SourceCode); - - // Check if the editor file has been modified externally. - CheckExternalFileModification(); - - ret = true; - } - } - - return ret; -} - -void rgBuildView::UpdateFindWidgetViewAttachment(QWidget* pView, bool isVisible) -{ - assert(pView != nullptr); - if (pView != nullptr) - { - if (m_pFindWidget != nullptr) - { - QLayout* pLayout = static_cast(pView->layout()); - assert(pLayout != nullptr); - if (pLayout != nullptr) - { - if (isVisible) - { - // Only make the widget visible if the source editor is currently visible. - bool isEditorVisible = pView->isVisible(); - if (isEditorVisible) - { - m_pFindWidget->setParent(pView); - // Insert the find widget into the top of the layout above the source editor. - m_pFindWidget->setVisible(isVisible); - m_pFindWidget->raise(); - - // Update the position of the find widget. - UpdateFindWidgetGeometry(); - } - } - else - { - pLayout->removeWidget(m_pFindWidget); - m_pFindWidget->setVisible(isVisible); - } - } - } - } -} - -void rgBuildView::UpdateSourceEditorTitlebar(rgSourceCodeEditor* pCodeEditor) -{ - std::string sourceFilePath = GetFilepathForEditor(pCodeEditor); - if (!sourceFilePath.empty()) - { - // If the source file has already been disassembled, check if line correlation is currently enabled. - bool isCorrelationEnabled = false; - bool isDisassembled = IsGcnDisassemblyGenerated(sourceFilePath); - if (isDisassembled) - { - isCorrelationEnabled = IsLineCorrelationEnabled(pCodeEditor); - } - else - { - // The file hasn't been disassembled yet, so don't display a warning in the editor's titlebar. - isCorrelationEnabled = true; - } - - // Update the title bar to show the current correlation state for the file. - assert(m_pSourceEditorTitlebar != nullptr); - if (m_pSourceEditorTitlebar != nullptr && IsLineCorrelationSupported()) - { - m_pSourceEditorTitlebar->SetIsCorrelationEnabled(isCorrelationEnabled); - } - } -} - -bool rgBuildView::CanSwitchEditMode() -{ - bool ret = true; - - // If the user is currently viewing the Build Settings, ask them to save before changing the edit mode. - if (m_editMode == EditMode::BuildSettings) - { - // Require the user to decide whether or not to save their Build Settings changes. - ret = ShowSaveDialog(rgFilesToSave::BuildSettings); - } - - return ret; -} - -void rgBuildView::SwitchEditMode(EditMode mode) -{ - if (m_editMode != mode) - { - if (mode == EditMode::Empty) - { - SetViewContentsWidget(m_pEmptyPanel); - } - else - { - // Based on the incoming mode, hide/show specific widgets living within the BuildView. - switch (mode) - { - case EditMode::SourceCode: - { - // Enable maximizing the source editor/build settings container. - assert(m_pSourceViewContainer != nullptr); - if (m_pSourceViewContainer != nullptr) - { - m_pSourceViewContainer->SetIsMaximizable(true); - } - - // Hide the build settings, and show the code editor. - if (m_pCurrentCodeEditor != nullptr) - { - // Set the code editor instance in the view. - SetViewContentsWidget(m_pCurrentCodeEditor); - } - - // Set the appropriate boolean in rgViewManager - // to facilitate focusing the correct widget. - m_pViewManager->SetIsSourceViewCurrent(true); - } - break; - case EditMode::BuildSettings: - { - // Disable maximizing the source editor/build settings container. - assert(m_pSourceViewContainer != nullptr); - if (m_pSourceViewContainer != nullptr) - { - m_pSourceViewContainer->SetIsMaximizable(false); - } - - assert(m_pSourceEditorTitlebar != nullptr); - if (m_pSourceEditorTitlebar != nullptr) - { - // Hide the Source Code Editor titlebar message. - m_pSourceEditorTitlebar->SetTitlebarContentsVisibility(false); - } - - if (m_pDisassemblyViewSplitter != nullptr) - { - // Is there a container that's currently maximized in the splitter? - QWidget* pMaximizedWidget = m_pDisassemblyViewSplitter->GetMaximizedWidget(); - if (pMaximizedWidget != nullptr) - { - // Restore the maximized view before switching to the build settings. - m_pDisassemblyViewSplitter->Restore(); - } - } - - // Switch from showing the code editor, to showing the build settings. - SetViewContentsWidget(m_pBuildSettingsWidget); - - // Set the build settings frame border color. - SetAPISpecificBorderColor(); - - // If the disassembly view exists, hide it. - if (m_pDisassemblyViewContainer != nullptr) - { - ToggleDisassemblyViewVisibility(false); - } - - // Initialize focus. - if (m_pBuildSettingsView != nullptr) - { - m_pBuildSettingsView->SetInitialWidgetFocus(); - } - - // Set the appropriate booleans in rgViewManager - // to facilitate focusing the correct widget. - m_pViewManager->SetIsSourceViewCurrent(false); - m_pViewManager->SetIsPSOEditorViewCurrent(false); - m_pViewManager->SetIsBuildSettingsViewCurrent(true); - } - break; - default: - // Invoke the mode-specific edit mode switch handler. - HandleModeSpecificEditMode(mode); - m_pViewManager->SetIsSourceViewCurrent(false); - m_pViewManager->SetIsPSOEditorViewCurrent(true); - m_pViewManager->SetIsBuildSettingsViewCurrent(false); - break; - } - - // Update the file menu save text and action. - emit EditModeChanged(mode); - } - - // Update the current mode. - m_editMode = mode; - } -} - -void rgBuildView::SwitchToFirstRemainingFile() -{ - // If there are code editors remaining, switch to the first remaining item. - if (!m_sourceCodeEditors.empty()) - { - rgMenu* pMenu = GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - pMenu->SelectLastRemainingItem(); - } - - // Switch to viewing the rgSourceCodeEditor for the newly selected item. - SwitchEditMode(EditMode::SourceCode); - } - else - { - // When the last file has been removed, the editor is in the empty state. - SwitchEditMode(EditMode::Empty); - } -} - -void rgBuildView::CreateBuildSettingsView() -{ - assert(m_pProject != nullptr); - if (m_pProject != nullptr) - { - // Ensure that the incoming clone index is valid for the current project. - bool isValidRange = (m_cloneIndex >= 0 && m_cloneIndex < m_pProject->m_clones.size()); - assert(isValidRange); - - if (isValidRange) - { - // Ensure that the clone is valid before creating the rgBuildSettingsView. - std::shared_ptr pClone = m_pProject->m_clones[m_cloneIndex]; - - // Verify that the clone exists. - assert(pClone != nullptr); - if (pClone != nullptr) - { - assert(m_pFactory != nullptr); - if (m_pFactory != nullptr) - { - // Create the build settings interface. - m_pBuildSettingsView = m_pFactory->CreateBuildSettingsView(this, pClone->m_pBuildSettings, false); - assert(m_pBuildSettingsView != nullptr); - - // If the build settings view was created successfully, connect the signals. - if (m_pBuildSettingsView != nullptr) - { - // Create the widget. - m_pBuildSettingsWidget = new rgBuildSettingsWidget(this); - m_pBuildSettingsWidget->setFocusPolicy(Qt::FocusPolicy::StrongFocus); - m_pBuildSettingsWidget->setFrameStyle(QFrame::Box); - m_pBuildSettingsWidget->setLayout(new QVBoxLayout); - - // Create the Settings buttons view. - m_pSettingsButtonsView = new rgSettingsButtonsView(this); - - // Hide the Restore Default Settings button from the project build settings. - m_pSettingsButtonsView->HideRestoreDefaultSettingsButton(true); - - // Create a scroll area to contain the build settings view. - rgScrollArea* pScrollArea = new rgScrollArea(this); - pScrollArea->setObjectName(STR_BUILD_VIEW_SETTINGS_SCROLLAREA); - pScrollArea->setStyleSheet(STR_BUILD_VIEW_SETTINGS_SCROLLAREA_STYLESHEET); - pScrollArea->setFrameShape(QFrame::NoFrame); - pScrollArea->setFocusPolicy(Qt::FocusPolicy::NoFocus); - pScrollArea->setWidget(m_pBuildSettingsView); - pScrollArea->setWidgetResizable(true); - - // Connect the scroll area click to set the border to the API-specific color. - bool isConnected = connect(pScrollArea, &rgScrollArea::ScrollAreaClickedEvent, this, &rgBuildView::SetAPISpecificBorderColor); - assert(isConnected); - - // Add various widgets to this tab. - m_pBuildSettingsWidget->layout()->addWidget(pScrollArea); - m_pBuildSettingsWidget->layout()->addWidget(m_pSettingsButtonsView); - - // Hide the build settings view after creating it. - m_pBuildSettingsWidget->hide(); - - // Connect signals for the build settings view. - ConnectBuildSettingsSignals(); - } - } - } - } - } -} - -void rgBuildView::CreateFindWidget() -{ - // Verify that this gets invoked only once. - assert(m_pFindWidget == nullptr); - if (m_pFindWidget == nullptr) - { - // Create the find widget, register with the scaling manager. - m_pFindWidget = new rgFindTextWidget(this); - ScalingManager::Get().RegisterObject(m_pFindWidget); - - // The find widget is hidden by default. - m_pFindWidget->hide(); - - // Connect the find widget signals. - ConnectFindSignals(); - - // Create the source code searcher interface. - m_pSourceSearcher = new rgSourceEditorSearcher(); - } -} - -void rgBuildView::CreateIsaDisassemblyView() -{ - // Create a factory matching the API mode. - rgProjectAPI currentApi = rgConfigManager::Instance().GetCurrentAPI(); - std::shared_ptr pFactory = rgFactory::CreateFactory(currentApi); - assert(pFactory != nullptr); - if (pFactory != nullptr) - { - rgIsaDisassemblyView* pDisassemblyView = pFactory->CreateDisassemblyView(this); - assert(pDisassemblyView != nullptr); - if (pDisassemblyView != nullptr) - { - m_pDisassemblyView = pDisassemblyView; - - // Wrap the disassembly view in a view container. - m_pDisassemblyViewContainer = new rgViewContainer(); - m_pDisassemblyViewContainer->SetMainWidget(m_pDisassemblyView); - - // Connect the container single click signal to disassembly view focus in handler. - bool isConnected = connect(m_pDisassemblyViewContainer, &rgViewContainer::ViewContainerMouseClickEventSignal, m_pDisassemblyView, - &rgIsaDisassemblyView::HandleDisassemblyTabViewClicked); - assert(isConnected); - - // Set the object name for the disassembly view container. - m_pDisassemblyViewContainer->setObjectName(STR_RG_ISA_DISASSEMBLY_VIEW_CONTAINER); - - // Add the disassembly view to the disassembly splitter. - m_pDisassemblyViewSplitter->AddMaximizableWidget(m_pDisassemblyViewContainer); - - // Hide the disassembly view when it is first created. - m_pDisassemblyView->setVisible(true); - - // Add the view to the view manager in the disassembly view position so the tabbing order is correct. - m_pViewManager->AddView(m_pDisassemblyViewContainer, true, static_cast(rgViewManagerViewContainerIndex::DisassemblyView)); - } - } -} - -bool rgBuildView::GetInputFileOutputs(std::shared_ptr pBuildOutputs, InputFileToBuildOutputsMap& outputs) const -{ - bool ret = false; - - assert(pBuildOutputs != nullptr); - if (pBuildOutputs != nullptr) - { - outputs = pBuildOutputs->m_perFileOutput; - ret = true; - } - - return ret; -} - -rgSourceCodeEditor* rgBuildView::GetEditorForFilepath(const std::string& fullFilepath, rgSrcLanguage lang) -{ - // The source code editor to use for the given filename. - rgSourceCodeEditor* pEditor = nullptr; - - if (!fullFilepath.empty()) - { - auto editorIter = m_sourceCodeEditors.find(fullFilepath); - if (editorIter != m_sourceCodeEditors.end()) - { - pEditor = editorIter->second; - } - else - { - pEditor = new rgSourceCodeEditor(this, lang); - m_sourceCodeEditors[fullFilepath] = pEditor; - - // Connect to the specific editor's signals. - bool isConnected = connect(pEditor, &rgSourceCodeEditor::OpenHeaderFileRequested, this, &rgBuildView::HandleSourceEditorOpenHeaderRequest); - assert(isConnected); - - QFileInfo fileInfo(fullFilepath.c_str()); - m_fileModifiedTimeMap[pEditor] = fileInfo.lastModified(); - - ConnectSourcecodeEditorSignals(pEditor); - - // Set the fonts for the source code editor. - rgConfigManager& configManager = rgConfigManager::Instance(); - std::shared_ptr pGlobalSettings = configManager.GetGlobalConfig(); - assert(pGlobalSettings != nullptr); - if (pGlobalSettings != nullptr) - { - QFont font; - font.setFamily(QString::fromStdString(pGlobalSettings->m_fontFamily)); - font.setPointSize(pGlobalSettings->m_fontSize); - assert(pEditor != nullptr); - if (pEditor != nullptr) - { - pEditor->setFont(font); - } - } - } - } - return pEditor; -} - -void rgBuildView::CancelCurrentBuild() -{ - // Destroy all project outputs when the project build is canceled. - DestroyProjectBuildArtifacts(); - - // Reset the "is currently building" flag. - HandleIsBuildInProgressChanged(false); - - // Signal that this build should be canceled - // (this handle is being watched by the thread that launches the CLI). - m_cancelBuildSignal = true; - - CurrentBuildCancelled(); -} - -void rgBuildView::FocusOnSourceCodeEditor() -{ - // Switch the focus to the file editor to begin editing the file. - if (m_pCurrentCodeEditor != nullptr) - { - m_pCurrentCodeEditor->setFocus(); - } -} - -void rgBuildView::HandleScrollCodeEditorToLine(int lineNum) -{ - m_pCurrentCodeEditor->ScrollToLine(lineNum); - QTextCursor cursor(m_pCurrentCodeEditor->document()->findBlockByLineNumber(lineNum - 1)); - m_pCurrentCodeEditor->setTextCursor(cursor); - - // Switch focus to the code editor. - m_pCurrentCodeEditor->setFocus(); -} - -void rgBuildView::RenameFile(const std::string& oldFilepath, const std::string& newFilepath) -{ - auto editorIter = m_sourceCodeEditors.find(oldFilepath); - if (editorIter != m_sourceCodeEditors.end()) - { - rgSourceCodeEditor* pEditor = editorIter->second; - - // Erase the existing file path, and insert the new one. - m_sourceCodeEditors.erase(editorIter); - m_sourceCodeEditors[newFilepath] = pEditor; - } - - // Update the project's source file list with the new filepath. - rgConfigManager::UpdateSourceFilepath(oldFilepath, newFilepath, m_pProject, m_cloneIndex); - - // Save the updated project file. - rgConfigManager::Instance().SaveProjectFile(m_pProject); -} - -void rgBuildView::RenameProject(const std::string& fullPath) -{ - // Cache the original file path being renamed. - assert(m_pProject != nullptr); - if (m_pProject != nullptr) - { - std::string originalFilePath = m_pProject->m_projectFileFullPath; - - // Rename the project config file. - bool isRenamed = QFile::rename(m_pProject->m_projectFileFullPath.c_str(), fullPath.c_str()); - assert(isRenamed); - - if (isRenamed) - { - // Set full path. - m_pProject->m_projectFileFullPath = fullPath; - - // Set project name. - std::string filename; - rgUtils::ExtractFileName(fullPath, filename, false); - m_pProject->m_projectName = filename; - rgConfigManager& configManager = rgConfigManager::Instance(); - - // Update the recent project list to reference the new path. - configManager.UpdateRecentProjectPath(originalFilePath, fullPath, m_pProject->m_api); - - // Save the project file. - configManager.SaveProjectFile(m_pProject); - - // Update main window title text. - emit ProjectLoaded(m_pProject); - } - } -} - -void rgBuildView::ToggleFindWidgetVisibility(bool isVisible) -{ - if (m_editMode == EditMode::SourceCode) - { - // Attach the Find widget to the source editor view. - UpdateFindWidgetViewAttachment(m_pSourceViewStack, isVisible); - - assert(m_pFindWidget != nullptr); - if (m_pFindWidget != nullptr) - { - if (isVisible) - { - m_pFindWidget->SetFocused(); - } - } - } -} - -void rgBuildView::SaveEditorTextToFile(rgSourceCodeEditor* pEditor, const std::string& fullPath) -{ - bool isEditorValid = (pEditor != nullptr); - assert(isEditorValid); - - // Only save if the editor is modified. - if (isEditorValid && pEditor->document()->isModified()) - { - bool isSaveSuccessful = rgUtils::WriteTextFile(fullPath, pEditor->toPlainText().toStdString()); - assert(isSaveSuccessful); - - // Remember most recent time file was modified. - QFileInfo fileInfo(fullPath.c_str()); - m_fileModifiedTimeMap[pEditor] = fileInfo.lastModified(); - - // Indicate that a freshly saved file is considered unmodified. - pEditor->document()->setModified(false); - } -} - -void rgBuildView::DiscardEditorChanges(rgSourceCodeEditor* pEditor) -{ - bool isEditorValid = (pEditor != nullptr); - assert(isEditorValid); - if (isEditorValid) - { - pEditor->document()->setModified(false); - } -} - -void rgBuildView::UpdateFindWidgetGeometry() -{ - assert(m_pFindWidget != nullptr); - if (m_pFindWidget != nullptr) - { - if (m_pCurrentCodeEditor != nullptr) - { - // Compute the geometry for the widget relative to the source editor. - int scrollbarWidth = m_pCurrentCodeEditor->verticalScrollBar()->width(); - if (!m_pCurrentCodeEditor->verticalScrollBar()->isVisible()) - { - scrollbarWidth = 0; - } - - // Start the Find widget at the far left of the attached control, and shift it to the - // right as far as possible within the parent. - int widgetHorizontalLocation = 0; - - // The total amount of horizontal space available for the Find widget to fit into. - int availableEditorWidth = m_pCurrentCodeEditor->width() - scrollbarWidth; - - // Try to display the find widget with the maximum dimensions that can fit within the source editor. - int findWidgetWidth = m_pFindWidget->maximumWidth(); - if (findWidgetWidth > availableEditorWidth) - { - findWidgetWidth = availableEditorWidth; - } - else - { - widgetHorizontalLocation += (availableEditorWidth - findWidgetWidth - s_FIND_TEXT_WIDGET_HORIZONTAL_MARGIN); - assert(widgetHorizontalLocation >= 0); - if (widgetHorizontalLocation < 0) - { - widgetHorizontalLocation = 0; - } - } - - // Use the unmodified height of the Find Widget in the final dimension. - int findWidgetHeight = m_pFindWidget->maximumHeight(); - - // Set the geometry for the widget manually. - // Offset vertically so the widget doesn't overlap the editor's titlebar. - m_pFindWidget->setGeometry(widgetHorizontalLocation, s_FIND_TEXT_WIDGET_VERTICAL_MARGIN, findWidgetWidth, findWidgetHeight); - } - } -} - -void rgBuildView::UpdateSourceFileCorrelationState(const std::string& filePath, bool isCorrelated) -{ - assert(m_pProject != nullptr); - if (m_pProject != nullptr) - { - bool isValidCloneIndex = m_cloneIndex >= 0 && m_cloneIndex < m_pProject->m_clones.size(); - assert(isValidCloneIndex); - if (isValidCloneIndex) - { - auto firstFile = m_pProject->m_clones[m_cloneIndex]->m_sourceFiles.begin(); - auto lastFile = m_pProject->m_clones[m_cloneIndex]->m_sourceFiles.end(); - - // Search for the given source file in the project's list of source files. - rgSourceFilePathSearcher pathSearcher(filePath); - auto fileIter = std::find_if(firstFile, lastFile, pathSearcher); - if (fileIter != lastFile) - { - // Update the correlation state for the file. - fileIter->m_isCorrelated = isCorrelated; - - // Save the project file each time the state is changed. - rgConfigManager::Instance().SaveProjectFile(m_pProject); - } - } - } -} - -void rgBuildView::UpdateSourceEditorSearchContext() -{ - // Update the find widget's searcher to search the new editor. - assert(m_pSourceSearcher != nullptr); - assert(m_pFindWidget != nullptr); - if (m_pSourceSearcher != nullptr && m_pFindWidget != nullptr) - { - // Update the FindWidget's search context to use the source editor searcher. - m_pFindWidget->SetSearchContext(m_pSourceSearcher); - m_pSourceSearcher->SetTargetEditor(m_pCurrentCodeEditor); - } -} - -void rgBuildView::CheckExternalFileModification() -{ - // If there are no active code editors, no files can be modified. - if (m_pCurrentCodeEditor != nullptr) - { - // Get file modification time from the last time the file was saved in RGA. - QDateTime expectedLastModified = m_fileModifiedTimeMap[m_pCurrentCodeEditor]; - - // Get file info for the editor file. - std::string filename = GetFilepathForEditor(m_pCurrentCodeEditor); - QFileInfo fileInfo(filename.c_str()); - - // If the modification time is not the same as remembered, the file has been changed externally. - if (fileInfo.lastModified() != expectedLastModified) - { - // Notify other components in the system that this file has been modified outside the app. - emit CurrentFileModified(); - - QString messageText = QString(filename.c_str()) + "\n\n" + STR_RELOAD_FILE_DIALOG_TEXT; - - // Show message box to ask if the user want to reload the file. - int response = QMessageBox::question(this, STR_RELOAD_FILE_DIALOG_TITLE, messageText, QMessageBox::Yes, QMessageBox::No); - - // Get user response. - switch (response) - { - case QMessageBox::Yes: - ReloadFile(filename); - break; - case QMessageBox::No: - m_fileModifiedTimeMap[m_pCurrentCodeEditor] = fileInfo.lastModified(); - - // Indicate the document is unsaved, regardless of any previous state. - m_pCurrentCodeEditor->document()->setModified(true); - break; - default: - // Should never get here. - assert(false); - } - } - } -} - -void rgBuildView::SetConfigSplitterPositions() -{ - rgConfigManager& configManager = rgConfigManager::Instance(); - - // Build output splitter. - configManager.SetSplitterValues(STR_SPLITTER_NAME_BUILD_OUTPUT, m_pOutputSplitter->sizes().toVector().toStdVector()); - - // Disassembly/source view splitter. - configManager.SetSplitterValues(STR_SPLITTER_NAME_SOURCE_DISASSEMBLY, m_pDisassemblyViewSplitter->sizes().toVector().toStdVector()); -} - -void rgBuildView::RestoreViewLayout() -{ - rgConfigManager& configManager = rgConfigManager::Instance(); - std::vector splitterValues; - - // Build output splitter. - bool hasSplitterValues = configManager.GetSplitterValues(STR_SPLITTER_NAME_BUILD_OUTPUT, splitterValues); - if (hasSplitterValues) - { - m_pOutputSplitter->setSizes(QVector::fromStdVector(splitterValues).toList()); - } - - // Disassembly/source view splitter. - hasSplitterValues = configManager.GetSplitterValues(STR_SPLITTER_NAME_SOURCE_DISASSEMBLY, splitterValues); - if (hasSplitterValues) - { - m_pDisassemblyViewSplitter->setSizes(QVector::fromStdVector(splitterValues).toList()); - } -} - -bool rgBuildView::IsBuildInProgress() const -{ - return m_isBuildInProgress; -} - -void rgBuildView::GetUnsavedSourceFiles(QStringList& unsavedSourceFiles) -{ - // Build a list of all unsaved file with modifications. - auto editorIter = m_sourceCodeEditors.begin(); - while (editorIter != m_sourceCodeEditors.end()) - { - rgSourceCodeEditor* pEditor = editorIter->second; - std::string fullPath = editorIter->first; - - bool isEditorValid = (pEditor != nullptr); - assert(isEditorValid); - - // Add file to the list if it is unsaved (modified). - if (isEditorValid && pEditor->document()->isModified()) - { - unsavedSourceFiles << fullPath.c_str(); - } - - editorIter++; - } -} - -bool rgBuildView::OpenIncludeFile(const std::string& fullFilePath) -{ - bool ret = false; - if (rgUtils::IsFileExists(fullFilePath)) - { - // Check if RGA is configured to use the system's default app, or the user's app of choice. - std::string includeViewer = rgConfigManager::Instance().GetIncludeFileViewer(); - if (includeViewer.compare(STR_GLOBAL_SETTINGS_SRC_VIEW_INCLUDE_VIEWER_DEFAULT) == 0) - { - // Launch the system's default viewer. - QUrl fileUrl = QUrl::fromLocalFile(fullFilePath.c_str()); - QDesktopServices::openUrl(fileUrl); - ret = true; - } - else - { - // Launch the user's editor of choice. - QStringList argList; - argList.push_back(fullFilePath.c_str()); - ret = QProcess::startDetached(includeViewer.c_str(), argList); - } - } - - return ret; -} - -void rgBuildView::HandleSaveSettingsButtonClicked() -{ - SetAPISpecificBorderColor(); - - if (m_editMode == EditMode::SourceCode) - { - SaveCurrentFile(); - } - else if (m_editMode == EditMode::BuildSettings) - { - // Disable the "Save" button. - assert(m_pSettingsButtonsView != nullptr); - if (m_pSettingsButtonsView != nullptr) - { - m_pSettingsButtonsView->EnableSaveButton(false); - } - - m_pBuildSettingsView->SaveSettings(); - } -} - -void rgBuildView::HandleRestoreDefaultsSettingsClicked() -{ - SetAPISpecificBorderColor(); - - // Ask the user for confirmation. - bool isConfirmation = rgUtils::ShowConfirmationMessageBox(STR_BUILD_SETTINGS_DEFAULT_SETTINGS_CONFIRMATION_TITLE, STR_BUILD_SETTINGS_DEFAULT_SETTINGS_CONFIRMATION, this); - - if (isConfirmation) - { - // Disable the "Save" button. - assert(m_pSettingsButtonsView != nullptr); - if (m_pSettingsButtonsView != nullptr) - { - m_pSettingsButtonsView->EnableSaveButton(false); - } - - assert(m_pBuildSettingsView != nullptr); - if (m_pBuildSettingsView != nullptr) - { - m_pBuildSettingsView->RestoreDefaultSettings(); - } - } -} - -void rgBuildView::HandleSetFrameBorderGreen() -{ - m_pBuildSettingsWidget->setStyleSheet(STR_BUILD_VIEW_BUILD_SETTINGS_WIDGET_STYLESHEET_GREEN); -} - -void rgBuildView::HandleSetFrameBorderRed() -{ - m_pBuildSettingsWidget->setStyleSheet(STR_BUILD_VIEW_BUILD_SETTINGS_WIDGET_STYLESHEET_RED); -} - -void rgBuildView::HandleSetFrameBorderBlack() -{ - m_pBuildSettingsWidget->setStyleSheet(STR_BUILD_VIEW_BUILD_SETTINGS_WIDGET_STYLESHEET_BLACK); -} - -void rgBuildView::HandleDisassemblyViewSizeMaximize() -{ - assert(m_pDisassemblyView); - assert(m_pDisassemblyViewContainer); - - if (m_pDisassemblyView != nullptr) - { - m_pDisassemblyView->setMaximumWidth(QWIDGETSIZE_MAX); - } - if (m_pDisassemblyViewContainer != nullptr) - { - m_pDisassemblyViewContainer->setMaximumWidth(QWIDGETSIZE_MAX); - } -} - -void rgBuildView::HandleDisassemblyViewSizeRestore() -{ - HandleDisassemblyTableWidthResizeRequested(0); -} - -void rgBuildView::HandleSplitterMoved(int pos, int index) -{ - // Update the splitter dimensions in the config file. - SetConfigSplitterPositions(); - - // Emit a signal to indicate change in splitter position. - emit SplitterMoved(); -} - -std::string rgBuildView::GetCurrentProjectAPIName() const -{ - std::string projectAPI = ""; - - bool ok = rgUtils::ProjectAPIToString(m_pProject->m_api, projectAPI); - assert(ok); - - return projectAPI; -} - -void rgBuildView::HandleDisassemblyViewClicked() -{ - qApp->focusObjectChanged(m_pDisassemblyView); - m_pDisassemblyView->setFocus(); -} - -bool rgBuildView::SaveProjectConfigFile() const -{ - return rgConfigManager::Instance().SaveProjectFile(m_pProject); -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgBuildViewGraphics.cpp b/RadeonGPUAnalyzerGUI/Src/rgBuildViewGraphics.cpp deleted file mode 100644 index 9d826f8..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgBuildViewGraphics.cpp +++ /dev/null @@ -1,238 +0,0 @@ -// C++. -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -rgBuildViewGraphics::rgBuildViewGraphics(rgProjectAPI api, QWidget* pParent) - : rgBuildView(api, pParent) - , m_pipelineStateIndex(0), - m_pAddCreateContextMenu(new QMenu(this)), - m_pActionAddExistingFile(new QAction(STR_ADD_EXISTING_FILE, this)), - m_pActionCreateNewFile(new QAction(STR_CREATE_NEW_FILE, this)) -{ - m_pAddCreateContextMenu->setCursor(Qt::PointingHandCursor); - m_pAddCreateContextMenu->addAction(m_pActionCreateNewFile); - m_pAddCreateContextMenu->addAction(m_pActionAddExistingFile); -} - -void rgBuildViewGraphics::HandlePipelineStateSettingsMenuButtonClicked() -{ - OpenPipelineStateSettingsView(); -} - -void rgBuildViewGraphics::HandleModeSpecificEditMode(EditMode newMode) -{ - // The rgBuildViewGraphics is able to switch to the PipelineSettings page. - if (newMode == EditMode::PipelineSettings) - { - // Disable maximizing the source editor/build settings container. - assert(m_pSourceViewContainer != nullptr); - if (m_pSourceViewContainer != nullptr) - { - m_pSourceViewContainer->SetIsMaximizable(false); - } - - assert(m_pSourceEditorTitlebar != nullptr); - if (m_pSourceEditorTitlebar != nullptr) - { - // Hide the Source Code Editor titlebar message. - m_pSourceEditorTitlebar->SetTitlebarContentsVisibility(false); - } - - assert(m_pDisassemblyViewSplitter != nullptr); - if (m_pDisassemblyViewSplitter != nullptr) - { - // Is there a container that's currently maximized in the splitter? - QWidget* pMaximizedWidget = m_pDisassemblyViewSplitter->GetMaximizedWidget(); - if (pMaximizedWidget != nullptr) - { - // Restore the maximized view before switching to the build settings. - m_pDisassemblyViewSplitter->Restore(); - } - } - - // Switch to showing the Pipeline State editor. - assert(m_pPsoEditorFrame != nullptr); - assert(m_pPipelineStateView != nullptr); - if (m_pPsoEditorFrame != nullptr && m_pPipelineStateView != nullptr) - { - // If the FindWidget exists, update its search context. - if (m_pPsoFindWidget != nullptr) - { - rgPipelineStateSearcher* pPsoTreeSearcher = m_pPipelineStateView->GetSearcher(); - assert(pPsoTreeSearcher != nullptr); - if (pPsoTreeSearcher != nullptr) - { - m_pPsoFindWidget->SetSearchContext(pPsoTreeSearcher); - } - } - - // Switch to the pipeline state view. - SetViewContentsWidget(m_pPsoEditorFrame); - } - - // If the disassembly view exists, hide it. - if (m_pDisassemblyViewContainer != nullptr) - { - ToggleDisassemblyViewVisibility(false); - } - - // Initialize focus in the PSO editor. - if (m_pPipelineStateView != nullptr) - { - m_pPipelineStateView->SetInitialWidgetFocus(); - } - } -} - -void rgBuildViewGraphics::ConnectPSOFindSignals() -{ - // Connect the find widget's close toggle handler. - bool isConnected = connect(m_pPsoFindWidget, &rgFindTextWidget::CloseWidgetSignal, this, &rgBuildViewGraphics::HandleFindWidgetVisibilityToggled); - assert(isConnected); -} - -void rgBuildViewGraphics::HandleFindWidgetVisibilityToggled() -{ - if (m_pPsoFindWidget != nullptr) - { - bool isVisible = m_pPsoFindWidget->isVisible(); - ToggleFindWidgetVisibility(!isVisible); - } -} - -void rgBuildViewGraphics::HandleLoadPipelineStateFile(const std::string& filePath) -{ - // Change the mouse cursor to hour glass cursor. - QApplication::setOverrideCursor(Qt::WaitCursor); - - // Load the pipeline state file. - bool isOk = LoadPipelineStateFile(filePath); - - assert(isOk); - if (isOk) - { - // Update the find widget to use the new pipeline searcher context. - assert(m_pPsoFindWidget != nullptr); - if (m_pPsoFindWidget != nullptr) - { - rgPipelineStateSearcher* pPsoTreeSearcher = m_pPipelineStateView->GetSearcher(); - assert(pPsoTreeSearcher != nullptr); - if (pPsoTreeSearcher != nullptr) - { - m_pPsoFindWidget->SetSearchContext(pPsoTreeSearcher); - } - } - - // Save the project file with the updated pipeline state file path. - rgConfigManager& configManager = rgConfigManager::Instance(); - configManager.SaveProjectFile(m_pProject); - - // Extract directory from full path. - std::string fileDirectory; - bool isOk = rgUtils::ExtractFileDirectory(filePath, fileDirectory); - assert(isOk); - - if (isOk) - { - // Update last selected directory in global config. - rgConfigManager::Instance().SetLastSelectedDirectory(fileDirectory); - } - - // Report status to status bar. - emit SetStatusBarText(STR_PIPELINE_STATE_EDITOR_FILE_LOADED_SUCCESSFULLY, gs_STATUS_BAR_NOTIFICATION_TIMEOUT_MS); - } - else - { - // Report status to status bar. - emit SetStatusBarText(STR_PIPELINE_STATE_EDITOR_FILE_FAILED_LOADING, gs_STATUS_BAR_NOTIFICATION_TIMEOUT_MS); - } - - // Change the mouse cursor back. - QApplication::restoreOverrideCursor(); -} - -void rgBuildViewGraphics::ToggleFindWidgetVisibility(bool isVisible) -{ - if (m_editMode == EditMode::PipelineSettings) - { - assert(m_pPipelineStateView != nullptr); - if (m_pPipelineStateView != nullptr) - { - assert(m_pPsoFindWidget != nullptr); - if (m_pPsoFindWidget != nullptr) - { - if (isVisible) - { - // Get the currently-selected text in the pipeline state tree. - std::string searchString; - if (m_pPipelineStateView->GetSelectedText(searchString)) - { - // Insert the currently-selected text into the find widget. - m_pPsoFindWidget->SetSearchString(searchString); - } - - // Show the text find widget. - m_pPsoFindWidget->show(); - - // Focus on the find widget after making it visible. - m_pPsoFindWidget->SetFocused(); - } - else - { - // Hide the text find widget. - m_pPsoFindWidget->hide(); - - // Switch focus back to the pipeline state editor. - m_pPipelineStateView->setFocus(); - } - } - } - } - else - { - // Invoke the base implementation to handle the find widget finding in other edit modes. - rgBuildView::ToggleFindWidgetVisibility(isVisible); - } -} - -void rgBuildViewGraphics::UpdateFindWidgetGeometry() -{ - if (m_editMode != EditMode::PipelineSettings) - { - // Invoke the base implementation to handle other edit modes. - rgBuildView::UpdateFindWidgetGeometry(); - } -} - -void rgBuildViewGraphics::OpenPipelineStateSettingsView() -{ - SwitchEditMode(EditMode::PipelineSettings); -} - -void rgBuildViewGraphics::HandleStateEditorHidden() -{ - // Hide the find widget. - ToggleFindWidgetVisibility(false); -} - -void rgBuildViewGraphics::HandleStateEditorResized() -{ - // Update the geometry for the find widget within the editor view. - if (m_pPsoFindWidget != nullptr) - { - UpdateFindWidgetGeometry(); - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgBuildViewOpenCL.cpp b/RadeonGPUAnalyzerGUI/Src/rgBuildViewOpenCL.cpp deleted file mode 100644 index c387637..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgBuildViewOpenCL.cpp +++ /dev/null @@ -1,877 +0,0 @@ -// C++. -#include -#include -#include - -// Qt. -#include -#include - -// Infra. -#include "QtCommon/Scaling/ScalingManager.h" -#include "Utils/Include/rgaSharedUtils.h" - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -rgBuildViewOpenCL::rgBuildViewOpenCL(QWidget* pParent) - : rgBuildView(rgProjectAPI::OpenCL, pParent) -{ -} - -void rgBuildViewOpenCL::ConnectBuildSettingsSignals() -{ - // Connect the parent's signals. - rgBuildView::ConnectBuildSettingsSignals(); - - rgBuildSettingsViewOpenCL* pBuildSettingsViewOpenCL = static_cast(m_pBuildSettingsView); - assert(pBuildSettingsViewOpenCL != nullptr); - - if (pBuildSettingsViewOpenCL != nullptr) - { - bool isConnected = connect(pBuildSettingsViewOpenCL, &rgBuildSettingsViewOpenCL::PendingChangesStateChanged, this, &rgBuildView::HandleBuildSettingsPendingChangesStateChanged); - assert(isConnected); - - isConnected = connect(pBuildSettingsViewOpenCL, &rgBuildSettingsViewOpenCL::ProjectBuildSettingsSaved, this, &rgBuildView::HandleBuildSettingsSaved); - assert(isConnected); - - // Connect to build settings view's edit line's "focus in" event to color the frame green. - isConnected = connect(pBuildSettingsViewOpenCL, &rgBuildSettingsViewOpenCL::SetFrameBorderGreenSignal, this, &rgBuildView::HandleSetFrameBorderGreen); - assert(isConnected); - - // Connect to build settings view's edit line's "focus out" event to color the frame black. - isConnected = connect(pBuildSettingsViewOpenCL, &rgBuildSettingsViewOpenCL::SetFrameBorderBlackSignal, this, &rgBuildView::HandleSetFrameBorderBlack); - assert(isConnected); - } -} - -bool rgBuildViewOpenCL::ConnectMenuSignals() -{ - bool isConnected = false; - - // Connect the file menu's file item entry point changed signal. - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr) - { - rgMenuOpenCL* pMenuOpenCL = static_cast(m_pFileMenu); - assert(pMenuOpenCL != nullptr); - if (pMenuOpenCL != nullptr) - { - // Connect the OpenCL menu's "Selected entry point changed" handler. - isConnected = connect(pMenuOpenCL, &rgMenuOpenCL::SelectedEntrypointChanged, this, &rgBuildViewOpenCL::HandleSelectedEntrypointChanged); - assert(isConnected); - - // Connect the rgBuildView's entry point changed signal to the file menu's handler. - isConnected = connect(this, &rgBuildViewOpenCL::SelectedEntrypointChanged, pMenuOpenCL, &rgMenuOpenCL::HandleSelectedEntrypointChanged); - assert(isConnected); - - // Connect the file menu item selection handler for each new item. - isConnected = connect(pMenuOpenCL, &rgMenuOpenCL::MenuItemClicked, this, &rgBuildViewOpenCL::HandleMenuItemClicked); - assert(isConnected); - - // Notify the file menu that a new source file has been added. - isConnected = connect(this, &rgBuildViewOpenCL::AddedSourceFileToProject, m_pFileMenu, &rgMenuOpenCL::HandleSourceFileAdded); - assert(isConnected); - } - } - - return isConnected; -} - -void rgBuildViewOpenCL::CurrentBuildCancelled() -{ - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr) - { - rgMenuOpenCL* pMenuOpenCL = static_cast(m_pFileMenu); - assert(pMenuOpenCL != nullptr); - - if (pMenuOpenCL != nullptr) - { - // Don't allow the user to expand file item's entry point list. - pMenuOpenCL->SetIsShowEntrypointListEnabled(false); - } - } -} - -void rgBuildViewOpenCL::CurrentBuildSucceeded() -{ - // Invoke the CLI to load the start line numbers for each entrypoint. - LoadEntrypointLineNumbers(); - - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr) - { - rgMenuOpenCL* pMenuOpenCL = static_cast(m_pFileMenu); - assert(pMenuOpenCL != nullptr); - if (pMenuOpenCL != nullptr) - { - // Allow the user to expand the file's entry point list. - pMenuOpenCL->SetIsShowEntrypointListEnabled(true); - } - } - - // Update the file menu item with the clone's build output. - rgMenuOpenCL* pMenuOpenCL = static_cast(m_pFileMenu); - pMenuOpenCL->UpdateBuildOutput(m_buildOutputs); - - // Update the correlation state for each source code editor based on which source - // files were built successfully. - std::string outputGpu; - std::shared_ptr pBuildOutput = nullptr; - bool isOutputValid = rgUtils::GetFirstValidOutputGpu(m_buildOutputs, outputGpu, pBuildOutput); - if (isOutputValid && pBuildOutput != nullptr) - { - // Store the path to the current source file using the file menu. - std::string currentSourceFilePath; - rgMenu* pMenu = GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - currentSourceFilePath = pMenu->GetSelectedFilePath(); - } - - // Enable line correlation for all source files that were built successfully. - std::shared_ptr pBuildOutputOpenCL = - std::dynamic_pointer_cast(pBuildOutput); - - assert(pBuildOutputOpenCL != nullptr); - if (pBuildOutputOpenCL != nullptr) - { - auto sourcePathIterStart = pBuildOutputOpenCL->m_perFileOutput.begin(); - auto sourcePathIterEnd = pBuildOutputOpenCL->m_perFileOutput.end(); - for (auto inputFilePathIter = sourcePathIterStart; inputFilePathIter != sourcePathIterEnd; ++inputFilePathIter) - { - // Get a pointer to the source editor for each input file. - const std::string& sourceFilePath = inputFilePathIter->first; - - // Skip updating the current file within the loop. It will be updated last. - if (currentSourceFilePath.compare(sourceFilePath) != 0) - { - // Only update the correlation if the source file still exists in the project. - // Previously-built files that have already been removed from the project may - // have artifacts loaded. - auto editorIter = m_sourceCodeEditors.find(sourceFilePath); - if (editorIter != m_sourceCodeEditors.end()) - { - rgSourceCodeEditor* pEditor = GetEditorForFilepath(sourceFilePath); - - // Emit the signal used to update the correlation enabledness. - emit LineCorrelationEnabledStateChanged(pEditor, true); - } - } - } - - // Update the currently selected file last. - rgSourceCodeEditor* pEditor = GetEditorForFilepath(currentSourceFilePath); - if (pEditor != nullptr) - { - // Emit the signal used to update the correlation enabledness. - emit LineCorrelationEnabledStateChanged(pEditor, true); - } - } - } -} - -bool rgBuildViewOpenCL::CreateMenu(QWidget* pParent) -{ - m_pFileMenu = static_cast(m_pFactory->CreateFileMenu(pParent)); - - // Notify the file menu when the build succeeded. - bool isConnected = connect(this, &rgBuildViewOpenCL::ProjectBuildSuccess, m_pFileMenu, &rgMenuOpenCL::ProjectBuildSuccess); - assert(isConnected); - - // Notify the file menu to update file menu item coloring - // when an already built project is being loaded. - isConnected = connect(this, &rgBuildViewOpenCL::UpdateFileColoring, m_pFileMenu, &rgMenuOpenCL::ProjectBuildSuccess); - assert(isConnected); - - // Register the file menu with scaling manager. - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr) - { - ScalingManager::Get().RegisterObject(m_pFileMenu); - } - - return m_pFileMenu != nullptr; -} - -void rgBuildViewOpenCL::ConnectDisassemblyViewApiSpecificSignals() -{ - assert(m_pDisassemblyView != nullptr); - if (m_pDisassemblyView != nullptr) - { - // Connect the handler invoked when the user changes the selected entrypoint. - bool isConnected = connect(this, &rgBuildViewOpenCL::SelectedEntrypointChanged, - m_pDisassemblyView, &rgIsaDisassemblyView::HandleSelectedEntrypointChanged); - assert(isConnected); - - // Connect the rgIsaDisassemblyView's entry point changed handler. - isConnected = connect(m_pDisassemblyView, &rgIsaDisassemblyView::SelectedEntrypointChanged, - this, &rgBuildViewOpenCL::HandleSelectedEntrypointChanged); - assert(isConnected); - } -} - -void rgBuildViewOpenCL::DestroyProjectBuildArtifacts() -{ - // Invoke the base implementation used to destroy project build artifacts. - rgBuildView::DestroyProjectBuildArtifacts(); - - // Clear any old build artifacts from the OpenCL-specific file menu items. - ClearFileItemsEntrypointList(); -} - -bool rgBuildViewOpenCL::IsSourceFileInProject(const std::string& sourceFilePath) const -{ - bool res = false; - - std::vector sourceFiles; - rgConfigManager::Instance().GetProjectSourceFilePaths(m_pProject, m_cloneIndex, sourceFiles); - - for (std::vector::iterator iter = sourceFiles.begin(); iter != sourceFiles.end(); ++iter) - { - if (rgaSharedUtils::ComparePaths(sourceFilePath, *iter)) - { - res = true; - break; - } - } - - return res; -} - -rgMenu* rgBuildViewOpenCL::GetMenu() const -{ - return m_pFileMenu; -} - -void rgBuildViewOpenCL::FocusOnFileMenu() -{ - // Switch the focus to the file menu. - if (m_pFileMenu != nullptr) - { - m_pFileMenu->setFocus(); - } -} - -bool rgBuildViewOpenCL::PopulateMenu() -{ - bool ret = false; - - // Fill up the file path list with the paths corrected by the user. - std::vector sourceFilePaths; - rgConfigManager::Instance().GetProjectSourceFilePaths(m_pProject, m_cloneIndex, sourceFilePaths); - if (!sourceFilePaths.empty()) - { - // Add all the project's source files into the rgBuildView. - for (int fileIndex = 0; fileIndex < sourceFilePaths.size(); ++fileIndex) - { - const std::string& filePath = sourceFilePaths[fileIndex]; - - // Check that the file still exists before attempting to load it. - bool isFileExists = rgUtils::IsFileExists(filePath); - assert(isFileExists); - if (isFileExists) - { - // Add the selected file to the menu. - if (AddFile(filePath)) - { - // Set the source code view text with the contents of the selected file. - SetSourceCodeText(filePath); - - // The rgBuildView was successfully populated with the current project. - ret = true; - } - } - else - { - // Build an error string saying the file couldn't be found on disk. - std::stringstream errorString; - errorString << STR_ERR_CANNOT_LOAD_SOURCE_FILE_MSG; - errorString << filePath; - - // Show the user the error message. - rgUtils::ShowErrorMessageBox(errorString.str().c_str(), this); - } - } - - // Select the first available file. - if (ret) - { - m_pFileMenu->SelectFirstItem(); - } - } - else - { - // It's OK if the project being loaded doesn't include any source files, so return true. - ret = true; - } - - return ret; -} - -bool rgBuildViewOpenCL::IsGcnDisassemblyGenerated(const std::string& inputFilePath) const -{ - bool isCurrentFileDisassembled = false; - - auto targetGpuOutputsIter = m_buildOutputs.find(m_currentTargetGpu); - if (targetGpuOutputsIter != m_buildOutputs.end()) - { - std::shared_ptr pBuildOutput = - std::dynamic_pointer_cast(targetGpuOutputsIter->second); - - assert(pBuildOutput != nullptr); - if (pBuildOutput != nullptr) - { - auto inputFileOutputsIter = pBuildOutput->m_perFileOutput.find(inputFilePath); - if (inputFileOutputsIter != pBuildOutput->m_perFileOutput.end()) - { - rgFileOutputs& fileOutputs = inputFileOutputsIter->second; - isCurrentFileDisassembled = !fileOutputs.m_outputs.empty(); - } - } - } - - return isCurrentFileDisassembled; -} - -bool rgBuildViewOpenCL::LoadSessionMetadata(const std::string& metadataFilePath, std::shared_ptr& pBuildOutput) -{ - bool ret = false; - - std::shared_ptr pGpuOutputOpenCL = nullptr; - ret = rgXMLSessionConfig::ReadSessionMetadataOpenCL(metadataFilePath, pGpuOutputOpenCL); - pBuildOutput = pGpuOutputOpenCL; - - return ret; -} - -void rgBuildViewOpenCL::ShowCurrentFileDisassembly() -{ - bool isCurrentFileDisassembled = false; - - // Show the currently selected file's first entry point disassembly (if there is no currently selected entry). - const std::string& inputFilepath = m_pFileMenu->GetSelectedFilePath(); - rgMenuFileItem* pSelectedFileItem = m_pFileMenu->GetSelectedFileItem(); - assert(pSelectedFileItem != nullptr); - - if (pSelectedFileItem != nullptr) - { - rgMenuFileItemOpenCL* pOpenCLFileItem = static_cast(pSelectedFileItem); - assert(pOpenCLFileItem != nullptr); - - if (pOpenCLFileItem != nullptr) - { - std::string currentEntrypointName; - bool isEntrySelected = pOpenCLFileItem->GetSelectedEntrypointName(currentEntrypointName); - - // Get the list of entry point names for the selected input file. - std::vector entrypointNames; - pOpenCLFileItem->GetEntrypointNames(entrypointNames); - - // Select the first available entry point if any exist. - if (!entrypointNames.empty()) - { - // Show the first entry point in the disassembly table. - std::string& entrypointName = (isEntrySelected ? currentEntrypointName : entrypointNames[0]); - m_pDisassemblyView->HandleSelectedEntrypointChanged(m_currentTargetGpu, inputFilepath, entrypointName); - - // Emit a signal indicating that the selected entry point has changed. - emit SelectedEntrypointChanged(m_currentTargetGpu, inputFilepath, entrypointName); - - isCurrentFileDisassembled = true; - } - } - } - - // Toggle the view based on if the current file has been disassembled or not. - ToggleDisassemblyViewVisibility(isCurrentFileDisassembled); -} - -bool rgBuildViewOpenCL::AddFile(const std::string& fileFullPath, bool isNewFile) -{ - bool wasAdded = false; - if (m_pFileMenu) - { - rgMenuOpenCL* pFileMenu = nullptr; - pFileMenu = static_cast(m_pFileMenu); - if (pFileMenu != nullptr) - { - wasAdded = pFileMenu->AddItem(fileFullPath, isNewFile); - } - } - - return wasAdded; -} - -bool rgBuildViewOpenCL::CreateNewSourceFileInProject() -{ - // Generate a new empty source file in the correct location. - std::string sourceFilename = STR_DEFAULT_SOURCE_FILENAME; - - std::string fullSourcefilePath; - bool ret = CreateNewSourceFile(sourceFilename, fullSourcefilePath); - - if (ret) - { - // This should be a full filename, but new files don't have that. - if (AddFile(fullSourcefilePath, true)) - { - // Display the file's source code. - SetSourceCodeText(fullSourcefilePath); - } - } - - return ret; -} - -void rgBuildViewOpenCL::SetDefaultFocusWidget() const -{ - assert(m_pBuildSettingsView != nullptr); - if (m_pBuildSettingsView != nullptr) - { - m_pBuildSettingsView->SetInitialWidgetFocus(); - } -} - -bool rgBuildViewOpenCL::CreateNewSourceFile(const std::string& sourceFileName, std::string& fullSourceFilePath) -{ - bool ret = false; - - // True if a new project was created. - bool wasProjectCreated = false; - - // True if we are creating a new file in an existing project. - bool isExistingProject = (m_pProject != nullptr); - - if (!isExistingProject) - { - wasProjectCreated = CreateNewEmptyProject(); - - if (wasProjectCreated) - { - emit ProjectCreated(); - } - } - - if (isExistingProject || wasProjectCreated) - { - std::string newFilename; - std::string newFileExtension; - - // Generate a path to where the new empty file will live in the projects directory. - bool gotExtension = rgUtils::ProjectAPIToSourceFileExtension(m_pProject->m_api, newFileExtension); - assert(gotExtension); - if (gotExtension) - { - rgConfigManager::GenerateNewSourceFilepath(m_pProject->m_projectName, m_cloneIndex, sourceFileName, newFileExtension, newFilename, fullSourceFilePath); - - // Ensure that the folder where the file will be saved already exists. - std::string sourcefileFolder; - rgUtils::ExtractFileDirectory(fullSourceFilePath, sourcefileFolder); - if (!rgUtils::IsDirExists(sourcefileFolder)) - { - bool isDirCreated = rgUtils::CreateFolder(sourcefileFolder); - assert(isDirCreated); - } - - // Create a new file at the target location. - QFile emptyFile(fullSourceFilePath.c_str()); - emptyFile.open(QIODevice::ReadWrite); - - // Add the template source code to the newly created file. - QTextStream stream(&emptyFile); - stream << rgUtils::GenerateTemplateCode(m_pProject->m_api, newFilename).c_str() << endl; - emptyFile.close(); - - // Add the source file's path to the project's clone. - rgConfigManager::Instance().AddSourceFileToProject(fullSourceFilePath, m_pProject, m_cloneIndex); - - // Save the project after adding a source file. - rgConfigManager::Instance().SaveProjectFile(m_pProject); - - // We are done. - ret = true; - } - } - - return ret; -} - -bool rgBuildViewOpenCL::AddExistingSourcefileToProject(const std::string& sourceFilePath) -{ - bool ret = false; - - bool isProjectCreated = (m_pProject != nullptr); - if (!isProjectCreated) - { - isProjectCreated = CreateNewEmptyProject(); - - if (isProjectCreated) - { - emit ProjectCreated(); - } - } - - if (isProjectCreated) - { - if (!IsSourceFileInProject(sourceFilePath)) - { - rgConfigManager& configManager = rgConfigManager::Instance(); - - // Add the source file's path to the project's clone. - configManager.AddSourceFileToProject(sourceFilePath, m_pProject, m_cloneIndex); - - // Save the project after adding a sourcefile. - configManager.SaveProjectFile(m_pProject); - - // Add the selected file to the menu. - AddFile(sourceFilePath); - - // Set the source code view text with the contents of the selected file. - SetSourceCodeText(sourceFilePath); - - // The file was added to the project successfully. - ret = true; - - // This will make the newly-added file the current item, - // so grey out the Build settings button. - emit AddedSourceFileToProject(); - } - - if (!ret) - { - // Report the error. - std::stringstream msg; - msg << STR_ERR_CANNOT_ADD_FILE_A << sourceFilePath << STR_ERR_CANNOT_ADD_FILE_B; - rgUtils::ShowErrorMessageBox(msg.str().c_str(), this); - } - } - - return ret; -} - -bool rgBuildViewOpenCL::GetEntrypointNameForLineNumber(const std::string& filePath, int lineNumber, std::string& entryName) const -{ - bool found = false; - - // 1. Check if "lineNumber" is within some kernel code. - const auto& fileSrcLineData = m_entrypointLineNumbers.find(filePath); - if (fileSrcLineData != m_entrypointLineNumbers.end()) - { - for (const auto& entrySrcLineData : fileSrcLineData->second) - { - const std::pair startAndEndLines = entrySrcLineData.second; - if (lineNumber >= startAndEndLines.first && lineNumber <= startAndEndLines.second) - { - entryName = entrySrcLineData.first; - found = true; - break; - } - } - } - - // 2. Check if "lineNumber" is present in the line correlation table for currently active entry. - if (!found) - { - found = m_pDisassemblyView->IsLineCorrelatedInEntry(filePath, m_currentTargetGpu, entryName, lineNumber); - - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr) - { - // Fall back to selecting the current entry point in the selected file item. - rgMenuFileItem* pFileItem = m_pFileMenu->GetFileItemFromPath(filePath); - assert(pFileItem != nullptr); - if (pFileItem != nullptr) - { - rgMenuFileItemOpenCL* pFileItemOpenCL = static_cast(pFileItem); - assert(pFileItemOpenCL != nullptr); - if (pFileItemOpenCL != nullptr) - { - std::string entrypointName; - if (pFileItemOpenCL->GetSelectedEntrypointName(entrypointName)) - { - entryName = entrypointName; - } - } - } - } - } - - return found; -} - -void rgBuildViewOpenCL::HandleSelectedFileChanged(const std::string& oldFilepath, const std::string& newFilepath) -{ - // Get a pointer to the editor responsible for displaying the new file. - rgSourceCodeEditor* pEditor = GetEditorForFilepath(newFilepath, rgSrcLanguage::OpenCL); - assert(pEditor != nullptr); - if (pEditor != nullptr) - { - bool isEditorSwitched = SwitchToEditor(pEditor); - if (isEditorSwitched) - { - // Switch the disassembly view to show the currently-selected entry point in the newly-selected file item. - if (m_pDisassemblyView != nullptr && !m_isBuildInProgress) - { - // Open the disassembly view for the source file only if it's disassembled. - if (IsGcnDisassemblyGenerated(newFilepath)) - { - rgMenuFileItem* pFileItem = m_pFileMenu->GetFileItemFromPath(newFilepath); - assert(pFileItem != nullptr); - if (pFileItem != nullptr) - { - rgMenuFileItemOpenCL* pFileItemOpenCL = static_cast(pFileItem); - assert(pFileItemOpenCL != nullptr); - if (pFileItemOpenCL != nullptr) - { - // Retrieve the name of the currently-selected entry point (if there is one). - std::string selectedEntrypointName; - bool isEntrypointSelected = pFileItemOpenCL->GetSelectedEntrypointName(selectedEntrypointName); - - // Update the visibility of the disassembly view. - ToggleDisassemblyViewVisibility(isEntrypointSelected); - - if (isEntrypointSelected) - { - // Make the disassembly view visible because the file has build outputs to display. - emit SelectedEntrypointChanged(m_currentTargetGpu, newFilepath, selectedEntrypointName); - } - - // Update the titlebar for the current source editor. - UpdateSourceEditorTitlebar(pEditor); - } - } - } - else - { - // Hide the disassembly view when switching to a file that hasn't been disassembled. - ToggleDisassemblyViewVisibility(false); - } - } - } - } -} - -void rgBuildViewOpenCL::HandleSourceFileSelectedLineChanged(rgSourceCodeEditor* pEditor, int lineNumber) -{ - // Handle updating source correlation only when the project isn't currently being built. - if (!m_isBuildInProgress) - { - if (m_pDisassemblyView != nullptr && !m_pDisassemblyView->IsEmpty()) - { - const std::string& inputFilename = GetFilepathForEditor(pEditor); - bool isDisassembled = IsGcnDisassemblyGenerated(inputFilename); - if (isDisassembled) - { - int correlatedLineNumber = kInvalidCorrelationLineIndex; - - bool isCorrelationEnabled = IsLineCorrelationEnabled(pEditor); - if (isCorrelationEnabled) - { - correlatedLineNumber = lineNumber; - } - - // If the line is associated with a named entrypoint, highlight it in the file menu item. - std::string entryName; - bool isValid = GetEntrypointNameForLineNumber(inputFilename, lineNumber, entryName); - if (isValid) - { - rgMenuOpenCL* pMenuOpenCL = static_cast(m_pFileMenu); - assert(pMenuOpenCL != nullptr); - if (pMenuOpenCL != nullptr) - { - pMenuOpenCL->HandleSelectedEntrypointChanged(inputFilename, entryName); - } - } - - // Send the input source file's correlation line index to the disassembly view. - m_pDisassemblyView->HandleInputFileSelectedLineChanged(m_currentTargetGpu, inputFilename, entryName, correlatedLineNumber); - } - } - } -} - -void rgBuildViewOpenCL::HandleSelectedEntrypointChanged(const std::string& inputFilePath, const std::string& selectedEntrypointName) -{ - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr) - { - rgMenuOpenCL* pFileMenuOpenCL = static_cast(m_pFileMenu); - if (pFileMenuOpenCL != nullptr) - { - // Trigger the file menu to be updated, which will change the current selection in the current item's entry point list. - pFileMenuOpenCL->HandleSelectedEntrypointChanged(inputFilePath, selectedEntrypointName); - } - } - - // Highlight the start line for the given entry point in the source editor. - HighlightEntrypointStartLine(inputFilePath, selectedEntrypointName); -} - -void rgBuildViewOpenCL::HandleMenuItemClicked(rgMenuFileItem* pItem) -{ - if (ShowSaveDialog()) - { - m_pFileMenu->HandleSelectedFileChanged(pItem); - } -} - -void rgBuildViewOpenCL::ClearFileItemsEntrypointList() -{ - rgMenuOpenCL* pMenuOpenCL = static_cast(m_pFileMenu); - assert(pMenuOpenCL != nullptr); - if (pMenuOpenCL != nullptr) - { - // Clear references to build outputs from the file menu, - pMenuOpenCL->ClearBuildOutputs(); - } -} - -int rgBuildViewOpenCL::FindEntrypointStartLine(rgSourceCodeEditor* pEditor, int listKernelsStartLine) const -{ - int actualStartLine = listKernelsStartLine; - - // Verify that the current source editor is valid. - assert(pEditor != nullptr); - if (pEditor != nullptr) - { - // Start at the given line and search for the next opening brace. This is the "real" start of the entrypoint. - int searchLine = actualStartLine; - bool searchingForStartLine = true; - while (searchingForStartLine) - { - QString lineText; - bool gotLineText = pEditor->GetTextAtLine(searchLine, lineText); - if (gotLineText) - { - // Start at the index of the brace, and check if there's anything else in the line other than whitespace. - int braceIndex = lineText.indexOf("{"); - if (braceIndex != -1) - { - std::string lineTextString = lineText.toStdString(); - - // Search for alphanumeric characters the occur after the opening brace. - auto startCharacter = lineTextString.begin() + (braceIndex + 1); - auto endCharacter = lineTextString.end(); - - // Create a list of bools, used to determine if there are any alphanumeric characters in the line after the opening brace. - std::vector isAlphanumericList; - isAlphanumericList.resize(lineTextString.size()); - - // Step through each character in the line. If it's alphanumeric, add a "true" to the output list in the character's position. - std::transform(startCharacter, endCharacter, isAlphanumericList.begin(), [](char c) { return (isalnum(c) != 0); }); - - // If there are any 'true' values in the isAlphanumericList, it means that an alphanumeric character appeared after the opening brace. - auto alphanumericCharactersIter = std::find(isAlphanumericList.begin(), isAlphanumericList.end(), true); - if (alphanumericCharactersIter == isAlphanumericList.end()) - { - // There was only whitespace after the opening brace. Advance one more line to where the entry point actually starts. - searchLine++; - } - - actualStartLine = searchLine; - searchingForStartLine = false; - } - else - { - // Step down to the next line to check if there's an opening brace for the entrypoint. - searchLine++; - } - } - else - { - searchingForStartLine = false; - } - } - } - - return actualStartLine; -} - -void rgBuildViewOpenCL::HighlightEntrypointStartLine(const std::string& inputFilePath, const std::string& selectedEntrypointName) -{ - // Find the input file in the map of entry point start line numbers. - auto inputFileIter = m_entrypointLineNumbers.find(inputFilePath); - if (inputFileIter != m_entrypointLineNumbers.end()) - { - // Search for the start line number for the given entry point name. - EntryToSourceLineRange& fileEntrypointsInfo = inputFileIter->second; - auto lineNumberIter = fileEntrypointsInfo.find(selectedEntrypointName); - if (lineNumberIter != fileEntrypointsInfo.end()) - { - rgSourceCodeEditor* pEditor = GetEditorForFilepath(inputFilePath); - assert(pEditor != nullptr); - if (pEditor != nullptr) - { - // Retrieve the entrypoint's start line index according to the "list-kernels" results. - int listKernelsEntrypointStartLine = lineNumberIter->second.first; - - // If necessary, advance to the line with the entrypoint's opening brace. This is the real start of the entrypoint. - int actualStartLine = FindEntrypointStartLine(pEditor, listKernelsEntrypointStartLine); - - // Scroll to the start of the entrypoint. - pEditor->ScrollToLine(actualStartLine); - - // Move the cursor to the line where the entry point starts. - QTextCursor cursor(pEditor->document()->findBlockByLineNumber(actualStartLine - 1)); - pEditor->setTextCursor(cursor); - - // Highlight the start line for the entrypoint. - QList lineIndices; - lineIndices.push_back(actualStartLine); - pEditor->SetHighlightedLines(lineIndices); - } - } - } -} - -bool rgBuildViewOpenCL::LoadEntrypointLineNumbers() -{ - bool ret = false; - - // Destroy the existing entry point line numbers map. - m_entrypointLineNumbers.clear(); - - // Invoke the CLI To query entry point names and start line numbers. - ret = rgCliLauncher::ListKernels(m_pProject, m_cloneIndex, m_entrypointLineNumbers); - if (!ret) - { - // Let the user know that the query failed. - emit SetStatusBarText(STR_ERR_FAILED_TO_GET_ENTRYPOINT_LINE_NUMBERS, gs_STATUS_BAR_NOTIFICATION_TIMEOUT_MS); - } - - return ret; -} - -void rgBuildViewOpenCL::SetAPISpecificBorderColor() -{ - HandleSetFrameBorderGreen(); -} - -bool rgBuildViewOpenCL::IsLineCorrelationSupported() const -{ - return true; -} - -void rgBuildViewOpenCL::UpdateApplicationNotificationMessage() -{ - // Add OpenCL application notification message here, when needed. -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgBuildViewVulkan.cpp b/RadeonGPUAnalyzerGUI/Src/rgBuildViewVulkan.cpp deleted file mode 100644 index a6631ad..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgBuildViewVulkan.cpp +++ /dev/null @@ -1,1782 +0,0 @@ -// C++. -#include -#include -#include -#include - -// Qt. -#include -#include -#include -#include - -// Infra. -#include -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// PSO editor container frame name. -static const char* s_PSO_EDITOR_FRAME_NAME = "PSOEditorContainerFrame"; -static const char* s_APPLICATION_INFORMATION_MESSAGE = "Used vk-spv-offline mode."; -static const char* s_APPLICATION_INFORMATION_TOOLTIP = "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* pParent) - : rgBuildViewGraphics(rgProjectAPI::Vulkan, pParent) -{ -} - -void rgBuildViewVulkan::ConnectBuildSettingsSignals() -{ - // Connect the parent's signals. - rgBuildView::ConnectBuildSettingsSignals(); - - // Connect the notification of pending state changes from the Vulkan build settings to the build view. - bool isConnected = connect(static_cast(m_pBuildSettingsView), &rgBuildSettingsViewVulkan::PendingChangesStateChanged, this, &rgBuildView::HandleBuildSettingsPendingChangesStateChanged); - assert(isConnected); - - // Connect the notification that the build settings have been saved from the Vulkan build settings to the build view. - isConnected = connect(static_cast(m_pBuildSettingsView), &rgBuildSettingsViewVulkan::ProjectBuildSettingsSaved, this, &rgBuildView::HandleBuildSettingsSaved); - assert(isConnected); - - // Connect to build settings view's edit line's "focus in" event to color the frame red. - isConnected = connect(static_cast(m_pBuildSettingsView), &rgBuildSettingsViewVulkan::SetFrameBorderRedSignal, this, &rgBuildView::HandleSetFrameBorderRed); - assert(isConnected); - - // Connect to build settings view's edit line's "focus out" event to color the frame black. - isConnected = connect(static_cast(m_pBuildSettingsView), &rgBuildSettingsViewVulkan::SetFrameBorderBlackSignal, this, &rgBuildView::HandleSetFrameBorderBlack); - assert(isConnected); -} - -void rgBuildViewVulkan::SetDefaultFocusWidget() const -{ - assert(m_pBuildSettingsView != nullptr); - if (m_pBuildSettingsView != nullptr) - { - m_pBuildSettingsView->SetInitialWidgetFocus(); - } -} - -void rgBuildViewVulkan::SetPSOEditorDefaultFocusWidget() const -{ - assert(m_pPipelineStateView != nullptr); - if (m_pPipelineStateView != nullptr) - { - m_pPipelineStateView->SetInitialWidgetFocus(); - } -} - -void rgBuildViewVulkan::SetAPISpecificBorderColor() -{ - HandleSetFrameBorderRed(); -} - -bool rgBuildViewVulkan::ConnectMenuSignals() -{ - // Connect the actions for the context menu. - bool isConnected = connect(m_pActionAddExistingFile, &QAction::triggered, this, &rgBuildViewVulkan::HandleAddExistingFile); - assert(isConnected); - isConnected = connect(m_pActionCreateNewFile, &QAction::triggered, this, &rgBuildViewVulkan::HandleCreateNewFile); - assert(isConnected); - - rgMenuGraphics* pMenu = static_cast(m_pFileMenu); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - // Connect the file menu's "Add existing file" button handler. - isConnected = connect(pMenu, &rgMenuGraphics::AddExistingFileButtonClicked, this, &rgBuildViewVulkan::HandleAddFileButtonClicked); - assert(isConnected); - - // Connect the file menu item's drag and drop handler. - isConnected = connect(pMenu, &rgMenuGraphics::DragAndDropExistingFile, this, &rgBuildViewVulkan::HandleExistingFileDragAndDrop); - assert(isConnected); - - // Connect the load PSO file handler with drag and drop file. - isConnected = connect(pMenu, &rgMenuGraphics::DragAndDropExistingPsoFile, this, &rgBuildViewVulkan::HandleLoadPipelineStateFile); - assert(isConnected); - - // Connect the file menu's "Remove file" button handler. - isConnected = connect(pMenu, &rgMenuGraphics::RemoveFileButtonClicked, this, &rgBuildViewVulkan::HandleRemoveFileButtonClicked); - assert(isConnected); - - // Connect the file menu's "Restore original SPIR-V binary" handler. - isConnected = connect(pMenu, &rgMenuGraphics::RestoreOriginalSpirvClicked, this, &rgBuildViewVulkan::HandleRestoreOriginalSpvClicked); - assert(isConnected); - - // Connect the file menu item selection handler for each new item. - isConnected = connect(pMenu, &rgMenuGraphics::MenuItemClicked, this, &rgBuildViewVulkan::HandleMenuItemClicked); - assert(isConnected); - - // Connect the file menu item focus next view signal. - isConnected = connect(pMenu, &rgMenuGraphics::FocusNextView, this, &rgBuildView::HandleFocusNextView); - assert(isConnected); - - // Connect the file menu item focus previous view signal. - isConnected = connect(pMenu, &rgMenuGraphics::FocusPrevView, this, &rgBuildView::HandleFocusPrevView); - assert(isConnected); - - // Connect the file menu clicked signal. - isConnected = connect(pMenu, &rgMenuGraphics::MenuClicked, this, &rgBuildViewVulkan::HandlePipelineStateTreeFocusOut); - assert(isConnected); - - // Connect the "Pipeline state" button in the file menu. - rgMenuPipelineStateItem* pPipelineStateItem = pMenu->GetPipelineStateItem(); - assert(pPipelineStateItem != nullptr); - if (pPipelineStateItem != nullptr) - { - isConnected = connect(pPipelineStateItem, &rgMenuPipelineStateItem::PipelineStateButtonClicked, this, &rgBuildViewVulkan::HandlePipelineStateMenuItemClicked); - assert(isConnected); - } - } - - return isConnected; -} - -bool rgBuildViewVulkan::HandlePipelineStateFileSaved() -{ - bool isOk = false; - std::string errorString; - - std::shared_ptr pVulkanClone = - std::dynamic_pointer_cast(m_pProject->m_clones[m_cloneIndex]); - - assert(pVulkanClone != nullptr); - if (pVulkanClone != nullptr) - { - // Determine which PSO state file is being edited. - const rgPipelineState& currentPsoState = pVulkanClone->m_psoStates[m_pipelineStateIndex]; - - // Save the pipeline state file. - isOk = m_pPipelineStateModel->SavePipelineStateFile(currentPsoState.m_pipelineStateFilePath, errorString); - assert(isOk); - } - - assert(isOk); - if (!isOk) - { - // The pipeline state failed to save properly. Is the user currently viewing the PSO editor? - if (m_editMode != EditMode::PipelineSettings) - { - // If the user isn't in the PSO editor, switch to it so they can resolve the problem. - SwitchEditMode(EditMode::PipelineSettings); - } - - // Show the error string to the user, letting them know that the PSO file was not saved correctly. - std::stringstream errorStream; - errorStream << STR_ERR_CANNOT_SAVE_PIPELINE_STATE_FILE; - errorStream << " "; - errorStream << errorString; - rgUtils::ShowErrorMessageBox(errorStream.str().c_str(), this); - } - - return isOk; -} - -void rgBuildViewVulkan::HandlePipelineStateFileLoaded() -{ - // Open the file browser in the last selected directory. - std::string pipelineStateFilePath = rgConfigManager::Instance().GetLastSelectedFolder(); - - std::shared_ptr pVulkanClone = - std::dynamic_pointer_cast(m_pProject->m_clones[m_cloneIndex]); - - assert(pVulkanClone != nullptr); - if (pVulkanClone != nullptr) - { - // Select the relevant file filter based on the pipeline type (compute, graphics). - bool isGraphicsPipeline = (pVulkanClone->m_pipeline.m_type == rgPipelineType::Graphics); - const char* psoFileFilter = isGraphicsPipeline ? STR_DEFAULT_PIPELINE_FILE_EXTENSION_FILTER_GRAPHICS : - STR_DEFAULT_PIPELINE_FILE_EXTENSION_FILTER_COMPUTE; - - // Display an "Open file" dialog to let the user choose - // which pipeline state configuration file to use. - bool isOk = rgUtils::OpenFileDialog(this, pipelineStateFilePath, - STR_PIPELINE_STATE_FILE_DIALOG_CAPTION, psoFileFilter); - - if (isOk) - { - HandleLoadPipelineStateFile(pipelineStateFilePath); - } - } -} - -bool rgBuildViewVulkan::LoadPipelineStateFile(const std::string& pipelineStateFilePath) -{ - bool isOk = false; - - std::shared_ptr pVulkanClone = - std::dynamic_pointer_cast(m_pProject->m_clones[m_cloneIndex]); - - std::string errorString; - assert(pVulkanClone != nullptr); - if (pVulkanClone != nullptr) - { - // Determine which pipeline state file is being edited. - rgPipelineState& currentPsoState = pVulkanClone->m_psoStates[m_pipelineStateIndex]; - - // Attempt to load the pipeline state file in the model. - isOk = m_pPipelineStateModel->LoadPipelineStateFile(this, pipelineStateFilePath, pVulkanClone->m_pipeline.m_type, errorString); - assert(isOk); - if (isOk) - { - // Assign the pipeline state file in the project. - currentPsoState.m_originalPipelineStateFilePath = pipelineStateFilePath; - - // Initialize the model. - m_pPipelineStateView->InitializeModel(m_pPipelineStateModel); - - // Scale the settings tree after each load. - m_pPipelineStateView->ScaleSettingsTree(); - } - } - - assert(isOk); - if (isOk) - { - // Emit a signal indicating that the specified PSO file has been loaded successfully. - emit PsoFileLoaded(); - } - else - { - // Show the error string to the user, letting them know that the PSO file was not saved correctly. - std::stringstream errorStream; - errorStream << STR_ERR_CANNOT_LOAD_PIPELINE_STATE_FILE; - errorStream << " "; - errorStream << errorString; - emit SetStatusBarText(errorStream.str().c_str()); - } - - return isOk; -} - -void rgBuildViewVulkan::HandlePipelineStateMenuItemClicked(rgMenuPipelineStateItem* pItem) -{ - if (ShowSaveDialog()) - { - SwitchEditMode(EditMode::PipelineSettings); - - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr) - { - m_pFileMenu->HandlePipelineStateButtonClicked(true); - } - - assert(pItem != nullptr); - if (pItem != nullptr) - { - pItem->SetCurrent(true); - } - - // Reset the find text widget. - assert(m_pPipelineStateView != nullptr); - if (m_pPipelineStateView != nullptr) - { - m_pPipelineStateView->ResetSearch(); - } - - // Set the PSO editor frame color to Vulkan red. - HandlePipelineStateTreeFocusIn(); - } -} - -void rgBuildViewVulkan::HandleMenuItemClicked(rgMenuFileItem* pItem) -{ - if (ShowSaveDialog()) - { - m_pFileMenu->HandleSelectedFileChanged(pItem); - } -} - -rgMenu* rgBuildViewVulkan::GetMenu() const -{ - return m_pFileMenu; -} - -rgPipelineStateModel* rgBuildViewVulkan::GetPipelineStateModel() -{ - return m_pPipelineStateModel; -} - -bool rgBuildViewVulkan::PopulateMenu() -{ - bool isLoadFailed = false; - - std::shared_ptr pVulkanClone = - std::dynamic_pointer_cast(m_pProject->m_clones[m_cloneIndex]); - - assert(pVulkanClone != nullptr); - if (pVulkanClone != nullptr) - { - // Determine the type of pipeline to populate the menu widget with. - bool isGraphicsPipeline = (pVulkanClone->m_pipeline.m_type == rgPipelineType::Graphics); - - // 1st non-empty stage item. - size_t firstNonEmptyStage = -1; - - // Step through each stage type in a graphics pipeline by default. - size_t firstStage = static_cast(rgPipelineStage::Vertex); - size_t lastStage = static_cast(rgPipelineStage::Fragment); - - // If a compute pipeline is being loaded, only attempt to load the single Compute stage. - if (!isGraphicsPipeline) - { - firstStage = lastStage = static_cast(rgPipelineStage::Compute); - } - - for (size_t stageIndex = firstStage; stageIndex <= lastStage; ++stageIndex) - { - const std::string& stageFilePath = pVulkanClone->m_pipeline.m_shaderStages[stageIndex]; - - if (!stageFilePath.empty()) - { - // Check that the file still exists before attempting to load it. - bool isFileExists = rgUtils::IsFileExists(stageFilePath); - assert(isFileExists); - if (isFileExists) - { - // Add the selected file to the menu. - SetStageSourceFile(static_cast(stageIndex), stageFilePath); - firstNonEmptyStage = (firstNonEmptyStage == -1 ? stageIndex : firstNonEmptyStage); - } - else - { - // Build an error string saying the file couldn't be found on disk. - std::stringstream errorString; - errorString << STR_ERR_CANNOT_LOAD_SOURCE_FILE_MSG; - errorString << stageFilePath; - - // Show the user the error message. - rgUtils::ShowErrorMessageBox(errorString.str().c_str(), this); - - isLoadFailed = true; - } - } - } - - // Select the 1st non-empty File Menu item. - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr && firstNonEmptyStage != -1) - { - auto pMenuItem = m_pFileMenu->GetStageItem(static_cast(firstNonEmptyStage)); - if (pMenuItem != nullptr && !pMenuItem->GetFilename().empty()) - { - m_pFileMenu->HandleSelectedFileChanged(pMenuItem); - } - } - } - - return !isLoadFailed; -} - -bool rgBuildViewVulkan::IsGcnDisassemblyGenerated(const std::string& inputFilePath) const -{ - bool isCurrentFileDisassembled = false; - - auto targetGpuOutputsIter = m_buildOutputs.find(m_currentTargetGpu); - if (targetGpuOutputsIter != m_buildOutputs.end()) - { - std::shared_ptr pBuildOutput = - std::dynamic_pointer_cast(targetGpuOutputsIter->second); - - assert(pBuildOutput != nullptr); - if (pBuildOutput != nullptr) - { - auto inputFileIter = pBuildOutput->m_perFileOutput.find(inputFilePath); - if (inputFileIter != pBuildOutput->m_perFileOutput.end()) - { - rgFileOutputs& fileOutputs = inputFileIter->second; - isCurrentFileDisassembled = !fileOutputs.m_outputs.empty(); - } - } - } - - return isCurrentFileDisassembled; -} - -bool rgBuildViewVulkan::LoadSessionMetadata(const std::string& metadataFilePath, std::shared_ptr& pBuildOutput) -{ - bool ret = false; - std::shared_ptr pGpuOutputVulkan = nullptr; - ret = rgXMLSessionConfig::ReadSessionMetadataVulkan(metadataFilePath, pGpuOutputVulkan); - assert(ret); - if (ret) - { - pBuildOutput = pGpuOutputVulkan; - } - - return ret; -} - -void rgBuildViewVulkan::ReloadFile(const std::string& filePath) -{ - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr) - { - rgMenuFileItemGraphics* pFileItem = static_cast(m_pFileMenu->GetFileItemFromPath(filePath)); - assert(pFileItem); - if (pFileItem != nullptr) - { - // If it's a SPIR-V binary file, disassemble it and update the disassembly text in the code editor. - if (pFileItem->GetFileType() == rgVulkanInputType::Spirv) - { - std::string cliOutput, compilerPath; - const std::string& disasmFilePath = m_spvDisasmFiles[pFileItem->GetStage()]; - assert(!disasmFilePath.empty()); - if (!disasmFilePath.empty()) - { - // Get the "alternative compiler path" setting value. - std::shared_ptr pVulkanClone = - std::dynamic_pointer_cast(m_pProject->m_clones[m_cloneIndex]); - - assert(pVulkanClone != nullptr && pVulkanClone->m_pBuildSettings != nullptr); - if (pVulkanClone != nullptr && pVulkanClone->m_pBuildSettings != nullptr) - { - compilerPath = std::get(pVulkanClone->m_pBuildSettings->m_compilerPaths); - } - - bool isOk = rgCliLauncher::DisassembleSpvToText(compilerPath, filePath, disasmFilePath, cliOutput); - HandleNewCLIOutputString(cliOutput); - if (isOk) - { - SetSourceCodeText(disasmFilePath); - - // Update the last modification time. - QFileInfo fileInfo(filePath.c_str()); - m_fileModifiedTimeMap[m_pCurrentCodeEditor] = fileInfo.lastModified(); - } - } - } - else - { - SetSourceCodeText(filePath); - } - } - } -} - -void rgBuildViewVulkan::ShowCurrentFileDisassembly() -{ - bool isCurrentFileDisassembled = false; - - // Show the currently selected file's first entry point disassembly (if there is no currently selected entry). - const std::string& inputFilepath = m_pFileMenu->GetSelectedFilePath(); - rgMenuFileItem* pSelectedFileItem = m_pFileMenu->GetSelectedFileItem(); - assert(pSelectedFileItem != nullptr); - - if (pSelectedFileItem != nullptr) - { - rgMenuFileItemGraphics* pFileItemPipelineStage = static_cast(pSelectedFileItem); - assert(pFileItemPipelineStage != nullptr); - - if (pFileItemPipelineStage != nullptr) - { - isCurrentFileDisassembled = IsGcnDisassemblyGenerated(inputFilepath); - if (isCurrentFileDisassembled) - { - // Show the first entry point in the disassembly table. - const std::string& currentEntrypointName = STR_DEFAULT_VULKAN_GLSL_ENTRYPOINT_NAME; - m_pDisassemblyView->HandleSelectedEntrypointChanged(m_currentTargetGpu, inputFilepath, currentEntrypointName); - - // Emit a signal indicating that the selected entry point has changed. - emit SelectedEntrypointChanged(m_currentTargetGpu, inputFilepath, currentEntrypointName); - } - } - } - - // Toggle the view based on if the current file has been disassembled or not. - ToggleDisassemblyViewVisibility(isCurrentFileDisassembled); -} - -void rgBuildViewVulkan::SaveFile(rgMenuFileItemGraphics* pFileItem) -{ - // Get the file editor for the file menu item. - rgSourceCodeEditor* pFileEditor = nullptr; - const std::string filePath = pFileItem->GetFilename(); - auto iter = m_sourceCodeEditors.find(filePath); - assert(iter != m_sourceCodeEditors.end()); - if (iter != m_sourceCodeEditors.end()) - { - pFileEditor = iter->second; - } - - assert(pFileEditor != nullptr); - assert(m_cloneIndex < m_pProject->m_clones.size()); - if (pFileEditor != nullptr && m_pFileMenu != nullptr && - (m_cloneIndex < m_pProject->m_clones.size())) - { - // Check if the file needs reassembling (modified SPIR-V disassembly). - bool needReassemble = false; - assert(pFileItem != nullptr); - if (pFileItem != nullptr) - { - needReassemble = (pFileItem->GetFileType() == rgVulkanInputType::Spirv); - } - - // Check if we're saving a modified disassembled SPIR-V text first time. - // If so, we have to replace the original spv binary with the modified disassembly file in the Project. - if (needReassemble && pFileEditor->document()->isModified()) - { - rgPipelineStage stage = pFileItem->GetStage(); - const std::string& spvDisasmFilePath = m_spvDisasmFiles[stage]; - QFileInfo fileInfo(spvDisasmFilePath.c_str()); - - // Write the editor text to file if the file path is valid. - if (!spvDisasmFilePath.empty()) - { - SaveEditorTextToFile(pFileEditor, spvDisasmFilePath); - } - - // 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 = fileInfo.fileName().toStdString() + ". " + STR_SOURCE_EDITOR_TITLEBAR_SPIRV_DISASM_SAVED_A + " " + - STR_FILE_CONTEXT_MENU_RESTORE_SPV + " " + STR_SOURCE_EDITOR_TITLEBAR_SPIRV_DISASM_SAVED_B; - pFileEditor->SetTitleBarText(msg); - - // If it's the current item, display the message on the title bar. - if (m_pFileMenu->IsCurrentlySelectedFileItem(pFileItem) && m_pSourceEditorTitlebar != nullptr) - { - m_pSourceEditorTitlebar->ShowMessage(msg); - } - - // Switch "last modified time" to the spv disassembly file. - m_fileModifiedTimeMap[pFileEditor] = fileInfo.lastModified(); - - // Replace the spv binary file with its disassembly in the project, File Menu and in the Code Editor map. - const std::string& spvFilePath = pFileItem->GetFilename(); - auto editor = m_sourceCodeEditors.find(spvFilePath); - assert(editor != m_sourceCodeEditors.end()); - if (editor != m_sourceCodeEditors.end()) - { - // Replace file path in the Code Editor map. - m_sourceCodeEditors.erase(editor); - m_sourceCodeEditors[spvDisasmFilePath] = pFileEditor; - } - - // Store the original spv binary path to the project so that a user can restore it later. - std::shared_ptr pVulkanClone = - std::dynamic_pointer_cast(m_pProject->m_clones[m_cloneIndex]); - assert(pVulkanClone != nullptr); - if (pVulkanClone != nullptr) - { - pVulkanClone->m_spvBackup.m_type = pVulkanClone->m_pipeline.m_type; - pVulkanClone->m_spvBackup.m_shaderStages[stage] = spvFilePath; - - // Replace file path in the project. - pVulkanClone->m_pipeline.m_shaderStages[stage] = spvDisasmFilePath; - rgConfigManager::Instance().SaveProjectFile(m_pProject); - } - - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr) - { - // Replace file path in the File Menu. - m_pFileMenu->ReplaceStageFile(stage, spvDisasmFilePath, rgVulkanInputType::SpirvTxt); - - // Add "restore spv" option to the file menu item. - m_pFileMenu->GetStageItem(stage)->AddContextMenuActionRestoreSpv(); - } - - // Replace file path in the Build Output. - ReplaceInputFileInBuildOutput(spvFilePath, spvDisasmFilePath); - - // Replace file path in the Disassembly View tables. - if (m_pDisassemblyView != nullptr) - { - m_pDisassemblyView->ReplaceInputFilePath(spvFilePath, spvDisasmFilePath); - } - } - } -} - -void rgBuildViewVulkan::SaveCurrentFile() -{ - assert(m_pCurrentCodeEditor != nullptr && m_pSourceEditorTitlebar != nullptr && m_pFileMenu != nullptr); - if (m_pCurrentCodeEditor != nullptr && m_pSourceEditorTitlebar != nullptr && m_pFileMenu != nullptr) - { - bool needDisassembleSpv = false; - - rgMenuFileItemGraphics* pCurrentMenuItem = m_pFileMenu->GetCurrentFileMenuItem(); - if (pCurrentMenuItem != nullptr) - { - needDisassembleSpv = (pCurrentMenuItem->GetFileType() == rgVulkanInputType::Spirv); - } - - // Check if we're saving a modified disassembled SPIR-V text first time. - // If so, we have to replace the original spv binary with the modified disassembly file in the Project. - if (needDisassembleSpv && m_pCurrentCodeEditor->document()->isModified()) - { - rgPipelineStage stage = m_pFileMenu->GetCurrentStage(); - const std::string& spvDisasmFilePath = m_spvDisasmFiles[stage]; - QFileInfo fileInfo(spvDisasmFilePath.c_str()); - - // Write the editor text to file if the file path is valid. - if (!spvDisasmFilePath.empty()) - { - SaveEditorTextToFile(m_pCurrentCodeEditor, spvDisasmFilePath); - } - - // 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 = fileInfo.fileName().toStdString() + ". " + STR_SOURCE_EDITOR_TITLEBAR_SPIRV_DISASM_SAVED_A + " " + - STR_FILE_CONTEXT_MENU_RESTORE_SPV + " " + STR_SOURCE_EDITOR_TITLEBAR_SPIRV_DISASM_SAVED_B; - m_pCurrentCodeEditor->SetTitleBarText(msg); - m_pSourceEditorTitlebar->ShowMessage(msg); - - // Switch "last modified time" to the spv disassembly file. - m_fileModifiedTimeMap[m_pCurrentCodeEditor] = fileInfo.lastModified(); - - // Replace the spv binary file with its disassembly in the project, File Menu and in the Code Editor map. - const std::string& spvFilePath = m_pFileMenu->GetSelectedFilePath(); - auto editor = m_sourceCodeEditors.find(spvFilePath); - assert(editor != m_sourceCodeEditors.end()); - if (editor != m_sourceCodeEditors.end()) - { - // Replace file path in the Code Editor map. - m_sourceCodeEditors.erase(editor); - m_sourceCodeEditors[spvDisasmFilePath] = m_pCurrentCodeEditor; - } - - // Store the original spv binary path to the project so that a user can restore it later. - std::shared_ptr pVulkanClone = - std::dynamic_pointer_cast(m_pProject->m_clones[m_cloneIndex]); - assert(pVulkanClone != nullptr); - if (pVulkanClone != nullptr) - { - pVulkanClone->m_spvBackup.m_type = pVulkanClone->m_pipeline.m_type; - pVulkanClone->m_spvBackup.m_shaderStages[stage] = spvFilePath; - - // Replace file path in the project. - pVulkanClone->m_pipeline.m_shaderStages[stage] = spvDisasmFilePath; - rgConfigManager::Instance().SaveProjectFile(m_pProject); - } - - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr) - { - // Replace file path in the File Menu. - m_pFileMenu->ReplaceStageFile(stage, spvDisasmFilePath, rgVulkanInputType::SpirvTxt); - - // Add "restore spv" option to the file menu item. - m_pFileMenu->GetStageItem(stage)->AddContextMenuActionRestoreSpv(); - } - - // Replace file path in the Build Output. - ReplaceInputFileInBuildOutput(spvFilePath, spvDisasmFilePath); - - // Replace file path in the Disassembly View tables. - if (m_pDisassemblyView != nullptr) - { - m_pDisassemblyView->ReplaceInputFilePath(spvFilePath, spvDisasmFilePath); - } - } - else - { - rgBuildView::SaveCurrentFile(); - } - } -} - -void rgBuildViewVulkan::SaveSourceFile(const std::string& sourceFilePath) -{ - // Do not save the file if it's a SPIR-V disassembly and the corresponding File Menu item - // has the "SPIR-V binary" file type. - bool isSpvBinary = false; - if (m_pFileMenu != nullptr) - { - rgMenuFileItemGraphics* pFileItem = static_cast(m_pFileMenu->GetFileItemFromPath(sourceFilePath)); - assert(pFileItem != nullptr); - if (pFileItem != nullptr) - { - isSpvBinary = (pFileItem->GetFileType() == rgVulkanInputType::Spirv); - } - } - - if (!isSpvBinary) - { - rgBuildView::SaveSourceFile(sourceFilePath); - } -} - -bool rgBuildViewVulkan::SaveCurrentState() -{ - // Save the pipeline state. - bool status = HandlePipelineStateFileSaved(); - - assert(status); - if (status) - { - // Save all file items in the Vulkan way (meaning, check if they - // are SPIR-V files that need to be reassembled and act accordingly. - rgMenuGraphics* pMenu = static_cast(GetMenu()); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - std::vector fileItems = pMenu->GetAllFileItems(); - for (rgMenuFileItem* pItem : fileItems) - { - rgMenuFileItemGraphics* pItemGraphics = static_cast(pItem); - assert(pItemGraphics != nullptr); - if (pItemGraphics != nullptr) - { - SaveFile(pItemGraphics); - } - } - } - - // Call the base implementation to save the remaining files/settings. - return rgBuildView::SaveCurrentState(); - } - - return status; -} - -void rgBuildViewVulkan::ConnectPipelineStateViewSignals() -{ - assert(m_pPipelineStateView != nullptr); - if (m_pPipelineStateView != nullptr) - { - // Connect the save button handler. - bool isConnected = connect(m_pPipelineStateView, &rgPipelineStateView::SaveButtonClicked, this, &rgBuildViewVulkan::HandlePipelineStateFileSaved); - assert(isConnected); - - // Connect the load button handler. - isConnected = connect(m_pPipelineStateView, &rgPipelineStateView::LoadButtonClicked, this, &rgBuildViewVulkan::HandlePipelineStateFileLoaded); - assert(isConnected); - - // Connect the load PSO file handler with drag and drop file. - isConnected = connect(m_pPipelineStateView, &rgPipelineStateView::DragAndDropExistingFile, this, &rgBuildViewVulkan::HandleLoadPipelineStateFile); - assert(isConnected); - - // Connect the PSO file loaded handler. - isConnected = connect(this, &rgBuildViewGraphics::PsoFileLoaded, m_pPipelineStateView, &rgPipelineStateView::HandlePsoFileLoaded); - assert(isConnected); - - // Connect the pipeline state view's editor's resized handler. - isConnected = connect(m_pPipelineStateView, &rgPipelineStateView::EditorResized, this, &rgBuildViewGraphics::HandleStateEditorResized); - assert(isConnected); - - // Connect the pipeline state tree in focus signal. - isConnected = connect(m_pPipelineStateView, &rgPipelineStateView::PipelineStateTreeFocusIn, this, &rgBuildViewVulkan::HandlePipelineStateTreeFocusIn); - assert(isConnected); - - // Connect the pipeline state tree focus out signal. - isConnected = connect(m_pPipelineStateView, &rgPipelineStateView::PipelineStateTreeFocusOut, this, &rgBuildViewVulkan::HandlePipelineStateTreeFocusOut); - assert(isConnected); - - isConnected = connect(m_pViewManager, &rgViewManager::PSOEditorWidgetFocusOutSignal, this, &rgBuildViewVulkan::HandlePipelineStateTreeFocusOut); - assert(isConnected); - - isConnected = connect(m_pViewManager, &rgViewManager::PSOEditorWidgetFocusInSignal, this, &rgBuildViewVulkan::HandlePipelineStateTreeFocusIn); - assert(isConnected); - } -} - -void rgBuildViewVulkan::InitializeModeSpecificViews() -{ - // Create the pipeline state model. - CreatePipelineStateModel(); - - // Create the Vulkan Pipeline State editor view. - CreatePipelineStateView(this); -} - -void rgBuildViewVulkan::FocusOnFileMenu() -{ - // Switch the focus to the file menu. - if (m_pFileMenu != nullptr) - { - m_pFileMenu->setFocus(); - } -} - -bool rgBuildViewVulkan::CreateDefaultGraphicsPipeline() -{ - return CreateProject(rgPipelineType::Graphics); -} - -bool rgBuildViewVulkan::CreateDefaultComputePipeline() -{ - return CreateProject(rgPipelineType::Compute); -} - -void rgBuildViewVulkan::HandleFileRenamed(const std::string& oldFilepath, const std::string& newFilepath) -{ - auto editorIter = m_sourceCodeEditors.find(oldFilepath); - if (editorIter != m_sourceCodeEditors.end()) - { - rgSourceCodeEditor* pEditor = editorIter->second; - - assert(pEditor != nullptr); - if (pEditor != nullptr) - { - // Erase the existing file path, and insert the new one. - m_sourceCodeEditors.erase(editorIter); - m_sourceCodeEditors[newFilepath] = pEditor; - } - } - - // Update the project's source file list with the new filepath. - std::shared_ptr pProject = std::dynamic_pointer_cast(m_pProject); - assert(pProject != nullptr); - if (pProject != nullptr) - { - rgConfigManager::UpdateShaderStageFilePath(oldFilepath, newFilepath, pProject, m_cloneIndex); - - // Save the updated project file. - rgConfigManager::Instance().SaveProjectFile(pProject); - } -} - -void rgBuildViewVulkan::HandleSelectedFileChanged(const std::string& oldFilepath, const std::string& newFilepath) -{ - // Get a pointer to the editor responsible for displaying the new file. - rgSourceCodeEditor* pEditor = GetEditorForFilepath(newFilepath); - assert(pEditor != nullptr); - if (pEditor != nullptr) - { - bool isEditorSwitched = SwitchToEditor(pEditor); - if (isEditorSwitched) - { - // Switch the disassembly view to show the currently-selected entry point in the newly-selected file item. - if (m_pDisassemblyView != nullptr && !m_isBuildInProgress) - { - // Open the disassembly view for the source file only if it's disassembled. - if (IsGcnDisassemblyGenerated(newFilepath)) - { - // Update the visibility of the disassembly view. - ToggleDisassemblyViewVisibility(true); - - // Make the disassembly view visible because the file has build outputs to display. - std::string selectedEntrypointName = STR_DEFAULT_VULKAN_GLSL_ENTRYPOINT_NAME; - emit SelectedEntrypointChanged(m_currentTargetGpu, newFilepath, selectedEntrypointName); - - // Update the titlebar for the current source editor. - UpdateSourceEditorTitlebar(pEditor); - } - else - { - // Hide the disassembly view when switching to a file that hasn't been disassembled. - ToggleDisassemblyViewVisibility(false); - } - } - } - } -} - -void rgBuildViewVulkan::HandleSourceFileSelectedLineChanged(rgSourceCodeEditor* pEditor, int lineNumber) -{ - // Handle updating source correlation only when the project isn't currently being built. - if (!m_isBuildInProgress) - { - if (m_pDisassemblyView != nullptr && !m_pDisassemblyView->IsEmpty()) - { - const std::string& inputFilename = GetFilepathForEditor(pEditor); - bool isDisassembled = IsGcnDisassemblyGenerated(inputFilename); - if (isDisassembled) - { - int correlatedLineNumber = kInvalidCorrelationLineIndex; - - // If the line is associated with a named entry point, highlight it in the file menu item. - std::string entryName = STR_DEFAULT_VULKAN_GLSL_ENTRYPOINT_NAME; - - // Send the input source file's correlation line index to the disassembly view. - m_pDisassemblyView->HandleInputFileSelectedLineChanged(m_currentTargetGpu, inputFilename, entryName, correlatedLineNumber); - } - } - } -} - -void rgBuildViewVulkan::HandleAddFileButtonClicked(rgPipelineStage stage) -{ - if (ShowSaveDialog()) - { - // Check if the user would like to add an existing file or create a default one. - // Set the current stage. - m_stageClicked = stage; - - // Show the context menu for adding/creating file. - m_pAddCreateContextMenu->exec(QCursor::pos()); - } -} - -void rgBuildViewVulkan::HandleAddExistingFile() -{ - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr) - { - std::string filePathToAdd; - bool isOk = rgUtils::OpenFileDialog(this, rgProjectAPI::Vulkan, filePathToAdd); - if (isOk && !filePathToAdd.empty() && rgUtils::IsFileExists(filePathToAdd) && - !m_pFileMenu->IsFileInMenu(filePathToAdd)) - { - // Convert the path separators to match the style used in the session metadata. - std::string nativeFilePath = QDir::toNativeSeparators(filePathToAdd.c_str()).toStdString(); - SetStageSourceFile(m_stageClicked, nativeFilePath); - - // Insert the new source file path into the pipeline. - rgConfigManager& configManager = rgConfigManager::Instance(); - configManager.AddShaderStage(m_stageClicked, nativeFilePath, m_pProject, m_cloneIndex); - - // Save the pipeline project now that the new file is added to the stage. - configManager.SaveProjectFile(m_pProject); - - // Remove focus from build settings and pipeline state buttons. - rgMenuVulkan* pVulkanFileMenu = static_cast(m_pFileMenu); - assert(pVulkanFileMenu != nullptr); - if (pVulkanFileMenu != nullptr) - { - pVulkanFileMenu->SetButtonsNoFocus(); - } - } - else if (!filePathToAdd.empty()) - { - // Inform the user the the file already exists. - std::stringstream msg; - msg << STR_ERR_CANNOT_ADD_FILE_A << filePathToAdd << STR_ERR_CANNOT_ADD_FILE_B; - rgUtils::ShowErrorMessageBox(msg.str().c_str(), this); - } - } -} - -void rgBuildViewVulkan::HandleCreateNewFile() -{ - // Create a new source file with the default filename. - std::string baseFilename = STR_DEFAULT_SOURCE_FILENAME; - - // Attempt to create a new source file for the given stage. The final filename may differ - // from the requested name if the requested filename already exists in the project. - std::string pathFinalFilePath; - CreateNewSourceFile(m_stageClicked, baseFilename, pathFinalFilePath); - - // Show the contents of the new file within the editor. - SetSourceCodeText(pathFinalFilePath); - - // Update the focus indices. - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr) - { - m_pFileMenu->UpdateFocusIndex(); - } -} - -void rgBuildViewVulkan::HandleExistingFileDragAndDrop(rgPipelineStage stage, const std::string& filePathToAdd) -{ - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr && !filePathToAdd.empty()) - { - if (!m_pFileMenu->IsFileInMenu(filePathToAdd) && - rgUtils::IsFileExists(filePathToAdd)) - { - // Convert the path separators to match the style used in the session metadata. - std::string nativeFilePath = QDir::toNativeSeparators(filePathToAdd.c_str()).toStdString(); - SetStageSourceFile(stage, nativeFilePath); - - // Insert the new source file path into the pipeline. - rgConfigManager& configManager = rgConfigManager::Instance(); - configManager.AddShaderStage(stage, nativeFilePath, m_pProject, m_cloneIndex); - - // Save the pipeline project now that the new file is added to the stage. - configManager.SaveProjectFile(m_pProject); - } - else - { - // Inform the user the the file already exists. - std::stringstream msg; - msg << STR_ERR_CANNOT_ADD_FILE_A << filePathToAdd << STR_ERR_CANNOT_ADD_FILE_B; - rgUtils::ShowErrorMessageBox(msg.str().c_str(), this); - - // Restore the item from being current (remove the highlight - // that was assigned to it when it was hovered in the drag process). - m_pFileMenu->SetCurrent(stage, false); - } - } -} - -void rgBuildViewVulkan::HandleRemoveFileButtonClicked(rgPipelineStage stage) -{ - if (ShowSaveDialog()) - { - bool projectExists = (m_pProject != nullptr); - if (projectExists) - { - // Ensure that the incoming clone index is valid for the current project. - bool isValidRange = (m_cloneIndex >= 0 && m_cloneIndex < m_pProject->m_clones.size()); - assert(isValidRange); - - if (isValidRange) - { - std::shared_ptr pGraphicsClone - = std::dynamic_pointer_cast(m_pProject->m_clones[m_cloneIndex]); - - std::string stageFilePath; - bool isStageOccupied = rgConfigManager::Instance().GetShaderStageFilePath(stage, pGraphicsClone, stageFilePath); - - assert(isStageOccupied); - if (isStageOccupied) - { - std::stringstream msg; - msg << stageFilePath << STR_MENU_BAR_CONFIRM_REMOVE_FILE_DIALOG_WARNING; - - // Ask the user if they really want to remove the source file. - if (ShowRemoveFileConfirmation(msg.str(), stageFilePath)) - { - // Remove the source file's path from the project's clone. - rgConfigManager::Instance().RemoveShaderStage(stage, pGraphicsClone); - - // Save the project after removing a source file. - rgConfigManager::Instance().SaveProjectFile(m_pProject); - - // Update the file menu to remove the filename from the stage item. - rgMenuVulkan* pVulkanFileMenu = static_cast(m_pFileMenu); - assert(pVulkanFileMenu != nullptr); - if (pVulkanFileMenu != nullptr) - { - bool switchToNextFile = false; - - // Remove the source file from the stage item. - pVulkanFileMenu->ClearStageSourceFile(stage); - - // Clear out the source view only if this is the currently displayed file. - rgMenuFileItemGraphics* pStageItem = pVulkanFileMenu->GetStageItem(stage); - assert(pStageItem != nullptr); - if (pStageItem != nullptr) - { - // Set all of the sub buttons to have pointing hand cursor. - pStageItem->SetCursor(Qt::PointingHandCursor); - - // Clear the edit mode. - if (m_editMode == EditMode::SourceCode && pVulkanFileMenu->GetCurrentStage() == pStageItem->GetStage()) - { - switchToNextFile = true; - - // Clear out the source view only if one of the buttons - // isn't currently selected. - if (!pVulkanFileMenu->IsButtonPressed()) - { - SwitchEditMode(EditMode::Empty); - } - } - } - - RemoveEditor(stageFilePath, switchToNextFile); - - // Set the focus to the file menu so subsequent tabs will be processed. - pVulkanFileMenu->setFocus(); - - // Emit a signal to update various menu items. - const bool isMenuEmpty = pVulkanFileMenu->IsEmpty(); - emit pVulkanFileMenu->FileMenuItemCountChanged(isMenuEmpty); - } - - DestroyBuildOutputsForFile(stageFilePath); - - // Remove the file's build outputs from the disassembly view. - if (m_pDisassemblyView != nullptr) - { - m_pDisassemblyView->RemoveInputFileEntries(stageFilePath); - - // Hide the disassembly view when there's no data in it. - if (m_pDisassemblyView->IsEmpty()) - { - // Minimize the disassembly view before hiding it to preserve correct rgBuildView layout. - m_pDisassemblyViewSplitter->Restore(); - - // Hide the disassembly view now that it's empty. - ToggleDisassemblyViewVisibility(false); - } - } - } - } - } - } - } -} - -void rgBuildViewVulkan::HandleRestoreOriginalSpvClicked(rgPipelineStage stage) -{ - auto pVulkanClone = std::dynamic_pointer_cast(m_pProject->m_clones[m_cloneIndex]); - - rgMenuFileItemGraphics* pFileItem = m_pFileMenu->GetStageItem(stage); - assert(pFileItem != nullptr && m_pFileMenu != nullptr); - if (pFileItem != nullptr && m_pFileMenu != nullptr) - { - const std::string spvDisasm = pFileItem->GetFilename(); - const std::string origSpv = pVulkanClone->m_spvBackup.m_shaderStages[stage]; - - if (ShowRevertToSpvBinaryConfirmation(origSpv)) - { - // Replace files in the project clone. - pVulkanClone->m_pipeline.m_shaderStages[stage] = origSpv; - pVulkanClone->m_spvBackup.m_shaderStages[stage].clear(); - - // Save the project file. - rgConfigManager::Instance().SaveProjectFile(m_pProject); - - // Replace file path in the Code Editor map. - m_sourceCodeEditors.erase(spvDisasm); - m_sourceCodeEditors[origSpv] = m_pCurrentCodeEditor; - - // Delete the edited backup SPIR-V text file from disk. - QFile file(spvDisasm.c_str()); - file.remove(); - - // Update the modification date. - QFileInfo fileInfo(origSpv.c_str()); - m_fileModifiedTimeMap[m_pCurrentCodeEditor] = fileInfo.lastModified(); - - // Disassemble the original SPIR-V binary. - std::string spvDisasmOutput; - if (DisasmSpvFile(origSpv, spvDisasmOutput)) - { - SetSourceCodeText(spvDisasmOutput); - - // Store the path to the disassembled file so that we know where to save the modified disassembly text later. - m_spvDisasmFiles[stage] = spvDisasmOutput; - - // Store the spv last modification time. - QFileInfo fileInfo(origSpv.c_str()); - m_fileModifiedTimeMap[m_pCurrentCodeEditor] = fileInfo.lastModified(); - } - - // Replace file path in the File Menu. - m_pFileMenu->ReplaceStageFile(stage, origSpv, rgVulkanInputType::Spirv); - - // Replace file path in the Build Output. - ReplaceInputFileInBuildOutput(spvDisasmOutput, origSpv); - - // Replace file path in the Disassembly View tables. - if (m_pDisassemblyView != nullptr) - { - m_pDisassemblyView->ReplaceInputFilePath(spvDisasmOutput, origSpv); - } - - // Remove the "Restore original SPIR-V binary" item from the File Menu's context menu. - pFileItem->RemoveContextMenuActionRestoreSpv(); - - // Clear the Source Editor Title message for this editor. - m_pCurrentCodeEditor->SetTitleBarText(""); - m_pSourceEditorTitlebar->SetTitlebarContentsVisibility(false); - } - } -} - -bool rgBuildViewVulkan::CreateMenu(QWidget* pParent) -{ - m_pFileMenu = static_cast(m_pFactory->CreateFileMenu(pParent)); - - // Register the file menu with scaling manager. - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr) - { - ScalingManager::Get().RegisterObject(m_pFileMenu); - } - - return m_pFileMenu != nullptr; -} - -void rgBuildViewVulkan::HandleEnumListWidgetStatus(bool isOpen) -{ - assert(m_pPipelineStateView != nullptr); - if (m_pPipelineStateView != nullptr) - { - m_pPipelineStateView->SetEnumListWidgetStatus(isOpen); - } -} - -void rgBuildViewVulkan::CreatePipelineStateModel() -{ - std::shared_ptr pGraphicsFactory = std::dynamic_pointer_cast(m_pFactory); - - assert(pGraphicsFactory != nullptr); - if (pGraphicsFactory != nullptr) - { - m_pPipelineStateModel = static_cast(pGraphicsFactory->CreatePipelineStateModel(this)); - assert(m_pPipelineStateModel != nullptr); - if (m_pPipelineStateModel != nullptr) - { - // Connect the list widget status signal. - bool isConnected = connect(m_pPipelineStateModel, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal, this, &rgBuildViewVulkan::HandleEnumListWidgetStatus); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgBuildViewVulkan::HotKeyPressedSignal, m_pPipelineStateModel, &rgPipelineStateModelVulkan::HotKeyPressedSignal); - assert(isConnected); - - assert(m_pProject != nullptr); - if (m_pProject != nullptr) - { - // Ensure that the incoming clone index is valid for the current project. - bool res = (m_cloneIndex >= 0 && m_cloneIndex < m_pProject->m_clones.size()); - assert(res); - - if (res) - { - std::shared_ptr pVulkanClone = - std::dynamic_pointer_cast(m_pProject->m_clones[m_cloneIndex]); - - assert(pVulkanClone != nullptr); - if (pVulkanClone != nullptr) - { - bool isPipelineStateInitialized = false; - std::string errorString; - - rgPipelineState& currentPipelineState = pVulkanClone->m_psoStates[m_pipelineStateIndex]; - bool isStateFileExists = rgUtils::IsFileExists(currentPipelineState.m_pipelineStateFilePath); - if (isStateFileExists) - { - // Load the state file from disk. - isPipelineStateInitialized = - m_pPipelineStateModel->LoadPipelineStateFile(this, currentPipelineState.m_pipelineStateFilePath, pVulkanClone->m_pipeline.m_type, errorString); - - assert(isPipelineStateInitialized); - if (!isPipelineStateInitialized) - { - std::stringstream errorStream; - errorStream << STR_ERR_CANNOT_LOAD_PIPELINE_STATE_FILE; - errorStream << " "; - errorStream << errorString; - emit SetStatusBarText(errorStream.str().c_str()); - } - } - - // If the pipeline state file didn't exist, or failed to load, initialize the default configuration. - if (!isPipelineStateInitialized) - { - // Initialize the pipeline state model based on the pipeline type. - m_pPipelineStateModel->InitializeDefaultPipelineState(this, pVulkanClone->m_pipeline.m_type); - - // Save the new default pipeline state. - isPipelineStateInitialized = m_pPipelineStateModel->SavePipelineStateFile(currentPipelineState.m_pipelineStateFilePath, errorString); - } - - // Was the pipeline state file loaded or created successfully? - assert(isPipelineStateInitialized); - if (!isPipelineStateInitialized) - { - std::stringstream errorStream; - errorStream << STR_ERR_CANNOT_INITIALIZE_PIPELINE_STATE_FILE; - errorStream << errorString; - rgUtils::ShowErrorMessageBox(errorStream.str().c_str(), this); - } - } - } - } - } - } -} - -void rgBuildViewVulkan::CreatePipelineStateView(QWidget* pParent) -{ - // Create a border frame for the pipeline state editor. - m_pPsoEditorFrame = new QFrame(this); - m_pPsoEditorFrame->setFocusPolicy(Qt::FocusPolicy::StrongFocus); - m_pPsoEditorFrame->setFrameStyle(QFrame::Box); - m_pPsoEditorFrame->setLayout(new QVBoxLayout); - m_pPsoEditorFrame->setObjectName(s_PSO_EDITOR_FRAME_NAME); - - // Create a new Pipeline State editor view. - m_pPipelineStateView = new rgPipelineStateView(pParent); - - assert(m_pPipelineStateView != nullptr); - if (m_pPipelineStateView != nullptr) - { - // Add the state editor view to the parent frame. - m_pPsoEditorFrame->layout()->addWidget(m_pPipelineStateView); - - // Create the find widget, register with the scaling manager. - m_pPsoFindWidget = new rgFindTextWidget(m_pPipelineStateView); - ScalingManager::Get().RegisterObject(m_pPsoFindWidget); - - // The find widget is hidden by default. - m_pPsoFindWidget->hide(); - - // Add the find widget to rgPipelineStateView's grid. - m_pPipelineStateView->InsertFindWidget(m_pPsoFindWidget); - - // Connect the find widget signals. - ConnectPSOFindSignals(); - - assert(m_pProject != nullptr); - if (m_pProject != nullptr) - { - // Ensure that the incoming clone index is valid for the current project. - bool res = (m_cloneIndex >= 0 && m_cloneIndex < m_pProject->m_clones.size()); - assert(res); - - if (res) - { - std::shared_ptr pClone = - std::dynamic_pointer_cast(m_pProject->m_clones[m_cloneIndex]); - - assert(pClone != nullptr); - if (pClone != nullptr) - { - // Initialize the PSO editor model. - m_pPipelineStateView->InitializeModel(m_pPipelineStateModel); - - // Connect signals for the new pipeline state view. - ConnectPipelineStateViewSignals(); - - // The view is hidden initially. - m_pPsoEditorFrame->hide(); - } - } - } - } -} - -void rgBuildViewVulkan::ConnectDisassemblyViewApiSpecificSignals() -{ - assert(m_pDisassemblyView != nullptr); - if (m_pDisassemblyView != nullptr) - { - // Connect the handler invoked when the user changes the selected entry point. - bool isConnected = connect(this, &rgBuildViewVulkan::SelectedEntrypointChanged, - m_pDisassemblyView, &rgIsaDisassemblyView::HandleSelectedEntrypointChanged); - assert(isConnected); - - // Connect the remove button focus events. - isConnected = connect(m_pDisassemblyView, &rgIsaDisassemblyView::RemoveFileMenuButtonFocus, - m_pFileMenu, &rgMenuVulkan::HandleRemoveFileMenuButtonFocus); - assert(isConnected); - } -} - -bool rgBuildViewVulkan::IsLineCorrelationEnabled(rgSourceCodeEditor* pSourceEditor) -{ - // Source line correlation with disassembly is not available in Vulkan mode. - return false; -} - -bool rgBuildViewVulkan::IsSourceFileInProject(const std::string& sourceFilePath) const -{ - bool res = false; - - // Step through all possible pipeline stages to check if the given source file exists. - uint32_t firstStage = static_cast(rgPipelineStage::Vertex); - uint32_t lastStage = static_cast(rgPipelineStage::Compute); - - assert(m_pProject != nullptr); - if (m_pProject != nullptr) - { - // Ensure that the incoming clone index is valid for the current project. - bool isValidRange = (m_cloneIndex >= 0 && m_cloneIndex < m_pProject->m_clones.size()); - - assert(isValidRange); - if (isValidRange) - { - std::shared_ptr pVulkanClone = std::dynamic_pointer_cast(m_pProject->m_clones[m_cloneIndex]); - for (uint32_t stageIndex = firstStage; stageIndex < lastStage; ++stageIndex) - { - rgPipelineStage currentStage = static_cast(stageIndex); - - std::string stageFilePath; - if (rgConfigManager::Instance().GetShaderStageFilePath(currentStage, pVulkanClone, stageFilePath)) - { - if (!stageFilePath.empty() && stageFilePath.compare(sourceFilePath) == 0) - { - res = true; - break; - } - } - } - } - } - - return res; -} - -bool rgBuildViewVulkan::ShowRevertToSpvBinaryConfirmation(const std::string& filePath) -{ - std::string msg = STR_MENU_BAR_VULKAN_CONFIRM_REVERT_TO_ORIG_SPV_A; - msg += std::string("\n") + filePath + ".\n"; - msg += STR_MENU_BAR_VULKAN_CONFIRM_REVERT_TO_ORIG_SPV_B; - - return rgUtils::ShowConfirmationMessageBox(STR_MENU_BAR_CONFIRM_REMOVE_FILE_DIALOG_TITLE, msg.c_str(), this); -} - -bool rgBuildViewVulkan::ReplaceInputFileInBuildOutput(const std::string& oldFilePath, const std::string& newFilePath) -{ - assert(!oldFilePath.empty()); - assert(!newFilePath.empty()); - bool ret = (!oldFilePath.empty() && !newFilePath.empty()); - if (ret) - { - auto firstTargetGpu = m_buildOutputs.begin(); - auto lastTargetGpu = m_buildOutputs.end(); - for (auto targetGpuIter = firstTargetGpu; targetGpuIter != lastTargetGpu; ++targetGpuIter) - { - ret = false; - std::shared_ptr pBuildOutput = targetGpuIter->second; - - // Search for outputs for the given source file and replace its key (input file path) with the new one. - assert(pBuildOutput != nullptr); - if (pBuildOutput != nullptr) - { - auto it = pBuildOutput->m_perFileOutput.find(oldFilePath); - if (it != pBuildOutput->m_perFileOutput.end()) - { - auto outputs = it->second; - pBuildOutput->m_perFileOutput.erase(it); - pBuildOutput->m_perFileOutput[newFilePath] = outputs; - ret = true; - } - } - } - } - - return ret; -} - -bool rgBuildViewVulkan::CreateNewSourceFile(rgPipelineStage stage, const std::string& sourceFileName, std::string& fullSourceFilepath) -{ - bool ret = false; - - // True if we are creating a new file in an existing project. - bool isExistingProject = (m_pProject != nullptr); - - if (isExistingProject) - { - std::shared_ptr pVulkanUtils = std::dynamic_pointer_cast(rgUtilsGraphics::CreateUtility(rgProjectAPI::Vulkan)); - assert(pVulkanUtils != nullptr); - if (pVulkanUtils != nullptr) - { - // Use the Vulkan factory to build a file extension based on the stage being added. - std::stringstream fileExtension; - fileExtension << "."; - fileExtension << pVulkanUtils->PipelineStageToAbbreviation(stage); - - // Generate a path to where the new empty file will live in the projects directory. - std::string newFilename; - rgConfigManager::GenerateNewSourceFilepath(m_pProject->m_projectName, m_cloneIndex, sourceFileName, fileExtension.str(), newFilename, fullSourceFilepath); - - // Ensure that the folder where the file will be saved already exists. - std::string sourcefileFolder; - rgUtils::ExtractFileDirectory(fullSourceFilepath, sourcefileFolder); - if (!rgUtils::IsDirExists(sourcefileFolder)) - { - bool isDirCreated = rgUtils::CreateFolder(sourcefileFolder); - assert(isDirCreated); - } - - // Create a new file at the target location. - QFile emptyFile(fullSourceFilepath.c_str()); - emptyFile.open(QIODevice::ReadWrite); - - // Use the Vulkan factory to fill the new file with the default code for the stage being created. - QTextStream stream(&emptyFile); - stream << pVulkanUtils->GetDefaultShaderCode(stage).c_str() << endl; - emptyFile.close(); - - // Add the source file's path to the project's clone. - rgConfigManager::Instance().AddShaderStage(stage, fullSourceFilepath, m_pProject, m_cloneIndex); - - // Save the project after adding a source file. - rgConfigManager::Instance().SaveProjectFile(m_pProject); - - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr) - { - rgMenuVulkan* pVulkanFileMenu = static_cast(m_pFileMenu); - assert(pVulkanFileMenu != nullptr); - if (pVulkanFileMenu != nullptr) - { - // Set the source file in the stage item. - pVulkanFileMenu->SetStageSourceFile(stage, fullSourceFilepath, rgVulkanInputType::Glsl, true); - - // Use GLSL syntax highlighting. - assert(m_pCurrentCodeEditor != nullptr); - if (m_pCurrentCodeEditor != nullptr) - { - m_pCurrentCodeEditor->SetSyntaxHighlighting(rgSrcLanguage::GLSL); - } - } - } - - // We are done. - ret = true; - } - } - - return ret; -} - -bool rgBuildViewVulkan::CreateProject(rgPipelineType pipelineType) -{ - // True if we are creating a new file in an existing project. - bool res = (m_pProject != nullptr); - - if (!res) - { - res = CreateNewEmptyProject(); - - if (res) - { - assert(m_pProject != nullptr); - if (m_pProject != nullptr) - { - // Ensure that the incoming clone index is valid for the current project. - bool res = (m_cloneIndex >= 0 && m_cloneIndex < m_pProject->m_clones.size()); - assert(res); - - if (res) - { - std::shared_ptr pClone = - std::dynamic_pointer_cast(m_pProject->m_clones[m_cloneIndex]); - - // Initialize the clone's pipeline type. - pClone->m_pipeline.m_type = pipelineType; - - // Create the pipeline CreateInfo object. - CreatePipelineStateFile(); - - // The pipeline type was updated after the clone was created, so re-save the - // project with the new change. - rgConfigManager& configManager = rgConfigManager::Instance(); - configManager.SaveProjectFile(m_pProject); - } - } - } - } - - if (res) - { - emit ProjectCreated(); - } - - return res; -} - -void rgBuildViewVulkan::CreatePipelineStateFile() -{ - assert(m_pProject != nullptr); - if (m_pProject != nullptr) - { - // Ensure that the incoming clone index is valid for the current project. - bool res = (m_cloneIndex >= 0 && m_cloneIndex < m_pProject->m_clones.size()); - assert(res); - - if (res) - { - std::shared_ptr pClone = - std::dynamic_pointer_cast(m_pProject->m_clones[m_cloneIndex]); - - assert(pClone != nullptr); - if (pClone != nullptr) - { - size_t pipelineCount = pClone->m_psoStates.size(); - - // Generate a suitable pipeline name based on the number of existing pipelines. - std::stringstream pipelineNameStream; - pipelineNameStream << STR_DEFAULT_PIPELINE_NAME; - pipelineNameStream << pipelineCount; - std::string pipelineStateName = pipelineNameStream.str(); - - bool isGraphicsPipeline = (pClone->m_pipeline.m_type == rgPipelineType::Graphics); - const char* psoFileExtension = isGraphicsPipeline ? STR_DEFAULT_PIPELINE_FILE_EXTENSION_GRAPHICS : - STR_DEFAULT_PIPELINE_FILE_EXTENSION_COMPUTE; - - // Build a file path to a new pipeline state file. - std::string pipelineStateFilePath; - rgConfigManager::GenerateNewPipelineFilepath(m_pProject->m_projectName, m_cloneIndex, pipelineStateName, psoFileExtension, pipelineStateFilePath); - - // 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 directoryPath; - bool isOk = rgUtils::ExtractFileDirectory(pipelineStateFilePath, directoryPath); - if (isOk) - { - bool directoryExists = rgUtils::IsDirExists(directoryPath); - if (!directoryExists) - { - isOk = rgUtils::CreateFolder(directoryPath); - } - } - - if (isOk) - { - rgPipelineState pipelineStateFile = {}; - pipelineStateFile.m_name = pipelineStateName; - pipelineStateFile.m_pipelineStateFilePath = pipelineStateFilePath; - pipelineStateFile.m_isActive = true; - - // Add the new PSO file to the current clone's PSO states vector. - pClone->m_psoStates.push_back(pipelineStateFile); - } - } - } - } -} - -void rgBuildViewVulkan::SetStageSourceFile(rgPipelineStage stage, const std::string& filePathToAdd) -{ - assert(m_pFileMenu != nullptr); - if (m_pFileMenu != nullptr) - { - std::shared_ptr pVulkanUtils = std::dynamic_pointer_cast(rgUtilsGraphics::CreateUtility(rgProjectAPI::Vulkan)); - assert(pVulkanUtils != nullptr); - if (pVulkanUtils != nullptr) - { - rgMenuVulkan* pVulkanFileMenu = static_cast(m_pFileMenu); - assert(pVulkanFileMenu != nullptr); - if (pVulkanFileMenu != nullptr) - { - // Detect type of the file. - auto fileType = rgUtils::DetectInputFileType(filePathToAdd); - - // Set the source file in the stage item. - bool fileAdded = pVulkanFileMenu->SetStageSourceFile(stage, filePathToAdd, fileType.first, false); - - // Enable reverting to original SPIR-V binary if it's present in the Project Clone. - if (fileAdded && fileType.first == rgVulkanInputType::SpirvTxt) - { - std::shared_ptr pVulkanClone = - std::dynamic_pointer_cast(m_pProject->m_clones[m_cloneIndex]); - - assert(pVulkanClone != nullptr); - if (pVulkanClone != nullptr) - { - if (!pVulkanClone->m_spvBackup.m_shaderStages[stage].empty()) - { - m_pFileMenu->GetStageItem(stage)->AddContextMenuActionRestoreSpv(); - } - } - } - - if (fileAdded && m_pCurrentCodeEditor != nullptr) - { - // Enable corresponding syntax highlighting. - m_pCurrentCodeEditor->SetSyntaxHighlighting(fileType.second); - - // If the file being added is a SPIR-V binary, disassemble it and show the disassembly text in the source editor. - if (fileType.first == rgVulkanInputType::Spirv) - { - std::string spvDisasmFile; - if (DisasmSpvFile(filePathToAdd, spvDisasmFile)) - { - SetSourceCodeText(spvDisasmFile); - - // Store the path to the disassembled file so that we know where to save the modified disassembly text later. - m_spvDisasmFiles[stage] = spvDisasmFile; - - // Store the spv last modification time. - QFileInfo fileInfo(filePathToAdd.c_str()); - m_fileModifiedTimeMap[m_pCurrentCodeEditor] = fileInfo.lastModified(); - } - } - else - { - SetSourceCodeText(filePathToAdd); - } - } - } - } - } -} - -bool rgBuildViewVulkan::DisasmSpvFile(const std::string& spvFile, std::string& spvDisasmFile) -{ - std::string projDir; - bool isOk = rgUtils::ExtractFileDirectory(m_pProject->m_projectFileFullPath, projDir); - assert(isOk); - if (isOk && rgUtils::ConstructSpvDisasmFileName(projDir, spvFile, spvDisasmFile)) - { - // Create a sub-folder in the Project folder for the spv disasm file if it does not exist. - std::string subfolder, compilerPath; - isOk = rgUtils::ExtractFileDirectory(spvDisasmFile, subfolder); - assert(isOk); - if (isOk) - { - // Get the "alternative compiler path" setting value. - std::shared_ptr pVulkanClone = - std::dynamic_pointer_cast(m_pProject->m_clones[m_cloneIndex]); - - assert(pVulkanClone != nullptr && pVulkanClone->m_pBuildSettings != nullptr); - if (pVulkanClone != nullptr && pVulkanClone->m_pBuildSettings != nullptr) - { - compilerPath = std::get(pVulkanClone->m_pBuildSettings->m_compilerPaths); - } - rgUtils::CreateFolder(subfolder); - std::string cliOutput; - isOk = rgCliLauncher::DisassembleSpvToText(compilerPath, spvFile, spvDisasmFile, cliOutput); - HandleNewCLIOutputString(cliOutput); - } - } - - return isOk; -} - -bool rgBuildViewVulkan::IsLineCorrelationSupported() const -{ - return false; -} - -rgMenuGraphics* rgBuildViewVulkan::GetGraphicsFileMenu() -{ - return m_pFileMenu; -} - -void rgBuildViewVulkan::HandlePipelineStateTreeFocusIn() -{ - // Change the container frame's color. - assert(m_pPsoEditorFrame != nullptr); - if (m_pPsoEditorFrame != nullptr) - { - // Set the default widget focus. - m_pPipelineStateView->SetInitialWidgetFocus(); - - // Change the color of the PSO editor frame border. - QString styleSheetString = QString("#") + s_PSO_EDITOR_FRAME_NAME + QString(" { border: 1px solid red; background-color: transparent}"); - m_pPsoEditorFrame->setStyleSheet(styleSheetString); - } -} - -void rgBuildViewVulkan::HandlePipelineStateTreeFocusOut() -{ - // Change the container frame's color. - assert(m_pPsoEditorFrame != nullptr); - if (m_pPsoEditorFrame != nullptr) - { - QString styleSheetString = QString("#") + s_PSO_EDITOR_FRAME_NAME + QString(" { border: 1px solid black }"); - m_pPsoEditorFrame->setStyleSheet(styleSheetString); - } -} - -void rgBuildViewVulkan::UpdateApplicationNotificationMessage() -{ - std::string message = ""; - std::string tooltip = ""; - size_t pos = m_pCliOutputWindow->GetText().find("vk-spv-offline"); - if (pos != std::string::npos) - { - message = s_APPLICATION_INFORMATION_MESSAGE; - tooltip = s_APPLICATION_INFORMATION_TOOLTIP; - - // Emit the signal to update the application notification message. - emit UpdateApplicationNotificationMessageSignal(message, tooltip); - } -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgCliLauncher.cpp b/RadeonGPUAnalyzerGUI/Src/rgCliLauncher.cpp deleted file mode 100644 index 6919ff8..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgCliLauncher.cpp +++ /dev/null @@ -1,570 +0,0 @@ -// C++. -#include -#include - -// Infra. -#include -#include - -// Local. -#include -#include -#include -#include -#include - -// OpenCL includes. -#include -#include - -// Vulkan includes. -#include -#include - -// Common between the CLI and the GUI. -#include -#include - -void BuildRgaExecutableCommandString(std::stringstream& commandStream) -{ - // Add the RGA executable name to invoke, and a space. - commandStream << STR_EXECUTABLE_NAME; - commandStream << " "; -} - -// A helper function responsible for building a base command string for CLI invocation. -void BuildCompileProjectCommandString(std::stringstream& commandStream, const std::string& outputPath, const std::string& binaryName) -{ - BuildRgaExecutableCommandString(commandStream); - - // Add the current build mode to the command. - const std::string& currentMode = rgConfigManager::Instance().GetCurrentModeString(); - commandStream << CLI_OPT_INPUT_TYPE << " " << currentMode << " "; - - // ISA disassembly in text and CSV formats. - commandStream << CLI_OPT_ISA << " \"" << outputPath << "disassem.txt\" " << CLI_OPT_PARSE_ISA << " "; - - // Include line numbers in the CSV file. - commandStream << CLI_OPT_LINE_NUMBERS << " "; - - // Add the output path for the resource usage analysis file. - commandStream << CLI_OPT_STATISTICS << " \"" << outputPath << STR_RESOURCE_USAGE_CSV_FILENAME << "\" "; - - // Output binary file. - const rgProjectAPI currentAPI = rgConfigManager::Instance().GetCurrentAPI(); - commandStream << CLI_OPT_BINARY << " \"" << outputPath << binaryName << "\" "; - if (currentAPI == rgProjectAPI::Vulkan) - { - if (binaryName.compare(STR_BUILD_SETTINGS_OUTPUT_BINARY_FILE_NAME) != 0) - { - // If the user gave a custom name, instruct the CLI not to add a suffix, - // so that we use the user's custom file name as is. - commandStream << CLI_NO_BINARY_FILE_EXTENSION_SWITCH << " "; - } - } - - // CLI log file path. - const std::string& cliLogFilePath = rgConfigManager::Instance().GetCLILogFilePath(); - if (!cliLogFilePath.empty()) - { - commandStream << CLI_OPT_LOG << " \"" << cliLogFilePath << "\" "; - } -} - -void BuildOutputViewCommandHeader(std::shared_ptr pProject, const std::string& targetGpu, std::string& invocationText) -{ - std::stringstream textStream; - - // Build an output line for each CLI invocation. Print the command string that's about to be invoked. - textStream << STR_OUTPUT_WINDOW_BUILDING_PROJECT_HEADER_A; - - // Include the project's API in the build header line. - std::string projectApiString; - bool isOk = rgUtils::ProjectAPIToString(pProject->m_api, projectApiString); - assert(isOk); - if (isOk) - { - textStream << projectApiString; - } - - // Also include the project name and target GPU. - textStream << STR_OUTPUT_WINDOW_BUILDING_PROJECT_HEADER_B; - textStream << pProject->m_projectName; - textStream << STR_OUTPUT_WINDOW_BUILDING_PROJECT_HEADER_C; - textStream << targetGpu; - - // Insert a separator line above and below the build output line. - std::string buildHeaderString = textStream.str(); - int numDashesToInsert = static_cast(buildHeaderString.length()); - std::string dashedLines = std::string(numDashesToInsert, '-'); - - // Surround the project build header text with dashed line separators. - std::stringstream cmdLineOutputStream; - cmdLineOutputStream << dashedLines << std::endl; - cmdLineOutputStream << buildHeaderString << std::endl; - cmdLineOutputStream << dashedLines << std::endl; - - invocationText = cmdLineOutputStream.str(); -} - -bool rgCliLauncher::BuildProjectCloneOpenCL(std::shared_ptr pProject, int cloneIndex, const std::string& outputPath, const std::string& binaryName, - std::function cliOutputHandlingCallback, std::vector& gpusBuilt, bool& cancelSignal) -{ - bool ret = false; - if (pProject != nullptr) - { - rgLog::file << STR_LOG_BUILDING_PROJECT_CLONE_1 << pProject->m_projectName << STR_LOG_BUILDING_PROJECT_CLONE_2 << cloneIndex << std::endl; - - // A stream of all text collected from CLI invocation. - std::stringstream fullCliOutput; - - // Verify that the clone index is valid for the given project. - int numClones = static_cast(pProject->m_clones.size()); - bool isCloneIndexValid = (cloneIndex >= 0 && cloneIndex < numClones); - assert(isCloneIndexValid); - if (isCloneIndexValid) - { - std::shared_ptr pTargetClone = pProject->m_clones[cloneIndex]; - - // Generate the command line invocation command. - std::stringstream cmd; - - // Build the compile project command string. - BuildCompileProjectCommandString(cmd, outputPath, binaryName); - - // Build settings. - std::string buildSettings; - std::shared_ptr pClBuildSettings = - std::static_pointer_cast(pTargetClone->m_pBuildSettings); - assert(pClBuildSettings != nullptr); - ret = rgCliUtils::GenerateOpenClBuildSettingsString(*pClBuildSettings, buildSettings); - assert(ret); - if (!buildSettings.empty()) - { - cmd << buildSettings << " "; - } - - // Execute the CLI for each target GPU, appending the GPU to the command. - for (const std::string& targetGpu : pTargetClone->m_pBuildSettings->m_targetGpus) - { - if (!cancelSignal) - { - // Print the command string that's about to be used to invoke the RGA CLI build process. - std::string cliInvocationCommandString; - BuildOutputViewCommandHeader(pProject, targetGpu, cliInvocationCommandString); - - // Append the command string header text to the output string. - std::stringstream cmdLineOutputStream; - cmdLineOutputStream << cliInvocationCommandString; - - // Construct the full CLI command string including the current target GPU. - std::stringstream fullCmdWithGpu; - fullCmdWithGpu << cmd.str(); - - // Specify the Metadata file path. - fullCmdWithGpu << CLI_OPT_SESSION_METADATA << " \"" << outputPath << targetGpu << "_" << STR_SESSION_METADATA_FILENAME << "\" "; - - // Specify which GPU to build outputs for. - fullCmdWithGpu << CLI_OPT_ASIC << " " << targetGpu << " "; - - // Append each input file to the end of the CLI command. - for (const rgSourceFileInfo& fileInfo : pTargetClone->m_sourceFiles) - { - // Surround the path to the input file with quotes to prevent breaking the CLI parser. - fullCmdWithGpu << "\""; - fullCmdWithGpu << fileInfo.m_filePath; - fullCmdWithGpu << "\" "; - } - - // Add the full CLI execution string to the output window's log. - cmdLineOutputStream << fullCmdWithGpu.str(); - - // Send the new output text to the output window. - if (cliOutputHandlingCallback != nullptr) - { - cliOutputHandlingCallback(cmdLineOutputStream.str()); - } - - // Execute the command and grab the output. - rgLog::file << STR_LOG_LAUNCHING_CLI << rgLog::noflush << std::endl << fullCmdWithGpu.str() << std::endl << rgLog::flush; - gtString cmdLineOutputAsGtStr; - ret = osExecAndGrabOutput(fullCmdWithGpu.str().c_str(), cancelSignal, cmdLineOutputAsGtStr); - - assert(ret); - if (ret) - { - // Add the GPU to the output list if it was built successfully. - gpusBuilt.push_back(targetGpu); - } - - // Append the CLI's output to the string containing the entire execution output. - fullCliOutput << cmdLineOutputAsGtStr.asASCIICharArray(); - - // Invoke the callback used to send new CLI output to the GUI. - if (cliOutputHandlingCallback != nullptr) - { - cliOutputHandlingCallback(cmdLineOutputAsGtStr.asASCIICharArray()); - } - } - else - { - // Stop the process if build is canceled. - break; - } - } - } - else - { - // Invoke the callback used to send new CLI output to the GUI. - if (cliOutputHandlingCallback != nullptr) - { - std::stringstream errorStream; - errorStream << STR_OUTPUT_WINDOW_BUILDING_PROJECT_FAILED_TEXT; - errorStream << STR_OUTPUT_WINDOW_BUILDING_PROJECT_FAILED_INVALID_CLONE; - cliOutputHandlingCallback(errorStream.str()); - } - } - } - - return ret; -} - -bool rgCliLauncher::BuildProjectCloneVulkan(std::shared_ptr pProject, int cloneIndex, const std::string& outputPath, const std::string& binaryName, - std::function cliOutputHandlingCallback, std::vector& gpusBuilt, bool& cancelSignal) -{ - bool ret = false; - if (pProject != nullptr) - { - rgLog::file << STR_LOG_BUILDING_PROJECT_CLONE_1 << pProject->m_projectName << STR_LOG_BUILDING_PROJECT_CLONE_2 << cloneIndex << std::endl; - - // A stream of all text collected from CLI invocation. - std::stringstream fullCliOutput; - - // Verify that the clone index is valid for the given project. - int numClones = static_cast(pProject->m_clones.size()); - bool isCloneIndexValid = (cloneIndex >= 0 && cloneIndex < numClones); - assert(isCloneIndexValid); - if (isCloneIndexValid) - { - std::shared_ptr pTargetClone = pProject->m_clones[cloneIndex]; - assert(pTargetClone != nullptr); - if (pTargetClone != nullptr) - { - std::shared_ptr pVulkanClone = std::dynamic_pointer_cast(pTargetClone); - assert(pVulkanClone != nullptr); - if (pVulkanClone != nullptr) - { - // Generate the command line invocation command. - std::stringstream cmd; - - // Build settings. - std::string buildSettings; - std::shared_ptr pBuildSettingsVulkan = - std::static_pointer_cast(pTargetClone->m_pBuildSettings); - assert(pBuildSettingsVulkan != nullptr); - - // Build the compile project command string. - BuildCompileProjectCommandString(cmd, outputPath, pBuildSettingsVulkan->m_binaryFileName); - - ret = rgCliUtils::GenerateVulkanBuildSettingsString(*pBuildSettingsVulkan, buildSettings); - assert(ret); - if (!buildSettings.empty()) - { - cmd << buildSettings << " "; - } - - std::shared_ptr pVulkanUtil = std::dynamic_pointer_cast(rgUtilsGraphics::CreateUtility(rgProjectAPI::Vulkan)); - assert(pVulkanUtil != nullptr); - if (pVulkanUtil != nullptr) - { - // Execute the CLI for each target GPU, appending the GPU to the command. - for (const std::string& targetGpu : pTargetClone->m_pBuildSettings->m_targetGpus) - { - if (!cancelSignal) - { - // Print the command string that's about to be used to invoke the RGA CLI build process. - std::string cliInvocationCommandString; - BuildOutputViewCommandHeader(pProject, targetGpu, cliInvocationCommandString); - - // Append the command string header text to the output string. - std::stringstream cmdLineOutputStream; - cmdLineOutputStream << cliInvocationCommandString; - - // Construct the full CLI command string including the current target GPU. - std::stringstream fullCmdWithGpu; - fullCmdWithGpu << cmd.str(); - - // Specify the Metadata file path. - fullCmdWithGpu << CLI_OPT_SESSION_METADATA << " \"" << outputPath << targetGpu << "_" << STR_SESSION_METADATA_FILENAME << "\" "; - - // Specify which GPU to build outputs for. - fullCmdWithGpu << CLI_OPT_ASIC << " " << targetGpu << " "; - - // Provide the pipeline state object configuration file. - for (auto psoStateFile : pVulkanClone->m_psoStates) - { - // Only append the path for the active PSO config. - if (psoStateFile.m_isActive) - { - // Append the pipeline's state file path. - fullCmdWithGpu << CLI_OPT_PSO << " \"" << psoStateFile.m_pipelineStateFilePath << "\" "; - break; - } - } - - // Append each active pipeline stage's input file to the command line. - if (pVulkanClone->m_pipeline.m_type == rgPipelineType::Graphics) - { - size_t firstStage = static_cast(rgPipelineStage::Vertex); - size_t lastStage = static_cast(rgPipelineStage::Fragment); - - // Step through each stage in a graphics pipeline. If the project's - // stage is not empty, append the stage's shader file to the cmdline. - for (size_t stageIndex = firstStage; stageIndex <= lastStage; ++stageIndex) - { - rgPipelineStage currentStage = static_cast(stageIndex); - - // Try to find the given stage within the pipeline's stage map. - const auto& stageInputFile = pVulkanClone->m_pipeline.m_shaderStages[stageIndex]; - if (!stageInputFile.empty()) - { - // A source file exists in this stage. Append it to the command line. - std::string stageAbbreviation = pVulkanUtil->PipelineStageToAbbreviation(currentStage); - - // Check to see if the file has txt extension. - if (rgUtils::IsSpvasTextFile(stageInputFile, stageAbbreviation)) - { - // Append "-spvas" to stage abbreviation. - stageAbbreviation += CLI_OPT_SPVAS_TEXT_FILE; - } - - // Append the stage type and shader file path to the command line. - fullCmdWithGpu << "--" << stageAbbreviation << " \"" << stageInputFile << "\" "; - } - } - } - else if (pVulkanClone->m_pipeline.m_type == rgPipelineType::Compute) - { - rgPipelineStage currentStage = rgPipelineStage::Compute; - - // Does the pipeline have a compute shader source file? - const auto& computeShaderInputSourceFilePath = pVulkanClone->m_pipeline.m_shaderStages[static_cast(currentStage)]; - if (!computeShaderInputSourceFilePath.empty()) - { - // A source file exists in this stage. Append it to the command line. - std::string stageAbbreviation = pVulkanUtil->PipelineStageToAbbreviation(currentStage); - - // Check to see if the file has txt extension. - if (rgUtils::IsSpvasTextFile(computeShaderInputSourceFilePath, stageAbbreviation)) - { - // Append "-spvas" to stage abbreviation. - stageAbbreviation += CLI_OPT_SPVAS_TEXT_FILE; - } - - // Append the stage type and shader file path to the command line. - fullCmdWithGpu << "--" << stageAbbreviation << " \"" << computeShaderInputSourceFilePath << "\" "; - } - } - else - { - // The pipeline type can only be graphics or compute. - // If we get here something is wrong with the project clone. - assert(false); - ret = false; - } - - // Verify that all operations up to this point were successful. - assert(ret); - if (ret) - { - // Add the full CLI execution string to the output window's log. - cmdLineOutputStream << fullCmdWithGpu.str(); - - // Send the new output text to the output window. - if (cliOutputHandlingCallback != nullptr) - { - cliOutputHandlingCallback(cmdLineOutputStream.str()); - } - - // Execute the command and grab the output. - rgLog::file << STR_LOG_LAUNCHING_CLI << rgLog::noflush << std::endl << fullCmdWithGpu.str() << std::endl << rgLog::flush; - gtString cmdLineOutputAsGtStr; - ret = osExecAndGrabOutput(fullCmdWithGpu.str().c_str(), cancelSignal, cmdLineOutputAsGtStr); - - assert(ret); - if (ret) - { - // Add the GPU to the output list if it was built successfully. - gpusBuilt.push_back(targetGpu); - } - - // Append the CLI's output to the string containing the entire execution output. - fullCliOutput << cmdLineOutputAsGtStr.asASCIICharArray(); - - // Invoke the callback used to send new CLI output to the GUI. - if (cliOutputHandlingCallback != nullptr) - { - cliOutputHandlingCallback(cmdLineOutputAsGtStr.asASCIICharArray()); - } - } - else - { - // Send a failure error message to the output window. - if (cliOutputHandlingCallback != nullptr) - { - cliOutputHandlingCallback(STR_ERR_FAILED_TO_GENERATE_BUILD_COMMAND); - } - } - } - else - { - // Stop the process if build is canceled. - break; - } - } - } - } - } - } - else - { - // Invoke the callback used to send new CLI output to the GUI. - if (cliOutputHandlingCallback != nullptr) - { - std::stringstream errorStream; - errorStream << STR_OUTPUT_WINDOW_BUILDING_PROJECT_FAILED_TEXT; - errorStream << STR_OUTPUT_WINDOW_BUILDING_PROJECT_FAILED_INVALID_CLONE; - cliOutputHandlingCallback(errorStream.str()); - } - } - } - - return ret; -} - -bool rgCliLauncher::DisassembleSpvToText(const std::string& compilerBinFolder, const std::string& spvFullFilePath, - const std::string& outputFilePath, std::string& cliOutput) -{ - bool ret = false; - - // Generate the command line backend invocation command. - std::stringstream commandStream; - BuildRgaExecutableCommandString(commandStream); - - // Add the current build mode to the command. - const std::string& currentMode = rgConfigManager::Instance().GetCurrentModeString(); - commandStream << CLI_OPT_INPUT_TYPE << " " << currentMode << " "; - - // Append the alternative compiler path if it's not empty. - if (!compilerBinFolder.empty()) - { - commandStream << CLI_OPT_COMPILER_BIN_DIR << " \"" << compilerBinFolder << "\" "; - } - - // Append the ISA text output path as well as the target SPIR-V to disassemble. - commandStream << CLI_OPT_VULKAN_SPV_DIS << " \"" << outputFilePath << "\" \"" << spvFullFilePath << "\""; - - // Launch the command line backend to generate the version info file. - bool cancelSignal = false; - gtString cliOutputAsGtStr; - bool isLaunchSuccessful = osExecAndGrabOutput(commandStream.str().c_str(), cancelSignal, cliOutputAsGtStr); - assert(isLaunchSuccessful); - - if (isLaunchSuccessful) - { - cliOutput = cliOutputAsGtStr.asASCIICharArray(); - - // Verify that the file was indeed created. - bool isOutputFileCreated = rgUtils::IsFileExists(outputFilePath); - assert(isOutputFileCreated); - ret = isOutputFileCreated; - } - - return ret; -} - -bool rgCliLauncher::GenerateVersionInfoFile(const std::string& fullPath) -{ - bool ret = false; - - // Generate the command line backend invocation command. - std::stringstream cmd; - - // Add the executable name. - BuildRgaExecutableCommandString(cmd); - - // Add the version-info option to the command. - cmd << CLI_OPT_VERSION_INFO << " \"" << fullPath << "\""; - - // Launch the command line backend to generate the version info file. - bool cancelSignal = false; - gtString cliOutputAsGtStr; - bool isLaunchSuccessful = osExecAndGrabOutput(cmd.str().c_str(), cancelSignal, cliOutputAsGtStr); - assert(isLaunchSuccessful); - - if (isLaunchSuccessful) - { - // Verify that the file was indeed created. - bool isOutputFileCreated = rgUtils::IsFileExists(fullPath); - assert(isOutputFileCreated); - ret = isOutputFileCreated; - } - - return ret; -} - -bool rgCliLauncher::ListKernels(std::shared_ptr pProject, int cloneIndex, std::map& entrypointLineNumbers) -{ - bool isParsingFailed = false; - - assert(pProject != nullptr); - if (pProject != nullptr) - { - bool isValidIndex = cloneIndex >= 0 && cloneIndex < pProject->m_clones.size(); - assert(isValidIndex); - if (isValidIndex && !pProject->m_clones.empty() && pProject->m_clones[cloneIndex] != nullptr) - { - // Append each input file to the end of the CLI command. - for (const rgSourceFileInfo& fileInfo : pProject->m_clones[cloneIndex]->m_sourceFiles) - { - // Generate the command line backend invocation command. - std::stringstream cmd; - - // Add the executable name. - BuildRgaExecutableCommandString(cmd); - - // Add the current build mode to the command. - const std::string& currentMode = rgConfigManager::Instance().GetCurrentModeString(); - cmd << CLI_OPT_INPUT_TYPE << " " << currentMode << " "; - - std::stringstream fullCmdWithGpu; - fullCmdWithGpu << cmd.str(); - - const std::string& sourceFilePath = fileInfo.m_filePath; - - // Add the version-info option to the command. - cmd << CLI_OPT_LIST_KERNELS << " " << "\"" << sourceFilePath << "\""; - - // Launch the command line backend to generate the version info file. - bool cancelSignal = false; - gtString cliOutputAsGtStr; - bool isLaunchSuccessful = osExecAndGrabOutput(cmd.str().c_str(), cancelSignal, cliOutputAsGtStr); - assert(isLaunchSuccessful); - if (isLaunchSuccessful) - { - // Parse the output and dump it into entrypointLineNumbers. - isParsingFailed = !rgCliKernelListParser::ReadListKernelsOutput(cliOutputAsGtStr.asASCIICharArray(), - entrypointLineNumbers[sourceFilePath]); - } - else - { - isParsingFailed = true; - } - } - } - } - - isParsingFailed = entrypointLineNumbers.empty(); - - return !isParsingFailed; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgCliOutputView.cpp b/RadeonGPUAnalyzerGUI/Src/rgCliOutputView.cpp deleted file mode 100644 index 834bf82..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgCliOutputView.cpp +++ /dev/null @@ -1,291 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include -#include -#include - -// Local. -#include -#include -#include -#include - -// Local constants -static const QString QSTR_CMPLR_ERROR_TOKEN = ": error:"; -static const QString QSTR_CMPLR_WARNING_TOKEN = ": warning:"; -static const QString QSTR_CMPLR_NOTE_TOKEN = ": note:"; -static const QChar QCHAR_CMPLR_ERROR_DELIMITER = ':'; -static const QChar QCHAR_L_PARENTHESIS = '('; -static const QChar QCHAR_R_PARENTHESIS = ')'; - -rgCliOutputView::rgCliOutputView(QWidget *parent) : - QWidget(parent) -{ - ui.setupUi(this); - - // Use the output text edit as the focus proxy for this view. - setFocusProxy(ui.outputTextEdit); - - // To receive focus, the user must tab or click onto the output window widget. - setFocusPolicy(Qt::StrongFocus); - - // Use monospace font style so that characters align. - QFont font("unexistent"); - font.setStyleHint(QFont::Monospace); - ui.outputTextEdit->setFont(font); - - // Set the status and tool tips. - ui.clearOutputPushButton->setStatusTip(STR_OUTPUT_WINDOW_CLEAR_BUTTON_STATUSTIP); - ui.clearOutputPushButton->setToolTip(STR_OUTPUT_WINDOW_CLEAR_BUTTON_TOOLTIP); - - // Connect the signals. - ConnectSignals(); - - // Set the event interceptor for TextEdit visible area. - ui.outputTextEdit->viewport()->installEventFilter(this); - - // Set the mouse cursor to pointing hand cursor. - SetCursor(); - - // Create shortcut actions. - CreateActions(); -} - -void rgCliOutputView::CreateActions() -{ - // Tab key navigation. - m_pTabKeyAction = new QAction(this); - m_pTabKeyAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_FILE_MENU_ACTIVATE_TAB)); - m_pTabKeyAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); - - addAction(m_pTabKeyAction); - bool isConnected = connect(m_pTabKeyAction, &QAction::triggered, this, &rgCliOutputView::HandleTabFocusPressed); - assert(isConnected); - - // Shift+Tab key navigation. - m_pShiftTabKeyAction = new QAction(this); - m_pShiftTabKeyAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_FILE_MENU_ACTIVATE_SHIFT_TAB)); - m_pShiftTabKeyAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); - - addAction(m_pShiftTabKeyAction); - isConnected = connect(m_pShiftTabKeyAction, &QAction::triggered, this, &rgCliOutputView::HandleShiftTabFocusPressed); - assert(isConnected); -} - -void rgCliOutputView::HandleTabFocusPressed() -{ - // Switch focus to the next child widget, - // unless the focus is on the last child widget, - // in which case switch focus to file menu. - if (m_currentSubWidget == CliOutputWindowSubWidgets::OutputWindow) - { - ui.clearOutputPushButton->setFocus(); - m_currentSubWidget = CliOutputWindowSubWidgets::ClearWindowButton; - } - else if (m_currentSubWidget == CliOutputWindowSubWidgets::ClearWindowButton) - { - m_currentSubWidget = CliOutputWindowSubWidgets::OutputWindow; - emit FocusNextView(); - } -} - -void rgCliOutputView::HandleShiftTabFocusPressed() -{ - // Switch focus to the next child widget, - // unless the focus is on the last child widget, - // in which case switch focus to file menu. - if (m_currentSubWidget == CliOutputWindowSubWidgets::OutputWindow) - { - emit FocusColumnPushButton(); - } - else if (m_currentSubWidget == CliOutputWindowSubWidgets::ClearWindowButton) - { - m_currentSubWidget = CliOutputWindowSubWidgets::OutputWindow; - emit FocusOutputWindow(); - } -} - -void rgCliOutputView::mousePressEvent(QMouseEvent *pEvent) -{ - m_currentSubWidget = CliOutputWindowSubWidgets::OutputWindow; - - // Pass the event onto the base class. - QWidget::mousePressEvent(pEvent); -} - -std::string rgCliOutputView::GetText() const -{ - return ui.outputTextEdit->toPlainText().toStdString(); -} - -void rgCliOutputView::focusInEvent(QFocusEvent* pEvent) -{ - m_currentSubWidget = CliOutputWindowSubWidgets::OutputWindow; -} - -void rgCliOutputView::ClearText() -{ - ui.outputTextEdit->clear(); -} - -bool rgCliOutputView::eventFilter(QObject* pObject, QEvent* pEvent) -{ - assert(pEvent != nullptr); - if (pEvent != nullptr) - { - // Intercept "mouse double-click" events for TextEdit area. - if (pEvent->type() == QMouseEvent::MouseButtonDblClick) - { - const QPoint clickedPos = static_cast(pEvent)->pos(); - QTextCursor textPos = ui.outputTextEdit->cursorForPosition(clickedPos); - SwitchToErrorLocation(textPos.blockNumber()); - } - else if (pEvent->type() == QMouseEvent::MouseButtonPress) - { - m_currentSubWidget = CliOutputWindowSubWidgets::OutputWindow; - } - } - - // Continue default processing for all other events. - return QObject::eventFilter(pObject, pEvent); -} - -void rgCliOutputView::ConnectSignals() -{ - bool isConnected = connect(this, &rgCliOutputView::EmitSetText, this, &rgCliOutputView::HandleAppendText); - assert(isConnected); - - isConnected = connect(ui.clearOutputPushButton, &QPushButton::clicked, this, &rgCliOutputView::HandleClearClicked); - assert(isConnected); -} - -void rgCliOutputView::ScrollToBottom() -{ - QScrollBar* pScrollBar = ui.outputTextEdit->verticalScrollBar(); - pScrollBar->setValue(pScrollBar->maximum()); -} - -void rgCliOutputView::HandleAppendText(const QString& str) -{ - ui.outputTextEdit->append(str); - ScrollToBottom(); - - // Focus on the output window when text is appended (this is the ONLY time the window will receive focus). - setFocus(); -} - -void rgCliOutputView::HandleClearClicked() -{ - ui.outputTextEdit->clear(); -} - -void rgCliOutputView::HandleBuildStarted() -{ - // Do not allow to clear the output window during a build. - ui.clearOutputPushButton->setEnabled(false); -} - -void rgCliOutputView::HandleBuildEnded() -{ - // Re-enable the clear button after the build is over. - ui.clearOutputPushButton->setEnabled(true); -} - -void rgCliOutputView::SetCursor() -{ - // Set the mouse cursor to pointing hand cursor. - ui.clearOutputPushButton->setCursor(Qt::PointingHandCursor); - ui.viewMaximizeButton->setCursor(Qt::PointingHandCursor); -} - -// -// Parse the error location generated by CLI Compiler. Returns a pair {file_name, line}. -// -static bool ParseErrorLocation(const QStringRef& loc, std::pair parsedLoc) -{ - // The clang and lld may produce 2 formats of error location messages: - // 1. C:\OpenCL\test.cl:4:7: error: ... - // `-- file_name---' ^ ^ - // line--' `--column - // - // 2. ...(C:\OpenCL\test.cl:4)... - // `-- file_name---' ^ - // line--' - // - // Note that the source file path may contain symbols lile ':', '(', ')', etc. - - bool found = false; - - // I. Try matching the 1st pattern. - int columnOffset, rParenthOffset = loc.lastIndexOf(QCHAR_R_PARENTHESIS); - if (rParenthOffset != -1 && (columnOffset = loc.lastIndexOf(QCHAR_CMPLR_ERROR_DELIMITER, rParenthOffset)) != -1) - { - // Parse the "loc" string backwards trying to find '(' matching the ')' found at rParenthOffset. - int parenthStackCount = 1, offset = rParenthOffset; - while (offset > 0 && parenthStackCount > 0) - { - const QChar sym = loc.at(--offset); - parenthStackCount += (sym == QCHAR_L_PARENTHESIS ? -1 : (sym == QCHAR_R_PARENTHESIS ? 1 : 0)); - } - - if (parenthStackCount == 0 && columnOffset > offset) - { - QStringRef lineNumStr = loc.mid(columnOffset + 1, rParenthOffset - columnOffset - 1); - parsedLoc.second = lineNumStr.toInt(&found); - if (found) - { - std::get<0>(parsedLoc) = loc.mid(offset + 1, columnOffset - offset - 1); - } - } - } - - - // II. Try mathching the 2nd pattern. - if (!found) - { - int offset, lineStartOffset, lineEndOffset; - - if ((offset = loc.indexOf(QSTR_CMPLR_ERROR_TOKEN)) != -1 || - (offset = loc.indexOf(QSTR_CMPLR_WARNING_TOKEN)) != -1 || - (offset = loc.indexOf(QSTR_CMPLR_NOTE_TOKEN)) != -1) - { - // 1. Skip the column number and parse the line number. - if ((lineEndOffset = loc.lastIndexOf(QCHAR_CMPLR_ERROR_DELIMITER, offset - 1)) != -1 && - (lineStartOffset = loc.lastIndexOf(QCHAR_CMPLR_ERROR_DELIMITER, lineEndOffset - 1)) != -1) - { - QStringRef lineStr = loc.mid(lineStartOffset + 1, lineEndOffset - lineStartOffset - 1); - std::get<1>(parsedLoc) = lineStr.toInt(&found); - } - - // 2. Copy the file name. - if (found) - { - std::get<0>(parsedLoc) = loc.left(lineStartOffset); - } - } - } - - return found; -} - -void rgCliOutputView::SwitchToErrorLocation(int blockNum) const -{ - if (blockNum > 0) - { - if (QTextDocument* doc = ui.outputTextEdit->document()) - { - QTextBlock block = doc->findBlockByNumber(blockNum); - QString blockText = block.text(); - QStringRef filePath; - int line; - - if (!blockText.isEmpty() && ParseErrorLocation(QStringRef(&blockText), { filePath, line })) - { - emit SwitchToFile(filePath.toString().toStdString(), line); - } - } - } -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgCliUtils.cpp b/RadeonGPUAnalyzerGUI/Src/rgCliUtils.cpp deleted file mode 100644 index 2630bde..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgCliUtils.cpp +++ /dev/null @@ -1,217 +0,0 @@ -// C++. -#include -#include - -// Local. -#include -#include -#include -#include - -// Common between CLI and GUI. -#include - - -bool rgCliUtils::GenerateOpenClBuildSettingsString(const rgBuildSettingsOpenCL& buildSettings, std::string& str, bool additionalOptions) -{ - bool ret = false; - std::stringstream cmd; - - // Include paths. - for (std::string includePath : buildSettings.m_additionalIncludeDirectories) - { - // Remove trailing slash symbols. - if (!includePath.empty() && (includePath[includePath.size() - 1] == '\\' || includePath[includePath.size() - 1] == '/')) - { - includePath.erase(includePath.size() - 1, 1); - } - cmd << CLI_OPT_ADDITIONAL_INCLUDE_PATH << " \"" << includePath << "\" "; - } - - // Preprocessor directives. - for (const std::string& currDirective : buildSettings.m_predefinedMacros) - { - cmd << CLI_OPT_PREPROCESSOR_DIRECTIVE << " " << currDirective << " "; - } - - // Accumulate the OpenCL-specific options in a separate stream. - std::stringstream clSpecificOptions; - - // OpenCL-specific build options. - if (buildSettings.m_isAggressiveMathOptimizations) - { - clSpecificOptions << CLI_OPT_CL_AGGRESSIVE_OPTIMIZATIONS << " "; - } - if (buildSettings.m_isCorrectlyRoundDivSqrt) - { - clSpecificOptions << CLI_OPT_CL_CORRECT_ROUND_DIV_SQRT << " "; - } - if (buildSettings.m_isNoNanNorInfinite) - { - clSpecificOptions << CLI_OPT_CL_IS_NAN_OR_INIFINITE << " "; - } - if (buildSettings.m_isUnsafeOptimizations) - { - clSpecificOptions << CLI_OPT_CL_UNSAFE_OPTIMIZATIONS << " "; - } - if (buildSettings.m_isIgnoreZeroSignedness) - { - clSpecificOptions << CLI_OPT_CL_IGNORE_ZERO_SIGNEDNESS << " "; - } - if (buildSettings.m_isEnableMAD) - { - clSpecificOptions << CLI_OPT_CL_ENABLE_MAD << " "; - } - if (buildSettings.m_isStrictAliasing) - { - clSpecificOptions << CLI_OPT_CL_STRICT_ALIASING << " "; - } - if (buildSettings.m_isDenormsAsZeros) - { - clSpecificOptions << CLI_OPT_CL_DENORMS_AS_ZEROES << " "; - } - if (buildSettings.m_isTreatDoubleAsSingle) - { - clSpecificOptions << CLI_OPT_CL_TREAT_DOUBLE_AS_SINGLE << " "; - } - - // Append the additional options if required. - if (additionalOptions && !buildSettings.m_additionalOptions.empty()) - { - clSpecificOptions << buildSettings.m_additionalOptions; - } - - // Add the OpenCL-specific options, if there are any. - if (!clSpecificOptions.str().empty()) - { - cmd << CLI_OPT_CL_OPTION << " \"" << clSpecificOptions.str() << "\" "; - } - - // Add the alternative compiler paths. - if (!std::get(buildSettings.m_compilerPaths).empty()) - { - cmd << CLI_OPT_COMPILER_BIN_DIR << " \"" << std::get(buildSettings.m_compilerPaths) << "\" "; - } - if (!std::get(buildSettings.m_compilerPaths).empty()) - { - cmd << CLI_OPT_COMPILER_INC_DIR << " \"" << std::get(buildSettings.m_compilerPaths) << "\" "; - } - if (!std::get(buildSettings.m_compilerPaths).empty()) - { - cmd << CLI_OPT_COMPILER_LIB_DIR << " \"" << std::get(buildSettings.m_compilerPaths) << "\" "; - } - - if (buildSettings.m_optimizationLevel != buildSettings.OPENCL_DEFAULT_OPT_LEVEL) - { - // Tokens to identify the user's selection. - const char* OPTIMIZATION_LEVEL_0_TOKEN = "O0"; - const char* OPTIMIZATION_LEVEL_1_TOKEN = "O1"; - const char* OPTIMIZATION_LEVEL_2_TOKEN = "O2"; - const char* OPTIMIZATION_LEVEL_3_TOKEN = "O3"; - - if (buildSettings.m_optimizationLevel.find(OPTIMIZATION_LEVEL_0_TOKEN) != std::string::npos) - { - cmd << CLI_OPT_CL_OPTMIZATION_LEVEL_0 << " "; - } - else if (buildSettings.m_optimizationLevel.find(OPTIMIZATION_LEVEL_1_TOKEN) != std::string::npos) - { - cmd << CLI_OPT_CL_OPTMIZATION_LEVEL_1 << " "; - } - else if (buildSettings.m_optimizationLevel.find(OPTIMIZATION_LEVEL_2_TOKEN) != std::string::npos) - { - cmd << CLI_OPT_CL_OPTMIZATION_LEVEL_2 << " "; - } - else if (buildSettings.m_optimizationLevel.find(OPTIMIZATION_LEVEL_3_TOKEN) != std::string::npos) - { - cmd << CLI_OPT_CL_OPTMIZATION_LEVEL_3 << " "; - } - } - - str = cmd.str(); - ret = true; - - return ret; -} - -bool rgCliUtils::GenerateVulkanBuildSettingsString(const rgBuildSettingsVulkan& buildSettings, std::string& str, bool additionalOptions) -{ - bool ret = false; - std::stringstream cmd; - - // Include paths. - for (std::string includePath : buildSettings.m_additionalIncludeDirectories) - { - // Remove trailing slash symbols. - if (!includePath.empty() && (includePath[includePath.size() - 1] == '\\' || includePath[includePath.size() - 1] == '/')) - { - includePath.erase(includePath.size() - 1, 1); - } - cmd << CLI_OPT_ADDITIONAL_INCLUDE_PATH << " \"" << includePath << "\" "; - } - - // Preprocessor directives. - for (const std::string& currDirective : buildSettings.m_predefinedMacros) - { - cmd << CLI_OPT_PREPROCESSOR_DIRECTIVE << " " << currDirective << " "; - } - - // Accumulate the Vulkan-specific options in a separate stream. - std::stringstream vulkanSpecificOptions; - - // Vulkan-specific build options. - if (buildSettings.m_isGenerateDebugInfoChecked) - { - vulkanSpecificOptions << CLI_OPT_VULKAN_GENERATE_DEBUG_INFORMATION << " "; - } - if (buildSettings.m_isNoExplicitBindingsChecked) - { - vulkanSpecificOptions << CLI_OPT_VULKAN_NO_EXPLICIT_BINDINGS << " "; - } - if (buildSettings.m_isUseHlslBlockOffsetsChecked) - { - vulkanSpecificOptions << CLI_OPT_VULKAN_HLSL_BLOCK_OFFSETS << " "; - } - if (buildSettings.m_isUseHlslIoMappingChecked) - { - vulkanSpecificOptions << CLI_OPT_VULKAN_HLSL_IOMAP << " "; - } - if (buildSettings.m_isEnableValidationLayersChecked) - { - cmd << CLI_OPT_VULKAN_VALIDATION << " "; - } - - if (!buildSettings.m_ICDLocation.empty()) - { - cmd << CLI_OPT_VULKAN_ICD_LOCATION << " " << "\"" << buildSettings.m_ICDLocation << "\" "; - } - - if (!buildSettings.m_glslangOptions.empty()) - { - // Wrap the argument for --glslang-opt with the required token to avoid ambiguity - // between rga and glslang options. - cmd << CLI_OPT_VULKAN_GLSLANG_OPTIONS << " " << "\"" << CLI_OPT_GLSLANG_TOKEN << - buildSettings.m_glslangOptions << CLI_OPT_GLSLANG_TOKEN << "\" "; - } - - if (!std::get(buildSettings.m_compilerPaths).empty()) - { - cmd << CLI_OPT_COMPILER_BIN_DIR << " \"" << std::get(buildSettings.m_compilerPaths) << "\" "; - } - - // Append the additional options if required. - if (additionalOptions && !buildSettings.m_additionalOptions.empty()) - { - vulkanSpecificOptions << buildSettings.m_additionalOptions; - } - - // Add the Vulkan-specific options, if there are any. - if (!vulkanSpecificOptions.str().empty()) - { - cmd << CLI_OPT_VULKAN_OPTION << " \"" << vulkanSpecificOptions.str() << "\" "; - } - - str = cmd.str(); - ret = true; - - return ret; -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgComboBox.cpp b/RadeonGPUAnalyzerGUI/Src/rgComboBox.cpp deleted file mode 100644 index a84ed94..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgComboBox.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// C++. -#include -#include - -// Local. -#include - -rgComboBox::rgComboBox(QWidget* pParent) : QComboBox(pParent) -{ -} - -void rgComboBox::mousePressEvent(QMouseEvent* pEvent) -{ - emit ComboBoxFocusInEvent(); - - // Pass the event onto the base class. - QComboBox::mousePressEvent(pEvent); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgConfigFile.cpp b/RadeonGPUAnalyzerGUI/Src/rgConfigFile.cpp deleted file mode 100644 index b729aea..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgConfigFile.cpp +++ /dev/null @@ -1,1633 +0,0 @@ -// C++. -#include -#include -#include - -// XML. -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Infra. -#include - -// *** INTERNALLY-LINKED AUXILIARY FUNCTIONS - BEGIN *** - -// Read v2.0 of the DefaultBuildSettings XML node from the config file. -static bool ExtractDefaultBuildSettings_2_0(tinyxml2::XMLNode* pDefaultBuildSettingsNode, std::shared_ptr& pGlobalSettings); - -// Read v2.1 of the DefaultBuildSettings XML node from the config file. -static bool ExtractDefaultBuildSettings_2_1(tinyxml2::XMLNode* pDefaultBuildSettingsNode, std::shared_ptr& pGlobalSettings); - -// Read v2.0 of the GlobalSettings XML node from the config file. -static bool ExtractGlobalSettings_2_0(tinyxml2::XMLNode* pGlobalSettingsNode, std::shared_ptr& pGlobalSettings); - -// Read v2.1 of the GlobalSettings XML node from the config file. -static bool ExtractGlobalSettings_2_1(tinyxml2::XMLNode* pGlobalSettingsNode, std::shared_ptr& pGlobalSettings); - -// Read v2.2 of the GlobalSettings XML node from the config file. -static bool ExtractGlobalSettings_2_2(tinyxml2::XMLNode* pGlobalSettingsNode, std::shared_ptr& pGlobalSettings); - -// Takes the comma-separated target devices list from the GUI, and returns the list of GPUs in it. -static void ExtractTargetGpus(const std::string& targetDevices, std::vector& gpuList) -{ - rgUtils::splitString(targetDevices, rgConfigManager::RGA_LIST_DELIMITER, gpuList); -} - -// Takes the comma-separated predefined macros list from the GUI, and returns the list of macros in it. -static void ExtractPredefinedMacros(const std::string& predefinedMacros, std::vector& macroList) -{ - rgUtils::splitString(predefinedMacros, rgConfigManager::RGA_LIST_DELIMITER, macroList); -} - -// Takes the comma-separated directory list from the GUI, and returns the list of directories in it. -static void ExtractAdditionalIncludeDirectories(const std::string& additionalIncludeDirectories, std::vector& dirList) -{ - rgUtils::splitString(additionalIncludeDirectories, rgConfigManager::RGA_LIST_DELIMITER, dirList); -} - -// Takes the comma-separated list of disassembly columns, and returns the list of the columns in it. -static void ExtractDisassemblyColumns(const std::string& disassemblyColumns, std::vector& columnIndices) -{ - std::vector splitTokens; - rgUtils::splitString(disassemblyColumns, rgConfigManager::RGA_LIST_DELIMITER, splitTokens); - - for (const std::string& token : splitTokens) - { - int index = std::stoi(token); - columnIndices.push_back(index == 1); - } -} - -static bool ExtractRecentProjects(tinyxml2::XMLNode* pNode, std::vector>& recentProjects) -{ - bool ret = false; - - assert(pNode != nullptr); - if (pNode != nullptr) - { - // Find the first project in the list of recent projects. - pNode = pNode->FirstChildElement(XML_NODE_GLOBAL_RECENT_PROJECT_ROOT); - - // If there aren't any recent project paths, return early, as there's nothing to parse. - if (pNode == nullptr) - { - ret = true; - } - else - { - // Step over each path to a recent project, and add it to the output list. - while (pNode != nullptr) - { - tinyxml2::XMLNode* pChildNode = pNode->FirstChildElement(XML_NODE_GLOBAL_RECENT_PROJECT_PATH); - assert(pChildNode != nullptr); - if (pChildNode != nullptr) - { - // Read the project path element. - std::string projectPath; - ret = rgXMLUtils::ReadNodeTextString(pChildNode, projectPath); - - assert(ret); - if (ret) - { - auto pRecentProject = std::make_shared(); - pRecentProject->projectPath = projectPath; - - // Get the project api element. - pChildNode = pChildNode->NextSiblingElement(XML_NODE_GLOBAL_RECENT_PROJECT_API); - - assert(pChildNode != nullptr); - if (pChildNode != nullptr) - { - // Read the project api element. - std::string projectAPI; - ret = rgXMLUtils::ReadNodeTextString(pChildNode, projectAPI); - - assert(ret); - if (ret) - { - pRecentProject->apiType = rgUtils::ProjectAPIToEnum(projectAPI); - } - } - recentProjects.push_back(pRecentProject); - } - } - - pNode = pNode->NextSiblingElement(XML_NODE_GLOBAL_RECENT_PROJECT_ROOT); - } - } - } - return ret; -} - -static bool ExtractFontInformation(tinyxml2::XMLNode* pNode, std::shared_ptr& pGlobalSettings) -{ - bool ret = false; - - assert(pNode != nullptr); - if (pNode != nullptr) - { - // Get the font family element. - tinyxml2::XMLNode* pChildNode = pNode->FirstChildElement(XML_NODE_GLOBAL_FONT_FAMILY_TYPE); - assert(pChildNode != nullptr); - if (pChildNode != nullptr) - { - // Read font family element. - assert(pGlobalSettings != nullptr); - if (pGlobalSettings != nullptr) - { - ret = rgXMLUtils::ReadNodeTextString(pChildNode, pGlobalSettings->m_fontFamily); - assert(ret); - if (ret) - { - // Get the font size element. - pChildNode = pChildNode->NextSiblingElement(XML_NODE_GLOBAL_FONT_SIZE); - assert(pChildNode != nullptr); - if (pChildNode != nullptr) - { - // Read the font size element. - unsigned fontSize; - ret = rgXMLUtils::ReadNodeTextUnsigned(pChildNode, fontSize); - assert(ret); - if (ret) - { - pGlobalSettings->m_fontSize = fontSize; - } - } - } - - // Read the include files viewer. - ret = rgXMLUtils::ReadNodeTextString(pChildNode, pGlobalSettings->m_includeFilesViewer); - assert(ret); - - if (!ret) - { - // If we could not read the include files viewer, that's OK. Use the system's default. - ret = true; - pGlobalSettings->m_includeFilesViewer = STR_GLOBAL_SETTINGS_SRC_VIEW_INCLUDE_VIEWER_DEFAULT; - } - } - } - } - return ret; -} - -static bool ExtractSplitterConfigs(tinyxml2::XMLNode* pNode, std::vector& splitterConfigs) -{ - bool ret = false; - - assert(pNode != nullptr); - if (pNode != nullptr) - { - // Get "Layout" node. - pNode = pNode->FirstChildElement(XML_NODE_GLOBAL_GUI_LAYOUT); - - if (pNode != nullptr) - { - // Get "Splitter" node. - pNode = pNode->FirstChildElement(XML_NODE_GLOBAL_GUI_SPLITTER); - - if (pNode == nullptr) - { - // this is a valid scenario if the config file was saved before the user opened a project, which means the splitter values may not have been defined yet. - ret = true; - } - else - { - while (pNode != nullptr) - { - std::string splitterName; - std::string splitterValues; - - // Get splitter name. - tinyxml2::XMLNode* pSplitterNode = pNode->FirstChildElement(XML_NODE_GLOBAL_GUI_SPLITTER_NAME); - ret = rgXMLUtils::ReadNodeTextString(pSplitterNode, splitterName); - - if (!ret) - { - break; - } - - // Get splitter values. - pSplitterNode = pNode->FirstChildElement(XML_NODE_GLOBAL_GUI_SPLITTER_VALUES); - ret = rgXMLUtils::ReadNodeTextString(pSplitterNode, splitterValues); - - if (!ret) - { - break; - } - - std::vector valueStringList; - std::vector valueIntList; - - // Create int list of splitter values from comma separated string. - rgUtils::splitString(splitterValues, rgConfigManager::RGA_LIST_DELIMITER, valueStringList); - for (std::string strValue : valueStringList) - { - valueIntList.push_back(stoi(strValue)); - } - - // Create splitter config object. - rgSplitterConfig splitterConfig; - splitterConfig.m_splitterName = splitterName; - splitterConfig.m_splitterValues = valueIntList; - splitterConfigs.push_back(splitterConfig); - - // Get next "Splitter" node. - pNode = pNode->NextSiblingElement(XML_NODE_GLOBAL_GUI_SPLITTER); - } - } - } - } - - return ret; -} - -static bool ExtractWindowGeometry(tinyxml2::XMLNode* pNode, rgWindowConfig& windowConfig) -{ - bool ret = false; - - assert(pNode != nullptr); - if (pNode != nullptr) - { - // Get "WindowSize" node. - pNode = pNode->FirstChildElement(XML_NODE_GLOBAL_GUI_WINDOW_GEOMETRY); - - if (pNode != nullptr) - { - std::string windowValueStr; - - // Get "WindowWidth" value. - tinyxml2::XMLNode* pWindowSizeNode = pNode->FirstChildElement(XML_NODE_GLOBAL_GUI_WINDOW_WIDTH); - if (pWindowSizeNode != nullptr) - { - ret = rgXMLUtils::ReadNodeTextString(pWindowSizeNode, windowValueStr); - int windowWidth = stoi(windowValueStr); - - // Get "WindowHeight" value. - pWindowSizeNode = pNode->FirstChildElement(XML_NODE_GLOBAL_GUI_WINDOW_HEIGHT); - if (pWindowSizeNode != nullptr) - { - ret = rgXMLUtils::ReadNodeTextString(pWindowSizeNode, windowValueStr); - int windowHeight = stoi(windowValueStr); - - // Get "WindowXPos" value. - pWindowSizeNode = pNode->FirstChildElement(XML_NODE_GLOBAL_GUI_WINDOW_X_POS); - if (pWindowSizeNode != nullptr) - { - ret = rgXMLUtils::ReadNodeTextString(pWindowSizeNode, windowValueStr); - int windowXPos = stoi(windowValueStr); - - // Get "WindowYPos" value. - pWindowSizeNode = pNode->FirstChildElement(XML_NODE_GLOBAL_GUI_WINDOW_Y_POS); - if (pWindowSizeNode != nullptr) - { - ret = rgXMLUtils::ReadNodeTextString(pWindowSizeNode, windowValueStr); - int windowYPos = stoi(windowValueStr); - - // Update window config object. - windowConfig.m_windowHeight = windowHeight; - windowConfig.m_windowWidth = windowWidth; - - // If the position values are negative, fix them here. - if (windowXPos < 0) - { - windowXPos = 0; - } - windowConfig.m_windowXPos = windowXPos; - if (windowYPos < 0) - { - windowYPos = 0; - } - windowConfig.m_windowYPos = windowYPos; - - // Get "WindowState" value. - pWindowSizeNode = pNode->FirstChildElement(XML_NODE_GLOBAL_GUI_WINDOW_STATE); - if (pWindowSizeNode != nullptr) - { - ret = rgXMLUtils::ReadNodeTextString(pWindowSizeNode, windowValueStr); - int windowState = stoi(windowValueStr); - windowConfig.m_windowState = windowState; - } - } - } - } - } - } - } - - return ret; -} - -// Extracts the general build settings in RGA: -// - Target Devices -// - Predefined macros -// - Additional include directories -// - Additional options -bool rgXmlConfigFileReaderImpl::ReadGeneralBuildSettings(tinyxml2::XMLNode* pNode, std::shared_ptr pBuildSettings) -{ - bool ret = false; - if (pNode != nullptr) - { - pNode = pNode->FirstChildElement(XML_NODE_TARGET_DEVICES); - ret = (pNode != nullptr); - assert(ret); - if (ret) - { - std::string targetDevices; - bool hasTargetDevices = rgXMLUtils::ReadNodeTextString(pNode, targetDevices); - if (hasTargetDevices) - { - // Target GPUs. - ExtractTargetGpus(targetDevices, pBuildSettings->m_targetGpus); - ret = (!pBuildSettings->m_targetGpus.empty()); - assert(ret); - } - - if (ret) - { - // Predefined macros. - pNode = pNode->NextSiblingElement(XML_NODE_PREDEFINED_MACROS); - ret = (pNode != nullptr); - assert(ret); - - if (ret) - { - std::string predefinedMacros; - bool shouldRead = rgXMLUtils::ReadNodeTextString(pNode, predefinedMacros); - - if (shouldRead) - { - ExtractPredefinedMacros(predefinedMacros, pBuildSettings->m_predefinedMacros); - } - - // Additional include directories. - pNode = pNode->NextSiblingElement(XML_NODE_ADDITIONAL_INCLUDE_DIRECTORIES); - ret = (pNode != nullptr); - assert(ret); - - if (ret) - { - std::string additionalIncludeDirectories; - shouldRead = rgXMLUtils::ReadNodeTextString(pNode, additionalIncludeDirectories); - if (shouldRead) - { - ExtractAdditionalIncludeDirectories(additionalIncludeDirectories, pBuildSettings->m_additionalIncludeDirectories); - } - - // Read additional build options element. - pNode = pNode->NextSiblingElement(XML_NODE_ADDITIONAL_OPTIONS); - ret = (pNode != nullptr); - assert(ret); - if (pNode != nullptr) - { - rgXMLUtils::ReadNodeTextString(pNode, pBuildSettings->m_additionalOptions); - } - } - } - } - } - } - return ret; -} - -// *** INTERNALLY-LINKED AUXILIARY FUNCTIONS - END *** - -// Factory for creating the relevant config file reader in runtime. -class rgXMLConfigFileReaderImplFactory -{ -public: - static std::shared_ptr CreateReader(const std::string& apiName) - { - std::shared_ptr pRet = nullptr; - if (apiName.compare(STR_API_NAME_OPENCL) == 0) - { - pRet = std::make_shared(); - } - else if (apiName.compare(STR_API_NAME_VULKAN) == 0) - { - pRet = std::make_shared(); - } - return pRet; - } -}; - -// Support for reading v2.0 of the project files -static bool ReadProjectConfigFile_2_0(tinyxml2::XMLDocument& doc, const char* pFileDataModelVersion, tinyxml2::XMLNode* pProjectNode, std::shared_ptr& pProject) -{ - bool ret = false; - if (pProjectNode != nullptr) - { - bool isProjectNode = (std::string(XML_NODE_PROJECT).compare(pProjectNode->Value()) == 0); - assert(isProjectNode); - ret = isProjectNode; - if (ret) - { - // Get the relevant API name. - tinyxml2::XMLNode* pNode = pProjectNode->FirstChild(); - bool isProgramApiNode = (pNode != nullptr) && (std::string(XML_NODE_API_NAME).compare(pNode->Value()) == 0); - assert(isProgramApiNode); - ret = isProgramApiNode; - if (ret) - { - std::string apiName; - ret = rgXMLUtils::ReadNodeTextString(pNode, apiName); - - // Create the concrete config file reader for the relevant API. - std::shared_ptr pReader = rgXMLConfigFileReaderImplFactory::CreateReader(apiName); - if (pReader != nullptr) - { - // Let the concrete parser handle the configuration. - ret = pReader->ReadProjectConfigFile(doc, pFileDataModelVersion, pProject); - assert(ret && pProject != nullptr); - } - } - } - } - - return ret; -} - -bool rgXmlConfigFile::ReadProjectConfigFile(const std::string& configFilePath, std::shared_ptr& pProject) -{ - bool ret = false; - - // Reset the output variable. - pProject = nullptr; - - // Load the XML document. - tinyxml2::XMLDocument doc; - tinyxml2::XMLError rc = doc.LoadFile(configFilePath.c_str()); - - if (rc == tinyxml2::XML_SUCCESS) - { - // Get the XML declaration node. - tinyxml2::XMLNode* pNode = doc.FirstChild(); - if (pNode != nullptr) - { - // Get the RGA Data Model version item. - pNode = pNode->NextSibling(); - if (pNode != nullptr) - { - tinyxml2::XMLElement* pElem = pNode->ToElement(); - if (pElem != nullptr) - { - // Get the data model version in order to verify - // that the project file is compatible. - const char* pDataModelVersion = pNode->ToElement()->GetText(); - - // All v2.0 and v2.1 project files have the same format - // for the initial and tags. - if (RGA_DATA_MODEL_2_0.compare(pDataModelVersion) == 0 || - RGA_DATA_MODEL_2_1.compare(pDataModelVersion) == 0 || - RGA_DATA_MODEL_2_2.compare(pDataModelVersion) == 0) - { - // Skip to the node. - pNode = pNode->NextSibling(); - ret = ReadProjectConfigFile_2_0(doc, pDataModelVersion, pNode, pProject); - } - else - { - assert(!"RGA Data Model version is not supported"); - ret = false; - } - - if (ret) - { - // Set the project file path. - pProject->m_projectFileFullPath = configFilePath; - } - } - } - } - } - - return ret; -} - -// *************************** -// *** WRITER AREA - BEGIN *** -// *************************** - -bool rgXmlConfigFileWriterImpl::WriteGeneralBuildSettings(const std::shared_ptr pBuildSettings, tinyxml2::XMLDocument& doc, tinyxml2::XMLElement* pBuildSettingsElement) -{ - bool ret = false; - - assert(pBuildSettings != nullptr); - assert(pBuildSettingsElement != nullptr); - if (pBuildSettings != nullptr && pBuildSettingsElement != nullptr) - { - // Target devices. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElement, XML_NODE_TARGET_DEVICES, rgUtils::BuildSemicolonSeparatedStringList(pBuildSettings->m_targetGpus).c_str()); - - // Predefined Macros. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElement, XML_NODE_PREDEFINED_MACROS, rgUtils::BuildSemicolonSeparatedStringList(pBuildSettings->m_predefinedMacros).c_str()); - - // Additional include directories. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElement, XML_NODE_ADDITIONAL_INCLUDE_DIRECTORIES, rgUtils::BuildSemicolonSeparatedStringList(pBuildSettings->m_additionalIncludeDirectories).c_str()); - - // Additional options. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElement, XML_NODE_ADDITIONAL_OPTIONS, pBuildSettings->m_additionalOptions.c_str()); - - ret = true; - } - - return ret; -} - -void rgXmlConfigFileWriterImpl::AddConfigFileDeclaration(tinyxml2::XMLDocument& doc) -{ - tinyxml2::XMLNode* pNode = doc.NewDeclaration(RGA_XML_DECLARATION); - doc.InsertEndChild(pNode); - - // Create the Data Model Version element. - tinyxml2::XMLElement* pElement = doc.NewElement(XML_NODE_DATA_MODEL_VERSION); - pElement->SetText(RGA_DATA_MODEL.c_str()); - doc.LinkEndChild(pElement); -} - -bool rgXmlGraphicsConfigFileReaderImpl::ReadPipeline(tinyxml2::XMLDocument& doc, tinyxml2::XMLNode* pParentClone, - bool isBackupSpv, rgPipelineShaders& pipeline) const -{ - bool ret = false; - - assert(pParentClone != nullptr); - if (pParentClone != nullptr) - { - tinyxml2::XMLElement* pPipelineElement = pParentClone->FirstChildElement(isBackupSpv ? XML_NODE_BACKUP_SPV_ROOT : XML_NODE_PIPELINE_SHADERS_ROOT); - ret = (isBackupSpv || pPipelineElement != nullptr); - assert(ret); - - if (pPipelineElement != nullptr) - { - tinyxml2::XMLNode* pPipelineTypeNode = pPipelineElement->FirstChildElement(XML_NODE_PIPELINE_TYPE); - assert(pPipelineTypeNode != nullptr); - if (pPipelineTypeNode != nullptr) - { - // Read the pipeline type node. - std::string pipelineType; - ret = rgXMLUtils::ReadNodeTextString(pPipelineTypeNode, pipelineType); - - // Lambda that implements reading a single pipeline file path element. - auto ReadPipelineShaderFile = [&](rgPipelineStage stage, const char* tag, std::function f) - { - std::string shaderFullFilePath; - tinyxml2::XMLNode* pNode = pPipelineTypeNode->NextSiblingElement(tag); - if (pNode != nullptr) - { - rgXMLUtils::ReadNodeTextString(pNode, shaderFullFilePath); - f(stage, shaderFullFilePath, pipeline); - } - }; - - if (ret && (pipelineType.compare(XML_NODE_PIPELINE_TYPE_GRAPHICS) == 0)) - { - // Create a new graphics pipeline object. - pipeline.m_type = rgPipelineType::Graphics; - - // Read the paths to shader input files. - ReadPipelineShaderFile(rgPipelineStage::Vertex, XML_NODE_PIPELINE_VERTEX_STAGE, rgUtils::SetStageShaderPath); - ReadPipelineShaderFile(rgPipelineStage::TessellationControl, XML_NODE_PIPELINE_TESS_CONTROL_STAGE, rgUtils::SetStageShaderPath); - ReadPipelineShaderFile(rgPipelineStage::TessellationEvaluation, XML_NODE_PIPELINE_TESS_EVAL_STAGE, rgUtils::SetStageShaderPath); - ReadPipelineShaderFile(rgPipelineStage::Geometry, XML_NODE_PIPELINE_GEOMETRY_STAGE, rgUtils::SetStageShaderPath); - ReadPipelineShaderFile(rgPipelineStage::Fragment, XML_NODE_PIPELINE_FRAGMENT_STAGE, rgUtils::SetStageShaderPath); - } - else if (ret && (pipelineType.compare(XML_NODE_PIPELINE_TYPE_COMPUTE) == 0)) - { - // Create a new compute pipeline object. - pipeline.m_type = rgPipelineType::Compute; - - // Read the compute shader input file. - ReadPipelineShaderFile(rgPipelineStage::Compute, XML_NODE_PIPELINE_COMPUTE_STAGE, rgUtils::SetStageShaderPath); - } - else - { - assert(false); - } - } - } - } - return ret; -} - -bool rgXmlGraphicsConfigFileReaderImpl::ReadPipelineState(std::shared_ptr pClone, tinyxml2::XMLDocument& doc, tinyxml2::XMLNode* pPipelineStateElement) const -{ - bool ret = false; - - // Find the project clone's pipeline state root element. - assert(pPipelineStateElement != nullptr); - if (pPipelineStateElement != nullptr) - { - // Find the first pipeline state element. - tinyxml2::XMLNode* pPipelineStateNode = pPipelineStateElement->FirstChildElement(XML_NODE_PIPELINE_STATE); - - if (pPipelineStateNode != nullptr) - { - // Loop over each state node to read the pipeline properties. - do - { - if (pPipelineStateNode != nullptr) - { - rgPipelineState state; - - // Read the PSO name. - tinyxml2::XMLNode* pPsoNameNode = pPipelineStateNode->FirstChildElement(XML_NODE_PIPELINE_NAME); - rgXMLUtils::ReadNodeTextString(pPsoNameNode, state.m_name); - - // Read the "is active" flag. - tinyxml2::XMLNode* pIsActiveNode = pPipelineStateNode->FirstChildElement(XML_NODE_PIPELINE_IS_ACTIVE); - rgXMLUtils::ReadNodeTextBool(pIsActiveNode, state.m_isActive); - - // Read the pipeline state file path. - tinyxml2::XMLNode* pPipelineStateFilePathNode = pPipelineStateNode->FirstChildElement(XML_NODE_PIPELINE_STATE_FILE_PATH); - rgXMLUtils::ReadNodeTextString(pPipelineStateFilePathNode, state.m_pipelineStateFilePath); - - // Read the original pipeline state file path. - tinyxml2::XMLNode* pOrigPipelineStateFilePathNode = pPipelineStateNode->FirstChildElement(XML_NODE_ORIGINAL_PIPELINE_STATE_FILE_PATH); - rgXMLUtils::ReadNodeTextString(pOrigPipelineStateFilePathNode, state.m_originalPipelineStateFilePath); - - pClone->m_psoStates.push_back(state); - } - - // Try to move on to processing the next state node. - pPipelineStateNode = pPipelineStateNode->NextSiblingElement(XML_NODE_PIPELINE_STATE); - - } while (pPipelineStateNode != nullptr); - } - - ret = true; - } - - return ret; -} - -bool rgXmlGraphicsConfigFileWriterImpl::WritePipeline(tinyxml2::XMLDocument& doc, tinyxml2::XMLElement* pParentClone, - bool isBackupSpv, const rgPipelineShaders& pipeline) const -{ - bool ret = false; - - assert(pParentClone != nullptr); - if (pParentClone != nullptr) - { - // Create the project clone's pipeline root element. - tinyxml2::XMLElement* pPipelineNode = doc.NewElement(isBackupSpv ? XML_NODE_BACKUP_SPV_ROOT : XML_NODE_PIPELINE_SHADERS_ROOT); - - assert(pPipelineNode != nullptr); - if (pPipelineNode != nullptr) - { - bool isGraphicsPipeline = pipeline.m_type == rgPipelineType::Graphics; - const char* pPipelineType = isGraphicsPipeline ? XML_NODE_PIPELINE_TYPE_GRAPHICS : XML_NODE_PIPELINE_TYPE_COMPUTE; - rgXMLUtils::AppendXMLElement(doc, pPipelineNode, XML_NODE_PIPELINE_TYPE, pPipelineType); - - // Lambda that implements writing a single pipeline file path element. - auto AppendPipelineShaderFile = [&](rgPipelineStage stage, const char* tag, std::function f) - { - std::string shaderPath; - if (f(pipeline, stage, shaderPath)) - { - rgXMLUtils::AppendXMLElement(doc, pPipelineNode, tag, shaderPath.c_str()); - } - }; - - if (isGraphicsPipeline) - { - - // Append each graphics pipeline shader stage's input file. - AppendPipelineShaderFile(rgPipelineStage::Vertex, XML_NODE_PIPELINE_VERTEX_STAGE, rgUtils::GetStageShaderPath); - AppendPipelineShaderFile(rgPipelineStage::TessellationControl, XML_NODE_PIPELINE_TESS_CONTROL_STAGE, rgUtils::GetStageShaderPath); - AppendPipelineShaderFile(rgPipelineStage::TessellationEvaluation, XML_NODE_PIPELINE_TESS_EVAL_STAGE, rgUtils::GetStageShaderPath); - AppendPipelineShaderFile(rgPipelineStage::Geometry, XML_NODE_PIPELINE_GEOMETRY_STAGE, rgUtils::GetStageShaderPath); - AppendPipelineShaderFile(rgPipelineStage::Fragment, XML_NODE_PIPELINE_FRAGMENT_STAGE, rgUtils::GetStageShaderPath); - } - else - { - // Append the pipeline's compute shader input file. - AppendPipelineShaderFile(rgPipelineStage::Compute, XML_NODE_PIPELINE_COMPUTE_STAGE, rgUtils::GetStageShaderPath); - } - - // Insert the pipeline element into the parent clone element. - pParentClone->InsertEndChild(pPipelineNode); - ret = true; - } - } - - return ret; -} - -bool rgXmlGraphicsConfigFileWriterImpl::WritePipelineState(const std::shared_ptr pClone, tinyxml2::XMLDocument& doc, tinyxml2::XMLElement* pParentCloneElement) const -{ - bool ret = false; - - assert(pClone != nullptr); - assert(pParentCloneElement != nullptr); - if (pClone != nullptr && pParentCloneElement != nullptr) - { - tinyxml2::XMLElement* pPipelineStateRoot = doc.NewElement(XML_NODE_PIPELINE_STATE_ROOT); - - assert(pPipelineStateRoot != nullptr); - if (pPipelineStateRoot != nullptr) - { - // Loop over each pipeline state in the clone. - for (auto pipelineState : pClone->m_psoStates) - { - // Create a new element for writing each state info. - tinyxml2::XMLElement* pPipelineStateElement = doc.NewElement(XML_NODE_PIPELINE_STATE); - - // Append the state name, the active flag, and the pipeline state file path data. - rgXMLUtils::AppendXMLElement(doc, pPipelineStateElement, XML_NODE_PIPELINE_NAME, pipelineState.m_name.c_str()); - rgXMLUtils::AppendXMLElement(doc, pPipelineStateElement, XML_NODE_PIPELINE_IS_ACTIVE, pipelineState.m_isActive); - rgXMLUtils::AppendXMLElement(doc, pPipelineStateElement, XML_NODE_PIPELINE_STATE_FILE_PATH, pipelineState.m_pipelineStateFilePath.data()); - rgXMLUtils::AppendXMLElement(doc, pPipelineStateElement, XML_NODE_ORIGINAL_PIPELINE_STATE_FILE_PATH, pipelineState.m_originalPipelineStateFilePath.data()); - - // Insert the state into the list of pipeline states. - pPipelineStateRoot->InsertEndChild(pPipelineStateElement); - } - - // Insert the pipeline state element in the project clone. - pParentCloneElement->InsertEndChild(pPipelineStateRoot); - - ret = true; - } - } - - return ret; -} - -class ConfigFileWriterFactory -{ -public: - static std::shared_ptr CreateWriter(rgProjectAPI api) - { - std::shared_ptr pRet = nullptr; - switch (api) - { - case rgProjectAPI::OpenCL: - pRet = std::make_shared(); - break; - case rgProjectAPI::Vulkan: - pRet = std::make_shared(); - break; - case rgProjectAPI::Unknown: - default: - // If we got here, there's a problem because the API type is unrecognized. - assert(false); - break; - } - return pRet; - } -}; - -bool rgXmlConfigFile::WriteProjectConfigFile(const rgProject& project, const std::string& configFilePath) -{ - bool ret = false; - - std::shared_ptr pWriter = ConfigFileWriterFactory::CreateWriter(project.m_api); - if (pWriter != nullptr) - { - ret = pWriter->WriteProjectConfigFile(project, configFilePath); - } - - return ret; -} - -// ************************* -// *** WRITER AREA - END *** -// ************************* - -// ************************** -// Global configuration file. -// ************************** -bool rgXmlConfigFile::ReadGlobalSettings(const std::string& globalConfigFilePath, std::shared_ptr& pGlobalSettings) -{ - bool ret = false; - - // Reset the output variable. - pGlobalSettings = std::make_shared(); - - // Load the XML document. - tinyxml2::XMLDocument doc; - tinyxml2::XMLError rc = doc.LoadFile(globalConfigFilePath.c_str()); - - if (rc == tinyxml2::XML_SUCCESS) - { - // Get the XML declaration node. - tinyxml2::XMLNode* pNode = doc.FirstChild(); - if (pNode != nullptr) - { - // Get the RGA Data Model version element. - pNode = pNode->NextSibling(); - if (pNode != nullptr) - { - tinyxml2::XMLElement* pElem = pNode->ToElement(); - if (pElem != nullptr) - { - // Determine which data model version to load. - const char* pDataModelVersion = pNode->ToElement()->GetText(); - rgConfigManager::Instance().SetConfigFileDataModelVersion(pDataModelVersion); - try - { - if (RGA_DATA_MODEL_2_0.compare(pDataModelVersion) == 0) - { - // Get next sibling, which should be the GlobalSettings element. - tinyxml2::XMLNode* pGlobalSettingsNode = pNode->NextSibling(); - ret = ExtractGlobalSettings_2_0(pGlobalSettingsNode, pGlobalSettings); - } - else if (RGA_DATA_MODEL_2_1.compare(pDataModelVersion) == 0) - { - // Get Next sibling, which should be the GlobalSettings element. - tinyxml2::XMLNode* pGlobalSettingsNode = pNode->NextSibling(); - ret = ExtractGlobalSettings_2_1(pGlobalSettingsNode, pGlobalSettings); - } - else if (RGA_DATA_MODEL_2_2.compare(pDataModelVersion) == 0) - { - // Get Next sibling, which should be the GlobalSettings element. - tinyxml2::XMLNode* pGlobalSettingsNode = pNode->NextSibling(); - ret = ExtractGlobalSettings_2_2(pGlobalSettingsNode, pGlobalSettings); - } - else - { - // Data model version is not supported. - ret = false; - } - } - catch (...) - { - ret = false; - } - } - - // Null xml element indicates a read failure at some point. - if (pElem == nullptr) - { - ret = false; - } - } - } - } - - return ret; -} - -bool rgXmlConfigFile::WriteGlobalSettings(std::shared_ptr pGlobalSettings, const std::string& globalConfigFilePath) -{ - assert(pGlobalSettings != nullptr); - - bool ret = false; - - if (pGlobalSettings != nullptr) - { - // Create the XML declaration node. - tinyxml2::XMLDocument doc; - rgXmlConfigFileWriterImpl::AddConfigFileDeclaration(doc); - - // Create the Global Settings element. - tinyxml2::XMLElement* pGlobalSettingsElem = doc.NewElement(XML_NODE_GLOBAL_LOG_FILE_GLOBAL_SETTINGS); - assert(pGlobalSettingsElem != nullptr); - if (pGlobalSettingsElem != nullptr) - { - // Create the log file location element. - rgXMLUtils::AppendXMLElement(doc, pGlobalSettingsElem, XML_NODE_GLOBAL_LOG_FILE_LOCATION, pGlobalSettings->m_logFileLocation.c_str()); - - // Create the last selected directory element. - rgXMLUtils::AppendXMLElement(doc, pGlobalSettingsElem, XML_NODE_GLOBAL_LAST_SELECTED_DIRECTORY, pGlobalSettings->m_lastSelectedDirectory.c_str()); - - // Create a root node for the list of recent projects. - tinyxml2::XMLElement* pRecentProjectsElem = doc.NewElement(XML_NODE_GLOBAL_RECENT_PROJECTS_ROOT); - assert(pRecentProjectsElem != nullptr); - if (pRecentProjectsElem != nullptr) - { - if (pGlobalSettings->m_recentProjects.size() > 0) - { - for (size_t projectIndex = 0; projectIndex < pGlobalSettings->m_recentProjects.size(); ++projectIndex) - { - tinyxml2::XMLElement* pRecentProjectElem = doc.NewElement(XML_NODE_GLOBAL_RECENT_PROJECT_ROOT); - if (pRecentProjectElem != nullptr) - { - // Save the most recent files, starting at the end of the list. - assert(pGlobalSettings->m_recentProjects[projectIndex] != nullptr); - if (pGlobalSettings->m_recentProjects[projectIndex] != nullptr) - { - const std::string& projectPath = pGlobalSettings->m_recentProjects[projectIndex]->projectPath; - - // Write the project path into the recent project element. - rgXMLUtils::AppendXMLElement(doc, pRecentProjectElem, XML_NODE_GLOBAL_RECENT_PROJECT_PATH, projectPath.c_str()); - - // Save the project api type. - std::string apiType; - bool ok = rgUtils::ProjectAPIToString(pGlobalSettings->m_recentProjects[projectIndex]->apiType, apiType); - assert(ok); - if (ok) - { - // Write the project api type into the recent project element. - rgXMLUtils::AppendXMLElement(doc, pRecentProjectElem, XML_NODE_GLOBAL_RECENT_PROJECT_API, apiType.c_str()); - } - pRecentProjectsElem->InsertEndChild(pRecentProjectElem); - } - } - } - } - - // Add the list of recent projects to the global settings node. - pGlobalSettingsElem->InsertEndChild(pRecentProjectsElem); - } - - // Create a root node for the font type and size. - tinyxml2::XMLElement* pFontFamilyElement = doc.NewElement(XML_NODE_GLOBAL_FONT_FAMILY_ROOT); - assert(pFontFamilyElement != nullptr); - if (pFontFamilyElement != nullptr) - { - // Write the font family into the font element. - rgXMLUtils::AppendXMLElement(doc, pFontFamilyElement, XML_NODE_GLOBAL_FONT_FAMILY_TYPE, pGlobalSettings->m_fontFamily.c_str()); - - // Write the font size into the font element. - rgXMLUtils::AppendXMLElement(doc, pFontFamilyElement, XML_NODE_GLOBAL_FONT_SIZE, pGlobalSettings->m_fontSize); - - // Add the font element to the global settings node. - pGlobalSettingsElem->InsertEndChild(pFontFamilyElement); - } - - // Write the include files viewer. - rgXMLUtils::AppendXMLElement(doc, pGlobalSettingsElem, XML_NODE_GLOBAL_INCLUDE_FILES_VIEWER, pGlobalSettings->m_includeFilesViewer.c_str()); - - // Create a comma-separated list from the column names that we have. - std::string disassemblyColumnStr = rgUtils::BuildSemicolonSeparatedBoolList(pGlobalSettings->m_visibleDisassemblyViewColumns); - rgXMLUtils::AppendXMLElement(doc, pGlobalSettingsElem, XML_NODE_GLOBAL_DISASSEMBLY_COLUMNS, disassemblyColumnStr.c_str()); - - // An element used to determine if project names will be generated or provided by the user. - rgXMLUtils::AppendXMLElement(doc, pGlobalSettingsElem, XML_NODE_USE_GENERATED_PROJECT_NAMES, pGlobalSettings->m_useDefaultProjectName); - - rgXMLUtils::AppendXMLElement(doc, pGlobalSettingsElem, XML_NODE_GLOBAL_DEFAULT_API, static_cast(pGlobalSettings->m_defaultAPI)); - - rgXMLUtils::AppendXMLElement(doc, pGlobalSettingsElem, XML_NODE_GLOBAL_PROMPT_FOR_API, pGlobalSettings->m_shouldPromptForAPI); - - rgXMLUtils::AppendXMLElement(doc, pGlobalSettingsElem, XML_NODE_GLOBAL_INPUT_FILE_EXT_GLSL, pGlobalSettings->m_inputFileExtGlsl.c_str()); - rgXMLUtils::AppendXMLElement(doc, pGlobalSettingsElem, XML_NODE_GLOBAL_INPUT_FILE_EXT_HLSL, pGlobalSettings->m_inputFileExtHlsl.c_str()); - rgXMLUtils::AppendXMLElement(doc, pGlobalSettingsElem, XML_NODE_GLOBAL_INPUT_FILE_EXT_SPV_TXT, pGlobalSettings->m_inputFileExtSpvTxt.c_str()); - rgXMLUtils::AppendXMLElement(doc, pGlobalSettingsElem, XML_NODE_GLOBAL_INPUT_FILE_EXT_SPV_BIN, pGlobalSettings->m_inputFileExtSpvBin.c_str()); - - rgXMLUtils::AppendXMLElement(doc, pGlobalSettingsElem, XML_NODE_GLOBAL_DEFAULT_SRC_LANG, (uint32_t)pGlobalSettings->m_defaultLang); - - // Create "GUI" element. - tinyxml2::XMLElement* pGuiElement = doc.NewElement(XML_NODE_GLOBAL_GUI); - assert(pGuiElement != nullptr); - if (pGuiElement != nullptr) - { - // Create "Layout" element. - tinyxml2::XMLElement* pLayoutElement = doc.NewElement(XML_NODE_GLOBAL_GUI_LAYOUT); - assert(pLayoutElement != nullptr); - if (pLayoutElement != nullptr) - { - if (pGlobalSettings->m_guiLayoutSplitters.size() > 0) - { - for (rgSplitterConfig splitterConfig : pGlobalSettings->m_guiLayoutSplitters) - { - // Create "Splitter" element. - tinyxml2::XMLElement* pSplitterElement = doc.NewElement(XML_NODE_GLOBAL_GUI_SPLITTER); - assert(pSplitterElement != nullptr); - if (pSplitterElement != nullptr) - { - // Add "SplitterName" element. - rgXMLUtils::AppendXMLElement(doc, pSplitterElement, XML_NODE_GLOBAL_GUI_SPLITTER_NAME, splitterConfig.m_splitterName.c_str()); - - // Add "SplitterValues" element. - std::string splitterValuesStr = rgUtils::BuildSemicolonSeparatedIntList(splitterConfig.m_splitterValues); - rgXMLUtils::AppendXMLElement(doc, pSplitterElement, XML_NODE_GLOBAL_GUI_SPLITTER_VALUES, splitterValuesStr.c_str()); - - // End of "Splitter" element. - pLayoutElement->InsertEndChild(pSplitterElement); - } - } - } - - // End of "Layout" element. - pGuiElement->InsertEndChild(pLayoutElement); - } - - // Create WindowSize element. - tinyxml2::XMLElement* pWindowSizeElement = doc.NewElement(XML_NODE_GLOBAL_GUI_WINDOW_GEOMETRY); - assert(pWindowSizeElement != nullptr); - if (pWindowSizeElement != nullptr) - { - // Add window X position element. - rgXMLUtils::AppendXMLElement(doc, pWindowSizeElement, XML_NODE_GLOBAL_GUI_WINDOW_X_POS, pGlobalSettings->m_guiWindowConfig.m_windowXPos); - - // Add window Y position element. - rgXMLUtils::AppendXMLElement(doc, pWindowSizeElement, XML_NODE_GLOBAL_GUI_WINDOW_Y_POS, pGlobalSettings->m_guiWindowConfig.m_windowYPos); - - // Add window width element. - rgXMLUtils::AppendXMLElement(doc, pWindowSizeElement, XML_NODE_GLOBAL_GUI_WINDOW_WIDTH, pGlobalSettings->m_guiWindowConfig.m_windowWidth); - - // Add window height element. - rgXMLUtils::AppendXMLElement(doc, pWindowSizeElement, XML_NODE_GLOBAL_GUI_WINDOW_HEIGHT, pGlobalSettings->m_guiWindowConfig.m_windowHeight); - - // Add window state. - rgXMLUtils::AppendXMLElement(doc, pWindowSizeElement, XML_NODE_GLOBAL_GUI_WINDOW_STATE, pGlobalSettings->m_guiWindowConfig.m_windowState); - - pGuiElement->InsertEndChild(pWindowSizeElement); - } - - // End of "GUI" element. - pGlobalSettingsElem->InsertEndChild(pGuiElement); - } - - // Add the Global Settings element to the document. - doc.InsertEndChild(pGlobalSettingsElem); - - // Create the Default Build Settings element. - tinyxml2::XMLElement* pDefaultBuildSettings = doc.NewElement(XML_NODE_GLOBAL_DEFAULT_BUILD_SETTINGS); - if (pDefaultBuildSettings != nullptr) - { - // Loop through each API type, and use an API-specific rgConfigFileWriter to write the default settings. - for (int apiIndex = static_cast(rgProjectAPI::OpenCL); apiIndex < static_cast(rgProjectAPI::ApiCount); ++apiIndex) - { - rgProjectAPI currentApi = static_cast(apiIndex); - - std::string apiString; - bool isOk = rgUtils::ProjectAPIToString(currentApi, apiString); - assert(isOk); - if (isOk) - { - std::shared_ptr pWriter = ConfigFileWriterFactory::CreateWriter(currentApi); - assert(pWriter != nullptr); - if (pWriter != nullptr) - { - // Add the new API element. - tinyxml2::XMLElement* pApiDefaultSettings = doc.NewElement(apiString.c_str()); - - // Create the Build Settings element for the API. - tinyxml2::XMLElement* pBuildSettingsNode = doc.NewElement(XML_NODE_BUILD_SETTINGS); - assert(pBuildSettingsNode != nullptr); - if (pBuildSettingsNode != nullptr) - { - // Write the API-specific default build settings element. - std::shared_ptr pDefaultApiBuildSettings = pGlobalSettings->m_pDefaultBuildSettings[apiString]; - assert(pDefaultApiBuildSettings != nullptr); - if (pDefaultApiBuildSettings != nullptr) - { - ret = pWriter->WriteBuildSettingsElement(pDefaultApiBuildSettings, doc, pBuildSettingsNode); - } - - // Insert the build settings node into the API parent node. - pApiDefaultSettings->InsertEndChild(pBuildSettingsNode); - } - - // Insert the OpenCL-specific default build settings element to the document. - pDefaultBuildSettings->InsertEndChild(pApiDefaultSettings); - } - } - } - - // Insert the Default Build Settings element to the document. - doc.InsertEndChild(pDefaultBuildSettings); - - // Save the configuration file. - tinyxml2::XMLError rc = doc.SaveFile(globalConfigFilePath.c_str()); - if (rc == tinyxml2::XML_SUCCESS) - { - ret = true; - } - assert(ret); - } - } - } - return ret; -} - -static bool ExtractDefaultBuildSettings_2_0(tinyxml2::XMLNode* pDefaultBuildSettingsNode, std::shared_ptr& pGlobalSettings) -{ - assert(pDefaultBuildSettingsNode != nullptr); - assert(pGlobalSettings != nullptr); - - // Make sure this is actually the DefaultBuildSettings node. - bool ret = ((pGlobalSettings != nullptr) && - (pDefaultBuildSettingsNode != nullptr) && - (std::strcmp(pDefaultBuildSettingsNode->Value(), XML_NODE_GLOBAL_DEFAULT_BUILD_SETTINGS) == 0)); - - if (ret) - { - // Get the OpenCL default build settings element. - tinyxml2::XMLNode* pOpenclNode = pDefaultBuildSettingsNode->FirstChildElement(STR_API_NAME_OPENCL); - if (pOpenclNode != nullptr) - { - tinyxml2::XMLElement* pElem = pOpenclNode->FirstChildElement(XML_NODE_BUILD_SETTINGS); - assert(pElem != nullptr); - ret = pElem != nullptr; - if (ret) - { - // Use the API-specific factory to create an API-specific build settings object. - std::shared_ptr pApiFactory = rgFactory::CreateFactory(rgProjectAPI::OpenCL); - assert(pApiFactory != nullptr); - ret = pApiFactory != nullptr; - if (pApiFactory != nullptr) - { - std::shared_ptr pApiBuildSettings = pApiFactory->CreateBuildSettings(nullptr); - assert(pApiBuildSettings != nullptr); - ret = pApiBuildSettings != nullptr; - if (pApiBuildSettings != nullptr) - { - // Create an API-specific build settings instance and parser object to read the settings. - std::shared_ptr pReader = rgXMLConfigFileReaderImplFactory::CreateReader(STR_API_NAME_OPENCL); - assert(pReader != nullptr); - ret = pReader != nullptr; - if (pReader != nullptr) - { - tinyxml2::XMLNode* pBuildSettingsNode = pOpenclNode->FirstChildElement(XML_NODE_BUILD_SETTINGS); - assert(pBuildSettingsNode != nullptr); - ret = pBuildSettingsNode != nullptr; - if (pBuildSettingsNode != nullptr) - { - // Extract the build settings common to all APIs. - ret = pReader->ReadGeneralBuildSettings(pBuildSettingsNode, pApiBuildSettings); - assert(ret); - - // Extract the default build settings. - const std::string version = rgConfigManager::Instance().GetConfigFileDataModelVersion(); - ret = pReader->ReadApiBuildSettings(pBuildSettingsNode, pApiBuildSettings, version); - assert(ret); - - // Store the default OpenCL build settings in our data object. - pGlobalSettings->m_pDefaultBuildSettings[STR_API_NAME_OPENCL] = pApiBuildSettings; - } - } - } - } - } - } - } - - return ret; -} - -static bool ExtractDefaultBuildSettings_2_1(tinyxml2::XMLNode* pDefaultBuildSettingsNode, std::shared_ptr& pGlobalSettings) -{ - assert(pDefaultBuildSettingsNode != nullptr); - assert(pGlobalSettings != nullptr); - - // Make sure this is actually the DefaultBuildSettings node - bool ret = ((pGlobalSettings != nullptr) && - (pDefaultBuildSettingsNode != nullptr) && - (std::strcmp(pDefaultBuildSettingsNode->Value(), XML_NODE_GLOBAL_DEFAULT_BUILD_SETTINGS) == 0)); - - if (ret) - { - // Get the first default build settings element. - tinyxml2::XMLNode* pApiSettingsNode = pDefaultBuildSettingsNode->FirstChildElement(); - - // Loop through each possible API type and read each API's default build settings. - for (int apiIndex = static_cast(rgProjectAPI::OpenCL); apiIndex < static_cast(rgProjectAPI::ApiCount); ++apiIndex) - { - if (pApiSettingsNode == nullptr) - { - // If there are missing APIs from the config file, just break from the loop. - break; - } - else - { - rgProjectAPI currentApi = static_cast(apiIndex); - - std::string apiString; - bool isOk = rgUtils::ProjectAPIToString(currentApi, apiString); - assert(isOk); - if (isOk) - { - // Use the API-specific factory to create an API-specific build settings object. - std::shared_ptr pApiFactory = rgFactory::CreateFactory(currentApi); - assert(pApiFactory != nullptr); - ret = pApiFactory != nullptr; - if (pApiFactory != nullptr) - { - std::shared_ptr pApiBuildSettings = pApiFactory->CreateBuildSettings(nullptr); - assert(pApiBuildSettings != nullptr); - ret = pApiBuildSettings != nullptr; - if (pApiBuildSettings != nullptr) - { - // Create an API-specific build settings instance and parser object to read the settings. - std::shared_ptr pReader = rgXMLConfigFileReaderImplFactory::CreateReader(apiString.c_str()); - assert(pReader != nullptr); - ret = pReader != nullptr; - if (pReader != nullptr) - { - tinyxml2::XMLNode* pBuildSettingsNode = pApiSettingsNode->FirstChildElement(XML_NODE_BUILD_SETTINGS); - assert(pBuildSettingsNode != nullptr); - ret = pBuildSettingsNode != nullptr; - if (pBuildSettingsNode != nullptr && pBuildSettingsNode->FirstChild() != nullptr) - { - // Extract the build settings common to all APIs. - ret = pReader->ReadGeneralBuildSettings(pBuildSettingsNode, pApiBuildSettings); - assert(ret); - - // Extract the API-specific default build settings. - const std::string version = rgConfigManager::Instance().GetConfigFileDataModelVersion(); - bool hasApiBuildSettings = pReader->ReadApiBuildSettings(pBuildSettingsNode, pApiBuildSettings, version); - - // TEMP: we don't have any valid Vulkan settings, so this can't be a required read. - if (apiIndex == static_cast(rgProjectAPI::Vulkan)) - { - // This is temporarily okay for VUlkan until we get some Vulkan-specific build settings. - } - else - { - // OpenCL, or possibly an error case. - assert(hasApiBuildSettings); - ret = hasApiBuildSettings; - } - - // Store the default API-specific build settings in our data object. - pGlobalSettings->m_pDefaultBuildSettings[apiString] = pApiBuildSettings; - } - } - } - } - } - - // Advance to the next API-specific build settings node. - pApiSettingsNode = pApiSettingsNode->NextSibling(); - } - } - } - - return ret; -} - -static bool ExtractGlobalSettings_2_0(tinyxml2::XMLNode* pGlobalSettingsNode, std::shared_ptr& pGlobalSettings) -{ - assert(pGlobalSettingsNode != nullptr); - assert(pGlobalSettings != nullptr); - - // Make sure this is actually the GlobalSettings nodes. - bool ret = ((pGlobalSettings != nullptr) && - (pGlobalSettingsNode != nullptr) && - (std::strcmp(pGlobalSettingsNode->Value(), XML_NODE_GLOBAL_LOG_FILE_GLOBAL_SETTINGS) == 0)); - - if (ret) - { - // Read the global settings. - tinyxml2::XMLElement* pElem = pGlobalSettingsNode->FirstChildElement(XML_NODE_GLOBAL_LOG_FILE_LOCATION); - if (ret && pElem != nullptr) - { - // Read the log file location. - ret = rgXMLUtils::ReadNodeTextString(pElem, pGlobalSettings->m_logFileLocation); - - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_LAST_SELECTED_DIRECTORY); - if (ret && pElem != nullptr) - { - // Attempt to read the last selected directory. It might be empty, in which case the call returns false, and that's ok. - rgXMLUtils::ReadNodeTextString(pElem, pGlobalSettings->m_lastSelectedDirectory); - - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_RECENT_PROJECTS_ROOT); - if (ret && pElem != nullptr) - { - // Read the list of recently-accessed projects. - ret = ExtractRecentProjects(pElem, pGlobalSettings->m_recentProjects); - - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_DISASSEMBLY_COLUMNS); - if (ret && pElem != nullptr) - { - // Get the disassembly columns as a single string. - std::string tmpDisassemblyColumns; - ret = rgXMLUtils::ReadNodeTextString(pElem, tmpDisassemblyColumns); - - // Parse the disassembly columns string, and save the items in the data object. - ExtractDisassemblyColumns(tmpDisassemblyColumns, pGlobalSettings->m_visibleDisassemblyViewColumns); - - // Read the option that determines if the project names are generated or provided by the user. - pElem = pElem->NextSiblingElement(XML_NODE_USE_GENERATED_PROJECT_NAMES); - if (ret && pElem != nullptr) - { - ret = rgXMLUtils::ReadNodeTextBool(pElem, pGlobalSettings->m_useDefaultProjectName); - assert(ret); - - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_GUI); - if (ret && pElem != nullptr) - { - // Extract splitter config objects from the "GUI" node. - ret = ExtractSplitterConfigs(pElem, pGlobalSettings->m_guiLayoutSplitters); - } - } - } - } - } - } - - // If the Global Settings could be read, then attempt to read the Default Build Settings. - if (ret) - { - tinyxml2::XMLNode* pDefaultBuildSettingsNode = pGlobalSettingsNode->NextSibling(); - ret = ExtractDefaultBuildSettings_2_0(pDefaultBuildSettingsNode, pGlobalSettings); - } - } - - return ret; -} - -static bool ExtractGlobalSettings_2_1(tinyxml2::XMLNode* pGlobalSettingsNode, std::shared_ptr& pGlobalSettings) -{ - // Make sure this is actually the GlobalSettings nodes. - tinyxml2::XMLElement* pElem = nullptr; - bool ret = (std::strcmp(pGlobalSettingsNode->Value(), XML_NODE_GLOBAL_LOG_FILE_GLOBAL_SETTINGS) == 0); - - if (ret) - { - // Read the log file location. - pElem = pGlobalSettingsNode->FirstChildElement(XML_NODE_GLOBAL_LOG_FILE_LOCATION); - ret = pElem != nullptr; - ret = ret && rgXMLUtils::ReadNodeTextString(pElem, pGlobalSettings->m_logFileLocation); - - // If the saved log directory does not exist, fall back to using the default one. - if (!rgUtils::IsDirExists(pGlobalSettings->m_logFileLocation)) - { - std::string appDataDir; - rgConfigManager::GetDefaultDataFolder(appDataDir); - pGlobalSettings->m_logFileLocation = appDataDir; - } - } - if (ret) - { - // Attempt to read the last selected directory. It might be empty, in which case the call returns false, and that's ok. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_LAST_SELECTED_DIRECTORY); - ret &= (pElem != nullptr); - if (ret) - { - rgXMLUtils::ReadNodeTextString(pElem, pGlobalSettings->m_lastSelectedDirectory); - } - } - if (ret) - { - // Read the list of recently-accessed projects. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_RECENT_PROJECTS_ROOT); - ret &= (pElem != nullptr); - ret = ret && ExtractRecentProjects(pElem, pGlobalSettings->m_recentProjects); - } - if (ret) - { - // Extract font family and size information. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_FONT_FAMILY_ROOT); - ret &= (pElem != nullptr); - ret = ret && ExtractFontInformation(pElem, pGlobalSettings); - } - if (ret) - { - // Extract default include files viewer. - // Before we move on keep the current node in case that we fail reading this node. - auto pElemBeforeRead = pElem; - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_INCLUDE_FILES_VIEWER); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextString(pElem, pGlobalSettings->m_includeFilesViewer); - if (!ret) - { - // If we couldn't read it from the file, just use the default. - pGlobalSettings->m_includeFilesViewer = STR_GLOBAL_SETTINGS_SRC_VIEW_INCLUDE_VIEWER_DEFAULT; - - // Roll back so that the next element read would be performed from the correct location. - pElem = pElemBeforeRead; - ret = true; - } - } - if (ret) - { - // Get the disassembly columns as a single string. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_DISASSEMBLY_COLUMNS); - ret &= (pElem != nullptr); - std::string tmpDisassemblyColumns; - ret = ret && rgXMLUtils::ReadNodeTextString(pElem, tmpDisassemblyColumns); - - // Parse the disassembly columns string, and save the items in the data object. - if (ret) - { - ExtractDisassemblyColumns(tmpDisassemblyColumns, pGlobalSettings->m_visibleDisassemblyViewColumns); - } - } - if (ret) - { - // Read the option that determines if the project names are generated or provided by the user. - pElem = pElem->NextSiblingElement(XML_NODE_USE_GENERATED_PROJECT_NAMES); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextBool(pElem, pGlobalSettings->m_useDefaultProjectName); - } - if (ret) - { - // Read the default API. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_DEFAULT_API); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextUnsigned(pElem, (unsigned int&)pGlobalSettings->m_defaultAPI); - } - if (ret) - { - // Read the "Should prompt for API" setting. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_PROMPT_FOR_API); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextBool(pElem, pGlobalSettings->m_shouldPromptForAPI); - } - if (ret) - { - // Read the input file associations. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_INPUT_FILE_EXT_GLSL); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextString(pElem, pGlobalSettings->m_inputFileExtGlsl); - if (ret) - { - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_INPUT_FILE_EXT_HLSL); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextString(pElem, pGlobalSettings->m_inputFileExtHlsl); - } - if (ret) - { - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_INPUT_FILE_EXT_SPV_TXT); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextString(pElem, pGlobalSettings->m_inputFileExtSpvTxt); - } - if (ret) - { - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_INPUT_FILE_EXT_SPV_BIN); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextString(pElem, pGlobalSettings->m_inputFileExtSpvBin); - } - } - if (ret) - { - // Read the default source language. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_DEFAULT_SRC_LANG); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextUnsigned(pElem, (uint32_t&)pGlobalSettings->m_defaultLang); - } - if (ret) - { - // Extract splitter config objects from the "GUI" node. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_GUI); - ret &= (pElem != nullptr); - ret = ret && ExtractSplitterConfigs(pElem, pGlobalSettings->m_guiLayoutSplitters); - } - - // If the Global Settings could be read, then attempt to read the Default Build Settings. - if (ret) - { - tinyxml2::XMLNode* pDefaultBuildSettingsNode = pGlobalSettingsNode->NextSibling(); - ret = ExtractDefaultBuildSettings_2_1(pDefaultBuildSettingsNode, pGlobalSettings); - } - - return ret; -} - -static bool ExtractGlobalSettings_2_2(tinyxml2::XMLNode* pGlobalSettingsNode, std::shared_ptr& pGlobalSettings) -{ - // Make sure this is actually the GlobalSettings nodes. - tinyxml2::XMLElement* pElem = nullptr; - bool ret = (std::strcmp(pGlobalSettingsNode->Value(), XML_NODE_GLOBAL_LOG_FILE_GLOBAL_SETTINGS) == 0); - - if (ret) - { - // Read the log file location. - pElem = pGlobalSettingsNode->FirstChildElement(XML_NODE_GLOBAL_LOG_FILE_LOCATION); - ret = pElem != nullptr; - ret = ret && rgXMLUtils::ReadNodeTextString(pElem, pGlobalSettings->m_logFileLocation); - - // If the saved log directory does not exist, fall back to using the default one. - if (!rgUtils::IsDirExists(pGlobalSettings->m_logFileLocation)) - { - std::string appDataDir; - rgConfigManager::GetDefaultDataFolder(appDataDir); - pGlobalSettings->m_logFileLocation = appDataDir; - } - } - if (ret) - { - // Attempt to read the last selected directory. It might be empty, in which case the call returns false, and that's ok. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_LAST_SELECTED_DIRECTORY); - ret &= (pElem != nullptr); - if (ret) - { - rgXMLUtils::ReadNodeTextString(pElem, pGlobalSettings->m_lastSelectedDirectory); - } - } - if (ret) - { - // Read the list of recently-accessed projects. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_RECENT_PROJECTS_ROOT); - ret &= (pElem != nullptr); - ret = ret && ExtractRecentProjects(pElem, pGlobalSettings->m_recentProjects); - } - if (ret) - { - // Extract font family and size information. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_FONT_FAMILY_ROOT); - ret &= (pElem != nullptr); - ret = ret && ExtractFontInformation(pElem, pGlobalSettings); - } - if (ret) - { - // Extract default include files viewer. - // Before we move on keep the current node in case that we fail reading this node. - auto pElemBeforeRead = pElem; - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_INCLUDE_FILES_VIEWER); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextString(pElem, pGlobalSettings->m_includeFilesViewer); - if (!ret) - { - // If we couldn't read it from the file, just use the default. - pGlobalSettings->m_includeFilesViewer = STR_GLOBAL_SETTINGS_SRC_VIEW_INCLUDE_VIEWER_DEFAULT; - - // Roll back so that the next element read would be performed from the correct location. - pElem = pElemBeforeRead; - ret = true; - } - } - if (ret) - { - // Get the disassembly columns as a single string. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_DISASSEMBLY_COLUMNS); - ret &= (pElem != nullptr); - std::string tmpDisassemblyColumns; - ret = ret && rgXMLUtils::ReadNodeTextString(pElem, tmpDisassemblyColumns); - - // Parse the disassembly columns string, and save the items in the data object. - if (ret) - { - ExtractDisassemblyColumns(tmpDisassemblyColumns, pGlobalSettings->m_visibleDisassemblyViewColumns); - } - } - if (ret) - { - // Read the option that determines if the project names are generated or provided by the user. - pElem = pElem->NextSiblingElement(XML_NODE_USE_GENERATED_PROJECT_NAMES); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextBool(pElem, pGlobalSettings->m_useDefaultProjectName); - } - if (ret) - { - // Read the default API. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_DEFAULT_API); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextUnsigned(pElem, (unsigned int&)pGlobalSettings->m_defaultAPI); - } - if (ret) - { - // Read the "Should prompt for API" setting. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_PROMPT_FOR_API); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextBool(pElem, pGlobalSettings->m_shouldPromptForAPI); - } - if (ret) - { - // Read the input file associations. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_INPUT_FILE_EXT_GLSL); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextString(pElem, pGlobalSettings->m_inputFileExtGlsl); - if (ret) - { - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_INPUT_FILE_EXT_HLSL); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextString(pElem, pGlobalSettings->m_inputFileExtHlsl); - } - if (ret) - { - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_INPUT_FILE_EXT_SPV_TXT); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextString(pElem, pGlobalSettings->m_inputFileExtSpvTxt); - } - if (ret) - { - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_INPUT_FILE_EXT_SPV_BIN); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextString(pElem, pGlobalSettings->m_inputFileExtSpvBin); - } - } - if (ret) - { - // Read the default source language. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_DEFAULT_SRC_LANG); - ret &= (pElem != nullptr); - ret = ret && rgXMLUtils::ReadNodeTextUnsigned(pElem, (uint32_t&)pGlobalSettings->m_defaultLang); - } - if (ret) - { - // Extract splitter config objects from the "GUI" node. - pElem = pElem->NextSiblingElement(XML_NODE_GLOBAL_GUI); - ret &= (pElem != nullptr); - ret = ret && ExtractSplitterConfigs(pElem, pGlobalSettings->m_guiLayoutSplitters); - } - if (ret) - { - // Extract window size config objects from the "GUI" node. - ret = ret && ExtractWindowGeometry(pElem, pGlobalSettings->m_guiWindowConfig); - } - - // If the Global Settings could be read, then attempt to read the Default Build Settings. - if (ret) - { - tinyxml2::XMLNode* pDefaultBuildSettingsNode = pGlobalSettingsNode->NextSibling(); - ret = ExtractDefaultBuildSettings_2_1(pDefaultBuildSettingsNode, pGlobalSettings); - } - - return ret; -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgConfigFileOpenCL.cpp b/RadeonGPUAnalyzerGUI/Src/rgConfigFileOpenCL.cpp deleted file mode 100644 index a946691..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgConfigFileOpenCL.cpp +++ /dev/null @@ -1,393 +0,0 @@ -// C++> -#include -#include - -// Infra. -#include - -// Local. -#include -#include -#include -#include - -bool rgConfigFileReaderOpenCL::ReadProjectConfigFile(tinyxml2::XMLDocument& doc, const char* pFileDataModelVersion, std::shared_ptr& pRgaProject) -{ - // Version 2.2 requires processing of binary output file, which - // is handled later. - bool isVersionCompatible = - (RGA_DATA_MODEL_2_0.compare(pFileDataModelVersion) == 0) || - (RGA_DATA_MODEL_2_1.compare(pFileDataModelVersion) == 0) || - (RGA_DATA_MODEL_2_2.compare(pFileDataModelVersion) == 0); - - assert(isVersionCompatible); - - bool ret = false; - pRgaProject = nullptr; - - if (isVersionCompatible) - { - // Find the project node. - tinyxml2::XMLNode* pNode = doc.FirstChildElement(XML_NODE_PROJECT); - if (pNode != nullptr) - { - pNode = pNode->FirstChild(); - - // Verify that this is an OpenCL API config file. - std::string pApiName; - ret = rgXMLUtils::ReadNodeTextString(pNode, pApiName); - if (ret && (pApiName.compare(STR_API_NAME_OPENCL) == 0) && pNode != nullptr) - { - // Go to the project name node. - pNode = pNode->NextSibling(); - - // Get the project name. - std::string projectName; - ret = rgXMLUtils::ReadNodeTextString(pNode, projectName); - if (!projectName.empty() && pNode != nullptr) - { - // Create the RGA project object. - std::shared_ptr pOpenCLProject = std::make_shared(); - pOpenCLProject->m_projectName = projectName; - pOpenCLProject->m_projectDataModelVersion = pFileDataModelVersion; - pRgaProject = pOpenCLProject; - - // Iterate through the project's clones: get the first clone. - pNode = pNode->NextSibling(); - tinyxml2::XMLNode* pClonesRoot = pNode; - - while (pClonesRoot != nullptr) - { - // Get the clone ID. - pNode = pClonesRoot->FirstChildElement(XML_NODE_CLONE_ID); - std::shared_ptr pClone = std::make_shared(); - ret = rgXMLUtils::ReadNodeTextUnsigned(pNode, pClone->m_cloneId); - if (ret && pNode != nullptr) - { - // Get the name of the clone. - pNode = pNode->NextSibling(); - - ret = rgXMLUtils::ReadNodeTextString(pNode, pClone->m_cloneName); - if (ret) - { - // Get the files in this clone. - pNode = pNode->NextSibling(); - tinyxml2::XMLElement* pFileNode = pNode->FirstChildElement(); - while (pFileNode != nullptr) - { - // Extract the full path of the current file. - std::string sourceFileInfoString; - ret = rgXMLUtils::ReadNodeTextString(pFileNode, sourceFileInfoString); - assert(ret); - if (ret && !sourceFileInfoString.empty()) - { - rgSourceFileInfo newSourceFile = {}; - newSourceFile.m_filePath = sourceFileInfoString; - - // Add the file path to our clone object. - pClone->m_sourceFiles.push_back(newSourceFile); - } - - // Go to the next file. - pFileNode = pFileNode->NextSiblingElement(); - } - - // Get the OpenCL build settings. - pNode = pNode->NextSiblingElement(XML_NODE_BUILD_SETTINGS); - std::shared_ptr pBuildSettings = std::make_shared(); - assert(pBuildSettings != nullptr); - if (pBuildSettings != nullptr) - { - // Read the general build settings that aren't specific to a single API. - ret = ret && ReadGeneralBuildSettings(pNode, pBuildSettings); - assert(ret); - if (ret) - { - // Read the build settings that apply only to API. - ret = ret && ReadApiBuildSettings(pNode, pBuildSettings, pOpenCLProject->m_projectDataModelVersion); - assert(ret); - if (ret) - { - // Add the build settings to the project clone. - pClone->m_pBuildSettings = pBuildSettings; - - // We are done, add this clone to the project object. - pOpenCLProject->m_clones.push_back(pClone); - } - } - } - } - } - - // Go to the next clone element. - pClonesRoot = pClonesRoot->NextSibling(); - } - } - } - } - } - - return ret; -} - -bool rgConfigFileReaderOpenCL::ReadApiBuildSettings(tinyxml2::XMLNode* pNode, std::shared_ptr pBuildSettings, const std::string& version) -{ - bool ret = false; - - const std::shared_ptr pBuildSettingsOpenCL = std::dynamic_pointer_cast(pBuildSettings); - - if (pNode != nullptr) - { - // OpenCL optimization level. - pNode = pNode->FirstChildElement(XML_NODE_OPENCL_OPT_LEVEL); - ret = rgXMLUtils::ReadNodeTextString(pNode, pBuildSettingsOpenCL->m_optimizationLevel); - } - - if (ret && pNode != nullptr) - { - // Double as single. - pNode = pNode->NextSiblingElement(XML_NODE_OPENCL_DOUBLE_AS_SINGLE); - ret = rgXMLUtils::ReadNodeTextBool(pNode, pBuildSettingsOpenCL->m_isTreatDoubleAsSingle); - } - - if (ret && pNode != nullptr) - { - // Denorms as zeros. - pNode = pNode->NextSiblingElement(XML_NODE_OPENCL_DENORMS_AS_ZEROS); - ret = rgXMLUtils::ReadNodeTextBool(pNode, pBuildSettingsOpenCL->m_isDenormsAsZeros); - } - - if (ret && pNode != nullptr) - { - // Strict aliasing. - pNode = pNode->NextSiblingElement(XML_NODE_OPENCL_STRICT_ALIASING); - ret = rgXMLUtils::ReadNodeTextBool(pNode, pBuildSettingsOpenCL->m_isStrictAliasing); - } - - if (ret && pNode != nullptr) - { - // Enable MAD. - pNode = pNode->NextSiblingElement(XML_NODE_OPENCL_ENABLE_MAD); - ret = rgXMLUtils::ReadNodeTextBool(pNode, pBuildSettingsOpenCL->m_isEnableMAD); - } - - if (ret && pNode != nullptr) - { - // Ignore zero signedness. - pNode = pNode->NextSiblingElement(XML_NODE_OPENCL_IGNORE_ZERO_SIGNEDNESS); - ret = rgXMLUtils::ReadNodeTextBool(pNode, pBuildSettingsOpenCL->m_isIgnoreZeroSignedness); - } - - if (ret && pNode != nullptr) - { - // Unsafe optimizations. - pNode = pNode->NextSiblingElement(XML_NODE_OPENCL_UNSAFE_OPT); - ret = rgXMLUtils::ReadNodeTextBool(pNode, pBuildSettingsOpenCL->m_isUnsafeOptimizations); - } - - if (ret && pNode != nullptr) - { - // Non NaN nor Infinite. - pNode = pNode->NextSiblingElement(XML_NODE_OPENCL_NO_NAN_NOR_INF); - ret = rgXMLUtils::ReadNodeTextBool(pNode, pBuildSettingsOpenCL->m_isNoNanNorInfinite); - } - - if (ret && pNode != nullptr) - { - // Aggressive math optimizations. - pNode = pNode->NextSiblingElement(XML_NODE_OPENCL_AGGRESSIVE_MATH_OPT); - ret = rgXMLUtils::ReadNodeTextBool(pNode, pBuildSettingsOpenCL->m_isAggressiveMathOptimizations); - } - - if (ret && pNode != nullptr) - { - // Correctly round div / sqrt. - pNode = pNode->NextSiblingElement(XML_NODE_OPENCL_CORRECT_ROUND_DIV_SQRT); - ret = rgXMLUtils::ReadNodeTextBool(pNode, pBuildSettingsOpenCL->m_isCorrectlyRoundDivSqrt); - } - - if (ret) - { - // Alternative compiler paths. - if (pNode != nullptr) - { - pNode = pNode->NextSiblingElement(XML_NODE_ALTERNATIVE_COMPILER_BIN_DIR); - rgXMLUtils::ReadNodeTextString(pNode, std::get(pBuildSettingsOpenCL->m_compilerPaths)); - } - if (pNode != nullptr) - { - pNode = pNode->NextSiblingElement(XML_NODE_ALTERNATIVE_COMPILER_INC_DIR); - rgXMLUtils::ReadNodeTextString(pNode, std::get(pBuildSettingsOpenCL->m_compilerPaths)); - } - if (pNode != nullptr) - { - pNode = pNode->NextSiblingElement(XML_NODE_ALTERNATIVE_COMPILER_LIB_DIR); - rgXMLUtils::ReadNodeTextString(pNode, std::get(pBuildSettingsOpenCL->m_compilerPaths)); - } - } - - return ret; -} - -bool rgConfigFileWriterOpenCL::WriteProjectConfigFile(const rgProject& project, const std::string& configFilePath) -{ - bool ret = false; - - // Create the XML declaration node. - tinyxml2::XMLDocument doc; - AddConfigFileDeclaration(doc); - - // Create the Project element. - tinyxml2::XMLElement* pProject = doc.NewElement(XML_NODE_PROJECT); - tinyxml2::XMLElement* pApi = doc.NewElement(XML_NODE_API_NAME); - std::string apiName; - ret = rgUtils::ProjectAPIToString(project.m_api, apiName); - if (ret) - { - // API name. - pApi->SetText(apiName.c_str()); - pProject->InsertFirstChild(pApi); - - // Project name. - tinyxml2::XMLElement* pProjectName = doc.NewElement(XML_NODE_PROJECT_NAME); - pProjectName->SetText(project.m_projectName.c_str()); - pProject->InsertEndChild(pProjectName); - - // Handle the project's clones. - std::vector cloneElems; - const rgProjectOpenCL& clProject = static_cast(project); - WriteOpenCLCloneElements(clProject, doc, cloneElems); - for (tinyxml2::XMLElement* pCloneElem : cloneElems) - { - pProject->LinkEndChild(pCloneElem); - } - - // Add the project node. - doc.InsertEndChild(pProject); - - // Save the file. - tinyxml2::XMLError rc = doc.SaveFile(configFilePath.c_str()); - ret = (rc == tinyxml2::XML_SUCCESS); - assert(ret); - } - - return ret; -} - -bool rgConfigFileWriterOpenCL::WriteBuildSettingsElement(const std::shared_ptr pBuildSettings, tinyxml2::XMLDocument& doc, tinyxml2::XMLElement*& pBuildSettingsElem) -{ - bool ret = false; - - assert(pBuildSettings != nullptr); - if (pBuildSettings != nullptr) - { - const std::shared_ptr pBuildSettingsOpenCL = std::dynamic_pointer_cast(pBuildSettings); - assert(pBuildSettingsOpenCL != nullptr); - - if (pBuildSettingsElem != nullptr && pBuildSettingsOpenCL != nullptr) - { - // Write API-agnostic build settings. - WriteGeneralBuildSettings(pBuildSettingsOpenCL, doc, pBuildSettingsElem); - - // Optimization Level. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_OPENCL_OPT_LEVEL, pBuildSettingsOpenCL->m_optimizationLevel.c_str()); - - // Treat Double As Single. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_OPENCL_DOUBLE_AS_SINGLE, pBuildSettingsOpenCL->m_isTreatDoubleAsSingle); - - // Denorms As Zeros. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_OPENCL_DENORMS_AS_ZEROS, pBuildSettingsOpenCL->m_isDenormsAsZeros); - - // Strict Aliasing. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_OPENCL_STRICT_ALIASING, pBuildSettingsOpenCL->m_isStrictAliasing); - - // Enable MAD. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_OPENCL_ENABLE_MAD, pBuildSettingsOpenCL->m_isEnableMAD); - - // Ignore Zero Signedness. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_OPENCL_IGNORE_ZERO_SIGNEDNESS, pBuildSettingsOpenCL->m_isIgnoreZeroSignedness); - - // Unsafe Optimizations. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_OPENCL_UNSAFE_OPT, pBuildSettingsOpenCL->m_isUnsafeOptimizations); - - // No Nan Nor Infinite. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_OPENCL_NO_NAN_NOR_INF, pBuildSettingsOpenCL->m_isNoNanNorInfinite); - - // Aggressive Math Optimizations. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_OPENCL_AGGRESSIVE_MATH_OPT, pBuildSettingsOpenCL->m_isAggressiveMathOptimizations); - - // Correctly Round Div Sqrt. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_OPENCL_CORRECT_ROUND_DIV_SQRT, pBuildSettingsOpenCL->m_isCorrectlyRoundDivSqrt); - - // Alternative compiler paths. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_ALTERNATIVE_COMPILER_BIN_DIR, std::get(pBuildSettingsOpenCL->m_compilerPaths).c_str()); - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_ALTERNATIVE_COMPILER_INC_DIR, std::get(pBuildSettingsOpenCL->m_compilerPaths).c_str()); - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_ALTERNATIVE_COMPILER_LIB_DIR, std::get(pBuildSettingsOpenCL->m_compilerPaths).c_str()); - - // Add the Build Settings element its parent. - doc.InsertEndChild(pBuildSettingsElem); - - ret = true; - } - } - - return ret; -} - -bool rgConfigFileWriterOpenCL::WriteOpenCLCloneElements(const rgProjectOpenCL& project, tinyxml2::XMLDocument& doc, std::vector& elems) -{ - bool ret = false; - - for (const std::shared_ptr& pClone : project.m_clones) - { - if (pClone != nullptr) - { - // Project clone. - tinyxml2::XMLElement* pCloneElement = doc.NewElement(XML_NODE_CLONE); - - // Clone ID. - tinyxml2::XMLElement* pCloneId = doc.NewElement(XML_NODE_CLONE_ID); - pCloneId->SetText(pClone->m_cloneId); - pCloneElement->LinkEndChild(pCloneId); - - // Clone name. - tinyxml2::XMLElement* pCloneName = doc.NewElement(XML_NODE_CLONE_NAME); - pCloneName->SetText(pClone->m_cloneName.c_str()); - pCloneElement->LinkEndChild(pCloneName); - - // Source files. - tinyxml2::XMLElement* pCloneSourceFiles = doc.NewElement(XML_NODE_CLONE_SOURCE_FILES); - - // Go through each and every source file, and create its element. - for (const rgSourceFileInfo& sourceFileInfo : pClone->m_sourceFiles) - { - // Create the file element. - tinyxml2::XMLElement* pFilePath = doc.NewElement(XML_NODE_FILE_PATH); - - std::stringstream fileStatusStream; - fileStatusStream << sourceFileInfo.m_filePath; - - pFilePath->SetText(fileStatusStream.str().c_str()); - - // Attach the file element to the Source Files node. - pCloneSourceFiles->LinkEndChild(pFilePath); - } - - // Add the Source Files node to the Clone element. - pCloneElement->LinkEndChild(pCloneSourceFiles); - - // Build settings. - tinyxml2::XMLElement* pBuildSettings = doc.NewElement(XML_NODE_BUILD_SETTINGS); - ret = WriteBuildSettingsElement(pClone->m_pBuildSettings, doc, pBuildSettings); - - if (ret) - { - pCloneElement->LinkEndChild(pBuildSettings); - elems.push_back(pCloneElement); - ret = true; - } - } - } - - return ret; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgConfigFileVulkan.cpp b/RadeonGPUAnalyzerGUI/Src/rgConfigFileVulkan.cpp deleted file mode 100644 index e6e1a95..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgConfigFileVulkan.cpp +++ /dev/null @@ -1,437 +0,0 @@ -// C++. -#include -#include -#include - -// Infra. -#include - -// Local. -#include -#include -#include -#include - -bool rgConfigFileReaderVulkan::ReadProjectClone(tinyxml2::XMLDocument& doc, tinyxml2::XMLNode* pClonesRoot, std::shared_ptr& pVulkanProject) -{ - // Get the clone ID. - tinyxml2::XMLNode* pNode = pClonesRoot->FirstChildElement(XML_NODE_CLONE_ID); - std::shared_ptr pClone = std::make_shared(); - bool ret = rgXMLUtils::ReadNodeTextUnsigned(pNode, pClone->m_cloneId); - if (ret && pNode != nullptr) - { - // Get the name of the clone. - pNode = pNode->NextSibling(); - ret = rgXMLUtils::ReadNodeTextString(pNode, pClone->m_cloneName); - } - - // Read the pipeline object. - ret = ret && ReadPipeline(doc, pClonesRoot, false , pClone->m_pipeline); - assert(ret); - - // Read the backup SPIR-V binary paths (optional). - ret = ret && ReadPipeline(doc, pClonesRoot, true, pClone->m_spvBackup); - assert(ret); - - if (ret) - { - // Create a Vulkan build settings object. - std::shared_ptr pBuildSettings = std::make_shared(); - assert(pBuildSettings != nullptr); - if ((ret = pBuildSettings != nullptr) == true) - { - // Read the pipeline state. - pNode = pNode->NextSiblingElement(XML_NODE_PIPELINE_STATE_ROOT); - assert(pNode != nullptr); - ret = (pNode != nullptr); - } - - ret = ret && ReadPipelineState(pClone, doc, pNode); - assert(ret); - - if (ret) - { - // Get the Vulkan build settings. - pNode = pNode->NextSiblingElement(XML_NODE_BUILD_SETTINGS); - assert(pNode != nullptr); - ret = pNode != nullptr; - } - - // Read the general build settings that aren't specific to a single API. - ret = ret && ReadGeneralBuildSettings(pNode, pBuildSettings); - assert(ret); - - // Read the build settings that apply only to Vulkan. - ret = ret && ReadApiBuildSettings(pNode, pBuildSettings, pVulkanProject->m_projectDataModelVersion); - assert(ret); - - if (ret) - { - // Add the build settings to the project clone. - pClone->m_pBuildSettings = pBuildSettings; - - // We are done, add this clone to the project object. - pVulkanProject->m_clones.push_back(pClone); - } - } - - return ret; -} - -bool rgConfigFileReaderVulkan::ReadProjectConfigFile(tinyxml2::XMLDocument& doc, const char* pFileDataModelVersion, std::shared_ptr& pRgaProject) -{ - // The config files are the same format for v2.0 and v2.1. - // Version 2.2 requires processing of binary output file, which - // is handled later. - bool isVersionCompatible = - (RGA_DATA_MODEL_2_0.compare(pFileDataModelVersion) == 0) || - (RGA_DATA_MODEL_2_1.compare(pFileDataModelVersion) == 0) || - (RGA_DATA_MODEL_2_2.compare(pFileDataModelVersion) == 0); - - assert(isVersionCompatible); - - bool ret = false; - pRgaProject = nullptr; - - if (isVersionCompatible) - { - // Find the project node. - tinyxml2::XMLNode* pNode = doc.FirstChildElement(XML_NODE_PROJECT); - if (pNode != nullptr) - { - pNode = pNode->FirstChild(); - - // Verify that this is an Vulkan API config file. - std::string pApiName; - ret = rgXMLUtils::ReadNodeTextString(pNode, pApiName); - if (ret && (pApiName.compare(STR_API_NAME_VULKAN) == 0) && pNode != nullptr) - { - // Go to the project name node. - pNode = pNode->NextSibling(); - - // Get the project name. - std::string projectName; - ret = rgXMLUtils::ReadNodeTextString(pNode, projectName); - if (!projectName.empty() && pNode != nullptr) - { - // Create the RGA project object. - std::shared_ptr pVulkanProject = std::make_shared(); - pVulkanProject->m_projectName = projectName; - pVulkanProject->m_projectDataModelVersion = pFileDataModelVersion; - pRgaProject = pVulkanProject; - - // Iterate through the project's clones: get the first clone. - pNode = pNode->NextSibling(); - tinyxml2::XMLNode* pClonesRoot = pNode; - - while (ret && pClonesRoot != nullptr) - { - // Read the project clone data. - ret = ReadProjectClone(doc, pClonesRoot, pVulkanProject); - - // Go to the next clone element. - pClonesRoot = pClonesRoot->NextSibling(); - } - } - } - } - } - - return ret; -} - -bool rgConfigFileReaderVulkan::ReadApiBuildSettings(tinyxml2::XMLNode* pNode, std::shared_ptr pBuildSettings, const std::string& version) -{ - bool ret = false; - - assert(pBuildSettings != nullptr); - if (pBuildSettings != nullptr) - { - const std::shared_ptr pBuildSettingsVulkan = std::dynamic_pointer_cast(pBuildSettings); - assert(pBuildSettingsVulkan != nullptr); - if (pBuildSettingsVulkan != nullptr) - { - if (RGA_DATA_MODEL_2_2.compare(version) == 0) - { - assert(pNode != nullptr); - if (pNode != nullptr) - { - // Binary output file name. - pNode = pNode->FirstChildElement(XML_NODE_GLOBAL_BINARY_OUTPUT_FILE_NAME); - ret = (pNode != nullptr); - assert(pNode != nullptr); - std::string binaryFileName; - bool shouldRead = rgXMLUtils::ReadNodeTextString(pNode, binaryFileName); - if (shouldRead) - { - pBuildSettingsVulkan->m_binaryFileName = binaryFileName; - } - } - - assert(pNode != nullptr); - if (ret && pNode != nullptr) - { - // Generate Debug Info. - pNode = pNode->NextSiblingElement(XML_NODE_VULKAN_GENERATE_DEBUG_INFO); - ret = rgXMLUtils::ReadNodeTextBool(pNode, pBuildSettingsVulkan->m_isGenerateDebugInfoChecked); - } - } - else - { - // Use the default binary output file name here. - pBuildSettingsVulkan->m_binaryFileName = STR_BUILD_SETTINGS_OUTPUT_BINARY_FILE_NAME; - - assert(pNode != nullptr); - if (pNode != nullptr) - { - // Generate Debug Info. - pNode = pNode->FirstChildElement(XML_NODE_VULKAN_GENERATE_DEBUG_INFO); - ret = rgXMLUtils::ReadNodeTextBool(pNode, pBuildSettingsVulkan->m_isGenerateDebugInfoChecked); - } - } - - if (ret && pNode != nullptr) - { - // No Explicit Bindings. - pNode = pNode->NextSiblingElement(XML_NODE_VULKAN_NO_EXPLICIT_BINDINGS); - ret = rgXMLUtils::ReadNodeTextBool(pNode, pBuildSettingsVulkan->m_isNoExplicitBindingsChecked); - } - - if (ret && pNode != nullptr) - { - // Use HLSL Block Offsets. - pNode = pNode->NextSiblingElement(XML_NODE_VULKAN_USE_HLSL_BLOCK_OFFSETS); - ret = rgXMLUtils::ReadNodeTextBool(pNode, pBuildSettingsVulkan->m_isUseHlslBlockOffsetsChecked); - } - - if (ret && pNode != nullptr) - { - // Use HLSL IO Mapping. - pNode = pNode->NextSiblingElement(XML_NODE_VULKAN_USE_HLSL_IO_MAPPING); - ret = rgXMLUtils::ReadNodeTextBool(pNode, pBuildSettingsVulkan->m_isUseHlslIoMappingChecked); - } - - if (ret && pNode != nullptr) - { - // Get ICD location. - pNode = pNode->NextSiblingElement(XML_NODE_VULKAN_ICD_LOCATION); - ret = (pNode != nullptr); - assert(pNode != nullptr); - - std::string icdLocation; - bool shouldRead = rgXMLUtils::ReadNodeTextString(pNode, icdLocation); - - if (shouldRead) - { - pBuildSettingsVulkan->m_ICDLocation = icdLocation; - } - } - - if (ret && pNode != nullptr) - { - // Use Enable validation layer. - pNode = pNode->NextSiblingElement(XML_NODE_VULKAN_ENABLE_VALIDATION_LAYER); - ret = rgXMLUtils::ReadNodeTextBool(pNode, pBuildSettingsVulkan->m_isEnableValidationLayersChecked); - } - - if (ret && pNode != nullptr) - { - // Remember where we were in case we fail reading. - auto pNodeOriginal = pNode; - - // Get glslang options. - pNode = pNode->NextSiblingElement(XML_NODE_VULKAN_GLSLANG_OPTIONS_LOCATION); - ret = (pNode != nullptr); - if (pNode != nullptr) - { - std::string glslangOptions; - bool shouldRead = rgXMLUtils::ReadNodeTextString(pNode, glslangOptions); - - if (shouldRead) - { - pBuildSettingsVulkan->m_glslangOptions = glslangOptions; - } - } - else - { - // If the rga project file does not have the additional glslang options - // node, that's OK - just assume that they are empty. - ret = true; - - // Roll back to the last node. - pNode = pNodeOriginal; - } - } - - // Alternative compiler paths. - if (ret && pNode != nullptr) - { - // Alternative compiler paths. - if (pNode != nullptr) - { - pNode = pNode->NextSiblingElement(XML_NODE_ALTERNATIVE_COMPILER_BIN_DIR); - rgXMLUtils::ReadNodeTextString(pNode, std::get(pBuildSettingsVulkan->m_compilerPaths)); - } - if (pNode != nullptr) - { - pNode = pNode->NextSiblingElement(XML_NODE_ALTERNATIVE_COMPILER_INC_DIR); - rgXMLUtils::ReadNodeTextString(pNode, std::get(pBuildSettingsVulkan->m_compilerPaths)); - } - if (pNode != nullptr) - { - pNode = pNode->NextSiblingElement(XML_NODE_ALTERNATIVE_COMPILER_LIB_DIR); - rgXMLUtils::ReadNodeTextString(pNode, std::get(pBuildSettingsVulkan->m_compilerPaths)); - } - } - } - } - - return ret; -} - -bool rgConfigFileWriterVulkan::WriteProjectConfigFile(const rgProject& project, const std::string& configFilePath) -{ - bool ret = false; - - // Create the XML declaration node. - tinyxml2::XMLDocument doc; - AddConfigFileDeclaration(doc); - - // Create the Project element. - tinyxml2::XMLElement* pProject = doc.NewElement(XML_NODE_PROJECT); - tinyxml2::XMLElement* pApi = doc.NewElement(XML_NODE_API_NAME); - std::string apiName; - ret = rgUtils::ProjectAPIToString(project.m_api, apiName); - if (ret) - { - // API name. - pApi->SetText(apiName.c_str()); - pProject->InsertFirstChild(pApi); - - // Project name. - tinyxml2::XMLElement* pProjectName = doc.NewElement(XML_NODE_PROJECT_NAME); - pProjectName->SetText(project.m_projectName.c_str()); - pProject->InsertEndChild(pProjectName); - - // Handle the project's clones. - std::vector cloneElems; - const rgProjectVulkan& vulkanProject = static_cast(project); - - WriteCloneElements(vulkanProject, doc, cloneElems); - for (tinyxml2::XMLElement* pCloneElem : cloneElems) - { - pProject->LinkEndChild(pCloneElem); - } - - // Add the project node. - doc.InsertEndChild(pProject); - - // Save the file. - tinyxml2::XMLError rc = doc.SaveFile(configFilePath.c_str()); - ret = (rc == tinyxml2::XML_SUCCESS); - assert(ret); - } - - return ret; -} - -bool rgConfigFileWriterVulkan::WriteBuildSettingsElement(const std::shared_ptr pBuildSettings, tinyxml2::XMLDocument& doc, tinyxml2::XMLElement*& pBuildSettingsElem) -{ - bool ret = false; - - assert(pBuildSettings != nullptr); - if (pBuildSettings != nullptr) - { - const std::shared_ptr pBuildSettingsVulkan = std::dynamic_pointer_cast(pBuildSettings); - assert(pBuildSettingsVulkan != nullptr); - if (pBuildSettingsVulkan != nullptr) - { - // Write API-agnostic build settings. - ret = WriteGeneralBuildSettings(pBuildSettings, doc, pBuildSettingsElem); - - // Write Vulkan-specific settings. - - // Binary output file name. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_GLOBAL_BINARY_OUTPUT_FILE_NAME, pBuildSettingsVulkan->m_binaryFileName.c_str()); - - // Generate debug information. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_VULKAN_GENERATE_DEBUG_INFO, pBuildSettingsVulkan->m_isGenerateDebugInfoChecked); - - // No Explicit Bindings. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_VULKAN_NO_EXPLICIT_BINDINGS, pBuildSettingsVulkan->m_isNoExplicitBindingsChecked); - - // Use HLSL Block Offsets. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_VULKAN_USE_HLSL_BLOCK_OFFSETS, pBuildSettingsVulkan->m_isUseHlslBlockOffsetsChecked); - - // Use HLSL IO Mapping. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_VULKAN_USE_HLSL_IO_MAPPING, pBuildSettingsVulkan->m_isUseHlslIoMappingChecked); - - // ICD location. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_VULKAN_ICD_LOCATION, pBuildSettingsVulkan->m_ICDLocation.c_str()); - - // Enable validation layers. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_VULKAN_ENABLE_VALIDATION_LAYER, pBuildSettingsVulkan->m_isEnableValidationLayersChecked); - - // Glslang additional options. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_VULKAN_GLSLANG_OPTIONS_LOCATION, pBuildSettingsVulkan->m_glslangOptions.c_str()); - - // Alternative compiler paths. - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_ALTERNATIVE_COMPILER_BIN_DIR, std::get(pBuildSettingsVulkan->m_compilerPaths).c_str()); - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_ALTERNATIVE_COMPILER_INC_DIR, std::get(pBuildSettingsVulkan->m_compilerPaths).c_str()); - rgXMLUtils::AppendXMLElement(doc, pBuildSettingsElem, XML_NODE_ALTERNATIVE_COMPILER_LIB_DIR, std::get(pBuildSettingsVulkan->m_compilerPaths).c_str()); - } - } - - return ret; -} - -bool rgConfigFileWriterVulkan::WriteCloneElements(const rgProjectVulkan& project, tinyxml2::XMLDocument& doc, std::vector& elems) -{ - bool ret = false; - - for (const std::shared_ptr& pClone : project.m_clones) - { - std::shared_ptr pVulkanClone = std::dynamic_pointer_cast(pClone); - if (pVulkanClone != nullptr) - { - // Project clone. - tinyxml2::XMLElement* pCloneElement = doc.NewElement(XML_NODE_CLONE); - - // Clone ID. - tinyxml2::XMLElement* pCloneId = doc.NewElement(XML_NODE_CLONE_ID); - pCloneId->SetText(pVulkanClone->m_cloneId); - pCloneElement->LinkEndChild(pCloneId); - - // Clone name. - tinyxml2::XMLElement* pCloneName = doc.NewElement(XML_NODE_CLONE_NAME); - pCloneName->SetText(pVulkanClone->m_cloneName.c_str()); - pCloneElement->LinkEndChild(pCloneName); - - // Write the pipeline input files. - ret = WritePipeline(doc, pCloneElement, false, pVulkanClone->m_pipeline); - - // Write the backup spv files if there are any. - const ShaderInputFileArray& spvBackupFiles = pVulkanClone->m_spvBackup.m_shaderStages; - if (std::find_if(spvBackupFiles.cbegin(), spvBackupFiles.cend(), [&](const std::string& s) {return !s.empty(); }) != spvBackupFiles.cend()) - { - ret = WritePipeline(doc, pCloneElement, true, pVulkanClone->m_spvBackup); - } - - // Build settings. - tinyxml2::XMLElement* pBuildSettings = doc.NewElement(XML_NODE_BUILD_SETTINGS); - ret = ret && WriteBuildSettingsElement(pClone->m_pBuildSettings, doc, pBuildSettings); - - // Write the pipeline state. - ret = ret && WritePipelineState(pVulkanClone, doc, pCloneElement); - - if (ret) - { - pCloneElement->LinkEndChild(pBuildSettings); - elems.push_back(pCloneElement); - ret = true; - } - } - } - - return ret; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgConfigManager.cpp b/RadeonGPUAnalyzerGUI/Src/rgConfigManager.cpp deleted file mode 100644 index 2cba2c1..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgConfigManager.cpp +++ /dev/null @@ -1,1288 +0,0 @@ -// C++. -#include -#include -#include - -// Qt. -#include - -// Infra. -#include -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// The initial API that the application starts in. -static const rgProjectAPI INITIAL_API_TYPE = rgProjectAPI::OpenCL; - -// The maximum number of recent files that the application is aware of. -static const int MAX_RECENT_FILES = 10; - -// The default number of days for log files to be considered as "old". -static const int DEFAULT_OLD_LOG_FILES_DAYS = 3; - -// GUI log file name prefix. -static const char* GUI_LOG_FILE_PREFIX = "rga-gui.log"; - -// CLI log file name prefix. -static const char* CLI_LOG_FILE_PREFIX = "rga-cli.log"; - -struct ProjectPathSearcher -{ - ProjectPathSearcher(const std::string& projectPath) : m_projectPath(projectPath) {} - - // A predicate that will compare each project path with a target path to search for. - bool operator()(const std::shared_ptr pRecentProject) const - { - bool result = false; - assert(pRecentProject != nullptr); - if (pRecentProject != nullptr) - { - result = pRecentProject->projectPath.compare(m_projectPath) == 0; - } - - return result; - } - - // The target project name to search for. - const std::string& m_projectPath; -}; - -// This class creates default configuration-related objects. -class DefaultConfigFactory -{ -public: - // Creates the default build settings for the given API. - static std::shared_ptr GetDefaultBuildSettings(rgProjectAPI api) - { - std::shared_ptr pRet = nullptr; - switch (api) - { - case rgProjectAPI::OpenCL: - pRet = CreateDefaultBuildSettingsOpenCL(); - break; - case rgProjectAPI::Vulkan: - pRet = CreateDefaultBuildSettingsVulkan(); - break; - case rgProjectAPI::Unknown: - default: - break; - } - return pRet; - } - -private: - - // Add default target GPU hardware. Suitable default target GPUs are discovered by looking at - // the list of supported devices and choosing the last item in the list. Items at the end of - // the list are the most recently released products. - static void AddDefaultTargetGpus(std::shared_ptr pBuildSettings, const std::string& apiMode) - { - // Use the version info's list of supported GPUs to determine the most recent - // hardware to build for by default. - rgConfigManager& configManager = rgConfigManager::Instance(); - std::shared_ptr pVersionInfo = configManager.GetVersionInfo(); - - assert(pVersionInfo != nullptr); - if (pVersionInfo != nullptr) - { - const char* kTokenRdna2 = "RDNA2"; - const char* kTokenRdna = "RDNA"; - const char* kTokenVega = "Vega"; - - // Find the set of GPU architectures supported in the current mode. - auto modeArchitecturesIter = pVersionInfo->m_gpuArchitectures.find(apiMode); - if (modeArchitecturesIter != pVersionInfo->m_gpuArchitectures.end()) - { - // Search for the latest target. Start with RDNA2, if not look for RDNA and Vega. As a fall back - // just take the first element. - const std::vector& modeArchitectures = modeArchitecturesIter->second; - auto lastArchitectureIter = std::find_if(modeArchitectures.begin(), modeArchitectures.end(), - [&](const rgGpuArchitecture& arch) { return arch.m_architectureName.compare(kTokenRdna2) == 0; }); - - if (lastArchitectureIter == modeArchitectures.end()) - { - // Search for the latest target. Start with RDNA, if not look for Vega. As a fall back - // just take the first element. - const std::vector& modeArchitectures = modeArchitecturesIter->second; - lastArchitectureIter = std::find_if(modeArchitectures.begin(), modeArchitectures.end(), - [&](const rgGpuArchitecture& arch) { return arch.m_architectureName.compare(kTokenRdna) == 0; }); - - if (lastArchitectureIter == modeArchitectures.end()) - { - lastArchitectureIter = std::find_if(modeArchitectures.begin(), modeArchitectures.end(), - [&](const rgGpuArchitecture& arch) { return arch.m_architectureName.compare(kTokenVega) == 0; }); - if (lastArchitectureIter == modeArchitectures.end()) - { - // Take the first element. - lastArchitectureIter = modeArchitectures.begin(); - - // We shouldn't be getting here normally. - assert(false); - } - } - } - - // Find the last family within the most recent architecture. - std::vector architectureFamilies = lastArchitectureIter->m_gpuFamilies; - std::sort(architectureFamilies.begin(), architectureFamilies.end(), - [&](const rgGpuFamily& family1, const rgGpuFamily& family2) - { - return family1.m_familyName < family2.m_familyName; - }); - - const auto& latestFamily = architectureFamilies.rbegin(); - const std::string& latestFamilyName = latestFamily->m_familyName; - - // Add the latest supported GPU family as the default target GPU. - pBuildSettings->m_targetGpus.push_back(latestFamilyName); - } - } - } - - // Creates the default OpenCL build settings. - static std::shared_ptr CreateDefaultBuildSettingsOpenCL() - { - std::shared_ptr pRet = std::make_shared(); - - assert(pRet != nullptr); - if (pRet != nullptr) - { - AddDefaultTargetGpus(pRet, STR_MODE_STRING_OPENCL); - } - - return pRet; - } - - // Creates the default Vulkan build settings. - static std::shared_ptr CreateDefaultBuildSettingsVulkan() - { - std::shared_ptr pRet = std::make_shared(); - - assert(pRet != nullptr); - if (pRet != nullptr) - { - AddDefaultTargetGpus(pRet, STR_MODE_STRING_VULKAN); - - // Set the default output binary file name. - pRet->m_binaryFileName = STR_BUILD_SETTINGS_OUTPUT_BINARY_FILE_NAME; - } - - return pRet; - } -}; - -// Generates the name of the config file. -static std::string GenConfigFileName() -{ - std::string configFileName = STR_GLOBAL_CONFIG_FILE_NAME_PREFIX; - std::string versionSuffix = std::string("_") + std::to_string(RGA_VERSION_MAJOR) + "_" + std::to_string(RGA_VERSION_MINOR); - configFileName += versionSuffix; - configFileName += "."; - configFileName += STR_GLOBAL_CONFIG_FILE_EXTENSION; - - return configFileName; -} - -bool rgSourceFilePathSearcher::operator()(const rgSourceFileInfo& fileInfo) const -{ - return fileInfo.m_filePath.compare(m_targetFilePath) == 0; -} - -bool rgConfigManager::Init() -{ - if (!m_isInitialized) - { - // Initialize the API used by the rgConfigManager. - m_currentAPI = INITIAL_API_TYPE; - - // Get the path to the default configuration file. - std::string appDataDir, configFileFullPath; - rgConfigManager::GetDefaultDataFolder(appDataDir); - - // If the output directory does not exist - create it. - if (!rgUtils::IsDirExists(appDataDir)) - { - bool isDirCreated = rgUtils::CreateFolder(appDataDir); - assert(isDirCreated); - } - - // If necessary - create the Projects sub-directory. - std::string projectSubDir; - GetDefaultProjectsFolder(projectSubDir); - if (!rgUtils::IsDirExists(projectSubDir)) - { - bool isDirCreated = rgUtils::CreateFolder(projectSubDir); - assert(isDirCreated); - } - - // Attempt to load the version info file cached in the RGA data folder. - std::string versionInfoFilePath; - rgConfigManager::GetDefaultDataFolder(versionInfoFilePath); - rgUtils::AppendFileNameToPath(versionInfoFilePath, STR_VERSION_INFO_FILE_NAME, versionInfoFilePath); - - // Ask the CLI to generate the version info file. - bool isSuccessful = rgCliLauncher::GenerateVersionInfoFile(versionInfoFilePath); - assert(isSuccessful); - - // Read the version info file. - m_pVersionInfo = std::make_shared(); - bool isVersionInfoFileRead = rgXMLCliVersionInfo::ReadVersionInfo(versionInfoFilePath, m_pVersionInfo); - assert(isVersionInfoFileRead); - if (isVersionInfoFileRead) - { - // Append the global configuration file name to the path. - std::string configFileName = GenConfigFileName(); - assert(!configFileName.empty()); - if (!configFileName.empty()) - { - rgUtils::AppendFileNameToPath(appDataDir, configFileName, configFileFullPath); - } - - // Check if the global configuration file exists. If not - create it. - bool isConfigFileExists = rgUtils::IsFileExists(configFileFullPath); - if (isConfigFileExists) - { - // Read the global configuration file and validate the operation's success. - m_isInitialized = rgXmlConfigFile::ReadGlobalSettings(configFileFullPath, m_pGlobalSettings); - - if (!m_isInitialized) - { - // Notify the user in case that we failed to read the config file. - std::stringstream msg; - msg << STR_ERR_FATAL_PREFIX << STR_ERR_CANNOT_READ_CONFIG_FILE_A << configFileFullPath << - std::endl << STR_ERR_DELETE_FILE_AND_RERUN << std::endl << STR_ERR_RGA_WILL_NOW_EXIT; - m_fatalErrorMsg = msg.str(); - } - - m_isInitialized = m_isInitialized && (m_pGlobalSettings != nullptr); - } - - // Write out a default configuration file when one either doesn't exist, or the read fails. - if (!m_isInitialized && m_fatalErrorMsg.empty()) - { - // Create the global configuration file. - m_pGlobalSettings = std::make_shared(); - - // Initialize default values in the new global settings instance. - assert(m_pGlobalSettings != nullptr); - if (m_pGlobalSettings != nullptr) - { - ResetToFactoryDefaults(*m_pGlobalSettings); - } - - // Loop through each supported API and create + store the default build settings for that API. - for (int apiIndex = static_cast(rgProjectAPI::OpenCL); apiIndex < static_cast(rgProjectAPI::ApiCount); ++apiIndex) - { - rgProjectAPI currentApi = static_cast(apiIndex); - - std::string apiString; - bool isOk = rgUtils::ProjectAPIToString(currentApi, apiString); - assert(isOk); - if (isOk) - { - std::shared_ptr pDefaultBuildSettings = GetDefaultBuildSettings(currentApi); - m_pGlobalSettings->m_pDefaultBuildSettings[apiString] = pDefaultBuildSettings; - } - } - - // Write out the new global settings file. - m_isInitialized = rgXmlConfigFile::WriteGlobalSettings(m_pGlobalSettings, configFileFullPath); - } - } - else - { - std::stringstream msg; - msg << STR_ERR_FATAL_PREFIX << STR_ERR_CANNOT_LOAD_VERSION_INFO_FILE << versionInfoFilePath << std::endl << - STR_ERR_DELETE_FILE_AND_RERUN << std::endl << STR_ERR_RGA_WILL_NOW_EXIT; - m_fatalErrorMsg = msg.str(); - rgLog::file << STR_LOG_FAILED_LOAD_VERSION_INFO_FILE << versionInfoFilePath << std::endl; - } - - if (m_isInitialized) - { - // Initialize GUI log file. - std::string logFileDir = (m_pGlobalSettings->m_logFileLocation.empty() ? appDataDir : m_pGlobalSettings->m_logFileLocation); - bool isSuccessful = rgaSharedUtils::InitLogFile(logFileDir, GUI_LOG_FILE_PREFIX, DEFAULT_OLD_LOG_FILES_DAYS); - assert(isSuccessful); - if (isSuccessful) - { - rgLog::file << STR_LOG_RGA_GUI_STARTED << std::endl; - } - - // Construct name for the CLI log file. - std::string cliLogName = rgaSharedUtils::ConstructLogFileName(CLI_LOG_FILE_PREFIX); - assert(!cliLogName.empty()); - if (!cliLogName.empty() && rgUtils::AppendFileNameToPath(appDataDir, cliLogName, cliLogName)) - { - m_cliLogFilePath = cliLogName; - } - - if (!isSuccessful || m_cliLogFilePath.empty()) - { - rgUtils::ShowErrorMessageBox(STR_ERR_CANNOT_OPEN_LOG_FILE); - } - } - } - - return m_isInitialized; -} - -void rgConfigManager::ResetToFactoryDefaults(rgGlobalSettings& globalSettings) -{ - // Initialize the default log file location. - rgConfigManager::GetDefaultDataFolder(globalSettings.m_logFileLocation); - - // Initialize the visible columns in the ISA disassembly table. - // Only the Address, Opcode and Operands columns are visible by default. - globalSettings.m_visibleDisassemblyViewColumns = - { - false, // rgIsaDisassemblyTableColumns::Address - true, // rgIsaDisassemblyTableColumns::Opcode - true, // rgIsaDisassemblyTableColumns::Operands - false, // rgIsaDisassemblyTableColumns::FunctionalUnit - false, // rgIsaDisassemblyTableColumns::Cycles - false, // rgIsaDisassemblyTableColumns::BinaryEncoding - }; - - // Default to always asking the user for a name when creating a new project. - globalSettings.m_useDefaultProjectName = false; - - // Default to always asking the user at startup which API to work in. - globalSettings.m_shouldPromptForAPI = true; - - // This is an odd option, because Unknown isn't actually an option we support in the GUI - // but it is theoretically okay, because by default the user is supposed to select it. - globalSettings.m_defaultAPI = rgProjectAPI::Unknown; - - // Default font family. - globalSettings.m_fontFamily = STR_BUILD_VIEW_FONT_FAMILY; - - // Default font size. - globalSettings.m_fontSize = 10; - - // Default app to open include files. - globalSettings.m_includeFilesViewer = STR_GLOBAL_SETTINGS_SRC_VIEW_INCLUDE_VIEWER_DEFAULT; - - globalSettings.m_inputFileExtGlsl = STR_GLOBAL_SETTINGS_FILE_EXT_GLSL; - globalSettings.m_inputFileExtHlsl = STR_GLOBAL_SETTINGS_FILE_EXT_HLSL; - globalSettings.m_inputFileExtSpvTxt = STR_GLOBAL_SETTINGS_FILE_EXT_SPVAS; - globalSettings.m_inputFileExtSpvBin = STR_GLOBAL_SETTINGS_FILE_EXT_SPV; - - globalSettings.m_defaultLang = rgSrcLanguage::GLSL; -} - -rgConfigManager& rgConfigManager::Instance() -{ - static rgConfigManager m_instance; - return m_instance; -} - -void rgConfigManager::AddSourceFileToProject(const std::string& sourceFilePath, std::shared_ptr pProject, int cloneIndex) const -{ - assert(pProject != nullptr); - if (pProject != nullptr) - { - // Ensure that the incoming clone index is valid for the current project. - bool isValidRange = (cloneIndex >= 0 && cloneIndex < pProject->m_clones.size()); - assert(isValidRange); - - if (isValidRange) - { - bool isPathEmpty = sourceFilePath.empty(); - assert(!isPathEmpty); - if (!isPathEmpty) - { - std::shared_ptr pClone = pProject->m_clones[cloneIndex]; - - // Add a new source file info instance to the list of source files in the clone. - rgSourceFileInfo newSourceFile = {}; - newSourceFile.m_filePath = sourceFilePath; - pClone->m_sourceFiles.push_back(newSourceFile); - } - } - } -} - -void rgConfigManager::AddShaderStage(rgPipelineStage stage, const std::string& sourceFilePath, std::shared_ptr pProject, int cloneIndex) const -{ - assert(pProject != nullptr); - if (pProject != nullptr) - { - // Ensure that the incoming clone index is valid for the current project. - bool isValidRange = (cloneIndex >= 0 && cloneIndex < pProject->m_clones.size()); - assert(isValidRange); - - if (isValidRange) - { - bool isPathEmpty = sourceFilePath.empty(); - assert(!isPathEmpty); - if (!isPathEmpty) - { - std::shared_ptr pClone = pProject->m_clones[cloneIndex]; - - std::shared_ptr pGraphicsClone = - std::dynamic_pointer_cast(pClone); - - // Add a new source file info instance to the list of source files in the clone. - size_t stageIndex = static_cast(stage); - pGraphicsClone->m_pipeline.m_shaderStages[stageIndex] = sourceFilePath; - } - } - } -} - -bool rgConfigManager::GetShaderStageFilePath(rgPipelineStage stage, std::shared_ptr pGraphicsClone, std::string& fullFilePath) const -{ - // Find the input file path for given pipeline stage shader. - size_t stageIndex = static_cast(stage); - const std::string& inputFilePath = pGraphicsClone->m_pipeline.m_shaderStages[stageIndex]; - - bool stageInUse = !inputFilePath.empty(); - if (stageInUse) - { - fullFilePath = inputFilePath; - } - - return stageInUse; -} - -void rgConfigManager::RemoveShaderStage(rgPipelineStage stage, std::shared_ptr pGraphicsClone) const -{ - assert(pGraphicsClone != nullptr); - if (pGraphicsClone != nullptr) - { - // Clear out the path to the input shader file for the given stage. - size_t stageIndex = static_cast(stage); - pGraphicsClone->m_pipeline.m_shaderStages[stageIndex].clear(); - } -} - -rgProjectAPI rgConfigManager::GetCurrentAPI() const -{ - return m_currentAPI; -} - -void rgConfigManager::SetCurrentAPI(rgProjectAPI projectAPI) -{ - m_currentAPI = projectAPI; -} - -void rgConfigManager::SetDefaultAPI(rgProjectAPI defaultAPI) -{ - m_pGlobalSettings->m_defaultAPI = defaultAPI; -} - -void rgConfigManager::SetPromptForAPIAtStartup(bool shouldPrompt) -{ - m_pGlobalSettings->m_shouldPromptForAPI = shouldPrompt; -} - -std::string rgConfigManager::GetCurrentModeString() const -{ - std::string modeString = "Invalid"; - - switch (m_currentAPI) - { - case rgProjectAPI::OpenCL: - modeString = STR_MODE_STRING_OPENCL; - break; - case rgProjectAPI::Vulkan: - modeString = STR_MODE_STRING_VULKAN; - break; - default: - assert(false); - break; - } - - return modeString; -} - -// A predicate used to find a given GPU family name within an ASIC architecture. -struct GpuFamilyNameFinder -{ - GpuFamilyNameFinder(const std::string& targetName) : m_targetName(targetName) {} - - // A predicate that will compare a GPU family's name with a target name. - bool operator()(const rgGpuFamily& gpuFamily) const - { - return gpuFamily.m_familyName.compare(m_targetName) == 0; - } - - // The target family name to search for. - std::string m_targetName; -}; - -bool rgConfigManager::IsGpuFamilySupported(const std::string& familyName) const -{ - bool isSupported = false; - - assert(m_pVersionInfo != nullptr); - if (m_pVersionInfo != nullptr) - { - // Get the list of supported architectures for the current mode. - std::string currentMode = GetCurrentModeString(); - auto gpuArchitectureIter = m_pVersionInfo->m_gpuArchitectures.find(currentMode); - if (gpuArchitectureIter != m_pVersionInfo->m_gpuArchitectures.end()) - { - // Step through each architecture's family list to try to find the given name. - std::vector supportedArchitectures = gpuArchitectureIter->second; - - for (const rgGpuArchitecture& currentArchitecture : supportedArchitectures) - { - const std::vector& families = currentArchitecture.m_gpuFamilies; - - // Search the list of GPU families for the incoming name. - GpuFamilyNameFinder familyNameSearcher(familyName); - auto familySearchIter = std::find_if(families.begin(), families.end(), familyNameSearcher); - if (familySearchIter != families.end()) - { - isSupported = true; - break; - } - } - } - } - - return isSupported; -} - -void rgConfigManager::RemoveSourceFilePath(std::shared_ptr pProject, int cloneIndex, const std::string& sourceFilePath) const -{ - assert(pProject != nullptr); - if (pProject != nullptr) - { - // Ensure that the incoming clone index is valid for the current project. - bool isValidRange = (cloneIndex >= 0 && cloneIndex < pProject->m_clones.size()); - assert(isValidRange); - - if (isValidRange) - { - // Empty the list of source files for the selected clone. - std::shared_ptr pClone = pProject->m_clones[cloneIndex]; - - bool isPathEmpty = sourceFilePath.empty(); - assert(!isPathEmpty); - if (!isPathEmpty) - { - // Search the list of source files in the clone to obtain an iterator to it. - rgSourceFilePathSearcher sourceFileSearcher(sourceFilePath); - auto sourceFileIter = std::find_if(pClone->m_sourceFiles.begin(), pClone->m_sourceFiles.end(), sourceFileSearcher); - bool isFileInList = (sourceFileIter != pClone->m_sourceFiles.end()); - assert(isFileInList); - - // If the path was found in the clone's source files, erase it. - if (isFileInList) - { - pClone->m_sourceFiles.erase(sourceFileIter); - } - } - } - } -} - -void rgConfigManager::GetProjectSourceFilePaths(std::shared_ptr pProject, int cloneIndex, std::vector& sourceFilePaths) const -{ - assert(pProject != nullptr); - if (pProject != nullptr) - { - // Ensure that the incoming clone index is valid for the current project. - bool isValidRange = (cloneIndex >= 0 && cloneIndex < pProject->m_clones.size()); - assert(isValidRange); - - if (isValidRange) - { - std::shared_ptr pClone = pProject->m_clones[cloneIndex]; - for (const rgSourceFileInfo& fileInfo : pClone->m_sourceFiles) - { - sourceFilePaths.push_back(fileInfo.m_filePath); - } - } - } -} - -void rgConfigManager::UpdateSourceFilepath(const std::string& oldFilepath, const std::string& newFilepath, std::shared_ptr pProject, int cloneIndex) -{ - // Ensure that the incoming clone index is valid for the current project. - bool isValidRange = (cloneIndex >= 0 && cloneIndex < pProject->m_clones.size()); - assert(isValidRange); - if (isValidRange) - { - // Use the clone given by the incoming index, and make sure it's valid. - std::shared_ptr pClone = pProject->m_clones[cloneIndex]; - assert(pClone); - - // Attempt to find the old file path referenced within the clone. - rgSourceFilePathSearcher sourceFileSearcher(oldFilepath); - auto fileIter = std::find_if(pClone->m_sourceFiles.begin(), pClone->m_sourceFiles.end(), sourceFileSearcher); - - // Verify that the old file path is referenced within the clone. - bool oldFilepathFound = fileIter != pClone->m_sourceFiles.end(); - assert(oldFilepathFound); - - // If the old file path exists in the clone, remove it. - if (oldFilepathFound) - { - pClone->m_sourceFiles.erase(fileIter); - } - - // Add the updated file path to the list of source files for the clone. - rgSourceFileInfo updatedFilePath = {}; - updatedFilePath.m_filePath = newFilepath; - pClone->m_sourceFiles.push_back(updatedFilePath); - } -} - -void rgConfigManager::UpdateShaderStageFilePath(const std::string& oldFilepath, const std::string& newFilepath, std::shared_ptr pProject, int cloneIndex) -{ - // Ensure that the incoming clone index is valid for the current project. - bool isValidRange = (cloneIndex >= 0 && cloneIndex < pProject->m_clones.size()); - assert(isValidRange); - if (isValidRange) - { - // Use the clone given by the incoming index, and make sure it's valid. - std::shared_ptr pClone = std::dynamic_pointer_cast(pProject->m_clones[cloneIndex]); - assert(pClone != nullptr); - if (pClone != nullptr) - { - ShaderInputFileArray& stageArray = pClone->m_pipeline.m_shaderStages; - for (int stageIndex = 0; stageIndex < stageArray.size(); ++stageIndex) - { - const std::string& stageFilePath = pClone->m_pipeline.m_shaderStages[stageIndex]; - if (stageFilePath.compare(oldFilepath) == 0) - { - // Update the file path for the shader stage. - pClone->m_pipeline.m_shaderStages[stageIndex] = newFilepath; - } - } - } - } -} - -void rgConfigManager::GetProjectFolder(const std::string& projectName, std::string& projectFolder) -{ - // Start with the default directory where project files live. - std::string projectsFolder; - rgConfigManager::GetDefaultProjectsFolder(projectsFolder); - - // Append the project name as a subdirectory. - rgUtils::AppendFolderToPath(projectsFolder, projectName, projectFolder); -} - -void rgConfigManager::GenerateNewSourceFilepath(const std::string& projectName, int cloneIndex, const std::string& sourceFilename, const std::string& sourcefileExtension, std::string& generatedFileName, std::string& fullSourceFilePath) -{ - // Get the path to the folder for the given project. - std::string projectFolder; - GetProjectFolder(projectName, projectFolder); - - // Generate a folder name for where the new clone source file will be stored. - std::string cloneFolderName = rgUtils::GenerateCloneName(cloneIndex); - - // Append the clone folder to the project folder. - std::string cloneFolderPath; - rgUtils::AppendFolderToPath(projectFolder, cloneFolderName, cloneFolderPath); - - // Append a suffix number onto the end of a filename to make it unique. - unsigned int suffix = 0; - - // Loop to generate a new filename with suffix until it's a unique item in the file menu. - do - { - std::stringstream filenameStream; - filenameStream << sourceFilename; - if (suffix > 0) - { - // Only insert the suffix if it is non-zero, so that generated filenames - // follow the pattern: src, src1, src2, src3, etc. - filenameStream << suffix; - } - generatedFileName = filenameStream.str(); - filenameStream << sourcefileExtension; - suffix++; - - // Store the path in the final destination, it will get tested in the while statement. - rgUtils::AppendFileNameToPath(cloneFolderPath, filenameStream.str(), fullSourceFilePath); - - } while (rgUtils::IsFileExists(fullSourceFilePath)); - - // Make sure all path separators are the same. - rgUtils::StandardizePathSeparator(fullSourceFilePath); -} - -void rgConfigManager::GenerateNewPipelineFilepath(const std::string& projectName, int cloneIndex, const std::string& pipelineFilename, const std::string& pipelineFileExtension, std::string& fullPipelineFilePath) -{ - // Get the path to the folder for the given project. - std::string projectFolder; - GetProjectFolder(projectName, projectFolder); - - // Generate the project's filename. - std::stringstream pipelineFileStream; - pipelineFileStream << pipelineFilename; - pipelineFileStream << pipelineFileExtension; - - // Generate a folder name for where the new clone source file will be stored. - std::string cloneFolderName = rgUtils::GenerateCloneName(cloneIndex); - - // Append the clone folder to the project folder. - std::string cloneFolderPath; - rgUtils::AppendFolderToPath(projectFolder, cloneFolderName, cloneFolderPath); - - // Generate the full path to the project file. - rgUtils::AppendFileNameToPath(cloneFolderPath, pipelineFileStream.str(), fullPipelineFilePath); - - // Make sure all path separators are the same. - rgUtils::StandardizePathSeparator(fullPipelineFilePath); -} - -std::shared_ptr rgConfigManager::LoadProjectFile(const std::string& projectFilePath) -{ - std::shared_ptr pProject = nullptr; - bool isProjectLoaded = rgXmlConfigFile::ReadProjectConfigFile(projectFilePath, pProject); - - bool isOk = isProjectLoaded && pProject != nullptr; - assert(isOk); - - if (isOk) - { - auto pRecentProject = std::make_shared(); - pRecentProject->projectPath = projectFilePath; - pRecentProject->apiType = pProject->m_api; - - // Add this path to the list of recently loaded projects. - AddRecentProjectPath(pRecentProject); - } - - return pProject; -} - -bool rgConfigManager::SaveProjectFile(std::shared_ptr pProject) -{ - bool ret = false; - if (pProject != nullptr) - { - // When saving a project, update the project's path in the list of recent projects. - const std::string projectFileFullPath = pProject->m_projectFileFullPath; - assert(!projectFileFullPath.empty()); - - if (m_pGlobalSettings != nullptr) - { - // Add this project if it does not exist. - ProjectPathSearcher searcher(projectFileFullPath); - auto projectPathIter = std::find_if(m_pGlobalSettings->m_recentProjects.begin(), m_pGlobalSettings->m_recentProjects.end(), searcher); - if (projectPathIter == m_pGlobalSettings->m_recentProjects.end()) - { - auto pRecentProject = std::make_shared(); - pRecentProject->projectPath = projectFileFullPath; - pRecentProject->apiType = pProject->m_api; - - AddRecentProjectPath(pRecentProject); - } - } - - std::string projectDirectory; - rgUtils::ExtractFileDirectory(projectFileFullPath, projectDirectory); - - if (!rgUtils::IsDirExists(projectDirectory)) - { - bool isDirCreated = rgUtils::CreateFolder(projectDirectory); - assert(isDirCreated); - } - - // Save the file. - rgXmlConfigFile::WriteProjectConfigFile(*pProject, projectFileFullPath); - ret = true; - } - return ret; -} - -void rgConfigManager::RevertToDefaultBuildSettings(rgProjectAPI api) -{ - std::string apiString; - bool isOk = rgUtils::ProjectAPIToString(api, apiString); - - assert(isOk); - if (isOk) - { - bool apiStringIsNotEmpty = !apiString.empty(); - assert(apiStringIsNotEmpty); - - if (apiStringIsNotEmpty) - { - // Find the settings for the API being reset. - auto defaultSettingsIter = m_pGlobalSettings->m_pDefaultBuildSettings.find(apiString); - if (defaultSettingsIter != m_pGlobalSettings->m_pDefaultBuildSettings.end()) - { - std::shared_ptr pDefaultBuildSettings = rgConfigManager::GetDefaultBuildSettings(api); - assert(pDefaultBuildSettings); - - // Assign the API's default settings as the global settings. - if (pDefaultBuildSettings != nullptr) - { - m_pGlobalSettings->m_pDefaultBuildSettings[apiString] = pDefaultBuildSettings; - } - } - } - } -} - -bool rgConfigManager::SaveGlobalConfigFile() const -{ - bool ret = false; - - // Get the path to the default configuration file. - std::string configFileFullPath; - rgConfigManager::GetDefaultDataFolder(configFileFullPath); - - // Append the global configuration file name to the path. - std::string configFileName = GenConfigFileName(); - assert(!configFileName.empty()); - if (!configFileName.empty()) - { - if (rgUtils::AppendFileNameToPath(configFileFullPath, configFileName, configFileFullPath)) - { - // Write out the settings. - ret = rgXmlConfigFile::WriteGlobalSettings(m_pGlobalSettings, configFileFullPath); - } - } - - return ret; -} - -void rgConfigManager::AddRecentProjectPath(std::shared_ptr pRecentProject) -{ - const rgConfigManager& configManager = rgConfigManager::Instance(); - std::shared_ptr pGlobalSettings = configManager.GetGlobalConfig(); - - // Create a copy of the filepath, because it may be modified below. - assert(pRecentProject != nullptr); - if (pRecentProject != nullptr) - { - const std::string pathToAdd = pRecentProject->projectPath; - - // Strips a string from path separator characters ("\, /"). - auto stripString = [](std::string& str) - { - str.erase(std::remove(str.begin(), str.end(), '\\'), str.end()); - str.erase(std::remove(str.begin(), str.end(), '/'), str.end()); - }; - - // Strip the path from path separator characters. - std::string strippedPath = pathToAdd; - stripString(strippedPath); - - // Is the project already in the list of recent projects? - auto pathIter = std::find_if(pGlobalSettings->m_recentProjects.begin(), pGlobalSettings->m_recentProjects.end(), - [&](std::shared_ptr pRecentProject) - { - // Strip the current string and compare. - bool status = false; - std::string str = ""; - assert(pRecentProject != nullptr); - if (pRecentProject != nullptr) - { - str = pRecentProject->projectPath; - stripString(str); - status = (0 == str.compare(strippedPath)); - } - return status; - }); - - // If the project already exists, remove it. - if (pathIter != pGlobalSettings->m_recentProjects.end()) - { - pGlobalSettings->m_recentProjects.erase(pathIter); - } - - // Add the project to the top of the list. - pGlobalSettings->m_recentProjects.push_back(pRecentProject); - - // If there are now more than the maximum number of recent projects, remove the oldest entry. - if (pGlobalSettings->m_recentProjects.size() > MAX_RECENT_FILES) - { - auto oldestRecentPath = (*pGlobalSettings->m_recentProjects.begin())->projectPath; - - // Remove the entry with the above file path. - ProjectPathSearcher searcher(oldestRecentPath); - auto projectPathIter = std::find_if(pGlobalSettings->m_recentProjects.begin(), pGlobalSettings->m_recentProjects.end(), searcher); - if (projectPathIter != pGlobalSettings->m_recentProjects.end()) - { - pGlobalSettings->m_recentProjects.erase(projectPathIter); - } - } - - // Save the configuration file after adding the new entry. - configManager.SaveGlobalConfigFile(); - } -} - -void rgConfigManager::UpdateRecentProjectPath(const std::string& oldFilePath, const std::string& newFilePath, rgProjectAPI api) -{ - const rgConfigManager& configManager = rgConfigManager::Instance(); - std::shared_ptr pGlobalSettings = configManager.GetGlobalConfig(); - - // Is the project already in the list of recent projects? - ProjectPathSearcher searcher(oldFilePath); - auto projectPathIter = std::find_if(pGlobalSettings->m_recentProjects.begin(), pGlobalSettings->m_recentProjects.end(), searcher); - if (projectPathIter != pGlobalSettings->m_recentProjects.end()) - { - // Compute the vector index of the path being updated. - int pathIndex = (projectPathIter - pGlobalSettings->m_recentProjects.begin()); - - // Verify that the index is valid. - bool isValidIndex = (pathIndex >= 0 && pathIndex < pGlobalSettings->m_recentProjects.size()); - assert(isValidIndex); - if (isValidIndex) - { - // If the path was already in the list, remove it and re-add it to the end of the list. It's now the most recent one. - assert(pGlobalSettings->m_recentProjects[pathIndex]); - if (pGlobalSettings->m_recentProjects[pathIndex] != nullptr) - { - pGlobalSettings->m_recentProjects[pathIndex]->projectPath = newFilePath; - } - } - } - - // Add the new path, which will bump it to the top, and save the config file. - auto pRecentProject = std::make_shared(); - pRecentProject->projectPath = newFilePath; - pRecentProject->apiType = api; - - AddRecentProjectPath(pRecentProject); -} - -// Reset the current API Build settings with those supplied. -void rgConfigManager::SetApiBuildSettings(const std::string& apiName, rgBuildSettings* pBuildSettings) -{ - assert(m_pGlobalSettings != nullptr); - if (m_pGlobalSettings != nullptr) - { - if (apiName.compare(STR_API_NAME_OPENCL) == 0) - { - std::shared_ptr pApiBuildSettings = std::dynamic_pointer_cast(m_pGlobalSettings->m_pDefaultBuildSettings[apiName]); - assert(pApiBuildSettings != nullptr); - if (pApiBuildSettings != nullptr) - { - *pApiBuildSettings = *dynamic_cast(pBuildSettings); - } - } - else if (apiName.compare(STR_API_NAME_VULKAN) == 0) - { - std::shared_ptr pApiBuildSettings = std::dynamic_pointer_cast(m_pGlobalSettings->m_pDefaultBuildSettings[apiName]); - assert(pApiBuildSettings != nullptr); - if (pApiBuildSettings != nullptr) - { - *pApiBuildSettings = *dynamic_cast(pBuildSettings); - } - } - else - { - assert(!"Unsupported apiName in SetApiBuildSettings"); - } - } -} - -std::shared_ptr rgConfigManager::GetGlobalConfig() const -{ - return m_pGlobalSettings; -} - -std::shared_ptr rgConfigManager::GetVersionInfo() const -{ - return m_pVersionInfo; -} - -void rgConfigManager::Close() const -{ - SaveGlobalConfigFile(); - rgLog::file << STR_LOG_CLOSING_RGA_GUI << std::endl; - rgaSharedUtils::CloseLogFile(); -} - -std::shared_ptr rgConfigManager::GetDefaultBuildSettings(rgProjectAPI api) -{ - return DefaultConfigFactory::GetDefaultBuildSettings(api); -} - -void rgConfigManager::GetDefaultDataFolder(std::string& defaultDataFolder) -{ - // Build the output path only once, then cache the result for subsequent calls. - static std::string outputPath; - if (outputPath.empty()) - { - QString systemDefaultDataPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); - rgUtils::AppendFolderToPath(systemDefaultDataPath.toStdString(), STR_APP_FOLDER_NAME, outputPath); - } - defaultDataFolder = outputPath; -} - -void rgConfigManager::GetDefaultDocumentsFolder(std::string& defaultDocumentsFolder) -{ - // Build the output path only once, then cache the result for subsequent calls. - static std::string outputPath; - if (outputPath.empty()) - { - QString systemDefaultDataPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); - rgUtils::AppendFolderToPath(systemDefaultDataPath.toStdString(), STR_APP_FOLDER_NAME, outputPath); - } - defaultDocumentsFolder = outputPath; -} - -void rgConfigManager::GetDefaultProjectsFolder(std::string& defaultProjectsFolder) -{ - // Projects are saved under the system's "Documents" folder. - rgConfigManager::GetDefaultDocumentsFolder(defaultProjectsFolder); - rgUtils::AppendFolderToPath(defaultProjectsFolder, STR_PROJECTS_FOLDER_NAME, defaultProjectsFolder); -} - -std::shared_ptr rgConfigManager::GetUserGlobalBuildSettings(rgProjectAPI api) const -{ - std::shared_ptr pRet = nullptr; - if (m_pGlobalSettings != nullptr) - { - // Translate the project API to string. - std::string apiName; - bool isOk = rgUtils::ProjectAPIToString(api, apiName); - if (isOk && !apiName.empty()) - { - // Get the relevant build settings. - auto iter = m_pGlobalSettings->m_pDefaultBuildSettings.find(apiName); - if (iter != m_pGlobalSettings->m_pDefaultBuildSettings.cend()) - { - pRet = iter->second; - } - } - } - - assert(pRet != nullptr); - return pRet; -} - -std::string rgConfigManager::GetLastSelectedFolder() const -{ - static const char* DEFAULT_FOLDER = "./"; - std::string ret = DEFAULT_FOLDER; - - // Get global configuration file. - std::shared_ptr pGlobalConfig = rgConfigManager::Instance().GetGlobalConfig(); - - // Only return if config file and string are valid, otherwise use default folder. - if (pGlobalConfig != nullptr && pGlobalConfig->m_lastSelectedDirectory != "") - { - ret = pGlobalConfig->m_lastSelectedDirectory; - } - - return ret; -} - -std::vector> rgConfigManager::GetRecentProjects() const -{ - assert(m_pGlobalSettings != nullptr); - bool isOk = (m_pGlobalSettings != nullptr); - return (isOk ? m_pGlobalSettings->m_recentProjects : std::vector>()); -} - -void rgConfigManager::SetGlobalConfig(const rgGlobalSettings& globalSettings) -{ - assert(m_pGlobalSettings != nullptr); - - // Never allow reseting the pointer to the global config, there should be only one such pointer. - // This function only makes sense when the object is initialized. In future, we need to make sure that this - // function accepts a value, and not a pointer. - if (m_pGlobalSettings != nullptr) - { - // Replace the global settings with the incoming instance. - *m_pGlobalSettings = globalSettings; - } -} - -void rgConfigManager::SetLastSelectedDirectory(const std::string& lastSelectedDirectory) -{ - assert(m_pGlobalSettings != nullptr); - if (m_pGlobalSettings != nullptr) - { - m_pGlobalSettings->m_lastSelectedDirectory = lastSelectedDirectory; - } -} - -std::string rgConfigManager::GenerateProjectFilepath(const std::string& projectName) -{ - // Get the path to the folder for the given project. - std::string projectFolder; - GetProjectFolder(projectName, projectFolder); - - // Generate the project's filename. - std::stringstream projectFilename; - projectFilename << projectName; - projectFilename << STR_PROJECT_FILE_EXTENSION; - - // Generate the full path to the project file. - std::string fullProjectPath; - rgUtils::AppendFileNameToPath(projectFolder, projectFilename.str(), fullProjectPath); - - return fullProjectPath; -} - -void rgConfigManager::SetWindowGeometry(int xPos, int yPos, int width, int height, int windowState) -{ - assert(m_pGlobalSettings != nullptr); - if (m_pGlobalSettings != nullptr) - { - rgWindowConfig windowConfig = m_pGlobalSettings->m_guiWindowConfig; - if (xPos >= 0) - { - windowConfig.m_windowXPos = xPos; - } - else - { - windowConfig.m_windowXPos = 0; - } - if (yPos >= 0) - { - windowConfig.m_windowYPos = yPos; - } - else - { - windowConfig.m_windowYPos = 0; - } - windowConfig.m_windowWidth = width; - windowConfig.m_windowHeight = height; - - // If the window is maximized, save the state. - windowConfig.m_windowState = windowState; - - // Update the window configuration. - m_pGlobalSettings->m_guiWindowConfig = windowConfig; - } -} - -void rgConfigManager::GetWindowGeometry(rgWindowConfig& windowValues) const -{ - assert(m_pGlobalSettings != nullptr); - if (m_pGlobalSettings != nullptr) - { - windowValues.m_windowXPos = m_pGlobalSettings->m_guiWindowConfig.m_windowXPos; - windowValues.m_windowYPos = m_pGlobalSettings->m_guiWindowConfig.m_windowYPos; - windowValues.m_windowHeight = m_pGlobalSettings->m_guiWindowConfig.m_windowHeight; - windowValues.m_windowWidth = m_pGlobalSettings->m_guiWindowConfig.m_windowWidth; - windowValues.m_windowState = m_pGlobalSettings->m_guiWindowConfig.m_windowState; - } -} - -void rgConfigManager::SetSplitterValues(const std::string& splitterName, const std::vector& splitterValues) -{ - assert(m_pGlobalSettings != nullptr); - if (m_pGlobalSettings != nullptr) - { - bool isNewItem = true; - - // Find name match. - for (rgSplitterConfig& splitterConfig : m_pGlobalSettings->m_guiLayoutSplitters) - { - // Name matches. - if (splitterConfig.m_splitterName == splitterName) - { - splitterConfig.m_splitterValues = splitterValues; - isNewItem = false; - break; - } - } - - // Create a new config item if necessary. - if (isNewItem) - { - // Construct new splitter config item. - rgSplitterConfig newSplitterConfig; - newSplitterConfig.m_splitterName = splitterName; - newSplitterConfig.m_splitterValues = splitterValues; - - // Add the new config item. - m_pGlobalSettings->m_guiLayoutSplitters.push_back(newSplitterConfig); - } - } -} - -bool rgConfigManager::GetSplitterValues(const std::string& splitterName, std::vector& splitterValues) const -{ - bool ret = false; - assert(m_pGlobalSettings != nullptr); - if (m_pGlobalSettings != nullptr) - { - // Find name match. - for (rgSplitterConfig& splitterConfig : m_pGlobalSettings->m_guiLayoutSplitters) - { - // Name matches. - if (splitterConfig.m_splitterName == splitterName) - { - splitterValues = splitterConfig.m_splitterValues; - ret = true; - break; - } - } - } - - return ret; -} - -void rgConfigManager::SetDisassemblyColumnVisibility(const std::vector& columnVisibility) -{ - assert(m_pGlobalSettings != nullptr); - if (m_pGlobalSettings != nullptr) - { - assert(m_pGlobalSettings->m_visibleDisassemblyViewColumns.size() == columnVisibility.size()); - m_pGlobalSettings->m_visibleDisassemblyViewColumns = columnVisibility; - } -} - -std::string rgConfigManager::GetFatalErrorMessage() const -{ - return m_fatalErrorMsg; -} - -void rgConfigManager::GetSupportedApis(std::vector& supportedAPIs) -{ - for (auto const& buildSetting : m_pGlobalSettings->m_pDefaultBuildSettings) - { - supportedAPIs.push_back(buildSetting.first); - } -} - -const std::string & rgConfigManager::GetCLILogFilePath() -{ - return m_cliLogFilePath; -} - -std::string rgConfigManager::GetIncludeFileViewer() const -{ - // By default, return the system default option. - std::string ret = STR_GLOBAL_SETTINGS_SRC_VIEW_INCLUDE_VIEWER_DEFAULT; - assert(m_pGlobalSettings != nullptr); - if (m_pGlobalSettings != nullptr) - { - // Get the user's app of choice. - ret = m_pGlobalSettings->m_includeFilesViewer; - } - return ret; -} - -void rgConfigManager::SetConfigFileDataModelVersion(const std::string& dataModelVersion) -{ - m_configFileDataModelVersion = dataModelVersion; -} - -std::string rgConfigManager::GetConfigFileDataModelVersion() const -{ - return m_configFileDataModelVersion; -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgCsvFileParser.cpp b/RadeonGPUAnalyzerGUI/Src/rgCsvFileParser.cpp deleted file mode 100644 index fd91a02..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgCsvFileParser.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// C++. -#include -#include -#include - -// Qt. -#include -#include - -// Local. -#include -#include - -bool rgCsvFileParser::Parse(std::string& errorString) -{ - bool isParsingFailed = false; - - QFile csvFile(m_csvFilePath.c_str()); - QTextStream fileStream(&csvFile); - - // Attempt to open the CSV file and parse each line. - bool isFileOpened = csvFile.open(QFile::ReadOnly | QFile::Text); - assert(isFileOpened); - if (isFileOpened) - { - // Read the first line and move on, as it's just column labels. - QString csvLine = fileStream.readLine(); - - int lineIndex = 2; - // Parse each new line in the CSV file. - do - { - // Read the next line in the file. - csvLine = fileStream.readLine(); - if (!csvLine.isEmpty()) - { - std::vector lineTokens; - ParseLine(csvLine.toStdString(), lineTokens); - - bool lineParsedSuccessfully = false; - if (!lineTokens.empty()) - { - lineParsedSuccessfully = ProcessLineTokens(lineTokens); - assert(lineParsedSuccessfully); - } - - // Was the line processed correctly? - if (!lineParsedSuccessfully) - { - // Build an error message indicating that parsing the file failed. - std::stringstream errorStream; - errorStream << STR_ERR_CSV_PARSING_FAILED_A; - errorStream << m_csvFilePath.c_str(); - errorStream << STR_ERR_CSV_PARSING_FAILED_B; - errorStream << lineIndex; - - // Return the error string. - errorString = errorStream.str(); - isParsingFailed = true; - } - } - - // Increment the line index currently being parsed. - lineIndex++; - } while (!fileStream.atEnd()); - } - else - { - // Failed to load the CSV file correctly. - std::stringstream errorStream; - errorStream << STR_ERR_CSV_PARSING_FAILED_A; - errorStream << m_csvFilePath.c_str(); - - // Return the error string. - errorString = errorStream.str(); - isParsingFailed = true; - } - - return !isParsingFailed; -} - -void rgCsvFileParser::ParseLine(const std::string& csvLine, std::vector& lineTokens) -{ - std::stringstream lineStream; - lineStream.str(csvLine); - std::string substr; - - // Step through the entire line of text, and split into tokens based on comma position. - while (std::getline(lineStream, substr, ',')) - { - // Are there any quotation marks within the token? If so, parsing is handled differently. - size_t numQuotesInToken = std::count(substr.begin(), substr.end(), '\"'); - switch (numQuotesInToken) - { - case 0: - { - // If there are no quotes, just add the token to the line tokens list. - lineTokens.push_back(substr); - } - break; - case 1: - { - // Found a start quote. Keep reading new tokens to find the matching end quote. - std::stringstream tokenStream; - do - { - // Add the token to the quoted column string. - tokenStream << substr << ','; - std::getline(lineStream, substr, ','); - } while (!(substr.find('"') != substr.npos)); - - // Add the final portion of the token to the stream. - tokenStream << substr; - - // Remove the quotation marks from the final token string. - std::string quotedToken = tokenStream.str(); - quotedToken.erase(std::remove(quotedToken.begin(), quotedToken.end(), '\"'), quotedToken.end()); - - // Add the token to the line tokens list. - lineTokens.push_back(quotedToken); - } - 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()); - lineTokens.push_back(substr); - } - break; - default: - // If this happens, the format of the ISA line likely wasn't handled correctly. - assert(false); - break; - } - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgEditorElement.cpp b/RadeonGPUAnalyzerGUI/Src/rgEditorElement.cpp deleted file mode 100644 index 4c55349..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgEditorElement.cpp +++ /dev/null @@ -1,811 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include -#include -#include - -// QtCommon. -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include - -// The tooltip used for editor items. -static const char* s_EDITOR_ELEMENT_TOOLTIP = "Click to edit."; - -// The width of a single indent within the tree. -static const int s_INDENTATION_WIDTH = 20; - -// The horizontal position where the Value column starts. -static const int s_VALUE_COLUMN_POSITION = 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 s_ROW_STYLESHEET = -"* \ -{ \ - background-color: rgb(255, 128 255, 255); \ -} \ - \ -*[selected=true] \ -{ \ - background-color: rgb(255, 255, 178, 255); \ -} \ - \ -*[resultOccurrence=true][currentResult=false][selected=false] \ -{ \ - background-color: rgb(192, 192, 192, 255); \ -} \ - \ -*[currentResult=true] \ -{ \ - background-color: rgb(255, 255, 178, 255); \ -} \ -"; - -rgEditorElement::rgEditorElement(QWidget* pParent, const std::string& memberName, rgEditorDataType dataType, std::function valueChangedCallback) - : QWidget(pParent) - , m_memberName(memberName) - , m_type(dataType) - , m_valueChangedCallback(valueChangedCallback) - , m_rowState(rgRowExpansionState::Expanded) - , m_isFilteredOut(false) - , m_styleFlags(static_cast(rgStyleFlags::None)) -{ - ui.setupUi(this); - - // Set the expand button's cursor to pointing hand cursor. - ui.expandPushButton->setCursor(Qt::PointingHandCursor); - - // Enable mouse tracking to receive mouse move events. - setMouseTracking(true); - - // Initialize controls within the row. - InitializeControls(); - - // Connect internal signals to slots. - ConnectSignals(); - - // Apply a stylesheet to the row that's used to alter the background color. - setStyleSheet(s_ROW_STYLESHEET); -} - -void rgEditorElement::AppendChildItem(rgEditorElement* pItem) -{ - pItem->m_pParentItem = this; - m_childItems.push_back(pItem); - - // Ensure that the expand button is visible when appending children. - ui.expandPushButton->setVisible(true); - - // Insert the new child to the end of the layout. - ui.childRowsLayout->addWidget(pItem); - - // Register the new row with the ScalingManager. - ScalingManager::Get().RegisterObject(pItem); - - // Update the widget geometry now that the newest child element has been added. - ui.childRowsLayout->update(); -} - -void rgEditorElement::ClearChildren() -{ - // Destroy all children and clear the child vector. - for (auto childIter = m_childItems.begin(); childIter != m_childItems.end(); ++childIter) - { - // Remove the child element from the children list layout. - ui.childRowsLayout->removeWidget(*childIter); - - // Destroy the child element. - RG_SAFE_DELETE(*childIter); - } - - m_childItems.clear(); - - // Since the row doesn't have any children, hide the expand/collapse button. - ui.expandPushButton->setVisible(false); - - ui.childRowsLayout->update(); -} - -rgEditorElement* rgEditorElement::FindNextAnscestor(rgEditorElement* pCurrentElement) -{ - rgEditorElement* pResult = nullptr; - - // If no current element has been provided, start at this element. - if (pCurrentElement == nullptr) - { - pCurrentElement = this; - } - - assert(pCurrentElement != nullptr); - if (pCurrentElement != nullptr) - { - // Get the direct parent to figure out if the current element has any children. - rgEditorElement* pParentElement = pCurrentElement->GetParentItem(); - if (pParentElement != nullptr) - { - // Does the selected row have a younger sibling? - int rowIndex = pCurrentElement->GetRowIndex(); - - int numYoungerSiblings = (pParentElement->ChildCount() - 1) - rowIndex; - if (numYoungerSiblings > 0) - { - int siblingRow = -1; - - // Try to find a visible younger sibling row. - for (int siblingIndex = 0; siblingIndex < numYoungerSiblings; ++siblingIndex) - { - rgEditorElement* pYoungerSibling = pParentElement->GetChild(rowIndex + siblingIndex + 1); - assert(pYoungerSibling != nullptr); - if (pYoungerSibling != nullptr && pYoungerSibling->isVisible()) - { - siblingRow = siblingIndex; - break; - } - } - - if (siblingRow != -1) - { - // Select the first youngest sibling. - pResult = pParentElement->GetChild(rowIndex + 1); - } - } - - if (pResult == nullptr) - { - // Need to find the first parent ancestor with a single child. - pResult = FindNextAnscestor(pParentElement); - } - } - } - - return pResult; -} - -rgEditorElement* rgEditorElement::FindLastVisibleDescendant(rgEditorElement* pCurrentElement) const -{ - rgEditorElement* pResult = nullptr; - - assert(pCurrentElement != nullptr); - if (pCurrentElement != nullptr) - { - // Find the last visible child starting from the bottom of the list. - int numChildren = pCurrentElement->ChildCount(); - for (int childIndex = numChildren - 1; childIndex >= 0; childIndex--) - { - rgEditorElement* pChild = pCurrentElement->GetChild(childIndex); - assert(pChild != nullptr); - if (pChild != nullptr) - { - // Only consider visible rows- skip hidden rows that are collapsed or filtered out. - if (pChild->isVisible()) - { - // If the child has children, and is expanded, find the last visible descendant. - int childCount = pChild->ChildCount(); - if (childCount > 0 && pChild->GetExpansionState() == rgRowExpansionState::Expanded) - { - // Search for the last descendant using the child as the root element. - pResult = FindLastVisibleDescendant(pChild); - } - else - { - // If there are no descendant rows, we have found the last descendant. - pResult = pChild; - } - - // If the row was visible, something got selected. We're done searching. - break; - } - } - } - } - - return pResult; -} - -rgEditorElement* rgEditorElement::GetLastVisibleDescendant() -{ - // Start searching for the descendant at this element. Returns itself if 0 children. - rgEditorElement* pResult = FindLastVisibleDescendant(this); - - // If there aren't any visible rows above the element, this element is the last visible descendant. - if (pResult == nullptr) - { - pResult = this; - } - - return pResult; -} - - -rgPipelineStateTree* rgEditorElement::GetParentStateTree() const -{ - rgPipelineStateTree* pParentTree = nullptr; - - // Start with the current row. - const rgEditorElement* pCurrentElement = this; - - // Step up through the row's parent elements. - while (pCurrentElement->GetParentItem() != nullptr) - { - pCurrentElement = pCurrentElement->GetParentItem(); - } - - // Ensure that the root parent element's tree pointer is valid. - assert(pCurrentElement->m_pParentTree != nullptr); - if (pCurrentElement->m_pParentTree != nullptr) - { - pParentTree = pCurrentElement->m_pParentTree; - } - - return pParentTree; -} - -void rgEditorElement::SetParentStateTree(rgPipelineStateTree* pParentTree) -{ - assert(pParentTree != nullptr); - if (pParentTree != nullptr) - { - m_pParentTree = pParentTree; - } -} - -void rgEditorElement::RemoveChild(rgEditorElement* pChildItem) -{ - auto childIter = std::find(m_childItems.begin(), m_childItems.end(), pChildItem); - if (childIter != m_childItems.cend()) - { - // Remove the child element from the children list layout. - ui.childRowsLayout->removeWidget(pChildItem); - - // Erase the target item from the list of children and destroy it. - m_childItems.erase(childIter); - - // Destroy the child element. - RG_SAFE_DELETE(pChildItem); - } -} - -rgEditorElement* rgEditorElement::GetChild(int rowIndex) const -{ - return m_childItems[rowIndex]; -} - -bool rgEditorElement::GetIsEditable() const -{ - // All types, besides 'void', can be edited within the treeview. - return m_type != rgEditorDataType::Void; -} - -int rgEditorElement::GetRowHeight() const -{ - return ui.rowInfo->height(); -} - -uint32_t rgEditorElement::GetStyleFlags() const -{ - return m_styleFlags; -} - -int rgEditorElement::ChildCount() const -{ - return static_cast(m_childItems.size()); -} - -int rgEditorElement::ColumnCount() const -{ - // Always show only two columns: Member name & Value. - return static_cast(rgRowData::RowDataCount); -} - -QVariant rgEditorElement::Data(int column) const -{ - QVariant result; - - if (column == static_cast(rgRowData::RowDataMemberName)) - { - result = QVariant(m_memberName.c_str()); - } - - return result; -} - -rgPipelineStateEditorWidget* rgEditorElement::GetEditorWidget() -{ - return nullptr; -} - -void rgEditorElement::AddStyleFlag(rgStyleFlags styleFlag) -{ - // Get the row's current style. - uint32_t rowStyleFlags = GetStyleFlags(); - - // Modify the row style flags by adding the given flag into the bitfield. - rowStyleFlags |= static_cast(styleFlag); - - // Apply the updated style flags to the row. - SetStyleFlags(rowStyleFlags); -} - -void rgEditorElement::RemoveStyleFlag(rgStyleFlags styleFlag) -{ - // Get the row's current style. - uint32_t rowStyleFlags = GetStyleFlags(); - - // Remove the given style flag. - rowStyleFlags &= ~static_cast(styleFlag); - - // Apply the updated style flags to the row. - SetStyleFlags(rowStyleFlags); -} - -rgEditorElement* rgEditorElement::GetParentItem() const -{ - return m_pParentItem; -} - -rgEditorDataType rgEditorElement::GetType() const -{ - return m_type; -} - -int rgEditorElement::GetRowIndex() const -{ - assert(m_pParentItem != nullptr); - if (m_pParentItem != nullptr) - { - // Find this item within the parent's children. - auto childIter = std::find(m_pParentItem->m_childItems.begin(), m_pParentItem->m_childItems.end(), this); - if (childIter != m_pParentItem->m_childItems.end()) - { - // Compute the child index for this item. - return (childIter - m_pParentItem->m_childItems.begin()); - } - } - - return 0; -} - -void rgEditorElement::SetExpansionState(rgRowExpansionState state, bool updateChildren) -{ - // Update the row's expansion state. - m_rowState = state; - - // Toggle the visibility of all children based on the row state. - bool isRowExpanded = (m_rowState == rgRowExpansionState::Expanded); - if (isRowExpanded) - { - ui.expandPushButton->setIcon(QIcon(gs_ICON_RESOURCE_EXPANDED_ROW)); - } - else - { - ui.expandPushButton->setIcon(QIcon(gs_ICON_RESOURCE_COLLAPSED_ROW)); - } - - int numChildren = ChildCount(); - for (int childIndex = 0; childIndex < numChildren; ++childIndex) - { - rgEditorElement* pChildElement = m_childItems[childIndex]; - assert(pChildElement != nullptr); - if (pChildElement != nullptr) - { - // If the row is not currently filtered out, make it visible. - if (!pChildElement->m_isFilteredOut) - { - // Set the visibility of child rows. - pChildElement->setVisible(isRowExpanded); - - // Recursively update children if necessary. - if (updateChildren) - { - m_childItems[childIndex]->SetExpansionState(state, updateChildren); - } - } - } - } -} - -rgRowExpansionState rgEditorElement::GetExpansionState() const -{ - return m_rowState; -} - -void rgEditorElement::SetStyleFlags(uint32_t styleFlags) -{ - // Don't change or repolish anything if the flags are not modified. - if (styleFlags != m_styleFlags) - { - // Update the style flags. - m_styleFlags = styleFlags; - - // Update the "selected" property in the row to highlight the currently-selected row. - bool isSelectedRow = (m_styleFlags & static_cast(rgStyleFlags::CurrentRow)) == static_cast(rgStyleFlags::CurrentRow); - ui.rowInfo->setProperty("selected", isSelectedRow); - - // Update the "currentResult" property in the row to highlight the current search result. - bool isCurrentResult = (m_styleFlags & static_cast(rgStyleFlags::SearchResultCurrent)) == static_cast(rgStyleFlags::SearchResultCurrent); - ui.rowInfo->setProperty("currentResult", isCurrentResult); - - // Update the "resultOccurrence" property in the row to indicate that this row includes a - // search result- it's just not the current search result. - bool isResultOccurrence = (m_styleFlags & static_cast(rgStyleFlags::SearchResultOccurrence)) == static_cast(rgStyleFlags::SearchResultOccurrence); - ui.rowInfo->setProperty("resultOccurrence", isResultOccurrence); - - // Repolish the row's visual style. - rgUtils::StyleRepolish(ui.rowInfo, true); - - // Update to repaint the row. - update(); - } -} - -void rgEditorElement::SetFocusedColumn(rgRowData column) -{ - // Set the focus on the member name label. Editor - // widgets can be focused on separately using tab. - if (column == rgRowData::RowDataMemberName) - { - ui.memberNameLabel->setFocus(); - } -} - -void rgEditorElement::SetValueChangedCallback(std::function valueChangedCallback) -{ - assert(valueChangedCallback != nullptr); - if (valueChangedCallback != nullptr) - { - m_valueChangedCallback = valueChangedCallback; - } -} - -void rgEditorElement::SetTooltipText() -{ - // Get the editor widget for the row. - // Some rows are used exclusively as parent rows, and don't make use of editor widgets. - rgPipelineStateEditorWidget* pEditorWidget = GetEditorWidget(); - if (pEditorWidget != nullptr) - { - // Find out if the element is editable. - bool isEditable = GetIsEditable(); - - // Check to see if the user is pointing to a valid cell. - if (isEditable) - { - // Set the cursor to pointing hand cursor. - pEditorWidget->setCursor(Qt::PointingHandCursor); - - // Set the tooltip text for the editor widget. - rgUtils::SetToolAndStatusTip(s_EDITOR_ELEMENT_TOOLTIP, pEditorWidget); - } - else - { - // Set the cursor to arrow cursor. - pEditorWidget->setCursor(Qt::ArrowCursor); - } - } -} - -void rgEditorElement::InitializeControls() -{ - // Set the member name in the label. - ui.memberNameLabel->setText(m_memberName.c_str()); -} - -void rgEditorElement::InitializeRows(rgEditorElement* pRootElement) -{ - if (pRootElement == nullptr) - { - pRootElement = this; - } - - assert(pRootElement != nullptr); - if (pRootElement != nullptr) - { - // Update the indentation for the row based on the number of ancestor parent rows. - pRootElement->UpdateIndentation(); - - // Set the tooltip text for the row. - pRootElement->SetTooltipText(); - - int numChildren = pRootElement->ChildCount(); - for (int childIndex = 0; childIndex < numChildren; ++childIndex) - { - rgEditorElement* pChild = pRootElement->GetChild(childIndex); - InitializeRows(pChild); - } - } -} - -void rgEditorElement::HandleValueChanged() -{ - ValueChangedHandler(); -} - -void rgEditorElement::ExpandTreeEntry() -{ - // Expand the tree entry. - SetExpansionState(rgRowExpansionState::Expanded); -} - -void rgEditorElement::HandleExpandClicked() -{ - // Toggle the expanded/collapsed state of the row. - rgRowExpansionState newRowState = (m_rowState == rgRowExpansionState::Expanded) ? - rgRowExpansionState::Collapsed : rgRowExpansionState::Expanded; - - // Update the expansion state. - SetExpansionState(newRowState); -} - -void rgEditorElement::HandleNameLabelFocusIn() -{ - // Get the parent tree that this element is connected to. - rgPipelineStateTree* pParentTree = GetParentStateTree(); - assert(pParentTree != nullptr); - if (pParentTree != nullptr) - { - // Set the current selection to this row and the member name column. - pParentTree->SetCurrentSelection(this, static_cast(rgRowData::RowDataMemberName)); - } -} - -void rgEditorElement::HandleEditorFocusIn() -{ - // Get the parent tree that this element is connected to. - rgPipelineStateTree* pParentTree = GetParentStateTree(); - assert(pParentTree != nullptr); - if (pParentTree != nullptr) - { - // Set the current selection to this row and the value column. - pParentTree->SetCurrentSelection(this, static_cast(rgRowData::RowDataMemberValue)); - } -} - -void rgEditorElement::HandleEditorFocusOut() -{ - // Get the parent tree that this element is connected to. - rgPipelineStateTree* pParentTree = GetParentStateTree(); - assert(pParentTree != nullptr); - if (pParentTree != nullptr) - { - // Select the current row only- no specific column. - pParentTree->SetCurrentSelection(this); - } -} - -int rgEditorElement::ComputeIndentationWidth(rgEditorElement* pElement) -{ - if (pElement != nullptr) - { - rgEditorElement* pParent = pElement->GetParentItem(); - if (pParent != nullptr) - { - return s_INDENTATION_WIDTH + ComputeIndentationWidth(pParent); - } - } - - return 0; -} - -void rgEditorElement::ConnectSignals() -{ - // Connect the row's expand/collapse button. - bool isConnected = connect(ui.expandPushButton, &QPushButton::clicked, this, &rgEditorElement::HandleExpandClicked); - assert(isConnected); - - // Connect the member name label's focus in signal. - isConnected = connect(ui.memberNameLabel, &rgLabel::LabelFocusInEventSignal, this, &rgEditorElement::HandleNameLabelFocusIn); - assert(isConnected); -} - -void rgEditorElement::UpdateIndentation() -{ - // Adjust the row's indentation spacer width based on number of ancestors. - int indentWidth = ComputeIndentationWidth(this); - - if (m_childItems.empty()) - { - ui.expandPushButton->setVisible(false); - indentWidth += ui.expandPushButton->width(); - } - - // Insert spacing at the beginning of the layout to indent. - QHBoxLayout* pLayout = static_cast(ui.rowInfo->layout()); - if (pLayout != nullptr && indentWidth > 0) - { - // If the spacer item has already been initialized, - // remove it and destroy it before re-creating a new one. - if (m_pSpacerItem != nullptr) - { - pLayout->removeItem(m_pSpacerItem); - RG_SAFE_DELETE(m_pSpacerItem); - } - - m_pSpacerItem = new QSpacerItem(indentWidth, 0, QSizePolicy::Fixed); - pLayout->insertSpacerItem(0, m_pSpacerItem); - } - - // Get the font metrics. - QFontMetrics fontMetrics(ui.memberNameLabel->font()); - - // Calculate the width of the member name label. - const QRect boundingRect = fontMetrics.boundingRect(m_memberName.c_str()); - const int width = boundingRect.width(); - - // Set the width of the value indent spacer. This aligns all editor widgets under the value - // column to the same horizontal position. - ui.valueIndentSpacer->changeSize(s_VALUE_COLUMN_POSITION - width, 0, QSizePolicy::Fixed); -} - -void rgEditorElement::ClearSearchStringData() -{ - m_stringHighlightData.clear(); - UpdateButtonSubString(); - ResetLineEditSubString(); - ResetLabelSubString(); -} - -void rgEditorElement::ClearSearchStringDataVector() -{ - m_stringHighlightData.clear(); -} - -void rgEditorElement::HighlightButtonSubString(int startLocation, const std::string& searchString, bool isCurrentMatch) -{ - m_isCurrentMatch = isCurrentMatch; - - // Update search string location. - UpdateStringMatchingLocation(startLocation, static_cast(searchString.size()), searchString); - UpdateButtonSubString(); -} - -void rgEditorElement::UpdateButtonSubString() -{ - QPushButton *pPushButton = ui.editorHost->findChild(); - ArrowIconWidget* pIconWidget = qobject_cast(pPushButton); - if (pIconWidget != nullptr) - { - // Update the button string. - pIconWidget->SetHighLightSubStringData(m_stringHighlightData); - pIconWidget->SetHighLightSubString(true); - pIconWidget->update(); - } -} - -void rgEditorElement::UpdateStringMatchingLocation(int startLocation, int length, const std::string& searchString) -{ - bool isFound = false; - - // Remove any entries that do not match the search string anymore. - int count = 0; - std::vector removeEntries; - for (auto& stringData : m_stringHighlightData) - { - if (stringData.m_highlightString != searchString) - { - removeEntries.push_back(count); - } - count++; - } - for (std::vector::reverse_iterator it = removeEntries.rbegin(); it != removeEntries.rend(); ++it) - { - m_stringHighlightData.remove(*it); - } - - // Update existing locations, if any. - for (auto& stringData : m_stringHighlightData) - { - if (stringData.m_startLocation == startLocation) - { - stringData.m_endLocation = startLocation + length; - stringData.m_highlightString = searchString; - isFound = true; - SetHighlightColor(stringData); - break; - } - } - - // Create a new entry if a matching entry not found. - if (!isFound) - { - StringHighlightData stringHighlightData = {}; - stringHighlightData.m_startLocation = startLocation; - stringHighlightData.m_endLocation = startLocation + length; - stringHighlightData.m_highlightString = searchString; - SetHighlightColor(stringHighlightData); - m_stringHighlightData.push_back(stringHighlightData); - } -} - -void rgEditorElement::SetHighlightColor(StringHighlightData& stringHighlightData) -{ - // The color in which the current match would be highlighted. - static const QColor s_HIGHLIGHT_COLOR_MATCH_OTHER = QColor::fromRgba(qRgba(254, 206, 0, 200)); - - // The color in which any match would be highlighted. - static QColor s_HIGHLIGHT_COLOR_MATCH_CURRENT = QColor::fromRgba(qRgba(165, 175, 146, 200)); - - if (m_isCurrentMatch) - { - stringHighlightData.m_highlightColor = s_HIGHLIGHT_COLOR_MATCH_CURRENT; - } - else - { - stringHighlightData.m_highlightColor = s_HIGHLIGHT_COLOR_MATCH_OTHER; - } -} - -void rgEditorElement::ResetButtonSubString() -{ - QPushButton *pPushButton = ui.editorHost->findChild(); - ArrowIconWidget* pIconWidget = qobject_cast(pPushButton); - assert(pIconWidget != nullptr); - if (pIconWidget != nullptr) - { - pIconWidget->ClearHighLightSubStringData(); - pIconWidget->SetHighLightSubString(false); - pIconWidget->update(); - } -} - -void rgEditorElement::ResetLineEditSubString() -{ - rgLineEdit* pLineEdit = ui.editorHost->findChild(); - if (pLineEdit != nullptr) - { - // Clear search string highlight. - pLineEdit->SetHighlightSubString(false); - pLineEdit->update(); - } -} - -void rgEditorElement::HighlightLineEditSubString(int startLocation, const std::string& searchString, bool isCurrentMatch) -{ - m_isCurrentMatch = isCurrentMatch; - - rgLineEdit* pLineEdit = ui.editorHost->findChild(); - if (pLineEdit != nullptr) - { - // Update search string location. - UpdateStringMatchingLocation(startLocation, static_cast(searchString.size()), searchString); - pLineEdit->SetHighlightSubStringData(m_stringHighlightData); - pLineEdit->SetHighlightSubString(true); - pLineEdit->update(); - } -} - -void rgEditorElement::ResetLabelSubString() -{ - rgLabel* pLabel = ui.rowInfo->findChild(); - if (pLabel != nullptr) - { - // Clear search string highlight. - pLabel->SetHighlightSubString(false); - pLabel->update(); - } -} - -void rgEditorElement::HighlightLabelSubString(int startLocation, const std::string& searchString, bool isCurrentMatch) -{ - m_isCurrentMatch = isCurrentMatch; - - rgLabel* pLabel = ui.rowInfo->findChild(); - if (pLabel != nullptr) - { - // Update search string location. - UpdateStringMatchingLocation(startLocation, static_cast(searchString.size()), searchString); - pLabel->SetHighlightSubStringData(m_stringHighlightData); - pLabel->SetHighlightSubString(true); - pLabel->update(); - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgEditorElementArrayElementAdd.cpp b/RadeonGPUAnalyzerGUI/Src/rgEditorElementArrayElementAdd.cpp deleted file mode 100644 index 34a362c..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgEditorElementArrayElementAdd.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// C++. -#include - -// Local. -#include -#include - -rgEditorElementArrayElementAdd::rgEditorElementArrayElementAdd(QWidget* pParent, const std::string& memberName, std::function elementRemovedCallback) - : rgEditorElement(pParent, memberName, rgEditorDataType::Array) - , m_elementRemovedCallback(elementRemovedCallback) -{ - m_pEditorWidget = new rgPipelineStateEditorWidgetArrayElementAdd(this); - assert(m_pEditorWidget != nullptr); - if (m_pEditorWidget != nullptr) - { - ui.editorLayout->insertWidget(0, m_pEditorWidget); - - // Connect the loss of focus handler. - bool isConnected = connect(m_pEditorWidget, &rgPipelineStateEditorWidget::FocusOutSignal, - this, &rgEditorElement::HandleEditorFocusOut); - assert(isConnected); - } -} - -rgPipelineStateEditorWidget* rgEditorElementArrayElementAdd::GetEditorWidget() -{ - return m_pEditorWidget; -} - -void rgEditorElementArrayElementAdd::AddNewElement() -{ - assert(m_pArraySizeElement != nullptr); - if (m_pArraySizeElement != nullptr) - { - // Is there a maximum size specified for this array? - bool maximumSizeReached = false; - uint32_t currentArraySize = m_pArraySizeElement->GetValue(); - if (m_maximumSize > 0) - { - maximumSizeReached = currentArraySize == static_cast(m_maximumSize); - } - - // Increase the array dimension if possible. - if (!maximumSizeReached) - { - m_pArraySizeElement->SetValue(currentArraySize + 1); - } - } -} - -void rgEditorElementArrayElementAdd::RemoveElement(int elementIndex) -{ - // Remove the given element, and shift all remaining elements down in the array. - assert(m_elementRemovedCallback != nullptr); - if (m_elementRemovedCallback != nullptr) - { - // Invoke the callback used to handle elements being removed from the array. - m_elementRemovedCallback(elementIndex); - } - - // Update the array size element. - int currentArraySize = static_cast(m_pArraySizeElement->GetValue()); - m_pArraySizeElement->SetValue(currentArraySize - 1); - - // Invoke the resized callback. - InvokeElementResizedCallback(); -} - -void rgEditorElementArrayElementAdd::InvokeElementResizedCallback() -{ - // Invoke the array resized callback if available. - if (m_arrayResizedCallback != nullptr) - { - m_arrayResizedCallback(); - } - - // If the array was resized, and no longer has any child elements, update the indentation. - if (m_childItems.empty()) - { - UpdateIndentation(); - } -} - -rgEditorElementNumeric* rgEditorElementArrayElementAdd::GetArraySizeElement() const -{ - return m_pArraySizeElement; -} - -void rgEditorElementArrayElementAdd::SetArraySizeElement(rgEditorElementNumeric* pArraySizeElement) -{ - assert(pArraySizeElement != nullptr); - if (pArraySizeElement != nullptr) - { - m_pArraySizeElement = pArraySizeElement; - } -} - -void rgEditorElementArrayElementAdd::SetMaximumArraySize(uint32_t maximumSize) -{ - m_maximumSize = maximumSize; -} - -void rgEditorElementArrayElementAdd::SetResizeCallback(std::function resizeCallback) -{ - assert(resizeCallback != nullptr); - if (resizeCallback != nullptr) - { - m_arrayResizedCallback = resizeCallback; - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgEditorElementArrayElementRemove.cpp b/RadeonGPUAnalyzerGUI/Src/rgEditorElementArrayElementRemove.cpp deleted file mode 100644 index 2493418..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgEditorElementArrayElementRemove.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// C++. -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include - -// Delete confirmation dialog box message. -static const char* s_CONFIRMATION_DIALOG_MESSAGE_A = "The \""; -static const char* s_CONFIRMATION_DIALOG_MESSAGE_B = "\" item will be erased. Are you sure?"; - -// Dynamic tooltip strings (the tooltip for the trash can -// icon is being built dynamically based on the element's index). -static const char* STR_TRASH_ICON_REMOVE_1 = "Remove "; -static const char* STR_TRASH_ICON_REMOVE_2 = " item (index "; -static const char* STR_TRASH_ICON_REMOVE_3 = ")."; - -rgEditorElementArrayElementRemove::rgEditorElementArrayElementRemove(QWidget* pParent, const std::string& memberName) - : rgEditorElement(pParent, memberName, rgEditorDataType::ArrayElement) -{ - m_pEditorWidget = new rgPipelineStateEditorWidgetArrayElementRemove(this); - assert(m_pEditorWidget != nullptr); - if (m_pEditorWidget != nullptr) - { - ui.editorLayout->insertWidget(0, m_pEditorWidget); - } - - // Connect internal signals to slots. - ConnectSignals(); -} - -rgPipelineStateEditorWidget* rgEditorElementArrayElementRemove::GetEditorWidget() -{ - return m_pEditorWidget; -} - -void rgEditorElementArrayElementRemove::ConnectSignals() -{ - // Connect the delete button handler. - bool isConnected = connect(m_pEditorWidget, &rgPipelineStateEditorWidgetArrayElementRemove::DeleteButtonClicked, - this, &rgEditorElementArrayElementRemove::HandleDeleteButtonClicked); - assert(isConnected); - - // Connect the loss of focus handler. - isConnected = connect(m_pEditorWidget, &rgPipelineStateEditorWidgetArrayElementRemove::FocusOutSignal, - this, &rgEditorElement::HandleEditorFocusOut); - assert(isConnected); -} - -void rgEditorElementArrayElementRemove::SetElementIndex(rgEditorElementArrayElementAdd* pParentArray, int childIndex) -{ - assert(pParentArray != nullptr); - if (pParentArray != nullptr) - { - m_pArrayRootElement = pParentArray; - m_childIndex = childIndex; - - // Update the tooltip. - std::stringstream tooltipTxt; - auto beginPos = m_memberName.find(" "); - assert(beginPos < m_memberName.size()-2); - if (beginPos < m_memberName.size() - 2) - { - // Build the tooltip string without the prefix. - std::string memebrNameNoPrefix = m_memberName.substr(beginPos + 1); - tooltipTxt << STR_TRASH_ICON_REMOVE_1 << memebrNameNoPrefix << STR_TRASH_ICON_REMOVE_2 << m_childIndex << STR_TRASH_ICON_REMOVE_3; - m_pEditorWidget->SetTrashCanIconTooltip(tooltipTxt.str().c_str()); - } - } -} - -void rgEditorElementArrayElementRemove::HandleDeleteButtonClicked() -{ - assert(m_pArrayRootElement != nullptr); - if (m_pArrayRootElement != nullptr) - { - // Expand the row clicked on. - ExpandTreeEntry(); - - // Remove highlight from the previous row, and select the current row. - rgPipelineStateTree* pStateTree = GetParentStateTree(); - assert(pStateTree != nullptr); - if (pStateTree != nullptr) - { - pStateTree->SetCurrentSelection(nullptr); - } - - // Show a confirmation dialog box. - std::string message = s_CONFIRMATION_DIALOG_MESSAGE_A + m_memberName + s_CONFIRMATION_DIALOG_MESSAGE_B; - bool result = rgUtils::ShowConfirmationMessageBox(STR_PIPELINE_STATE_EDITOR_DELETE_ELEMENT_CONFIRMATION_TITLE, message.c_str(), this); - - if (result) - { - assert(pStateTree != nullptr); - if (pStateTree != nullptr) - { - // Select the array root element before removing the child array element. - pStateTree->SetCurrentSelection(m_pArrayRootElement); - } - - // Delete the given element from the array. - m_pArrayRootElement->RemoveElement(m_childIndex); - } - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgEditorElementBool.cpp b/RadeonGPUAnalyzerGUI/Src/rgEditorElementBool.cpp deleted file mode 100644 index 06c2e7e..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgEditorElementBool.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// C++. -#include - -// Local. -#include -#include - -rgEditorElementBool::rgEditorElementBool(QWidget* pParent, const std::string& memberName, uint32_t* pValue) - : rgEditorElement(pParent, memberName, rgEditorDataType::Bool) - , m_pValue(pValue) -{ - m_pEditorWidget = new rgPipelineStateEditorWidgetBool(this); - assert(m_pEditorWidget != nullptr); - if (m_pEditorWidget != nullptr) - { - // Set the value for the widget. - m_pEditorWidget->SetValue(GetValue()); - - // Insert the editor widget into the row. - ui.editorLayout->insertWidget(0, m_pEditorWidget); - - // Connect internal editor signals. - bool isConnected = connect(m_pEditorWidget, &rgPipelineStateEditorWidgetBool::EditingFinished, this, &rgEditorElement::HandleValueChanged); - assert(isConnected); - - // Connect the editor widget focus in signal. - isConnected = connect(m_pEditorWidget, &rgPipelineStateEditorWidgetBool::FocusInSignal, this, &rgEditorElement::HandleEditorFocusIn); - assert(isConnected); - - // Connect the editor widget focus out signal. - isConnected = connect(m_pEditorWidget, &rgPipelineStateEditorWidgetBool::FocusOutSignal, this, &rgEditorElement::HandleEditorFocusOut); - assert(isConnected); - } -} - -QVariant rgEditorElementBool::Data(int column) const -{ - if (column == static_cast(rgRowData::RowDataMemberValue)) - { - return GetValue(); - } - else - { - return rgEditorElement::Data(column); - } -} - -rgPipelineStateEditorWidget* rgEditorElementBool::GetEditorWidget() -{ - return m_pEditorWidget; -} - -bool rgEditorElementBool::GetValue() const -{ - assert(m_pValue != nullptr); - return *m_pValue > 0 ? true : false; -} - -void rgEditorElementBool::SetValue(bool value) -{ - assert(m_pValue != nullptr); - if (m_pValue != nullptr) - { - *m_pValue = value; - } -} - -void rgEditorElementBool::ValueChangedHandler() -{ - assert(m_pEditorWidget != nullptr); - if (m_pEditorWidget != nullptr) - { - // Update the row's check state based on the editor widget's check state. - bool isChecked = m_pEditorWidget->GetValue(); - SetValue(isChecked); - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgEditorElementEnum.cpp b/RadeonGPUAnalyzerGUI/Src/rgEditorElementEnum.cpp deleted file mode 100644 index 6a361b5..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgEditorElementEnum.cpp +++ /dev/null @@ -1,123 +0,0 @@ -// C++. -#include -#include - -// Local. -#include -#include - -rgEditorElementEnum::rgEditorElementEnum(QWidget* pParent, const std::string& memberName, const rgEnumValuesVector& enumerators, uint32_t* pValue, bool isBitFlags) - : rgEditorElement(pParent, memberName, rgEditorDataType::Enum) - , m_enumerators(enumerators) - , m_pValue(pValue) - , m_isBitFlagsEnum(isBitFlags) - , m_pParent(pParent) -{ - // Ensure that the value pointer is valid. - assert(m_pValue != nullptr); - - m_pEditorWidget = new rgPipelineStateEditorWidgetEnum(m_isBitFlagsEnum, m_pParent); - m_pEditorWidget->setObjectName(QString::fromStdString(memberName)); - assert(m_pEditorWidget != nullptr); - if (m_pEditorWidget != nullptr) - { - // Initialize the editor widget with the list of enumerators and initial value. - m_pEditorWidget->SetEnumerators(enumerators); - m_pEditorWidget->SetValue(GetValue()); - - // Insert the editor widget into the new row. - ui.editorLayout->insertWidget(0, m_pEditorWidget); - - // Connect the editor's value change handler. - bool isConnected = connect(m_pEditorWidget, &rgPipelineStateEditorWidgetEnum::EditingFinished, this, &rgEditorElement::HandleValueChanged); - assert(isConnected); - - // Connect the editor widget focus in signal. - isConnected = connect(m_pEditorWidget, &rgPipelineStateEditorWidgetEnum::FocusInSignal, this, &rgEditorElement::HandleEditorFocusIn); - assert(isConnected); - - // Connect the editor widget focus out signal. - isConnected = connect(m_pEditorWidget, &rgPipelineStateEditorWidgetEnum::FocusOutSignal, this, &rgEditorElement::HandleEditorFocusOut); - assert(isConnected); - - // Connect the list widget status signal. - isConnected = connect(m_pEditorWidget, &rgPipelineStateEditorWidgetEnum::EnumListWidgetStatusSignal, this, &rgEditorElementEnum::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgEditorElementEnum::HotKeyPressedSignal, m_pEditorWidget, &rgPipelineStateEditorWidgetEnum::HandleHotKeyPressedSignal); - assert(isConnected); - } -} - -QVariant rgEditorElementEnum::Data(int column) const -{ - QVariant result = rgEditorElement::Data(column); - - if (column == static_cast(rgRowData::RowDataMemberValue)) - { - // Get the current enumeration value. - uint32_t currentValue = GetValue(); - - // Is this a normal enumeration or a set of bit flags? - if (m_isBitFlagsEnum) - { - std::string flagBits; - assert(m_pEditorWidget != nullptr); - if (m_pEditorWidget != nullptr) - { - m_pEditorWidget->GetFlagBitsString(flagBits); - } - - result = flagBits.c_str(); - } - else - { - // Search for the name/value pair of the current enumerator. - rgEnumeratorSearcher searcher(currentValue); - auto enumeratorPairIter = std::find_if(m_enumerators.begin(), m_enumerators.end(), searcher); - if (enumeratorPairIter != m_enumerators.end()) - { - result = enumeratorPairIter->m_name.c_str(); - } - } - } - - return result; -} - -rgPipelineStateEditorWidget* rgEditorElementEnum::GetEditorWidget() -{ - return m_pEditorWidget; -} - -const rgEnumValuesVector& rgEditorElementEnum::GetEnumerators() const -{ - return m_enumerators; -} - -uint32_t rgEditorElementEnum::GetValue() const -{ - return *m_pValue; -} - -void rgEditorElementEnum::SetValue(uint32_t value) -{ - *m_pValue = value; - - if (m_valueChangedCallback != nullptr) - { - m_valueChangedCallback(); - } -} - -void rgEditorElementEnum::ValueChangedHandler() -{ - assert(m_pEditorWidget != nullptr); - if (m_pEditorWidget != nullptr) - { - // Update the row's value using the editor widget's current value. - uint32_t enumValue = m_pEditorWidget->GetValue(); - SetValue(enumValue); - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgFactory.cpp b/RadeonGPUAnalyzerGUI/Src/rgFactory.cpp deleted file mode 100644 index 66c2fc5..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgFactory.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// C++. -#include - -// Local. -#include -#include -#include -#include - -std::shared_ptr rgFactory::CreateFactory(rgProjectAPI api) -{ - std::shared_ptr pFactory = nullptr; - - switch (api) - { - case rgProjectAPI::OpenCL: - { - pFactory = std::make_shared(); - } - break; - case rgProjectAPI::Vulkan: - { - pFactory = std::make_shared(); - } - break; - default: - // If this assert fires, a new API factory must be implemented. - assert(true); - break; - } - - // If this assert fires, the factory failed to be created properly. - assert(pFactory != nullptr); - - return pFactory; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgFactoryOpenCL.cpp b/RadeonGPUAnalyzerGUI/Src/rgFactoryOpenCL.cpp deleted file mode 100644 index 7df078a..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgFactoryOpenCL.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// C++. -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static rgStylesheetPackage s_STYLESHEET_PACKAGE = { STR_FILE_MENU_STYLESHEET_FILE, - STR_FILE_MENU_STYLESHEET_FILE_OPENCL, - STR_MAIN_WINDOW_STYLESHEET_FILE, - STR_APPLICATION_STYLESHEET_FILE_OPENCL, - STR_MAIN_WINDOW_STYLESHEET_FILE_OPENCL, - }; - -std::shared_ptr rgFactoryOpenCL::CreateAppState() -{ - return std::make_shared(); -} - -std::shared_ptr rgFactoryOpenCL::CreateProject(const std::string& projectName, const std::string& projectFileFullPath) -{ - return std::make_shared(projectName, projectFileFullPath); -} - -std::shared_ptr rgFactoryOpenCL::CreateProjectClone(const std::string& cloneName) -{ - // Create a copy of the global OpenCL build settings. - std::shared_ptr pGlobalCLSettings = rgConfigManager::Instance().GetUserGlobalBuildSettings(rgProjectAPI::OpenCL); - std::shared_ptr pCloneSettingsCopy = std::dynamic_pointer_cast(CreateBuildSettings(pGlobalCLSettings)); - - // Insert the copied global settings into the new project clone. - return std::make_shared(cloneName, pCloneSettingsCopy); -} - -std::shared_ptr rgFactoryOpenCL::CreateBuildSettings(std::shared_ptr pInitialBuildSettings) -{ - std::shared_ptr pBuildSettings = nullptr; - - if (pInitialBuildSettings != nullptr) - { - std::shared_ptr pBuildSettingsOpenCL = std::dynamic_pointer_cast(pInitialBuildSettings); - pBuildSettings = std::make_shared(*pBuildSettingsOpenCL); - } - else - { - pBuildSettings = std::make_shared(); - } - - return pBuildSettings; -} - -rgBuildSettingsView* rgFactoryOpenCL::CreateBuildSettingsView(QWidget* pParent, std::shared_ptr pBuildSettings, bool isGlobalSettings) -{ - assert(pBuildSettings != nullptr); - return new rgBuildSettingsViewOpenCL(pParent, *std::static_pointer_cast(pBuildSettings), isGlobalSettings); -} - -rgBuildView* rgFactoryOpenCL::CreateBuildView(QWidget* pParent) -{ - return new rgBuildViewOpenCL(pParent); -} - -rgIsaDisassemblyView* rgFactoryOpenCL::CreateDisassemblyView(QWidget* pParent) -{ - return new rgIsaDisassemblyViewOpenCL(pParent); -} - -rgMenu* rgFactoryOpenCL::CreateFileMenu(QWidget* pParent) -{ - // Create the api-specific file menu. - rgMenu* pMenu = new rgMenuOpenCL(pParent); - - // Apply the file menu stylesheet. - std::vector stylesheetFileNames; - stylesheetFileNames.push_back(s_STYLESHEET_PACKAGE.m_fileMenuStylesheet); - stylesheetFileNames.push_back(s_STYLESHEET_PACKAGE.m_fileMenuApiStylesheet); - bool status = rgUtils::LoadAndApplyStyle(stylesheetFileNames, pMenu); - assert(status); - - return pMenu; -} - -rgStartTab* rgFactoryOpenCL::CreateStartTab(QWidget* pParent) -{ - // Create the API-specific start tab. - rgStartTab* pStartTab = new rgStartTabOpenCL(pParent); - - return pStartTab; -} - -rgStatusBar* rgFactoryOpenCL::CreateStatusBar(QStatusBar* pStatusBar, QWidget* pParent) -{ - return new rgStatusBarOpenCL(pStatusBar, pParent); -} - -rgSettingsTab* rgFactoryOpenCL::CreateSettingsTab(QWidget* pParent) -{ - return new rgSettingsTabOpenCL(pParent); -} - -rgRenameProjectDialog* rgFactoryOpenCL::CreateRenameProjectDialog(std::string& projectName, QWidget* pParent) -{ - rgRenameProjectDialog* pRenameDialog = new rgRenameProjectDialog(projectName, pParent); - pRenameDialog->setWindowTitle(STR_RENAME_PROJECT_DIALOG_BOX_TITLE_OPENCL); - - // Register the rename dialog with the scaling manager. - ScalingManager::Get().RegisterObject(pRenameDialog); - - // Center the dialog on the view (registering with the scaling manager - // shifts it out of the center so we need to manually center it). - rgUtils::CenterOnWidget(pRenameDialog, pParent); - - return pRenameDialog; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgFactoryVulkan.cpp b/RadeonGPUAnalyzerGUI/Src/rgFactoryVulkan.cpp deleted file mode 100644 index 57ea6e3..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgFactoryVulkan.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// C++. -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// The Vulkan menu widget does not use API-specific styling. We specify the basic menu style file -// because the pipeline menu styles are graphics-API agnostic. -static rgStylesheetPackage s_STYLESHEET_PACKAGE = { STR_FILE_MENU_STYLESHEET_FILE, - STR_FILE_MENU_STYLESHEET_FILE_VULKAN, - STR_MAIN_WINDOW_STYLESHEET_FILE, - STR_APPLICATION_STYLESHEET_FILE_VULKAN, - STR_MAIN_WINDOW_STYLESHEET_FILE_VULKAN, - }; - -std::shared_ptr rgFactoryVulkan::CreateAppState() -{ - return std::make_shared(); -} - -std::shared_ptr rgFactoryVulkan::CreateProject(const std::string& projectName, const std::string& projectFileFullPath) -{ - return std::make_shared(projectName, projectFileFullPath); -} - -std::shared_ptr rgFactoryVulkan::CreateProjectClone(const std::string& cloneName) -{ - // Create a copy of the global Vulkan build settings. - std::shared_ptr pGlobalVulkanSettings = rgConfigManager::Instance().GetUserGlobalBuildSettings(rgProjectAPI::Vulkan); - std::shared_ptr pCloneSettingsCopy = std::dynamic_pointer_cast(CreateBuildSettings(pGlobalVulkanSettings)); - - // Insert the copied global settings into the new project clone. - return std::make_shared(cloneName, pCloneSettingsCopy); -} - -std::shared_ptr rgFactoryVulkan::CreateBuildSettings(std::shared_ptr pInitialBuildSettings) -{ - std::shared_ptr pBuildSettings = nullptr; - - // Create a new rgCLBuildSettings instance based on the incoming build settings. - if (pInitialBuildSettings != nullptr) - { - auto pBuildSettingsVulkan = std::dynamic_pointer_cast(pInitialBuildSettings); - pBuildSettings = std::make_shared(*pBuildSettingsVulkan); - } - else - { - pBuildSettings = std::make_shared(); - } - - return pBuildSettings; -} - -rgBuildSettingsView* rgFactoryVulkan::CreateBuildSettingsView(QWidget* pParent, std::shared_ptr pBuildSettings, bool isGlobalSettings) -{ - assert(pBuildSettings != nullptr); - return new rgBuildSettingsViewVulkan(pParent, *std::static_pointer_cast(pBuildSettings), isGlobalSettings); -} - -rgBuildView* rgFactoryVulkan::CreateBuildView(QWidget* pParent) -{ - return new rgBuildViewVulkan(pParent); -} - -rgIsaDisassemblyView* rgFactoryVulkan::CreateDisassemblyView(QWidget* pParent) -{ - return new rgIsaDisassemblyViewVulkan(pParent); -} - -rgMenu* rgFactoryVulkan::CreateFileMenu(QWidget* pParent) -{ - rgMenu* pMenu = new rgMenuVulkan(pParent); - - // Apply the file menu stylesheet. - std::vector stylesheetFileNames; - stylesheetFileNames.push_back(s_STYLESHEET_PACKAGE.m_fileMenuStylesheet); - stylesheetFileNames.push_back(s_STYLESHEET_PACKAGE.m_fileMenuApiStylesheet); - bool status = rgUtils::LoadAndApplyStyle(stylesheetFileNames, pMenu); - assert(status); - - return pMenu; -} - -rgStartTab* rgFactoryVulkan::CreateStartTab(QWidget* pParent) -{ - // Create the API-specific start tab. - rgStartTab* pStartTab = new rgStartTabVulkan(pParent); - - return pStartTab; -} - -rgStatusBar* rgFactoryVulkan::CreateStatusBar(QStatusBar* pStatusBar, QWidget* pParent) -{ - return new rgStatusBarVulkan(pStatusBar, pParent); -} - -rgPipelineStateModel* rgFactoryVulkan::CreatePipelineStateModel(QWidget* pParent) -{ - return new rgPipelineStateModelVulkan(pParent); -} - -rgSettingsTab* rgFactoryVulkan::CreateSettingsTab(QWidget* pParent) -{ - return new rgSettingsTabVulkan(pParent); -} - -rgRenameProjectDialog* rgFactoryVulkan::CreateRenameProjectDialog(std::string& projectName, QWidget* pParent) -{ - rgRenameProjectDialog* pRenameDialog = new rgRenameProjectDialog(projectName, pParent); - pRenameDialog->setWindowTitle(STR_RENAME_PROJECT_DIALOG_BOX_TITLE_VULKAN); - - // Register the rename dialog with the scaling manager. - ScalingManager::Get().RegisterObject(pRenameDialog); - - // Center the dialog on the view (registering with the scaling manager - // shifts it out of the center so we need to manually center it). - rgUtils::CenterOnWidget(pRenameDialog, pParent); - - return pRenameDialog; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgFindTextWidget.cpp b/RadeonGPUAnalyzerGUI/Src/rgFindTextWidget.cpp deleted file mode 100644 index 79df97c..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgFindTextWidget.cpp +++ /dev/null @@ -1,243 +0,0 @@ -// C++. -#include - -// Local. -#include -#include -#include -#include -#include - -rgFindTextWidget::rgFindTextWidget(QWidget* pParent) : - QWidget(pParent) -{ - // Initialize the interface object. - ui.setupUi(this); - - // Set the tooltip and status tip for the Find next button. - rgUtils::SetToolAndStatusTip(STR_EDIT_FIND_NEXT_TOOLTIP, ui.findNextPushButton); - - // Set the tooltip and status tip for the Find previous button. - rgUtils::SetToolAndStatusTip(STR_EDIT_FIND_PREVIOUS_TOOLTIP, ui.findPreviousPushButton); - - // Set the tooltip for the Close button. - rgUtils::SetToolAndStatusTip(STR_EDIT_FIND_CLOSE_TOOLTIP, ui.closePushButton); - - // Add a Search magnifying glass to the search textbox. - ui.searchLineEdit->setClearButtonEnabled(true); - ui.searchLineEdit->addAction(QIcon(gs_ICON_RESOURCE_FIND_MAGNIFYING_GLASS), QLineEdit::LeadingPosition); - - // Create the keyboard actions associated with the Find widget. - CreateActions(); - - // Connect all internal signals to handler slots. - ConnectSignals(); - - // Set the cursor to pointing hand cursor. - SetCursor(); - - // Set focus proxies for filter and match case buttons to be the line edit, - // so each time one of these buttons are clicked, the focus will remain with - // the line edit. - ui.filterRowsPushButton->setFocusProxy(ui.searchLineEdit); - ui.matchCasePushButton->setFocusProxy(ui.searchLineEdit); -} - -void rgFindTextWidget::SetFocused() -{ - // Focus on the line edit and select all existing text to make new searches quicker. - ui.searchLineEdit->setFocus(); - ui.searchLineEdit->selectAll(); - - // Update the search context options every time the search widget gets focus. - UpdateSearchOptions(); -} - -void rgFindTextWidget::SetSearchContext(ISearchable* pSearchContext) -{ - assert(pSearchContext != nullptr); - if (pSearchContext != nullptr) - { - m_pSearchContext = pSearchContext; - - // Toggle the search option button visibility based on the searcher's supported options. - uint32_t options = m_pSearchContext->GetSupportedOptions(); - ToggleOptionVisibility(options); - } -} - -void rgFindTextWidget::ToggleOptionVisibility(uint32_t options) -{ - ui.findPreviousPushButton->setVisible((options & ISearchable::SupportedOptions::FindPrevious) == ISearchable::SupportedOptions::FindPrevious); - ui.findNextPushButton->setVisible((options & ISearchable::SupportedOptions::FindNext) == ISearchable::SupportedOptions::FindNext); - ui.filterRowsPushButton->setVisible((options & ISearchable::SupportedOptions::FilterTree) == ISearchable::SupportedOptions::FilterTree); - ui.matchCasePushButton->setVisible((options & ISearchable::SupportedOptions::MatchCase) == ISearchable::SupportedOptions::MatchCase); -} - -void rgFindTextWidget::SetSearchString(const std::string& searchString) -{ - // Insert the text into the search line edit. - ui.searchLineEdit->setText(searchString.c_str()); -} - -void rgFindTextWidget::keyPressEvent(QKeyEvent* pEvent) -{ - // If the user pressed the escape key, close the widget. - if (pEvent->key() == Qt::Key_Escape) - { - // Reset the search when the user closes the Find widget. - m_pSearchContext->ResetSearch(); - - // Let the rgBuildView know that the Find widget has been closed. - emit CloseWidgetSignal(); - } - - // Invoke the baseclass QWidget implementation of the key handler. - QWidget::keyPressEvent(pEvent); -} - -void rgFindTextWidget::ConnectSignals() -{ - // Connect the handler for the close button. - bool isConnected = connect(ui.closePushButton, &QPushButton::clicked, this, &rgFindTextWidget::HandleCloseButtonClicked); - assert(isConnected); - - // Connect the find previous button to the associated action. - assert(m_pFindPreviousAction != nullptr); - if (m_pFindPreviousAction != nullptr) - { - // Connect the handler for the "Find previous" button. - isConnected = connect(ui.findPreviousPushButton, &QPushButton::clicked, this, &rgFindTextWidget::HandleFindPreviousButtonClicked); - assert(isConnected); - - // Add a hotkey action to the button. - ui.findPreviousPushButton->addAction(m_pFindPreviousAction); - } - - // Connect the find next button to the associated action. - assert(m_pFindNextAction != nullptr); - if (m_pFindNextAction != nullptr) - { - // Connect the handler for the "Find next" button. - isConnected = connect(ui.findNextPushButton, &QPushButton::clicked, this, &rgFindTextWidget::HandleFindNextButtonClicked); - assert(isConnected); - - // Add a hotkey action to the button. - ui.findNextPushButton->addAction(m_pFindNextAction); - } - - // Connect the handler invoked when the user presses the "Enter" key while the search textbox is selected. - isConnected = connect(ui.searchLineEdit, &QLineEdit::returnPressed, this, &rgFindTextWidget::HandleReturnPressedOnSearch); - assert(isConnected); - - // Connect the handler invoked when the user changes the - // check state of any of the search option buttons. - isConnected = connect(ui.filterRowsPushButton, &QPushButton::toggled, this, &rgFindTextWidget::HandleOptionButtonCheckChanged); - assert(isConnected); - isConnected = connect(ui.matchCasePushButton, &QPushButton::toggled, this, &rgFindTextWidget::HandleOptionButtonCheckChanged); - assert(isConnected); - - isConnected = connect(ui.searchLineEdit, &QLineEdit::textChanged, this, &rgFindTextWidget::HandleSearchTextChanged); - assert(isConnected); -} - -void rgFindTextWidget::HandleCloseButtonClicked() -{ - // Reset the search results. - m_pSearchContext->ResetSearch(); - - emit CloseWidgetSignal(); -} - -void rgFindTextWidget::HandleFindPreviousButtonClicked() -{ - // Use the search context to look for the previous match. - assert(m_pSearchContext != nullptr); - if (m_pSearchContext != nullptr) - { - m_pSearchContext->Find(ui.searchLineEdit->text(), ISearchable::SearchDirection::Previous); - } -} - -void rgFindTextWidget::HandleFindNextButtonClicked() -{ - // Use the search context to look for the next match. - assert(m_pSearchContext != nullptr); - if (m_pSearchContext != nullptr) - { - m_pSearchContext->Find(ui.searchLineEdit->text(), ISearchable::SearchDirection::Next); - } -} - -void rgFindTextWidget::HandleReturnPressedOnSearch() -{ - // Return starts the next search. - HandleFindNextButtonClicked(); -} - -void rgFindTextWidget::HandleOptionButtonCheckChanged(bool checked) -{ - // Update the search option flags in the search context. - UpdateSearchOptions(); -} - -void rgFindTextWidget::HandleSearchTextChanged(const QString& updatedText) -{ - HandleReturnPressedOnSearch(); -} - -void rgFindTextWidget::CreateActions() -{ - // Create the "Find next" action. - m_pFindNextAction = new QAction(tr(STR_EDIT_FIND_NEXT), this); - assert(m_pFindNextAction != nullptr); - if (m_pFindNextAction != nullptr) - { - // Configure the hotkey for the Find next action. - m_pFindNextAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_FIND_NEXT)); - - // Connect the handler for the "Find next" button. - bool isConnected = connect(m_pFindNextAction, &QAction::triggered, this, &rgFindTextWidget::HandleFindNextButtonClicked); - assert(isConnected); - } - - // Create the "Find previous" action. - m_pFindPreviousAction = new QAction(tr(STR_EDIT_FIND_PREVIOUS), this); - assert(m_pFindPreviousAction != nullptr); - if (m_pFindPreviousAction != nullptr) - { - // Configure the hotkey for the Find previous action. - m_pFindPreviousAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_FIND_PREVIOUS)); - - // Connect the handler for the "Find previous" button. - bool isConnected = connect(m_pFindPreviousAction, &QAction::triggered, this, &rgFindTextWidget::HandleFindPreviousButtonClicked); - assert(isConnected); - } -} - -void rgFindTextWidget::SetCursor() -{ - // Set the hand pointers for the buttons. - ui.filterRowsPushButton->setCursor(Qt::PointingHandCursor); - ui.matchCasePushButton->setCursor(Qt::PointingHandCursor); - ui.findNextPushButton->setCursor(Qt::PointingHandCursor); - ui.findPreviousPushButton->setCursor(Qt::PointingHandCursor); - ui.closePushButton->setCursor(Qt::PointingHandCursor); -} - -void rgFindTextWidget::UpdateSearchOptions() -{ - assert(m_pSearchContext != nullptr); - if (m_pSearchContext != nullptr) - { - // Update the search options by sending the option button states to the search context. - m_pSearchContext->SetSearchOptions({ - ui.filterRowsPushButton->isChecked(), - ui.matchCasePushButton->isChecked() - }); - - // Trigger the search. - m_pSearchContext->ResetSearch(); - m_pSearchContext->Find(ui.searchLineEdit->text(), ISearchable::SearchDirection::Next); - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgGlobalSettingsView.cpp b/RadeonGPUAnalyzerGUI/Src/rgGlobalSettingsView.cpp deleted file mode 100644 index 18717bd..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgGlobalSettingsView.cpp +++ /dev/null @@ -1,946 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include -#include -#include -#include -#include -#include - -// Infra. -#include -#include -#include -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include - -// Names of special widgets within the build settings view. -static const char* STR_GLOBAL_SETTINGS_COLUMN_VISIBILITY_LIST = "DisassemblyColumnVisibilityList"; -static const char* STR_GLOBAL_SETTINGS_COLUMN_LIST_ITEM_CHECKBOX = "ListWidgetCheckBox"; -static const char* STR_GLOBAL_SETTINGS_COLUMN_LIST_ITEM_ALL_CHECKBOX = "ListWidgetAllCheckBox"; - -// API-specific colors. -static const QColor s_API_COLOR_OPENCL = QColor(18, 152, 0); -static const QColor s_API_COLOR_VULKAN = QColor(135, 20, 16); - -// Columns push button font size. -const int s_PUSH_BUTTON_FONT_SIZE = 11; - -// The maximum font size allowed in the font size combo box. -static const int s_MAX_FONT_SIZE = 50; - -rgGlobalSettingsView::rgGlobalSettingsView(QWidget* pParent, const rgGlobalSettings& globalSettings) : - rgBuildSettingsView(pParent, true), - m_initialSettings(globalSettings), - m_pParent(pParent) -{ - // Setup the UI. - ui.setupUi(this); - - // Set the background to white. - QPalette pal = palette(); - pal.setColor(QPalette::Background, Qt::white); - this->setAutoFillBackground(true); - this->setPalette(pal); - - // Create the widget used to control column visibility. - CreateColumnVisibilityControls(); - - // Fill the column visibility dropdown with all of the possible column names. - PopulateColumnVisibilityList(); - - // Initialize the combo box for font size. - for (int i = 1; i < s_MAX_FONT_SIZE; i++) - { - ui.fontSizeComboBox->addItem(QString::number(i), QString::number(i)); - } - - // Push values to various widgets. - PushToWidgets(globalSettings); - - // Connect the signals. - ConnectSignals(); - - // Set the mouse cursor to the pointing hand cursor for various widgets. - SetCursor(); - - // Set the tool tip for default project name check box. - SetCheckboxToolTip(STR_GLOBAL_SETTINGS_CHECKBOX_TOOLTIP); - - // Set the tool tip for the two edit boxes. - SetEditBoxToolTips(); - - // Set the tooltip for the log file location. - ui.logFileLocationLabel->setToolTip(STR_GLOBAL_SETTINGS_LOG_FILE_LOCATION); - - // Set the tooltips for the disassembly section. - ui.disassemblyViewLabel->setToolTip(STR_GLOBAL_SETTINGS_DISASSEMBLY_SECTION_TOOLTIP); - - // Set the tooltips for the disassembly columns. - ui.disassemblyViewColunnsLabel->setToolTip(STR_GLOBAL_SETTINGS_DISASSEMBLY_COLUMNS_TOOLTIP); - - // Set the tooltips for the source code editor. - ui.sourceCodeEditorLabel->setToolTip(STR_GLOBAL_SETTINGS_SRC_VIEW_SECTION_TOOLTIP); - - // Set the tooltips for the font type in the source code editor. - ui.fontFamilyLabel->setToolTip(STR_GLOBAL_SETTINGS_SRC_VIEW_FONT_TYPE_TOOLTIP); - - // Set the tooltips for the font size in the source code editor. - ui.fontSizeLabel->setToolTip(STR_GLOBAL_SETTINGS_SRC_VIEW_FONT_SIZE_TOOLTIP); - - // Set the tooltips for the include files viewer. - ui.includeFilesViewerLabel->setToolTip(STR_GLOBAL_SETTINGS_SRC_VIEW_INCLUDE_FILES_VIEWER_TOOLTIP); - - // Set the tooltips for input files associations. - ui.assocExtGlslLabel->setToolTip(STR_GLOBAL_SETTNIGS_FILE_EXT_GLSL_TOOLTIP); - ui.assocExtHlslLabel->setToolTip(STR_GLOBAL_SETTNIGS_FILE_EXT_HLSL_TOOLTIP); - ui.assocExtSpvasLabel->setToolTip(STR_GLOBAL_SETTNIGS_FILE_EXT_SPV_TXT_TOOLTIP); - - // Set the tooltip for the default source language. - ui.defaultLangLabel->setToolTip(STR_GLOBAL_SETTINGS_DEFAULT_SRC_LANG_TOOLTIP); - - // Set the tooltip for the general section. - ui.generalLabel->setToolTip(STR_GLOBAL_SETTINGS_GENERAL_SECTION_TOOLTIP); - - // Set the tooltip for the default API section. - ui.defaultApiOnStartupLabel->setToolTip(STR_GLOBAL_SETTINGS_DEFAULT_STARTUP_API_TOOLTIP); - - // Set the tooltip for the Input Files section. - ui.inputFilesLabel->setToolTip(STR_GLOBAL_SETTINGS_INPUT_FILES_SECTION_TOOLTIP); - - // Set the tooltip for the SPIR-V binary. - ui.assocExtSpvBinaryLabel->setToolTip(STR_GLOBAL_SETTINGS_SPV_EXTENSIONS_TOOLTIP); - - // Set the fonts for the list widget push button. - QFont font = ui.columnVisibilityArrowPushButton->font(); - double scaleFactor = ScalingManager::Get().GetScaleFactor(); - font.setPointSize(gs_BUTTON_POINT_FONT_SIZE * scaleFactor); - ui.columnVisibilityArrowPushButton->setFont(font); - - // Hide HLSL components until support for HLSL is added. - ui.assocExtHlslLabel->hide(); - ui.assocExtHlslLineEdit->hide(); - ui.defaultLangLabel->hide(); - ui.defaultLangComboBox->hide(); - - // Set column visibility arrow push button properties. - rgProjectAPI currentApi = rgConfigManager::Instance().GetCurrentAPI(); - if (currentApi == rgProjectAPI::OpenCL) - { - ui.columnVisibilityArrowPushButton->SetBorderColor(s_API_COLOR_OPENCL); - ui.columnVisibilityArrowPushButton->SetShowBorder(true); - } - else if (currentApi == rgProjectAPI::Vulkan) - { - ui.columnVisibilityArrowPushButton->SetBorderColor(s_API_COLOR_VULKAN); - ui.columnVisibilityArrowPushButton->SetShowBorder(true); - } - else - { - // Should not get here. - assert(false); - } -} - -rgGlobalSettingsView::~rgGlobalSettingsView() -{ - // Remove the column dropdown focus event filters if they exist. - if (m_pDisassemblyColumnsListWidget != nullptr && m_pDisassemblyColumnsListEventFilter != nullptr) - { - m_pDisassemblyColumnsListWidget->removeEventFilter(m_pDisassemblyColumnsListEventFilter); - qApp->removeEventFilter(m_pDisassemblyColumnsListEventFilter); - } -} - -void rgGlobalSettingsView::showEvent(QShowEvent* pEvent) -{ - QWidget::showEvent(pEvent); - - // The global settings can be updated by other widgets in the application, - // so if this view does not think it has any pending changes, then reset - // the UI based on the config manager's global config, then update this - // view's intitialSettings to match and signal that there are no pending changes. - if (GetHasPendingChanges() == false) - { - std::shared_ptr pSettings = rgConfigManager::Instance().GetGlobalConfig(); - assert(pSettings != nullptr); - if (pSettings != nullptr) - { - PushToWidgets(*pSettings); - } - - m_initialSettings = PullFromWidgets(); - - HandlePendingChangesStateChanged(false); - } -} - -void rgGlobalSettingsView::PushToWidgets(const rgGlobalSettings& globalSettings) -{ - // Initialize the log file location. - QString logFileLocation(globalSettings.m_logFileLocation.c_str()); - ui.logFileLocationLineEdit->setText(logFileLocation); - - ListWidget::SetColumnVisibilityCheckboxes(m_pDisassemblyColumnsListWidget, globalSettings.m_visibleDisassemblyViewColumns); - - // Initialize the use-generated project names checkbox. - ui.projectNameCheckBox->setChecked(globalSettings.m_useDefaultProjectName); - - // Initialize the combo box for setting the default API. - ui.defaultApiOnStartupComboBox->setCurrentIndex(globalSettings.m_shouldPromptForAPI ? static_cast(rgProjectAPI::Unknown) : static_cast(globalSettings.m_defaultAPI)); - - // Font family. - QFont font; - font.setFamily(QString::fromStdString(globalSettings.m_fontFamily)); - ui.fontFamilyComboBox->setCurrentFont(font); - - // Font size. - const int index = ui.fontSizeComboBox->findData(globalSettings.m_fontSize); - if (index != -1) - { - ui.fontSizeComboBox->setCurrentIndex(index); - } - - // Include files viewer. - ui.includeFilesViewerLineEdit->setText(globalSettings.m_includeFilesViewer.c_str()); - - // Input file associations. - ui.assocExtGlslLineEdit->setText(globalSettings.m_inputFileExtGlsl.c_str()); - ui.assocExtHlslLineEdit->setText(globalSettings.m_inputFileExtHlsl.c_str()); - ui.assocExtSpvasLineEdit->setText(globalSettings.m_inputFileExtSpvTxt.c_str()); - ui.assocExtSpvBinaryLineEdit->setText(globalSettings.m_inputFileExtSpvBin.c_str()); - - // Default high level language. - ui.defaultLangComboBox->setCurrentIndex(globalSettings.m_defaultLang == rgSrcLanguage::GLSL ? 0 : 1); -} - -rgGlobalSettings rgGlobalSettingsView::PullFromWidgets() const -{ - std::shared_ptr pSettings = rgConfigManager::Instance().GetGlobalConfig(); - assert(pSettings != nullptr); - - // Make a local copy of this object so that it can be edited. - rgGlobalSettings settings(*pSettings); - - // Log file location. - settings.m_logFileLocation = ui.logFileLocationLineEdit->text().toStdString(); - - // Column visibility. - settings.m_visibleDisassemblyViewColumns = ListWidget::GetColumnVisibilityCheckboxes(m_pDisassemblyColumnsListWidget); - - // Use default project names. - settings.m_useDefaultProjectName = ui.projectNameCheckBox->isChecked(); - - // Default API. - int defaultApiComboBoxIndex = ui.defaultApiOnStartupComboBox->currentIndex(); - if (defaultApiComboBoxIndex >= 0 && defaultApiComboBoxIndex < static_cast(rgProjectAPI::ApiCount)) - { - settings.m_defaultAPI = static_cast(defaultApiComboBoxIndex); - - settings.m_shouldPromptForAPI = (defaultApiComboBoxIndex == static_cast(rgProjectAPI::Unknown)); - } - - // Font family. - QFont font = ui.fontFamilyComboBox->currentFont(); - settings.m_fontFamily = font.family().toStdString(); - - // Font size. - settings.m_fontSize = ui.fontSizeComboBox->itemData(ui.fontSizeComboBox->currentIndex()).toInt(); - - // Include files viewer. - settings.m_includeFilesViewer = ui.includeFilesViewerLineEdit->text().toStdString(); - - // Input file associations. - settings.m_inputFileExtGlsl = ui.assocExtGlslLineEdit->text().toStdString(); - settings.m_inputFileExtHlsl = ui.assocExtHlslLineEdit->text().toStdString(); - settings.m_inputFileExtSpvTxt = ui.assocExtSpvasLineEdit->text().toStdString(); - settings.m_inputFileExtSpvBin = ui.assocExtSpvBinaryLineEdit->text().toStdString(); - - // Default high level language. - settings.m_defaultLang = (ui.defaultLangComboBox->currentIndex() == 0 ? rgSrcLanguage::GLSL : rgSrcLanguage::HLSL); - - return settings; -} - -void rgGlobalSettingsView::ConnectSignals() -{ - // Browse log file location button. - bool isConnected = connect(this->ui.logFileLocationFolderOpenButton, &QPushButton::clicked, this, &rgGlobalSettingsView::HandleLogFileLocationBrowseButtonClick); - assert(isConnected); - - // Log file location line edit. - isConnected = connect(this->ui.logFileLocationLineEdit, &QLineEdit::editingFinished, this, &rgGlobalSettingsView::HandleLogFileEditingFinished); - assert(isConnected); - - // Log file location textChanged signal. - isConnected = connect(this->ui.logFileLocationLineEdit, &QLineEdit::textChanged, this, &rgGlobalSettingsView::HandleLogFileEditBoxChanged); - assert(isConnected); - - // Columns check box list widget button. - isConnected = connect(this->ui.columnVisibilityArrowPushButton, &QPushButton::clicked, this, &rgGlobalSettingsView::HandleViewColumnsButtonClick); - assert(isConnected); - - // Connect the use default program name check box. - isConnected = connect(this->ui.projectNameCheckBox, &QCheckBox::stateChanged, this, &rgGlobalSettingsView::HandleProjectNameCheckboxStateChanged); - assert(isConnected); - - // Connect the use default API combo box. - isConnected = connect(ui.defaultApiOnStartupComboBox, static_cast(&QComboBox::currentIndexChanged), this, &rgGlobalSettingsView::HandleComboBoxChanged); - assert(isConnected); - - // Connect the font family combo box. - isConnected = connect(ui.fontFamilyComboBox, &QFontComboBox::currentFontChanged, this, &rgGlobalSettingsView::HandleFontFamilyChanged); - assert(isConnected); - - // Connect the font size combo box. - isConnected = connect(ui.fontSizeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &rgGlobalSettingsView::HandleComboBoxChanged); - assert(isConnected); - - // GLSL File extension associations textChanged signal. - isConnected = connect(this->ui.assocExtGlslLineEdit, &QLineEdit::textChanged, this, &rgGlobalSettingsView::HandleTextBoxChanged); - assert(isConnected); - - // HLSL File extension associations textChanged signal. - isConnected = connect(this->ui.assocExtHlslLineEdit, &QLineEdit::textChanged, this, &rgGlobalSettingsView::HandleTextBoxChanged); - assert(isConnected); - - // SPV Text File extension associations textChanged signal. - isConnected = connect(this->ui.assocExtSpvasLineEdit, &QLineEdit::textChanged, this, &rgGlobalSettingsView::HandleTextBoxChanged); - assert(isConnected); - - // SPV Binary File extension associations textChanged signal. - isConnected = connect(this->ui.assocExtSpvBinaryLineEdit, &QLineEdit::textChanged, this, &rgGlobalSettingsView::HandleTextBoxChanged); - assert(isConnected); - - // GLSL File extension associations textChanged signal. - isConnected = connect(this->ui.assocExtGlslLineEdit, &rgLineEdit::LineEditFocusOutEvent, this, &rgGlobalSettingsView::HandleFocusOutEvent); - assert(isConnected); - - // HLSL File extension associations textChanged signal. - isConnected = connect(this->ui.assocExtHlslLineEdit, &rgLineEdit::LineEditFocusOutEvent, this, &rgGlobalSettingsView::HandleFocusOutEvent); - assert(isConnected); - - // SPV Text File extension associations textChanged signal. - isConnected = connect(this->ui.assocExtSpvasLineEdit, &rgLineEdit::LineEditFocusOutEvent, this, &rgGlobalSettingsView::HandleFocusOutEvent); - assert(isConnected); - - // SPV Binary File extension associations textChanged signal. - isConnected = connect(this->ui.assocExtSpvBinaryLineEdit, &rgLineEdit::LineEditFocusOutEvent, this, &rgGlobalSettingsView::HandleFocusOutEvent); - assert(isConnected); - - // Default shader language combobox currentIndexChanged signal. - isConnected = connect(this->ui.defaultLangComboBox, static_cast(&QComboBox::currentIndexChanged), this, &rgGlobalSettingsView::HandleComboBoxChanged); - assert(isConnected); - - // Include files viewer browse button. - isConnected = connect(this->ui.includeFilesViewerBrowseButton, &QPushButton::clicked, this, &rgGlobalSettingsView::HandleIncludeFilesViewerBrowseButtonClick); - assert(isConnected); - - // Include files viewer line edit. - isConnected = connect(this->ui.includeFilesViewerLineEdit, &QLineEdit::editingFinished, this, &rgGlobalSettingsView::HandleIncludeFilesViewerEditingFinished); - assert(isConnected); - - // Include files viewer text changed. - isConnected = connect(this->ui.includeFilesViewerLineEdit, &QLineEdit::textChanged, this, &rgGlobalSettingsView::HandleTextBoxChanged); - assert(isConnected); -} - -void rgGlobalSettingsView::ProcessInputFileBlank() const -{ - if (ui.assocExtGlslLineEdit->text().isEmpty()) - { - emit ui.assocExtGlslLineEdit->LineEditFocusOutEvent(); - } - else if (ui.assocExtHlslLineEdit->text().isEmpty()) - { - emit ui.assocExtHlslLineEdit->LineEditFocusOutEvent(); - } - else if (ui.assocExtSpvasLineEdit->text().isEmpty()) - { - emit ui.assocExtSpvasLineEdit->LineEditFocusOutEvent(); - } - else if (ui.assocExtSpvBinaryLineEdit->text().isEmpty()) - { - emit ui.assocExtSpvBinaryLineEdit->LineEditFocusOutEvent(); - } -} - -void rgGlobalSettingsView::HandleFocusOutEvent() -{ - static const char* STR_GLSL_LINE_EDIT = "assocExtGlslLineEdit"; - static const char* STR_HLSL_LINE_EDIT = "assocExtHlslLineEdit"; - static const char* STR_SPV_BIN_LINE_EDIT = "assocExtSpvBinaryLineEdit"; - static const char* STR_SPV_TEXT_LINE_EDIT = "assocExtSpvasLineEdit"; - static const char* STR_VALUE_BLANK_MESSAGE = "Input file type fields cannot be blank"; - - // Figure out the sender and process appropriately. - QObject* pSender = QObject::sender(); - assert(pSender != nullptr); - - rgLineEdit* pLineEdit = qobject_cast(pSender); - assert(pLineEdit != nullptr); - - // Process the click. - if (pLineEdit != nullptr) - { - QString text = pLineEdit->text(); - if (text.isEmpty()) - { - QWidget* pWidget = static_cast(pSender); - assert(pWidget != nullptr); - - // Set the focus back to this widget. - pWidget->setFocus(); - - // Set the value to the previous one. - QString name = pLineEdit->objectName(); - if (name.compare(STR_GLSL_LINE_EDIT) == 0) - { - pLineEdit->setText(QString::fromStdString(m_initialSettings.m_inputFileExtGlsl)); - } - else if (name.compare(STR_HLSL_LINE_EDIT) == 0) - { - pLineEdit->setText(QString::fromStdString(m_initialSettings.m_inputFileExtHlsl)); - } - else if (name.compare(STR_SPV_BIN_LINE_EDIT) == 0) - { - pLineEdit->setText(QString::fromStdString(m_initialSettings.m_inputFileExtSpvBin)); - } - else if (name.compare(STR_SPV_TEXT_LINE_EDIT) == 0) - { - pLineEdit->setText(QString::fromStdString(m_initialSettings.m_inputFileExtSpvTxt)); - } - - // Display an error message. - rgUtils::ShowErrorMessageBox(STR_VALUE_BLANK_MESSAGE, this); - } - } -} - -void rgGlobalSettingsView::HandlePendingChangesStateChanged(bool hasPendingChanges) -{ - // Let the base class determine if there is a need to signal listeners - // about the pending changes state. - rgBuildSettingsView::SetHasPendingChanges(hasPendingChanges); -} - -void rgGlobalSettingsView::HandleLogFileLocationBrowseButtonClick(bool /* checked */) -{ - // Get the current log file location. - QString currentLogFileLocation = QString::fromStdString(m_initialSettings.m_logFileLocation); - - // Open up a directory chooser. - QFileDialog dialog(this); - dialog.setFileMode(QFileDialog::Directory); - dialog.setDirectory(currentLogFileLocation); - if (dialog.exec()) - { - QStringList selectedDir = dialog.selectedFiles(); - - // Update the text box. - QString selectedDirectory = selectedDir.at(0); - if (!selectedDirectory.isEmpty()) - { - ui.logFileLocationLineEdit->setText(selectedDirectory); - - // Signal to any listeners that the values in the UI have changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - } - } -} - -void rgGlobalSettingsView::HandleIncludeFilesViewerBrowseButtonClick(bool checked) -{ - // Get the current viewer. - QString currentViewer = QString::fromStdString(m_initialSettings.m_logFileLocation); - -#ifdef _WIN32 - const char* fileFilter = "Executable files (*.exe)|*.exe"; -#else - const char* fileFilter = ""; -#endif - - // Open up a file dialog. - std::string selectedViewerPath; - bool isSelected = rgUtils::OpenFileDialog(this, selectedViewerPath, - STR_FILE_DIALOG_FILTER_INCLUDE_VIEWER, fileFilter) && - rgUtils::IsFileExists(selectedViewerPath); - - // If the user selected a path, and it is a valid one, process this request. - if (isSelected) - { - // Set the selected file path as the text in the text box. - ui.includeFilesViewerLineEdit->setText(selectedViewerPath.c_str()); - - // Signal to any listeners that the values in the UI have changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); - } -} - -void rgGlobalSettingsView::HandleViewColumnsButtonClick(bool /* checked */) -{ - // Make the list widget appear and process user selection from the list widget. - bool visible = m_pDisassemblyColumnsListWidget->isVisible(); - if (visible) - { - m_pDisassemblyColumnsListWidget->hide(); - - // Change the up arrow to a down arrow. - ui.columnVisibilityArrowPushButton->SetDirection(ArrowIconWidget::Direction::DownArrow); - } - else - { - // If the initial settings are different than the global settings, then we know the checkbox values were - // changed in another view. - std::shared_ptr pSettings = rgConfigManager::Instance().GetGlobalConfig(); - if (m_initialSettings.m_visibleDisassemblyViewColumns != pSettings->m_visibleDisassemblyViewColumns) - { - if (pSettings != nullptr) - { - ListWidget::SetColumnVisibilityCheckboxes(m_pDisassemblyColumnsListWidget, pSettings->m_visibleDisassemblyViewColumns); - } - } - - // Compute where to place the combo box relative to where the arrow button is. - QWidget* pWidget = ui.columnVisibilityArrowPushButton; - m_pDisassemblyColumnsListWidget->show(); - QRect rect = pWidget->geometry(); - QPoint pos(0, 0); - pos = pWidget->mapTo(this, pos); - pos.setY(pos.y() + rect.height()); - int height = QtCommon::QtUtil::GetListWidgetHeight(m_pDisassemblyColumnsListWidget); - int width = QtCommon::QtUtil::GetListWidgetWidth(m_pDisassemblyColumnsListWidget); - m_pDisassemblyColumnsListWidget->setGeometry(pos.x(), pos.y(), width + s_CHECK_BOX_WIDTH, height); - - // Change the down arrow to an up arrow. - ui.columnVisibilityArrowPushButton->SetDirection(ArrowIconWidget::Direction::UpArrow); - } -} - -void rgGlobalSettingsView::SetCursor() -{ - // Set the cursor to pointing hand cursor. - ui.columnVisibilityArrowPushButton->setCursor(Qt::PointingHandCursor); - ui.logFileLocationFolderOpenButton->setCursor(Qt::PointingHandCursor); - ui.projectNameCheckBox->setCursor(Qt::PointingHandCursor); - ui.defaultApiOnStartupComboBox->setCursor(Qt::PointingHandCursor); - ui.fontFamilyComboBox->setCursor(Qt::PointingHandCursor); - ui.fontSizeComboBox->setCursor(Qt::PointingHandCursor); - ui.includeFilesViewerBrowseButton->setCursor(Qt::PointingHandCursor); -} - -void rgGlobalSettingsView::HandleColumnVisibilityComboBoxItemClicked(const QString& text, bool checked) -{ - int firstColumn = rgIsaDisassemblyTableModel::GetTableColumnIndex(rgIsaDisassemblyTableColumns::Address); - int lastColumn = rgIsaDisassemblyTableModel::GetTableColumnIndex(rgIsaDisassemblyTableColumns::Count); - - std::vector columnVisibility = ListWidget::GetColumnVisibilityCheckboxes(m_pDisassemblyColumnsListWidget); - - // Make sure at least one check box is still checked. - bool isAtLeastOneChecked = std::any_of(columnVisibility.begin() + firstColumn, columnVisibility.begin() + lastColumn, [](bool b) { return b == true; }); - - if (checked || isAtLeastOneChecked) - { - // If the user checked the "All" option, Step through each column and set to visible. - if (text.compare(STR_DISASSEMBLY_TABLE_COLUMN_ALL) == 0 && (checked == true)) - { - for (int columnIndex = firstColumn; columnIndex < lastColumn; ++columnIndex) - { - columnVisibility[columnIndex] = checked; - } - - // Update the state of the dropdown check boxes to reflect that all options are checked. - ListWidget::SetColumnVisibilityCheckboxes(m_pDisassemblyColumnsListWidget, columnVisibility); - } - } - else - { - // The user tried to uncheck the last check box, but at least one box - // MUST be checked, so find that item in the ListWidget, and set it back to checked. - for (int row = 0; row < m_pDisassemblyColumnsListWidget->count(); row++) - { - QListWidgetItem* pItem = m_pDisassemblyColumnsListWidget->item(row); - QCheckBox* pCheckBox = (QCheckBox*)m_pDisassemblyColumnsListWidget->itemWidget(pItem); - QString checkBoxText = pCheckBox->text(); - if (checkBoxText.compare(text) == 0) - { - QCheckBox* pCheckBox = (QCheckBox*)m_pDisassemblyColumnsListWidget->itemWidget(pItem); - pCheckBox->setChecked(true); - } - } - } - - // See if the "All" box needs checking/un-checking. - ListWidget::UpdateAllCheckbox(m_pDisassemblyColumnsListWidget); - - // Update the "All" checkbox text color to grey or black. - UpdateAllCheckBoxText(); - - // Signal to any listeners that the values in the UI have changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); -} - -void rgGlobalSettingsView::HandleColumnVisibilityFilterStateChanged(bool checked) -{ - // Figure out the sender and process appropriately. - QObject* pSender = QObject::sender(); - assert(pSender != nullptr); - - // Find out which entry caused the signal. - QWidget* pItem = qobject_cast(pSender); - assert(pItem != nullptr); - - QCheckBox* pCheckBox = qobject_cast(pSender); - assert(pCheckBox != nullptr); - - // Process the click. - if (pCheckBox != nullptr) - { - HandleColumnVisibilityComboBoxItemClicked(pCheckBox->text(), checked); - } -} - -std::string rgGlobalSettingsView::GetDisassemblyColumnName(rgIsaDisassemblyTableColumns column) const -{ - std::string result; - - static std::map ColumnNameMap = - { - { rgIsaDisassemblyTableColumns::Address, STR_DISASSEMBLY_TABLE_COLUMN_ADDRESS }, - { rgIsaDisassemblyTableColumns::Opcode, STR_DISASSEMBLY_TABLE_COLUMN_OPCODE }, - { rgIsaDisassemblyTableColumns::Operands, STR_DISASSEMBLY_TABLE_COLUMN_OPERANDS }, - { rgIsaDisassemblyTableColumns::FunctionalUnit, STR_DISASSEMBLY_TABLE_COLUMN_FUNCTIONAL_UNIT }, - { rgIsaDisassemblyTableColumns::Cycles, STR_DISASSEMBLY_TABLE_COLUMN_CYCLES }, - { rgIsaDisassemblyTableColumns::BinaryEncoding, STR_DISASSEMBLY_TABLE_COLUMN_BINARY_ENCODING }, - }; - - auto columnNameIter = ColumnNameMap.find(column); - if (columnNameIter != ColumnNameMap.end()) - { - result = columnNameIter->second; - } - else - { - // The incoming column doesn't have a name string mapped to it. - assert(false); - } - - return result; -} - -void rgGlobalSettingsView::PopulateColumnVisibilityList() -{ - // Set up the function pointer responsible for handling column visibility filter state change. - using std::placeholders::_1; - std::function slotFunctionPointer = std::bind(&rgGlobalSettingsView::HandleColumnVisibilityFilterStateChanged, this, _1); - - // Remove the existing items first. - ClearListWidget(m_pDisassemblyColumnsListWidget); - - // Add the "All" entry. - ListWidget::AddListWidgetCheckboxItem(STR_DISASSEMBLY_TABLE_COLUMN_ALL, m_pDisassemblyColumnsListWidget, slotFunctionPointer, this, STR_GLOBAL_SETTINGS_COLUMN_VISIBILITY_LIST, STR_GLOBAL_SETTINGS_COLUMN_LIST_ITEM_ALL_CHECKBOX); - - // Loop through each column enum member. - int startColumn = rgIsaDisassemblyTableModel::GetTableColumnIndex(rgIsaDisassemblyTableColumns::Address); - int endColumn = rgIsaDisassemblyTableModel::GetTableColumnIndex(rgIsaDisassemblyTableColumns::Count); - - // Add an item for each column in the table. - for (int columnIndex = startColumn; columnIndex < endColumn; ++columnIndex) - { - // Add an item for each possible column in the table. - std::string columnName = GetDisassemblyColumnName(static_cast(columnIndex)); - ListWidget::AddListWidgetCheckboxItem(columnName.c_str(), m_pDisassemblyColumnsListWidget, slotFunctionPointer, this, STR_GLOBAL_SETTINGS_COLUMN_VISIBILITY_LIST, STR_GLOBAL_SETTINGS_COLUMN_LIST_ITEM_CHECKBOX); - } -} - -void rgGlobalSettingsView::UpdateAllCheckBoxText() -{ - bool areAllItemsChecked = true; - - // Check to see if all of the boxes are checked. - for (int i = 1; i < m_pDisassemblyColumnsListWidget->count(); i++) - { - QListWidgetItem* pItem = m_pDisassemblyColumnsListWidget->item(i); - assert(pItem != nullptr); - - QCheckBox* pCheckBox = qobject_cast(m_pDisassemblyColumnsListWidget->itemWidget(pItem)); - assert(pCheckBox != nullptr); - - if (pCheckBox->checkState() == Qt::CheckState::Unchecked) - { - areAllItemsChecked = false; - break; - } - } - - // If all boxes are checked, update the text color of the All check box. - QListWidgetItem* pItem = m_pDisassemblyColumnsListWidget->item(0); - if (pItem != nullptr) - { - QCheckBox* pCheckBox = qobject_cast(m_pDisassemblyColumnsListWidget->itemWidget(pItem)); - if (pCheckBox != nullptr) - { - if (areAllItemsChecked) - { - pCheckBox->setStyleSheet("QCheckBox#ListWidgetAllCheckBox {color: grey;}"); - } - else - { - pCheckBox->setStyleSheet("QCheckBox#ListWidgetAllCheckBox {color: black;}"); - } - } - } -} - -void rgGlobalSettingsView::CreateColumnVisibilityControls() -{ - // Setup the list widget that opens when the user clicks the column visibility arrow. - rgUtils::SetupComboList(m_pParent, m_pDisassemblyColumnsListWidget, ui.columnVisibilityArrowPushButton, m_pDisassemblyColumnsListEventFilter, false); - m_pDisassemblyColumnsListWidget->setObjectName(STR_GLOBAL_SETTINGS_COLUMN_VISIBILITY_LIST); - - // Update scale factor for widgets. - QFont font = ui.columnVisibilityArrowPushButton->font(); - double scaleFactor = ScalingManager::Get().GetScaleFactor(); - font.setPointSize(s_PUSH_BUTTON_FONT_SIZE * scaleFactor); - m_pDisassemblyColumnsListWidget->setStyleSheet(s_LIST_WIDGET_STYLE.arg(font.pointSize())); - - // Reset the current selection in the column visibility list. - m_pDisassemblyColumnsListWidget->setCurrentRow(0); -} - -void rgGlobalSettingsView::HandleProjectNameCheckboxStateChanged(int checked) -{ - // Signal to any listeners that the values in the UI have changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); -} - -void rgGlobalSettingsView::ClearListWidget(ListWidget* &pListWidget) -{ - assert(pListWidget != nullptr); - - // Disconnect slot/signal connection for each check box - for (int row = 0; row < pListWidget->count(); row++) - { - QListWidgetItem* pItem = pListWidget->item(row); - QCheckBox* pCheckBox = (QCheckBox*)pListWidget->itemWidget(pItem); - - if (pListWidget->objectName().compare(STR_GLOBAL_SETTINGS_COLUMN_VISIBILITY_LIST) == 0) - { - bool isDisconnected = disconnect(pCheckBox, &QCheckBox::clicked, this, &rgGlobalSettingsView::HandleColumnVisibilityFilterStateChanged); - assert(isDisconnected); - } - else - { - assert(false); - } - } - - // Clear the list widget. This also deletes each item. - pListWidget->clear(); -} - -void rgGlobalSettingsView::CloseListWidget() -{ - m_pDisassemblyColumnsListWidget->hide(); - ui.columnVisibilityArrowPushButton->SetDirection(ArrowIconWidget::Direction::DownArrow); -} - -void rgGlobalSettingsView::SetCheckboxToolTip(const std::string& text) -{ - ui.projectNameCheckBox->setToolTip(text.c_str()); -} - -void rgGlobalSettingsView::HandleLogFileEditingFinished() -{ - // Verify that the line edit text is not empty or the location is not invalid before losing the focus. - if (this->ui.logFileLocationLineEdit->text().isEmpty() || !rgUtils::IsDirExists(this->ui.logFileLocationLineEdit->text().toStdString())) - { - // If empty or invalid, use the saved location. - std::shared_ptr pGlobalConfig = rgConfigManager::Instance().GetGlobalConfig(); - assert(pGlobalConfig != nullptr); - if (pGlobalConfig != nullptr) - { - this->ui.logFileLocationLineEdit->setText(pGlobalConfig->m_logFileLocation.c_str()); - } - this->ui.logFileLocationLineEdit->setFocus(); - } - - // Signal to any listeners that the values in the UI have changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); -} - -void rgGlobalSettingsView::SetEditBoxToolTips() -{ - ui.logFileLocationLineEdit->setToolTip(ui.logFileLocationLineEdit->displayText()); -} - -void rgGlobalSettingsView::HandleLogFileEditBoxChanged(const QString& text) -{ - // Update the tooltip. - ui.logFileLocationLineEdit->setToolTip(text); - - // Restore the cursor to the original position when the text has changed. - QtCommon::QtUtil::RestoreCursorPosition cursorPosition(ui.logFileLocationLineEdit); - - // Signal to any listeners that the values in the UI have changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); -} - -void rgGlobalSettingsView::HandleTextBoxChanged(const QString& text) -{ - // Figure out the sender and process appropriately. - QObject* pSender = QObject::sender(); - assert(pSender != nullptr); - - rgLineEdit* pLineEdit = static_cast(pSender); - assert(pLineEdit != nullptr); - - // Signal whether the text box is empty or not. - if (pLineEdit != nullptr) - { - QString text = pLineEdit->text(); - if (text.isEmpty()) - { - emit InputFileNameBlankSignal(true); - } - else - { - emit InputFileNameBlankSignal(false); - } - } - - // Signal to any listeners that the values in the UI have changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); -} - -void rgGlobalSettingsView::HandleComboBoxChanged(int index) -{ - // Signal to any listeners that the values in the UI have changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); -} - -bool rgGlobalSettingsView::GetHasPendingChanges() const -{ - rgGlobalSettings currentSettings = PullFromWidgets(); - - bool hasChanges = !m_initialSettings.HasSameSettings(currentSettings); - - return hasChanges; -} - -bool rgGlobalSettingsView::RevertPendingChanges() -{ - std::shared_ptr pSettings = rgConfigManager::Instance().GetGlobalConfig(); - assert(pSettings != nullptr); - if (pSettings != nullptr) - { - PushToWidgets(*pSettings); - } - - // Make sure the rest of the UI knows that the settings don't need to be saved. - HandlePendingChangesStateChanged(false); - - return false; -} - -void rgGlobalSettingsView::RestoreDefaultSettings() -{ - // Reset our initial settings back to the defaults - rgConfigManager::Instance().ResetToFactoryDefaults(m_initialSettings); - - // Update the UI to reflect the new initial settings - PushToWidgets(m_initialSettings); - - // Update the ConfigManager to use the new settings. - rgConfigManager::Instance().SetGlobalConfig(m_initialSettings); - - // Save the settings file. - rgConfigManager::Instance().SaveGlobalConfigFile(); - - // Signal to any listeners that the values in the UI have changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); -} - -bool rgGlobalSettingsView::SaveSettings() -{ - // Reset the initial settings to match what the UI shows. - m_initialSettings = PullFromWidgets(); - - // Update the config manager to use these new settings. - rgConfigManager& configManager = rgConfigManager::Instance(); - configManager.SetGlobalConfig(m_initialSettings); - - // Save the settings. - bool isSaved = configManager.SaveGlobalConfigFile(); - - if (isSaved) - { - // Make sure the rest of the UI knows that the settings have been saved. - HandlePendingChangesStateChanged(false); - } - - return isSaved; -} - -std::string rgGlobalSettingsView::GetTitleString() -{ - std::string titleString = STR_SETTINGS_CONFIRMATION_APPLICATION_SETTINGS; - - return titleString; -} - -void rgGlobalSettingsView::HandleFontFamilyChanged(const QFont& font) -{ - // Signal to any listeners that the values in the UI have changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); -} - -void rgGlobalSettingsView::HandleIncludeFilesViewerEditingFinished() -{ - // Verify that the line edit text is not empty or the location is not invalid before losing the focus. - if (this->ui.includeFilesViewerLineEdit->text().isEmpty()) - { - this->ui.includeFilesViewerLineEdit->setText(STR_GLOBAL_SETTINGS_SRC_VIEW_INCLUDE_VIEWER_DEFAULT); - } - else if (this->ui.includeFilesViewerLineEdit->text().compare(STR_GLOBAL_SETTINGS_SRC_VIEW_INCLUDE_VIEWER_DEFAULT) != 0 && - !rgUtils::IsFileExists(this->ui.includeFilesViewerLineEdit->text().toStdString())) - { - // If empty or invalid, use the saved location. - std::shared_ptr pGlobalConfig = rgConfigManager::Instance().GetGlobalConfig(); - assert(pGlobalConfig != nullptr); - if (pGlobalConfig != nullptr) - { - this->ui.includeFilesViewerLineEdit->setText(pGlobalConfig->m_includeFilesViewer.c_str()); - } - this->ui.includeFilesViewerLineEdit->setFocus(); - } - - // Signal to any listeners that the values in the UI have changed. - HandlePendingChangesStateChanged(GetHasPendingChanges()); -} - -void rgGlobalSettingsView::SetInitialWidgetFocus() -{ - ui.logFileLocationLineEdit->setFocus(); -} - -bool rgGlobalSettingsView::IsInputFileBlank() const -{ - return ui.assocExtGlslLineEdit->text().isEmpty() || - ui.assocExtHlslLineEdit->text().isEmpty() || - ui.assocExtSpvasLineEdit->text().isEmpty() || - ui.assocExtSpvBinaryLineEdit->text().isEmpty(); -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgGotoLineDialog.cpp b/RadeonGPUAnalyzerGUI/Src/rgGotoLineDialog.cpp deleted file mode 100644 index 0fe994f..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgGotoLineDialog.cpp +++ /dev/null @@ -1,82 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include -#include - -// Local. -#include - - -rgGoToLineDialog::rgGoToLineDialog(int maxLineNumber, QWidget* pParent) : - QDialog(pParent), - m_lineNumber(0), - m_maxLineNumber(maxLineNumber) -{ - // Setup the UI. - ui.setupUi(this); - - // Disable the help button in the title bar. - setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); - - // Set the background to white. - QPalette pal = palette(); - pal.setColor(QPalette::Background, Qt::white); - this->setAutoFillBackground(true); - this->setPalette(pal); - - // Set the validator for the line number edit box. - QValidator *validator = new QIntValidator(0, m_maxLineNumber, this); - - // The line number edit box will only accept integers between 0 and m_maxLineNumber. - ui.lineNumberEdit->setValidator(validator); - - // Update the label with line number range. - ui.lineNumberLabel->setText(QString("Line number (1-") + QString::number(m_maxLineNumber) + QString("): ")); - - // Connect the signals. - ConnectSignals(); -} - -rgGoToLineDialog::~rgGoToLineDialog() -{ -} - -void rgGoToLineDialog::ConnectSignals() -{ - // Create a signal mapper to map the button clicks to the done(int) slot - // with appropriate result values. - QSignalMapper* pButtonSignalMapper = new QSignalMapper(this); - - // Yes button. - bool isConnected = connect(ui.okPushButton, SIGNAL(clicked()), pButtonSignalMapper, SLOT(map())); - assert(isConnected); - pButtonSignalMapper->setMapping(ui.okPushButton, rgGoToLineDialog::Ok); - - // Cancel button. - isConnected = connect(ui.cancelPushButton, SIGNAL(clicked()), pButtonSignalMapper, SLOT(map())); - assert(isConnected); - pButtonSignalMapper->setMapping(ui.cancelPushButton, rgGoToLineDialog::Cancel); - - // Signal mapper. - isConnected = connect(pButtonSignalMapper, SIGNAL(mapped(int)), this, SLOT(done(int))); - assert(isConnected); - - // The line number edit box. - isConnected = connect(ui.lineNumberEdit, &QLineEdit::textChanged, this, &rgGoToLineDialog::HandleLineNumberEntered); -} - -void rgGoToLineDialog::HandleLineNumberEntered(const QString& text) -{ - m_lineNumber = text.toInt(); -} - -int rgGoToLineDialog::GetLineNumber() const -{ - return m_lineNumber; -} - - - diff --git a/RadeonGPUAnalyzerGUI/Src/rgHandleTabFocusEventFilter.cpp b/RadeonGPUAnalyzerGUI/Src/rgHandleTabFocusEventFilter.cpp deleted file mode 100644 index 894561e..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgHandleTabFocusEventFilter.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// Qt. -#include -#include -#include - -// Local. -#include - -rgHandleTabFocusEventFilter& rgHandleTabFocusEventFilter::Get() -{ - static rgHandleTabFocusEventFilter instance; - return instance; -} - -bool rgHandleTabFocusEventFilter::eventFilter(QObject *pObject, QEvent *pEvent) -{ - bool ret = false; - - // Intercept tab key presses to handle focus change. - if (pEvent->type() == QEvent::KeyPress) - { - QKeyEvent* pKeyEvent = static_cast(pEvent); - Qt::KeyboardModifiers keyboardModifiers = QApplication::keyboardModifiers(); - if ((keyboardModifiers & Qt::ShiftModifier) && (pKeyEvent->key() == Qt::Key_Tab)) - { - emit ShiftTabPressed(); - ret = true; - } - else if ((pKeyEvent->key() == Qt::Key_Tab)) - { - emit TabPressed(); - ret = true; - } - } - - // Default event processing. - if (!ret) - { - ret = QObject::eventFilter(pObject, pEvent); - } - - return ret; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgHideListWidgetEventFilter.cpp b/RadeonGPUAnalyzerGUI/Src/rgHideListWidgetEventFilter.cpp deleted file mode 100644 index 790cfba..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgHideListWidgetEventFilter.cpp +++ /dev/null @@ -1,263 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include -#include -#include -#include - -// Infra. -#include -#include - -// Local. -#include - -// Object name associated with the column dropdown list. -static const char* STR_DISASSEMBLY_COLUMN_VISIBILITY_LIST = "DisassemblyColumnVisibilityList"; - -// Object name associated with the target GPU dropdown list. -static const char* STR_DISASSEMBLY_TARGET_GPU_LIST = "TargetGpuList"; - -// The object names for UI objects that the user can click on. -static const char* STR_COLUMN_VISIBLITY_ARROW_PUSH_BUTTON = "columnVisibilityArrowPushButton"; -static const char* STR_DISASSEMBLY_TARGET_GPU_PUSH_BUTTON = "targetGpuPushButton"; -static const char* STR_ISA_LIST_ARROW_PUSH_BUTTON = "isaListArrowPushButton"; -static const char* STR_QT_SCROLL_AREA_VIEWPORT = "qt_scrollarea_viewport"; -static const char* STR_VIEW_TITLE_BAR = "viewTitlebar"; -static const char* STR_VIEW_OPEN_CL_SETTINGS_VIEW = "rgOpenClSettingsView"; -static const char* STR_SETTINGS_TAB = "settingsTab"; -static const char* STR_START_TAB = "startTab"; -static const char* STR_TAB_WIDGET_STACKED_WIDGET = "qt_tabwidget_stackedwidget"; -static const char* STR_MAIN_TAB_WIDGET = "mainTabWidget"; -static const char* STR_HOME_PAGE = "homePage"; -static const char* STR_STACKED_WIDGET = "stackedWidget"; -static const char* STR_CENTRAL_WIDGET = "centralWidget"; -static const char* STR_RG_MAIN_WINDOW = "rgMainWindow"; -static const char* STR_RG_MAIN_WINDOW_TAB_BAR = "rgMainWindowTabBar"; -static const char* STR_RG_MAIN_WINDOW_MENU_BAR = "menuBar"; -static const char* STR_ENUM_COMBO_PUSH_BUTTON = "enumComboPushButton"; -static const char* STR_PSO_EDITOR_ADD_ELEMENT_BUTTON = "addElementButton"; -static const char* STR_PSO_EDITOR_DELETE_ELEMENT_BUTTON = "deleteElementButton"; -static const char* STR_PSO_EDITOR_LINE_EDIT = "lineEdit"; -static const char* STR_FILE_MENU_ADD_FILE_BUTTON = "addFilePushButton"; -static const char* STR_BUILD_SETTINGS_BUTTON_NAME = "buildSettingsButton"; -static const char* STR_FILE_MENU_NAME_GRAPHICS = "fileMenuGraphics"; -static const char* STR_FILE_MENU_ITEM_NAME_GRAPHICS = "fileMenuItemGraphics"; -static const char* STR_PSO_EDITOR_LOAD_BUTTON = "loadButton"; -static const char* STR_PSO_EDITOR_SAVE_BUTTON = "saveButton"; - -QStringList rgHideListWidgetEventFilter::m_stringList = -{ - STR_COLUMN_VISIBLITY_ARROW_PUSH_BUTTON, - STR_DISASSEMBLY_TARGET_GPU_PUSH_BUTTON, - STR_ISA_LIST_ARROW_PUSH_BUTTON, - STR_QT_SCROLL_AREA_VIEWPORT, - STR_VIEW_TITLE_BAR, - STR_VIEW_OPEN_CL_SETTINGS_VIEW, - STR_SETTINGS_TAB, - STR_START_TAB, - STR_TAB_WIDGET_STACKED_WIDGET, - STR_MAIN_TAB_WIDGET, - STR_HOME_PAGE, - STR_STACKED_WIDGET, - STR_CENTRAL_WIDGET, - STR_RG_MAIN_WINDOW, - STR_RG_MAIN_WINDOW_TAB_BAR, - STR_RG_MAIN_WINDOW_MENU_BAR, - STR_ENUM_COMBO_PUSH_BUTTON, - STR_PSO_EDITOR_ADD_ELEMENT_BUTTON, - STR_PSO_EDITOR_DELETE_ELEMENT_BUTTON, - STR_PSO_EDITOR_LINE_EDIT, - STR_FILE_MENU_ADD_FILE_BUTTON, - STR_BUILD_SETTINGS_BUTTON_NAME, - STR_FILE_MENU_NAME_GRAPHICS, - STR_FILE_MENU_ITEM_NAME_GRAPHICS, - STR_PSO_EDITOR_LOAD_BUTTON, - STR_PSO_EDITOR_SAVE_BUTTON, -}; - -rgHideListWidgetEventFilter::rgHideListWidgetEventFilter(QListWidget* pListWidget, ArrowIconWidget* pButton) : - QObject(pListWidget), - m_pListWidget(pListWidget), - m_pButton(pButton) -{ -} - -bool rgHideListWidgetEventFilter::eventFilter(QObject* pObject, QEvent* pEvent) -{ - assert(m_pListWidget != nullptr); - - bool filtered = false; - - if (m_pListWidget != nullptr) - { - if (pEvent->type() == QEvent::MouseButtonPress) - { - // If the user has clicked on a widget in the list and the object clicked on is not the pushbutton registered - // with this object (since it will be cleaned up by its slot later), then hide the list widget. - if (m_stringList.contains(pObject->objectName()) && m_pButton->objectName().compare(pObject->objectName()) != 0) - { - // Hide the list widget. - m_pListWidget->hide(); - - // Set the button icon to down arrow. - m_pButton->SetDirection(ArrowIconWidget::Direction::DownArrow); - - // Emit the list widget status changed signal. - emit EnumListWidgetStatusSignal(false); - } - } - else if (pEvent->type() == QEvent::KeyPress && m_pListWidget->isVisible()) - { - QKeyEvent* pKeyEvent = static_cast(pEvent); - assert(pKeyEvent != nullptr); - if (pKeyEvent != nullptr) - { - int currentRow = m_pListWidget->currentRow(); - int keyPressed = pKeyEvent->key(); - if (keyPressed == Qt::Key_Down) - { - if (currentRow < m_pListWidget->count() - 1) - { - currentRow++; - } - } - else if (keyPressed == Qt::Key_Up) - { - if (currentRow > 0) - { - currentRow--; - } - } - else if (keyPressed == Qt::Key_Enter || keyPressed == Qt::Key_Return || keyPressed == Qt::Key_Space) - { - // If this is the columns list widget, check/un-check the check box, - // else just emit the currentRowChanged signal. - if (m_pListWidget->objectName().compare(STR_DISASSEMBLY_TARGET_GPU_LIST) == 0) - { - emit m_pListWidget->currentRowChanged(currentRow); - - // Close the list widget. - m_pListWidget->hide(); - - // Set the button icon to down arrow. - m_pButton->SetDirection(ArrowIconWidget::Direction::DownArrow); - - // Emit the list widget status changed signal. - emit EnumListWidgetStatusSignal(false); - } - else if (m_pListWidget->objectName().compare(STR_DISASSEMBLY_COLUMN_VISIBILITY_LIST) == 0) - { - // Toggle the check state in the ISA column visibility dropdown. - QListWidgetItem* pItem = m_pListWidget->currentItem(); - if (pItem != nullptr) - { - QCheckBox* pCheckBox = qobject_cast(m_pListWidget->itemWidget(pItem)); - if (pCheckBox != nullptr) - { - if (pCheckBox->isChecked()) - { - pCheckBox->setCheckState(Qt::Unchecked); - } - else - { - pCheckBox->setCheckState(Qt::Checked); - } - - emit pCheckBox->clicked(); - } - } - } - } - else if (keyPressed == Qt::Key_Tab) - { - // Close the list widget. - m_pListWidget->hide(); - - // Set the button icon to down arrow. - m_pButton->SetDirection(ArrowIconWidget::Direction::DownArrow); - - // Emit the list widget status changed signal. - emit EnumListWidgetStatusSignal(false); - - // Pop open the column list widget if this is gpu list widget, - // else if this is the column list widget, give focus to output window. - if (m_pListWidget->objectName().compare(STR_DISASSEMBLY_TARGET_GPU_LIST) == 0) - { - emit OpenColumnListWidget(); - - // Update the rgIsaDisassemblyCustomTableView::m_currentSubWidget as well. - emit UpdateCurrentSubWidget(DisassemblyViewSubWidgets::ColumnPushButton); - } - else if (m_pListWidget->objectName().compare(STR_DISASSEMBLY_COLUMN_VISIBILITY_LIST) == 0) - { - emit FocusCliOutputWindow(); - - // Update the rgIsaDisassemblyCustomTableView::m_currentSubWidget as well. - emit UpdateCurrentSubWidget(DisassemblyViewSubWidgets::OutputWindow); - } - } - else if (keyPressed == Qt::Key_Backtab) - { - // Close the list widget. - m_pListWidget->hide(); - - // Set the button icon to down arrow. - m_pButton->SetDirection(ArrowIconWidget::Direction::DownArrow); - - // Emit the list widget status changed signal. - emit EnumListWidgetStatusSignal(false); - - // Pop open the gpu list widget if this is column list widget, - // else if this is the gpu list widget, give focus to disassembly view window. - if (m_pListWidget->objectName().compare(STR_DISASSEMBLY_COLUMN_VISIBILITY_LIST) == 0) - { - emit OpenGpuListWidget(); - - // Update the rgIsaDisassemblyCustomTableView::m_currentSubWidget as well. - emit UpdateCurrentSubWidget(DisassemblyViewSubWidgets::TargetGpuPushButton); - } - else if (m_pListWidget->objectName().compare(STR_DISASSEMBLY_TARGET_GPU_LIST) == 0) - { - emit FrameInFocusSignal(); - - // Update the rgIsaDisassemblyCustomTableView::m_currentSubWidget as well. - emit UpdateCurrentSubWidget(DisassemblyViewSubWidgets::TableView); - } - } - else if (keyPressed == Qt::Key_Escape) - { - m_pListWidget->close(); - - // Set the button icon to down arrow. - m_pButton->SetDirection(ArrowIconWidget::Direction::DownArrow); - - // Emit the list widget status changed signal. - emit EnumListWidgetStatusSignal(false); - } - m_pListWidget->setCurrentRow(currentRow); - - // Do not let Qt process this event any further. - filtered = true; - } - } - } - return filtered; -} - -void rgHideListWidgetEventFilter::AddObjectName(const QString& objectName) -{ - m_stringList.push_back(objectName); -} - -void rgHideListWidgetEventFilter::ClickPushButton() -{ - assert(m_pButton != nullptr); - if (m_pButton != nullptr) - { - m_pButton->clicked(); - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgIncludeDirectoriesView.cpp b/RadeonGPUAnalyzerGUI/Src/rgIncludeDirectoriesView.cpp deleted file mode 100644 index 32e3b12..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgIncludeDirectoriesView.cpp +++ /dev/null @@ -1,246 +0,0 @@ -// C++. -#include -#include -#include - -// Qt. -#include - -// Infra. -#include - -// Local. -#include -#include -#include -#include - -rgIncludeDirectoriesView::rgIncludeDirectoriesView(const char* pDelimiter, QWidget* pParent) : - rgOrderedListDialog(pDelimiter, pParent) -{ - // Initialize the browse button that gets inserted into the view. - InitializeBrowseButton(); - - // Set the window title. - setWindowTitle(STR_INCLUDE_DIR_DIALOG_SELECT_INCLUDE_DIRS); - - // Connect the signals. - ConnectSignals(); - - // Set the mouse cursor to the pointing hand cursor for various widgets. - SetCursor(); - - // Set the button fonts. - SetButtonFonts(); - - // Update various buttons. - UpdateButtons(); -} - -void rgIncludeDirectoriesView::ConnectSignals() -{ - assert(m_pBrowsePushButton != nullptr); - - // Browse new include directory button. - bool isConnected = connect(m_pBrowsePushButton, &QPushButton::clicked, this, &rgIncludeDirectoriesView::HandleIncludeFileLocationBrowseButtonClick); - assert(isConnected); -} - -void rgIncludeDirectoriesView::InitializeBrowseButton() -{ - // Create a new button to browse for new directories. - m_pBrowsePushButton = new QPushButton(this); - m_pBrowsePushButton->setText(STR_INCLUDE_DIR_DIALOG_BROWSE_BUTTON); - - assert(m_pBrowsePushButton != nullptr); - if (m_pBrowsePushButton != nullptr) - { - // This index specifies where the browse button will get inserted in the vertical layout of buttons in the dialog. - static const int BROWSE_BUTTON_INSERTION_INDEX = 2; - - // Add the new browse button to the view. - QVBoxLayout* pVerticalButtonsLayout = ui.verticalPushButtonsLayout; - assert(pVerticalButtonsLayout != nullptr); - if (pVerticalButtonsLayout != nullptr) - { - pVerticalButtonsLayout->insertWidget(BROWSE_BUTTON_INSERTION_INDEX, m_pBrowsePushButton); - ScalingManager::Get().RegisterObject(m_pBrowsePushButton); - } - } -} - -void rgIncludeDirectoriesView::SetCursor() -{ - assert(m_pBrowsePushButton != nullptr); - if (m_pBrowsePushButton != nullptr) - { - // Set the cursor to pointing hand cursor on the Browse button. - m_pBrowsePushButton->setCursor(Qt::PointingHandCursor); - } -} - -void rgIncludeDirectoriesView::SetButtonFonts() -{ - // Create a font based on other QPushButtons in within the view. - QFont font = ui.deletePushButton->font(); - font.setPointSize(gs_BUTTON_POINT_FONT_SIZE); - - assert(m_pBrowsePushButton != nullptr); - if (m_pBrowsePushButton != nullptr) - { - // Update font size for all the buttons. - m_pBrowsePushButton->setFont(font); - } -} - -void rgIncludeDirectoriesView::HandleIncludeFileLocationBrowseButtonClick(bool /* checked */) -{ - // Create a file chooser dialog. - QFileDialog fileDialog; - - // Get the last entry from the directories list and open the dialog there. - std::string latestPath = rgConfigManager::Instance().GetLastSelectedFolder(); - - // If the user has an item selected, use that as starting path. - // Otherwise use the last item in the list since it is probably most recent. - QListWidgetItem* pItem = ui.itemsList->currentItem(); - if (pItem != nullptr && !pItem->text().isEmpty() && QDir(pItem->text()).exists()) - { - latestPath = pItem->text().toStdString(); - } - else if (m_itemsList.size() > 0) - { - latestPath = m_itemsList.at(m_itemsList.size() - 1).toStdString(); - } - - bool shouldShowFindDirectoryDialog = true; - - while (shouldShowFindDirectoryDialog) - { - QString selectedDirectory = QFileDialog::getExistingDirectory(this, tr(STR_INCLUDE_DIR_DIALOG_SELECT_DIR_TITLE), - latestPath.c_str(), - QFileDialog::ShowDirsOnly); - - // If the user did not select an entry, don't update anything, just exit the loop. - if (selectedDirectory.isEmpty()) - { - shouldShowFindDirectoryDialog = false; - } - else - { - // If not a duplicate selection, update the list widget. - if (!m_itemsList.contains(selectedDirectory)) - { - QListWidgetItem* pItem = ui.itemsList->currentItem(); - if (pItem == nullptr) - { - // There was no selected item, - // so make sure there is a final entry that is empty, and edit that. - if (ui.itemsList->count() > 0) - { - pItem = ui.itemsList->item(ui.itemsList->count() - 1); - } - - if (pItem == nullptr || !pItem->text().isEmpty()) - { - // Add an empty row to the dialog - InsertBlankItem(); - assert(ui.itemsList->count() > 0); - - // Use the empty row for the new item - pItem = ui.itemsList->item(ui.itemsList->count() - 1); - } - } - - assert(pItem != nullptr); - pItem->setText(selectedDirectory); - - // If the last item in the UI is no longer empty, add another item. - pItem = ui.itemsList->item(ui.itemsList->count() - 1); - if (pItem == nullptr || !pItem->text().isEmpty()) - { - // Add an empty row to the dialog - InsertBlankItem(); - } - - // Don't show the find directory dialog again. - shouldShowFindDirectoryDialog = false; - } - else - { - // Display an error message when a duplicate directory is selected. - rgUtils::ShowErrorMessageBox(STR_INCLUDE_DIR_DIALOG_DIR_ALREADY_SELECTED, this); - - // Make the user try again. - shouldShowFindDirectoryDialog = true; - } - } - } - - // Update move buttons. - UpdateButtons(); -} - -void rgIncludeDirectoriesView::OnListItemChanged(QListWidgetItem* pItem) -{ - // Block signals from the list widget. - ui.itemsList->blockSignals(true); - - m_editingInvalidEntry = false; - - // Process the newly-entered data. - if (pItem != nullptr) - { - QString newDirectory = pItem->text(); - - bool directoryExists = QDir(newDirectory).exists(); - bool directoryDuplicate = m_itemsList.contains(newDirectory); - bool directoryValueEmpty = newDirectory.isEmpty(); - - int itemRow = ui.itemsList->row(pItem); - - if (directoryValueEmpty && itemRow != ui.itemsList->count() - 1) - { - // The user has emptied out the entry, so delete it. - // Simulate a click on the delete button to remove the entry from the UI. - ui.deletePushButton->click(); - } - else - { - // If the new directory exists, and it is not a duplicate entry, update local data. - if (!directoryExists || directoryDuplicate) - { - // Display an error message box. - if (!directoryExists) - { - rgUtils::ShowErrorMessageBox(STR_INCLUDE_DIR_DIALOG_DIR_DOES_NOT_EXIST, this); - } - else if (directoryDuplicate) - { - rgUtils::ShowErrorMessageBox(STR_INCLUDE_DIR_DIALOG_DIR_ALREADY_SELECTED, this); - } - - m_editingInvalidEntry = true; - } - - // Update local data. - if (itemRow < m_itemsList.count()) - { - m_itemsList[itemRow] = newDirectory; - } - else - { - m_itemsList.append(newDirectory); - } - } - - // Update tool tips. - UpdateToolTips(); - - // Unblock signals from the list widget. - ui.itemsList->blockSignals(false); - - // Update buttons. - UpdateButtons(); - } -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyCustomTableView.cpp b/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyCustomTableView.cpp deleted file mode 100644 index 742fa9e..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyCustomTableView.cpp +++ /dev/null @@ -1,371 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include -#include -#include -#include -#include - -// Local. -#include -#include -#include -#include -#include - -// The highlight color to use for correlated source lines. -static QColor s_CORRELATION_HIGHLIGHT_COLOR = QColor(Qt::yellow).lighter(170); -static QColor s_LIGHT_BLUE_SELECTION_COLOR = QColor(229, 243, 255); - -class rgTreeviewSelectionDelegateVulkan : public QItemDelegate -{ -public: - rgTreeviewSelectionDelegateVulkan(QObject* pParent = nullptr) : QItemDelegate(pParent) {} - - virtual void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const - { - QStyleOptionViewItem viewOption(option); - - QColor itemForegroundColor = index.data(Qt::ForegroundRole).value(); - - viewOption.palette.setColor(QPalette::HighlightedText, itemForegroundColor); - QColor backgroundColor(s_CORRELATION_HIGHLIGHT_COLOR); - viewOption.palette.setColor(QPalette::Highlight, backgroundColor); - - QItemDelegate::paint(pPainter, viewOption, index); - } -}; - -class rgTreeviewSelectionDelegateOpenCL : public QItemDelegate -{ -public: - rgTreeviewSelectionDelegateOpenCL(QObject* pParent = nullptr) : QItemDelegate(pParent) {} - - virtual void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const - { - QStyleOptionViewItem viewOption(option); - - QColor itemForegroundColor = index.data(Qt::ForegroundRole).value(); - - viewOption.palette.setColor(QPalette::HighlightedText, itemForegroundColor); - QColor backgroundColor(s_LIGHT_BLUE_SELECTION_COLOR); - viewOption.palette.setColor(QPalette::Highlight, backgroundColor); - - QItemDelegate::paint(pPainter, viewOption, index); - } -}; - -rgIsaDisassemblyCustomTableView::rgIsaDisassemblyCustomTableView(QWidget* pParent) : - QTreeView(pParent) -{ - // Enable treeview's header's click event. - QHeaderView* pHeaderView = this->header(); - assert(pHeaderView != nullptr); - pHeaderView->setSectionsClickable(true); - - // Connect signals. - ConnectSignals(); - - // Set the fonts. - QFont font = this->font(); - font.setFamily(STR_BUILD_VIEW_FONT_FAMILY); - font.setPointSize(gs_BUILD_VIEW_FONT_SIZE); - this->setFont(font); - - rgProjectAPI currentAPI = rgConfigManager::Instance().GetCurrentAPI(); - if (currentAPI == rgProjectAPI::Vulkan) - { - setItemDelegate(new rgTreeviewSelectionDelegateVulkan(this)); - } - else if (currentAPI == rgProjectAPI::OpenCL) - { - setItemDelegate(new rgTreeviewSelectionDelegateOpenCL(this)); - } - else - { - // Should not get here. - assert(false); - } - - // Set focus to no focus to avoid a rectangle around the cell clicked on. - setFocusPolicy(Qt::NoFocus); - - // Install the event filter to process tab and shift+tab key presses. - installEventFilter(this); -} - -void rgIsaDisassemblyCustomTableView::ConnectSignals() -{ - // Connect the header view. - QHeaderView* pHeaderView = this->header(); - assert(pHeaderView != nullptr); - - if (pHeaderView != nullptr) - { - bool isConnected = connect(pHeaderView, &QHeaderView::sectionClicked, this, &rgIsaDisassemblyCustomTableView::HandleHeaderClicked); - assert(isConnected); - } - - // Connect the vertical scroll bar's sliderPressed and valueChanged signals, - // so when the user clicks on the vertical scroll bar, or scrolls the view - // by clicking on the scroll bar, the frame container gets the focus. - QScrollBar* pScrollBar = this->verticalScrollBar(); - assert(pScrollBar != nullptr); - - if (pScrollBar != nullptr) - { - bool isConnected = connect(pScrollBar, &QScrollBar::sliderPressed, this, &rgIsaDisassemblyCustomTableView::HandleScrollBarClicked); - assert(isConnected); - - isConnected = connect(pScrollBar, &QScrollBar::valueChanged, this, &rgIsaDisassemblyCustomTableView::HandleScrollBarClicked); - assert(isConnected); - } - - // Connect the horizontal scroll bar's sliderPressed and valueChanged signals, - // so when the user clicks on the horizontal scroll bar, or scrolls the view - // by clicking on the scroll bar, the frame container gets the focus. - pScrollBar = this->horizontalScrollBar(); - assert(pScrollBar != nullptr); - - if (pScrollBar != nullptr) - { - bool isConnected = connect(pScrollBar, &QScrollBar::sliderPressed, this, &rgIsaDisassemblyCustomTableView::HandleScrollBarClicked); - assert(isConnected); - - isConnected = connect(pScrollBar, &QScrollBar::valueChanged, this, &rgIsaDisassemblyCustomTableView::HandleScrollBarClicked); - assert(isConnected); - } -} - -void rgIsaDisassemblyCustomTableView::SetLabelLinkWidgets(const std::vector& labelLinks) -{ - m_labelLinks = labelLinks; -} - -void rgIsaDisassemblyCustomTableView::SetModel(rgIsaDisassemblyTableModel* pModel) -{ - m_pModel = pModel; -} - -void rgIsaDisassemblyCustomTableView::drawRow(QPainter* pPainter, const QStyleOptionViewItem& options, const QModelIndex& index) const -{ - if (m_pModel != nullptr) - { - // Painting with this delegate can be completely disabled depending on the incoming index. - bool isPaintEnabled = true; - - QStyleOptionViewItem newOptions(options); - newOptions.palette.setBrush(QPalette::Base, Qt::white); - - bool isIndexValid = index.isValid(); - assert(isIndexValid); - if (isIndexValid) - { - // Is the current instruction row correlated with the currently selected line in the input file? - bool isLineCorrelatedWithInputFile = m_pModel->IsIsaLineCorrelated(index.row()); - if (isLineCorrelatedWithInputFile) - { - // Paint the row background with the highlight color. - pPainter->fillRect(options.rect, s_CORRELATION_HIGHLIGHT_COLOR); - - // If the row background gets painted manually, reset the row's background brush to be transparent. - newOptions.palette.setBrush(QPalette::Base, Qt::transparent); - } - - // If the index is a branch operand item, a separate label widget will render a clickable link instead. - bool isBranchOperation = m_pModel->IsBranchOperandItem(index); - if (isBranchOperation) - { - isPaintEnabled = false; - } - } - - if (isPaintEnabled) - { - // Invoke the default item paint implementation. - QTreeView::drawRow(pPainter, newOptions, index); - } - } -} - -void rgIsaDisassemblyCustomTableView::mousePressEvent(QMouseEvent* pEvent) -{ - // Reset the current sub widget to be the table view. - m_currentSubWidget = DisassemblyViewSubWidgets::TableView; - - // Detect if the user has clicked on any of the embedded Label links within the table. - bool isClickOnLabel = false; - for (auto pLabel : m_labelLinks) - { - if (pLabel->underMouse()) - { - isClickOnLabel = true; - break; - } - } - - QItemSelectionModel* pSelectionModel = selectionModel(); - if (isClickOnLabel) - { - // Block the tree's selection model from emitting signals while the label click is handled. - // This will prevent the "row has changed" signal from firing, since the user only intended to click on the Label link. - if (pSelectionModel != nullptr) - { - pSelectionModel->blockSignals(true); - } - } - - // Pass the event onto the base class. - QTreeView::mousePressEvent(pEvent); - - // Always unblock signals to the selection model before returning. - if (pSelectionModel != nullptr) - { - pSelectionModel->blockSignals(false); - } - - // Highlight the frame container. - emit FrameFocusInSignal(); -} - -void rgIsaDisassemblyCustomTableView::focusOutEvent(QFocusEvent* pEvent) -{ - emit FrameFocusOutSignal(); -} - -void rgIsaDisassemblyCustomTableView::focusInEvent(QFocusEvent* pEvent) -{ - emit FrameFocusInSignal(); -} - -void rgIsaDisassemblyCustomTableView::HandleHeaderClicked(int /* sectionNumber */) -{ - // Highlight the frame container. - emit FrameFocusInSignal(); -} - -void rgIsaDisassemblyCustomTableView::HandleScrollBarClicked() -{ - // Highlight the frame container. - emit FrameFocusInSignal(); -} - -void rgIsaDisassemblyCustomTableView::DisableScrollbarSignals() -{ - QScrollBar* pScrollBar = this->verticalScrollBar(); - assert(pScrollBar != nullptr); - - if (pScrollBar != nullptr) - { - pScrollBar->blockSignals(true); - } - - pScrollBar = this->horizontalScrollBar(); - assert(pScrollBar != nullptr); - - if (pScrollBar != nullptr) - { - pScrollBar->blockSignals(true); - } -} - -void rgIsaDisassemblyCustomTableView::EnableScrollbarSignals() -{ - QScrollBar* pScrollBar = this->verticalScrollBar(); - assert(pScrollBar != nullptr); - - if (pScrollBar != nullptr) - { - pScrollBar->blockSignals(false); - } - - pScrollBar = this->horizontalScrollBar(); - assert(pScrollBar != nullptr); - - if (pScrollBar != nullptr) - { - pScrollBar->blockSignals(false); - } -} - -void rgIsaDisassemblyCustomTableView::HandleUpdateCurrentSubWidget(DisassemblyViewSubWidgets currentWidget) -{ - m_currentSubWidget = currentWidget; -} - -bool rgIsaDisassemblyCustomTableView::eventFilter(QObject* pObject, QEvent* pEvent) -{ - bool isFiltered = false; - - if (pEvent->type() == QEvent::KeyPress) - { - QKeyEvent* pKeyEvent = static_cast(pEvent); - Qt::KeyboardModifiers keyboardModifiers = QApplication::keyboardModifiers(); - assert(pKeyEvent != nullptr); - if (pKeyEvent != nullptr) - { - if (pKeyEvent->key() == Qt::Key_Tab) - { - if (m_currentSubWidget == DisassemblyViewSubWidgets::SourceWindow) - { - emit FrameFocusInSignal(); - m_currentSubWidget = DisassemblyViewSubWidgets::TableView; - } - else if (m_currentSubWidget == DisassemblyViewSubWidgets::TableView) - { - emit FocusTargetGpuPushButton(); - m_currentSubWidget = DisassemblyViewSubWidgets::TargetGpuPushButton; - } - else if (m_currentSubWidget == DisassemblyViewSubWidgets::TargetGpuPushButton) - { - m_currentSubWidget = DisassemblyViewSubWidgets::ColumnPushButton; - emit FocusColumnPushButton(); - - } - else if (m_currentSubWidget == DisassemblyViewSubWidgets::ColumnPushButton) - { - m_currentSubWidget = DisassemblyViewSubWidgets::OutputWindow; - emit FocusCliOutputWindow(); - } - - isFiltered = true; - } - else if (pKeyEvent->key() == Qt::Key_Backtab) - { - if (m_currentSubWidget == DisassemblyViewSubWidgets::OutputWindow) - { - emit FocusColumnPushButton(); - m_currentSubWidget = DisassemblyViewSubWidgets::ColumnPushButton; - } - else if (m_currentSubWidget == DisassemblyViewSubWidgets::TableView) - { - emit FocusSourceWindow(); - emit FrameFocusOutSignal(); - m_currentSubWidget = DisassemblyViewSubWidgets::SourceWindow; - } - else if (m_currentSubWidget == DisassemblyViewSubWidgets::TargetGpuPushButton) - { - m_currentSubWidget = DisassemblyViewSubWidgets::TableView; - emit FrameFocusInSignal(); - - } - else if (m_currentSubWidget == DisassemblyViewSubWidgets::ColumnPushButton) - { - m_currentSubWidget = DisassemblyViewSubWidgets::TargetGpuPushButton; - emit FocusTargetGpuPushButton(); - } - - isFiltered = true; - } - else if ((keyboardModifiers & Qt::ControlModifier) && (pKeyEvent->key() == Qt::Key_R)) - { - emit SwitchDisassemblyContainerSize(); - } - } - } - - return isFiltered; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyTabView.cpp b/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyTabView.cpp deleted file mode 100644 index a2a74c3..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyTabView.cpp +++ /dev/null @@ -1,419 +0,0 @@ -// C++. -#include -#include - -// Infra. -#include - -// Local. -#include -#include -#include -#include -#include -#include - -// A separator used in joining an input source file path with an entry point name. -// Such a string is used to uniquely identify an entry point with potential for -// name collisions between separate source files. -static const char s_ENTRYPOINT_KEY_SEPARATOR = '|'; - -rgIsaDisassemblyTabView::rgIsaDisassemblyTabView(QWidget* pParent) : - QWidget(pParent) -{ - ui.setupUi(this); -} - -void rgIsaDisassemblyTabView::ClearCorrelationHighlight() -{ - if (m_pCurrentTable != nullptr) - { - // Passing an invalid line index to the table model will clear the correlated line. - m_pCurrentTable->UpdateCorrelatedSourceFileLine(kInvalidCorrelationLineIndex); - } -} - -bool rgIsaDisassemblyTabView::GetCurrentEntrypoint(std::string& currentEntrypoint) const -{ - bool ret = false; - - auto tableIter = m_disassemblyTableViewToEntrypoint.find(m_pCurrentTable); - if (tableIter != m_disassemblyTableViewToEntrypoint.end()) - { - currentEntrypoint = tableIter->second; - ret = true; - } - - return ret; -} - -int rgIsaDisassemblyTabView::GetTableCount() const -{ - return static_cast(m_entrypointDisassemblyTableViews.size()); -} - -bool rgIsaDisassemblyTabView::PopulateEntries(const std::vector& disassembledEntries) -{ - bool ret = true; - - // Create a disassembly table for each entry, and add it to the layout. - // Only a single entry point table will be visible at a time, and the user can switch between the current entry. - for (const rgEntryOutput& entry : disassembledEntries) - { - OutputFileTypeFinder outputFileTypeSearcher(rgCliOutputFileType::IsaDisassemblyCsv); - auto csvFileIter = std::find_if(entry.m_outputs.begin(), entry.m_outputs.end(), outputFileTypeSearcher); - if (csvFileIter != entry.m_outputs.end()) - { - // Create a new disassembly table view for each entry point. - rgIsaDisassemblyTableView* pTableView = new rgIsaDisassemblyTableView(this); - - // Get the path to the disassembly CSV file to load into the table. - const std::string& disassemblyCsvFilePath = csvFileIter->m_filePath; - - // Set the file path for the table. - pTableView->SetDisassemblyFilePath(disassemblyCsvFilePath); - - // Connect signals for the new table view. - ConnectTableViewSignals(pTableView); - - // Add the table to the tab's grid. - ui.tableGrid->addWidget(pTableView); - - // Register the table with the scaling manager. - ScalingManager::Get().RegisterObject(pTableView); - - // Hide the table initially, as only a single table can be shown at once. - pTableView->hide(); - - // Generate a key string used to identify a named entry point within a given input source file. - std::string entrypointNameKey = GenerateEntrypointKey(entry.m_inputFilePath, entry.m_entrypointName); - - // Associate the kernel name with the table showing the disassembly. - m_entrypointDisassemblyTableViews[entrypointNameKey] = pTableView; - - // Also associate the disassembly table with the entry point it's displaying data for. - m_disassemblyTableViewToEntrypoint[pTableView] = entrypointNameKey; - - // Add the new table to the list of tables associated with the input file. - std::vector& tableList = m_inputFileToIsaTableList[entry.m_inputFilePath]; - tableList.push_back(pTableView); - } - } - - return ret; -} - -void rgIsaDisassemblyTabView::RemoveInputFileEntries(const std::string& inputFilePath) -{ - auto resultsIter = m_inputFileToIsaTableList.find(inputFilePath); - if (resultsIter != m_inputFileToIsaTableList.end()) - { - // We found a list of table views that are used to display disassembly for the given input file. - std::vector& entryTables = resultsIter->second; - - // Step through each table and destroy it. - for (rgIsaDisassemblyTableView* pTableView : entryTables) - { - // Remove the references to the table from the entry point name to ISA table map. - RemoveEntrypointTable(pTableView); - - // Remove the table from the view. - ui.tableGrid->removeWidget(pTableView); - } - - // Remove the entry from the input file path to ISA table map. - auto filePathToTableIter = m_inputFileToIsaTableList.find(inputFilePath); - if (filePathToTableIter != m_inputFileToIsaTableList.end()) - { - m_inputFileToIsaTableList.erase(filePathToTableIter); - } - } -} - -void rgIsaDisassemblyTabView::SwitchToEntryPoint(const std::string& inputFilePath, const std::string& entrypointName) -{ - // Generate a key string used to identify a named entry point within a given input source file. - std::string entrypointNameKey = GenerateEntrypointKey(inputFilePath, entrypointName); - - // Find the disassembly table corresponding to the given entry point name. - auto entryIter = m_entrypointDisassemblyTableViews.find(entrypointNameKey); - if (entryIter != m_entrypointDisassemblyTableViews.end()) - { - rgIsaDisassemblyTableView* pTableView = entryIter->second; - assert(pTableView != nullptr); - - if (pTableView != nullptr && pTableView != m_pCurrentTable) - { - // Do not load the table if it was loaded already. - bool isTableCached = pTableView->IsDisassemblyLoaded(); - bool isTableLoaded = false; - - if (!isTableCached) - { - // Attempt to load the table. - // Get the disassembly file path. - const std::string& disassemblyFilePath = pTableView->GetDisassemblyFilePath(); - assert(!disassemblyFilePath.empty()); - - if (!disassemblyFilePath.empty()) - { - isTableLoaded = pTableView->LoadDisassembly(disassemblyFilePath); - if (!isTableLoaded) - { - // Tell the user that the disassembly file failed to load. - std::stringstream errorString; - errorString << STR_ERR_CANNOT_LOAD_DISASSEMBLY_CSV_FILE; - errorString << disassemblyFilePath; - rgUtils::ShowErrorMessageBox(errorString.str().c_str(), this); - } - } - - } - - // If the table was loaded, either previously or just now, update the UI. - assert(isTableCached || isTableLoaded); - if (isTableCached || isTableLoaded) - { - // Hide the currently-visible disassembly table. - if (m_pCurrentTable != nullptr) - { - m_pCurrentTable->hide(); - } - - // Show the disassembly table that we're switching to. - pTableView->show(); - m_pCurrentTable = pTableView; - - // Use the current table view as the focus proxy for this view. - setFocusProxy(pTableView); - - // Filter the table we are about to show, without resizing - // since the table is inheriting the filter from its predecessor. - pTableView->UpdateFilteredTable(); - } - } - } -} - -void rgIsaDisassemblyTabView::UpdateCorrelatedSourceFileLine(const std::string& inputFilePath, int lineNumber, std::string& entryName) -{ - if (!entryName.empty()) - { - // Switch to view the disassembly table for the named entrypoint. - SwitchToEntryPoint(inputFilePath, entryName); - } - - // Find the table used to present the given entrypoint's disassembly. - std::string entrypointNameKey = GenerateEntrypointKey(inputFilePath, entryName); - auto entrypointToTableIter = m_entrypointDisassemblyTableViews.find(entrypointNameKey); - if (entrypointToTableIter != m_entrypointDisassemblyTableViews.end()) - { - // Update the currently selected source line number. - rgIsaDisassemblyTableView* pEntrypointTable = entrypointToTableIter->second; - pEntrypointTable->UpdateCorrelatedSourceFileLine(lineNumber); - } -} - -bool rgIsaDisassemblyTabView::IsSourceLineCorrelatedForEntry(const std::string& inputFilePath, const std::string& entryName, int lineNumber) -{ - bool ret = false; - - // Generate a key string used to identify a named entry point within a given input source file. - std::string entrypointNameKey = GenerateEntrypointKey(inputFilePath, entryName); - - const auto& isaTableView = m_entrypointDisassemblyTableViews.find(entrypointNameKey); - if (isaTableView != m_entrypointDisassemblyTableViews.end()) - { - ret = isaTableView->second->IsSourceLineCorrelated(lineNumber); - } - return ret; -} - -bool rgIsaDisassemblyTabView::ReplaceInputFilePath(const std::string& oldFilePath, const std::string& newFilePath) -{ - assert(!oldFilePath.empty()); - assert(!newFilePath.empty()); - bool ret = (!oldFilePath.empty() && !newFilePath.empty()); - - if (ret) - { - // 1. Replace the file path in the "entry point --> disasm table view" map. - // There may be multiple matching elements since the keys in this map - // consist of the file path and the entry name: KEY = "file-path|entry-name". - std::vector::iterator> nodesToChange; - for (auto it = m_entrypointDisassemblyTableViews.begin(); it != m_entrypointDisassemblyTableViews.end(); ++it) - { - std::string filePath, entryName; - DecodeEntrypointKey(it->first, filePath, entryName); - if (filePath == oldFilePath) - { - nodesToChange.push_back(it); - } - } - - for (auto it : nodesToChange) - { - std::string filePath, entryName; - DecodeEntrypointKey(it->first, filePath, entryName); - auto pTableView = it->second; - m_entrypointDisassemblyTableViews.erase(it); - std::string newKey = GenerateEntrypointKey(newFilePath, entryName); - m_entrypointDisassemblyTableViews[newKey] = pTableView; - } - } - - if (ret) - { - // 2. Replace the file path in the "disasm table view --> entry point" map. - for (auto& val : m_disassemblyTableViewToEntrypoint) - { - std::string filePath, entryName; - DecodeEntrypointKey(val.second, filePath, entryName); - if (filePath == oldFilePath) - { - val.second = GenerateEntrypointKey(newFilePath, entryName); - } - } - } - - if (ret) - { - // 3. Replace the file path in the "input file --> disasm table views" map. - auto it = m_inputFileToIsaTableList.find(oldFilePath); - if ((ret = (it != m_inputFileToIsaTableList.end())) == true) - { - auto tableViews = it->second; - m_inputFileToIsaTableList.erase(it); - m_inputFileToIsaTableList[newFilePath] = tableViews; - } - } - - assert(ret); - - return ret; -} - -void rgIsaDisassemblyTabView::HandleColumnVisibilityFilterStateChanged() -{ - // Only filter the current table. - if (m_pCurrentTable != nullptr) - { - m_pCurrentTable->UpdateFilteredTable(); - - // Resize the current table after changing column visibility. - m_pCurrentTable->RequestTableResize(); - } -} - -void rgIsaDisassemblyTabView::ConnectTableViewSignals(rgIsaDisassemblyTableView* pTableView) -{ - // Connect a forwarding signal used to handle when the input source file's correlation highlight line is updated. - bool isConnected = connect(pTableView, &rgIsaDisassemblyTableView::InputSourceHighlightedLineChanged, this, &rgIsaDisassemblyTabView::InputSourceHighlightedLineChanged); - assert(isConnected); - - // Connect the disassembly table resized handler. - isConnected = connect(pTableView, &rgIsaDisassemblyTableView::DisassemblyTableWidthResizeRequested, this, &rgIsaDisassemblyTabView::DisassemblyTableWidthResizeRequested); - assert(isConnected); - - // Connect the disassembly table clicked handler. - isConnected = connect(pTableView, &rgIsaDisassemblyTableView::FrameFocusInSignal, this, &rgIsaDisassemblyTabView::FrameFocusInSignal); - assert(isConnected); - - // Connect a forwarding signal used to handle when the disassembly table loses focus. - isConnected = connect(pTableView, &rgIsaDisassemblyTableView::FrameFocusOutSignal, this, &rgIsaDisassemblyTabView::FrameFocusOutSignal); - assert(isConnected); - - // Connect the disassembly view's enable scroll bar signal. - isConnected = connect(this, &rgIsaDisassemblyTabView::EnableScrollbarSignals, pTableView, &rgIsaDisassemblyTableView::EnableScrollbarSignals); - assert(isConnected); - - // Connect the disassembly view's disable scroll bar signal. - isConnected = connect(this, &rgIsaDisassemblyTabView::DisableScrollbarSignals, pTableView, &rgIsaDisassemblyTableView::DisableScrollbarSignals); - assert(isConnected); - - // Connect the disassembly table's target GPU push button focus in signal. - isConnected = connect(pTableView, &rgIsaDisassemblyTableView::FocusTargetGpuPushButton, this, &rgIsaDisassemblyTabView::FocusTargetGpuPushButton); - assert(isConnected); - - // Connect the disassembly table's switch disassembly view size signal. - isConnected = connect(pTableView, &rgIsaDisassemblyTableView::SwitchDisassemblyContainerSize, this, &rgIsaDisassemblyTabView::SwitchDisassemblyContainerSize); - assert(isConnected); - - // Connect the disassembly table's columns push button focus in signal. - isConnected = connect(pTableView, &rgIsaDisassemblyTableView::FocusColumnPushButton, this, &rgIsaDisassemblyTabView::FocusColumnPushButton); - assert(isConnected); - - // Connect the disassembly table's cli output window focus in signal. - isConnected = connect(pTableView, &rgIsaDisassemblyTableView::FocusCliOutputWindow, this, &rgIsaDisassemblyTabView::FocusCliOutputWindow); - assert(isConnected); - - // Connect the disassembly table's source window focus in signal. - isConnected = connect(pTableView, &rgIsaDisassemblyTableView::FocusSourceWindow, this, &rgIsaDisassemblyTabView::FocusSourceWindow); - assert(isConnected); - - // Connect the disassembly tab view's update current sub widget signal. - isConnected = connect(this, &rgIsaDisassemblyTabView::UpdateCurrentSubWidget, pTableView, &rgIsaDisassemblyTableView::UpdateCurrentSubWidget); - assert(isConnected); - - // Connect the disassembly table's focus cli output window signal. - isConnected = connect(pTableView, &rgIsaDisassemblyTableView::FocusCliOutputWindow, this, &rgIsaDisassemblyTabView::FocusCliOutputWindow); - assert(isConnected); - -} - -std::string rgIsaDisassemblyTabView::GenerateEntrypointKey(const std::string& filePath, const std::string& entrypointName) const -{ - // In some cases it may not be possible to identify a given entry point by name when multiple - // entrypoints use the same name. Return a unique key based on the input filename and the - // entry point name, so that each entry point can be identified correctly. - return filePath + s_ENTRYPOINT_KEY_SEPARATOR + entrypointName; -} - -bool rgIsaDisassemblyTabView::DecodeEntrypointKey(const std::string& entrypointKey, std::string& filePath, std::string& entrypointName) const -{ - bool ret = false; - - // Attempt to split the given entry point key string into source file path and entry point name strings. - std::vector filePathAndEntrypointNameList; - rgUtils::splitString(entrypointKey, s_ENTRYPOINT_KEY_SEPARATOR, filePathAndEntrypointNameList); - - // Verify that only 2 tokens are found. One for the source file path, and another for entry point name. - size_t tokenCount = filePathAndEntrypointNameList.size(); - assert(tokenCount == 2); - if (tokenCount == 2) - { - filePath = filePathAndEntrypointNameList[0]; - entrypointName = filePathAndEntrypointNameList[1]; - ret = true; - } - - return ret; -} - -void rgIsaDisassemblyTabView::RemoveEntrypointTable(rgIsaDisassemblyTableView* pTableView) -{ - // Set the current table to null- it's going to be removed from the view. - if (m_pCurrentTable == pTableView) - { - m_pCurrentTable = nullptr; - } - - // Step through the map of entry point to table, and erase the one that matches the incoming table being removed. - auto tablesStartIter = m_entrypointDisassemblyTableViews.begin(); - auto tablesEndIter = m_entrypointDisassemblyTableViews.end(); - for (auto tableIter = tablesStartIter; tableIter != tablesEndIter; ++tableIter) - { - if (tableIter->second == pTableView) - { - m_entrypointDisassemblyTableViews.erase(tableIter); - break; - } - } - - // Find and remove the given table from the table to entry point name map. - auto tableIter = m_disassemblyTableViewToEntrypoint.find(pTableView); - if (tableIter != m_disassemblyTableViewToEntrypoint.end()) - { - m_disassemblyTableViewToEntrypoint.erase(tableIter); - } -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyTableModel.cpp b/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyTableModel.cpp deleted file mode 100644 index d3d9663..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyTableModel.cpp +++ /dev/null @@ -1,707 +0,0 @@ -// C++. -#include -#include -#include - -// Qt. -#include -#include -#include -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include - -// Shared with CLI. -#include - -// 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 modelCount, QWidget* pParent) : - ModelViewMapper(modelCount) -{ - // Create the table model. - m_pIsaTableModel = new QStandardItemModel(0, GetTableColumnIndex(rgIsaDisassemblyTableColumns::Count), pParent); - - // Add column headers to the table. - m_pIsaTableModel->setHorizontalHeaderItem(GetTableColumnIndex(rgIsaDisassemblyTableColumns::Address), new QStandardItem(STR_DISASSEMBLY_TABLE_COLUMN_ADDRESS)); - m_pIsaTableModel->setHorizontalHeaderItem(GetTableColumnIndex(rgIsaDisassemblyTableColumns::Opcode), new QStandardItem(STR_DISASSEMBLY_TABLE_COLUMN_OPCODE)); - m_pIsaTableModel->setHorizontalHeaderItem(GetTableColumnIndex(rgIsaDisassemblyTableColumns::Operands), new QStandardItem(STR_DISASSEMBLY_TABLE_COLUMN_OPERANDS)); - m_pIsaTableModel->setHorizontalHeaderItem(GetTableColumnIndex(rgIsaDisassemblyTableColumns::FunctionalUnit), new QStandardItem(STR_DISASSEMBLY_TABLE_COLUMN_FUNCTIONAL_UNIT)); - m_pIsaTableModel->setHorizontalHeaderItem(GetTableColumnIndex(rgIsaDisassemblyTableColumns::Cycles), new QStandardItem(STR_DISASSEMBLY_TABLE_COLUMN_CYCLES)); - m_pIsaTableModel->setHorizontalHeaderItem(GetTableColumnIndex(rgIsaDisassemblyTableColumns::BinaryEncoding), new QStandardItem(STR_DISASSEMBLY_TABLE_COLUMN_BINARY_ENCODING)); -} - -const std::vector& rgIsaDisassemblyTableModel::GetCorrelatedLineIndices() const -{ - return m_correlatedIsaLineIndices; -} - -QStandardItemModel* rgIsaDisassemblyTableModel::GetTableModel() const -{ - return m_pIsaTableModel; -} - -bool rgIsaDisassemblyTableModel::GetInputSourceLineNumberFromInstructionRow(int instructionLineIndex, int& inputSourceLineNumber) -{ - bool ret = false; - - auto inputSourceLineIter = m_instructionLineNumberToInputSourceLineNumber.find(instructionLineIndex); - if (inputSourceLineIter != m_instructionLineNumberToInputSourceLineNumber.end()) - { - // Return the input source file's line number that corresponds with the given disassembly line number. - inputSourceLineNumber = inputSourceLineIter->second; - ret = true; - } - - return ret; -} - -void rgIsaDisassemblyTableModel::GetLabelNameToLineIndexMap(std::map& linkLabels) const -{ - int numLines = static_cast(m_disassembledIsaLines.size()); - for (int lineIndex = 0; lineIndex < numLines; ++lineIndex) - { - std::shared_ptr pCurrentLine = m_disassembledIsaLines[lineIndex]; - if (pCurrentLine->m_type == rgIsaLineType::Label) - { - // Cast the line into a label line. - std::shared_ptr pLabelLine = std::static_pointer_cast(pCurrentLine); - - // Extract the label name and insert into the output map. - std::string labelName = pLabelLine->m_labelName; - linkLabels[labelName] = lineIndex; - } - } -} - -void rgIsaDisassemblyTableModel::GetLineIndexToLabelNameMap(std::map& linkLabels) const -{ - // Step through each disassembled line and collect all label line numbers, and their destination operand. - int numLines = static_cast(m_disassembledIsaLines.size()); - for (int lineIndex = 0; lineIndex < numLines; ++lineIndex) - { - std::shared_ptr pCurrentLine = m_disassembledIsaLines[lineIndex]; - if (pCurrentLine->m_type == rgIsaLineType::Instruction) - { - // Look for branch instructions, and extract the destination from the operands text. - std::shared_ptr pInstructionLine = std::static_pointer_cast(pCurrentLine); - if (pInstructionLine->m_functionalUnit.compare("Branch") == 0) - { - std::string jumpDestination = pInstructionLine->m_operands; - linkLabels[lineIndex] = jumpDestination; - } - } - } -} - -void rgIsaDisassemblyTableModel::InsertLabelRows() -{ - // Try to insert labels into the start column if possible. - int startColumn = GetTableColumnIndex(rgIsaDisassemblyTableColumns::Address); - int endColumn = GetTableColumnIndex(rgIsaDisassemblyTableColumns::Count); - - // The column index to insert the labels into. - m_labelColumnIndex = startColumn; - - // Check the global settings to determine which disassembly table columns are visible. - std::shared_ptr pGlobalSettings = rgConfigManager::Instance().GetGlobalConfig(); - assert(pGlobalSettings != nullptr); - if (pGlobalSettings != nullptr) - { - // Determine which column is the left-most visible column in the table. - for (int columnIndex = startColumn; columnIndex < endColumn; ++columnIndex) - { - bool isValidColumnIndex = (columnIndex >= startColumn) && (columnIndex < endColumn); - bool isVisible = pGlobalSettings->m_visibleDisassemblyViewColumns[columnIndex]; - if (isVisible) - { - m_labelColumnIndex = columnIndex; - break; - } - } - } - - // Step through each ISA line and update the model data if it's a label row. - int rowCount = static_cast(m_disassembledIsaLines.size()); - for (int rowIndex = 0; rowIndex < rowCount; ++rowIndex) - { - std::shared_ptr pIsaLine = m_disassembledIsaLines[rowIndex]; - - if (pIsaLine->m_type == rgIsaLineType::Label) - { - // Cast into a rgIsaLineLabel to extract the label name. - std::shared_ptr pLabelLine = std::static_pointer_cast(pIsaLine); - - // Add the label text to the model. - SetTableModelText(pLabelLine->m_labelName, rowIndex, m_labelColumnIndex); - - // Set the background color to yellow to make the label stand out more. - SetTableModelBackgroundColor(kBranchLabelBackgroundColor, rowIndex, m_labelColumnIndex); - } - } -} - -int rgIsaDisassemblyTableModel::GetTableColumnIndex(rgIsaDisassemblyTableColumns column) -{ - return static_cast(column); -} - -bool rgIsaDisassemblyTableModel::IsBranchOperandItem(const QModelIndex& modelIndex) -{ - bool isLabelLinkItem = false; - - // Find the disassembly row for the item. - int rowIndex = modelIndex.row(); - std::shared_ptr pIsaLine = m_disassembledIsaLines[rowIndex]; - - // Determine what kind of instruction is represented in this row. - if (pIsaLine->m_type == rgIsaLineType::Instruction) - { - // Cast the line to access the instruction data. - std::shared_ptr pInstructionLine = std::static_pointer_cast(pIsaLine); - - // Is this a branch instruction? - if (pInstructionLine->m_functionalUnit.compare("Branch") == 0) - { - // Is the given index in the Operands column? That's the column a label needs to be painted in. - int columnIndex = modelIndex.column(); - bool isOperandsColumn = columnIndex == GetTableColumnIndex(rgIsaDisassemblyTableColumns::Operands); - if (isOperandsColumn) - { - isLabelLinkItem = true; - } - } - } - - return isLabelLinkItem; -} - -bool rgIsaDisassemblyTableModel::IsColumnVisible(int columnIndex) const -{ - bool isVisible = false; - - // Check the global config settings to see if the column should be visible. - rgConfigManager& configManager = rgConfigManager::Instance(); - std::shared_ptr pGlobalSettings = configManager.GetGlobalConfig(); - assert(pGlobalSettings != nullptr); - if (pGlobalSettings != nullptr) - { - // Verify that the incoming column index is valid. - bool isValidIndex = (columnIndex >= 0) && (columnIndex < pGlobalSettings->m_visibleDisassemblyViewColumns.size()); - assert(isValidIndex); - if (isValidIndex) - { - isVisible = pGlobalSettings->m_visibleDisassemblyViewColumns[columnIndex]; - } - } - - return isVisible; -} - -bool rgIsaDisassemblyTableModel::IsIsaLineCorrelated(int lineIndex) const -{ - bool ret = false; - - // Check if the given line index exists in the current cache of correlated line indices. - auto lineIter = std::find(m_correlatedIsaLineIndices.begin(), m_correlatedIsaLineIndices.end(), lineIndex); - if (lineIter != m_correlatedIsaLineIndices.end()) - { - ret = true; - } - - return ret; -} - -bool rgIsaDisassemblyTableModel::IsSourceLineCorrelated(int lineIndex) const -{ - return (m_inputSourceLineIndexToInstructionLineIndices.find(lineIndex) != m_inputSourceLineIndexToInstructionLineIndices.end()); -} - -bool rgIsaDisassemblyTableModel::IsSourceLineInEntrypoint(int lineIndex) const -{ - bool ret = false; - - // Does the given line fall within the line number bounds for this entrypoint? - if ((lineIndex >= m_sourceFileEntrypointStartLine) && (lineIndex <= m_sourceFileEntrypointEndLine)) - { - ret = true; - } - - return ret; -} - -bool rgIsaDisassemblyTableModel::PopulateFromCsvFile(const std::string& csvFileFullPath) -{ - // Attempt to load the CSV file, and then update the model's data. - bool isDataLoaded = LoadCsvData(csvFileFullPath); - assert(isDataLoaded); - if (isDataLoaded) - { - // Initialize the model using the CSV data that was just loaded. - InitializeModelData(); - } - - return isDataLoaded; -} - -bool rgIsaDisassemblyTableModel::SetCorrelatedSourceLineIndex(int lineIndex) -{ - bool isCorrelated = false; - - // Determine the set of ISA instructions that should become highlighted. - std::vector isaLineIndices; - isCorrelated = GetDisassemblyLineIndicesFromInputSourceLine(lineIndex, isaLineIndices); - - if (isCorrelated) - { - // Assign the list of highlighted lines to paint. - m_correlatedIsaLineIndices = isaLineIndices; - } - else - { - // Clear the list and highlight nothing. - m_correlatedIsaLineIndices.clear(); - } - - return isCorrelated; -} - -bool rgIsaDisassemblyTableModel::GetDisassemblyLineIndicesFromInputSourceLine(int inputSourceLine, std::vector& disassemblyLines) -{ - bool ret = false; - - auto disassemblyInstructionLinesIter = m_inputSourceLineIndexToInstructionLineIndices.find(inputSourceLine); - if (disassemblyInstructionLinesIter != m_inputSourceLineIndexToInstructionLineIndices.end()) - { - // Return the list of disassembly line indices. - disassemblyLines = disassemblyInstructionLinesIter->second; - ret = true; - } - - return ret; -} - -int rgIsaDisassemblyTableModel::GetCsvColumnIndex(rgIsaDisassemblyCsvFileColumns column) const -{ - return static_cast(column); -} - -QColor rgIsaDisassemblyTableModel::GetFunctionalUnitColor(const std::string& functionalUnit) const -{ - QColor 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 }, - }; - - auto unit = kFunctionalUnitColors.find(functionalUnit); - if (unit != kFunctionalUnitColors.end()) - { - color = unit->second; - } - - return color; -} - -bool rgIsaDisassemblyTableModel::LoadCsvData(const std::string& csvFileFullPath) -{ - bool ret = true; - - // Clear out existing data. - m_disassembledIsaLines.clear(); - - QFile csvFile(csvFileFullPath.c_str()); - QTextStream fileStream(&csvFile); - - // Attempt to open the file to read each instruction line. - bool isFileOpened = csvFile.open(QFile::ReadOnly | QFile::Text); - assert(isFileOpened); - if (isFileOpened) - { - // Read the first ISA instruction line and just move on, as it's just column labels. - QString isaLine = fileStream.readLine(); - - // Parse each new line in the ISA disassembly file. - do - { - // Read the next line in the file. - isaLine = fileStream.readLine(); - if (!isaLine.isEmpty()) - { - // Parse the line that was just read into a new rgIsaLine. - std::shared_ptr pNewLine = nullptr; - int inputSourceLineIndex = kInvalidCorrelationLineIndex; - bool isSplitSuccessful = ParseCsvIsaLine(isaLine.toStdString(), pNewLine, inputSourceLineIndex); - - // Was the line processed correctly? - assert(isSplitSuccessful); - if (isSplitSuccessful) - { - assert(pNewLine != nullptr); - if (pNewLine != nullptr) - { - // Does the parsed ISA line have an associated input source line? - if (inputSourceLineIndex != kInvalidCorrelationLineIndex) - { - // Use a map to associate the current line of disassembly with the input source line index. - int disassemblyLineIndex = static_cast(m_disassembledIsaLines.size()); - m_instructionLineNumberToInputSourceLineNumber[disassemblyLineIndex] = inputSourceLineIndex; - - // Find the minimum line number of the entry point in the input file. - if (inputSourceLineIndex < m_sourceFileEntrypointStartLine) - { - m_sourceFileEntrypointStartLine = inputSourceLineIndex; - } - - // Find the maximum line number of the entry point in the input file. - if (inputSourceLineIndex > m_sourceFileEntrypointEndLine) - { - m_sourceFileEntrypointEndLine = inputSourceLineIndex; - } - - // Also create a mapping of input source code line index to a list of all associated disassembly instruction line indices. - std::vector& disassemblyLineIndices = m_inputSourceLineIndexToInstructionLineIndices[inputSourceLineIndex]; - disassemblyLineIndices.push_back(disassemblyLineIndex); - } - - // Add the ISA line's structure to the list of instruction lines. - m_disassembledIsaLines.push_back(pNewLine); - } - } - else - { - ret = false; - } - } - } while (!fileStream.atEnd()); - } - else - { - // Failed to open the disassembly file. - ret = false; - } - - return ret; -} - -void rgIsaDisassemblyTableModel::SetTableModelText(const std::string& modelText, uint rowIndex, uint columnIndex) -{ - // Set the cell's text, and make it left-aligned. - m_pIsaTableModel->setData(m_pIsaTableModel->index(rowIndex, columnIndex), QString(modelText.c_str())); - m_pIsaTableModel->setData(m_pIsaTableModel->index(rowIndex, columnIndex), Qt::AlignLeft, Qt::TextAlignmentRole); -} - -void rgIsaDisassemblyTableModel::SetTableModelTextColor(const QColor& modelColor, uint rowIndex) -{ - // Set the table's model color for each column in the given row. - for (int columnIndex = 0; columnIndex < GetTableColumnIndex(rgIsaDisassemblyTableColumns::Count); ++columnIndex) - { - // Set the foreground color role in the model. - m_pIsaTableModel->setData(m_pIsaTableModel->index(rowIndex, columnIndex), modelColor, Qt::ForegroundRole); - } -} - -void rgIsaDisassemblyTableModel::SetTableModelBackgroundColor(const QColor& modelColor, uint rowIndex, uint columnIndex) -{ - // Set the background color role in the model. - m_pIsaTableModel->setData(m_pIsaTableModel->index(rowIndex, columnIndex), modelColor, Qt::BackgroundColorRole); -} - -bool rgIsaDisassemblyTableModel::ParseCsvIsaLine(const std::string& disassembledLine, std::shared_ptr& parsedLine, int& inputSourceLineIndex) -{ - bool ret = false; - - // Some parsed CSV lines don't have an input sourcecode line number associated with them. In these cases, return -1. - inputSourceLineIndex = kInvalidCorrelationLineIndex; - - std::vector lineTokens; - std::stringstream lineStream; - lineStream.str(disassembledLine); - std::string substr; - - // Step through the entire line of text, and split into tokens based on comma position. - while (std::getline(lineStream, substr, ',')) - { - // Are there any quotation marks within the token? If so, parsing is handled differently. - size_t numQuotesInToken = std::count(substr.begin(), substr.end(), '\"'); - switch (numQuotesInToken) - { - case 0: - { - // If there are no quotes, just add the token to the line tokens list. - lineTokens.push_back(substr); - } - break; - case 1: - { - // Found a start quote. Keep reading new tokens to find the matching end quote. - std::stringstream tokenStream; - do - { - // Add the token to the quoted column string. - tokenStream << substr << ','; - std::getline(lineStream, substr, ','); - } while (!(substr.find('"') != substr.npos)); - - // Add the final portion of the token to the stream. - tokenStream << substr; - - // Remove the quotation marks from the final token string. - std::string quotedToken = tokenStream.str(); - quotedToken.erase(std::remove(quotedToken.begin(), quotedToken.end(), '\"'), quotedToken.end()); - - // Add the token to the line tokens list. - lineTokens.push_back(quotedToken); - } - 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()); - lineTokens.push_back(substr); - } - break; - default: - // If this happens, the format of the ISA line likely wasn't handled correctly. - assert(false); - } - } - - int numColumns = static_cast(lineTokens.size()); - const int numCsvColumns = static_cast(rgIsaDisassemblyCsvFileColumns::Count); - switch (numColumns) - { - case 1: - { - // This line is a label line that indicates a new section of instructions. - std::shared_ptr pLabelLine = std::make_shared(); - pLabelLine->m_labelName = lineTokens[0]; - - // The line was parsed successfully. - parsedLine = std::static_pointer_cast(pLabelLine); - ret = true; - } - break; - case numCsvColumns: - { - // Add each token to the output structure. - std::shared_ptr pInstructionLine = std::make_shared(); - - // Assign the values into the instruction line object. - pInstructionLine->m_address = lineTokens[GetCsvColumnIndex(rgIsaDisassemblyCsvFileColumns::Address)]; - pInstructionLine->m_opcode = lineTokens[GetCsvColumnIndex(rgIsaDisassemblyCsvFileColumns::Opcode)]; - pInstructionLine->m_operands = lineTokens[GetCsvColumnIndex(rgIsaDisassemblyCsvFileColumns::Operands)]; - pInstructionLine->m_functionalUnit = lineTokens[GetCsvColumnIndex(rgIsaDisassemblyCsvFileColumns::FunctionalUnit)]; - pInstructionLine->m_cycles = lineTokens[GetCsvColumnIndex(rgIsaDisassemblyCsvFileColumns::Cycles)]; - pInstructionLine->m_binaryEncoding = lineTokens[GetCsvColumnIndex(rgIsaDisassemblyCsvFileColumns::BinaryEncoding)]; - - // Extract the source line number as an integer. - inputSourceLineIndex = std::stoi(lineTokens[GetCsvColumnIndex(rgIsaDisassemblyCsvFileColumns::SourceLineNumber)].c_str()); - - // The line was parsed successfully, so assign it to the output instance. - parsedLine = std::static_pointer_cast(pInstructionLine); - ret = true; - } - break; - default: - // Catch cases where the type of line format is unhandled. - assert(false); - break; - } - - return ret; -} - -void rgIsaDisassemblyTableModel::ClearLabelLines() -{ - // Empty out the contents of all lines with labels. - int rowCount = static_cast(m_disassembledIsaLines.size()); - for (int rowIndex = 0; rowIndex < rowCount; ++rowIndex) - { - std::shared_ptr pIsaLine = m_disassembledIsaLines[rowIndex]; - if (pIsaLine->m_type == rgIsaLineType::Label) - { - // Add the label text to the model. - SetTableModelText("", rowIndex, m_labelColumnIndex); - - // Set the background color to white, because the data was erased. - SetTableModelBackgroundColor(QColor(Qt::white), rowIndex, m_labelColumnIndex); - } - } -} - -void rgIsaDisassemblyTableModel::GetColumnMaxWidths(const QVector& selectedRowNumbers, std::vector& widths) const -{ - const auto& pGlobalSettings = rgConfigManager::Instance().GetGlobalConfig(); - for (int col = 0, numColumns = m_pIsaTableModel->columnCount(); col < numColumns; ++col) - { - if (pGlobalSettings->m_visibleDisassemblyViewColumns[col]) - { - int maxWidth = 0; - if (selectedRowNumbers.at(selectedRowNumbers.size() - 1) < m_disassembledIsaLines.size()) - { - foreach (auto row, selectedRowNumbers) - { - if (m_disassembledIsaLines[row]->m_type == rgIsaLineType::Instruction) - { - QVariant cellText = m_pIsaTableModel->data(m_pIsaTableModel->index(row, col)); - maxWidth = std::max(maxWidth, cellText.toString().size()); - } - } - } - widths.push_back(maxWidth); - } - } -} - -void rgIsaDisassemblyTableModel::CopyRowsToClipboard(const QVector& selectedRowNumbers) -{ - const int MIN_COLUMN_OFFSET = 4; - std::shared_ptr pGlobalSettings = rgConfigManager::Instance().GetGlobalConfig(); - - // Calculate maximum width for each column in the selected ISA region. - std::vector maxColumnWidths; - GetColumnMaxWidths(selectedRowNumbers, maxColumnWidths); - - // Add a tab as a delimiter between each column. - const char COLUMN_DELIMITER_SYMBOL = ' '; - - // Build a string including each line in the selected range. - std::stringstream clipboardText; - foreach(auto rowIndex, selectedRowNumbers) - { - // Is the current row an instruction or a label? - std::shared_ptr pIsaLine = m_disassembledIsaLines[rowIndex]; - if (pIsaLine->m_type == rgIsaLineType::Instruction) - { - bool isFirstTokenInLine = true; - std::string prevColumnText = ""; - - // Add the contents of visible columns to the clipboard text. - for (int columnIndex = 0, prevVisibleColumnIndex = 0; columnIndex < pGlobalSettings->m_visibleDisassemblyViewColumns.size(); ++columnIndex) - { - // Is the current column visible? - bool isColumnVisible = pGlobalSettings->m_visibleDisassemblyViewColumns[columnIndex]; - if (isColumnVisible) - { - if (isFirstTokenInLine) - { - // We don't need to append the delimiter before the first token in the line. - isFirstTokenInLine = false; - } - else - { - // 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(prevVisibleColumnIndex < maxColumnWidths.size()); - std::string delimiter = ""; - for (size_t i = 0, numSpaces = MIN_COLUMN_OFFSET + maxColumnWidths[prevVisibleColumnIndex++] - prevColumnText.size(); - i < numSpaces; ++i) - { - delimiter += COLUMN_DELIMITER_SYMBOL; - } - clipboardText << delimiter; - } - - // Get the cell data. - QModelIndex cellIndex = m_pIsaTableModel->index(rowIndex, columnIndex); - QVariant cellText = m_pIsaTableModel->data(cellIndex); - - // If the data is invalid, get it from somewhere else. - if (!cellText.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 cellTextString = m_pIsaTableModel->data(m_pIsaTableModel->index(rowIndex, static_cast(rgIsaDisassemblyTableColumns::FunctionalUnit))).toString(); - if (cellTextString.compare("Branch") == 0) - { - std::shared_ptr pIsaLine = m_disassembledIsaLines[rowIndex]; - assert(pIsaLine != nullptr); - if (pIsaLine != nullptr) - { - std::shared_ptr pInstructionLine = std::static_pointer_cast(pIsaLine); - assert(pInstructionLine != nullptr); - if (pInstructionLine != nullptr) - { - cellText = QString::fromStdString(pInstructionLine->m_operands); - } - } - } - } - - // Add the data to the clipboard string stream. - clipboardText << (prevColumnText = cellText.toString().toStdString()); - } - } - } - else if (pIsaLine->m_type == rgIsaLineType::Label) - { - // Extract the label text from whatever column the label is in. - QModelIndex cellIndex = m_pIsaTableModel->index(rowIndex, m_labelColumnIndex); - QVariant cellText = m_pIsaTableModel->data(cellIndex); - - // Append the label name to the clipboard text. - clipboardText << cellText.toString().toStdString(); - } - - // Add a newline to the end of each row of data. - clipboardText << std::endl; - } - - // Add the text into the clipboard. - QClipboard* pClipboard = QApplication::clipboard(); - pClipboard->setText(clipboardText.str().c_str()); -} - -void rgIsaDisassemblyTableModel::InitializeModelData() -{ - // Update the number of rows in the table. - int lineCount = static_cast(m_disassembledIsaLines.size()); - m_pIsaTableModel->setRowCount(lineCount); - - // Step through each ISA line and update the row item's data. - for (int lineIndex = 0; lineIndex < lineCount; ++lineIndex) - { - std::shared_ptr pIsaLine = m_disassembledIsaLines[lineIndex]; - - if (pIsaLine->m_type == rgIsaLineType::Instruction) - { - std::shared_ptr pInstructionLine = std::static_pointer_cast(pIsaLine); - - // Update the model cells with data from each disassembled ISA instruction line. - SetTableModelText(pInstructionLine->m_address, lineIndex, GetTableColumnIndex(rgIsaDisassemblyTableColumns::Address)); - SetTableModelText(pInstructionLine->m_opcode, lineIndex, GetTableColumnIndex(rgIsaDisassemblyTableColumns::Opcode)); - SetTableModelText(pInstructionLine->m_functionalUnit, lineIndex, GetTableColumnIndex(rgIsaDisassemblyTableColumns::FunctionalUnit)); - SetTableModelText(pInstructionLine->m_cycles, lineIndex, GetTableColumnIndex(rgIsaDisassemblyTableColumns::Cycles)); - SetTableModelText(pInstructionLine->m_binaryEncoding, lineIndex, GetTableColumnIndex(rgIsaDisassemblyTableColumns::BinaryEncoding)); - - // Branch instructions are rendered with a separate delegate, so we don't need add them to the table model. - if (pInstructionLine->m_functionalUnit.compare("Branch") != 0) - { - SetTableModelText(pInstructionLine->m_operands, lineIndex, GetTableColumnIndex(rgIsaDisassemblyTableColumns::Operands)); - } - - // The functional unit column's text color is based on value. - QColor textColor = GetFunctionalUnitColor(pInstructionLine->m_functionalUnit); - SetTableModelTextColor(textColor, lineIndex); - } - } - - InsertLabelRows(); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyTableView.cpp b/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyTableView.cpp deleted file mode 100644 index 15d4e04..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyTableView.cpp +++ /dev/null @@ -1,589 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include -#include -#include -#include -#include -#include -#include - -// Infra. -#include - -// Local. -#include -#include -#include -#include -#include -#include - -// A class used to filter the ISA disassembly table columns. -class rgIsaDisassemblyTableModelFilteringModel : public QSortFilterProxyModel -{ -public: - rgIsaDisassemblyTableModelFilteringModel(rgIsaDisassemblyTableModel* pSourceModel, QObject* pParent = nullptr) : - QSortFilterProxyModel(pParent), m_pSourceModel(pSourceModel) {} - ~rgIsaDisassemblyTableModelFilteringModel() = default; - -protected: - // A column-filtering predicate. - virtual bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override - { - // Ask the model if the given column index should be displayed. - return m_pSourceModel->IsColumnVisible(source_column); - } - -private: - // The source model being filtered. - rgIsaDisassemblyTableModel* m_pSourceModel = nullptr; -}; - -rgIsaDisassemblyTableView::rgIsaDisassemblyTableView(QWidget* pParent) : - QWidget(pParent) -{ - ui.setupUi(this); - - // Use the instruction treeview as the focus proxy for this view. - setFocusProxy(ui.instructionsTreeView); - - // Create the model holding the disassembly table data. - m_pIsaTableModel = new rgIsaDisassemblyTableModel(0, this); - ui.instructionsTreeView->SetModel(m_pIsaTableModel); - - // Create a column-filtering model to filter the table model. - m_pIsaTableFilteringModel = new rgIsaDisassemblyTableModelFilteringModel(m_pIsaTableModel, this); - - // Set the item model for the filtering proxy model. - QStandardItemModel* pItemModel = m_pIsaTableModel->GetTableModel(); - m_pIsaTableFilteringModel->setSourceModel(pItemModel); - - // Set the filter model on the table. - ui.instructionsTreeView->setModel(m_pIsaTableFilteringModel); - - // Allow the last column to stretch. - ui.instructionsTreeView->header()->setStretchLastSection(true); - - // Initialize the context menu. - InitializeContextMenu(); - - // Connect the table's selection model. - ConnectSelectionSignals(); - - // Connect the signals. - ConnectSignals(); -} - -bool rgIsaDisassemblyTableView::IsLineInEntrypoint(int lineIndex) -{ - bool isInEntrypoint = false; - - // If the disassembly hasn't already been cached, load it. - bool isDisassemblyLoaded = IsDisassemblyLoaded(); - if (!isDisassemblyLoaded) - { - // Load the disassembly. - isDisassemblyLoaded = LoadDisassembly(GetDisassemblyFilePath()); - } - - assert(isDisassemblyLoaded); - if (isDisassemblyLoaded) - { - isInEntrypoint = m_pIsaTableModel->IsSourceLineInEntrypoint(lineIndex); - } - - return isInEntrypoint; -} - -bool rgIsaDisassemblyTableView::LoadDisassembly(const std::string& disassemblyCsvFilePath) -{ - m_isDisassemblyCached = m_pIsaTableModel->PopulateFromCsvFile(disassemblyCsvFilePath); - - if (m_isDisassemblyCached) - { - // Cache the path to the disassembly CSV file being loaded. - m_disassemblyFilePath = disassemblyCsvFilePath; - - // Initialize jump link labels that need to be inserted into specific table ells. - InitializeLinkLabels(); - - // Adjust the table column widths after populating with data. - QtCommon::QtUtil::AutoAdjustTableColumns(ui.instructionsTreeView, 10, 20); - } - - return m_isDisassemblyCached; -} - -void rgIsaDisassemblyTableView::RequestTableResize() -{ - // The maximum number of rows to measure when computing the width of each column. - static const int s_MAX_NUM_ROWS = 32; - - // The amount of extra padding to add when resizing. - static const int s_COLUMN_PADDING = 20; - - // Compute the ideal width of the table and emit a signal to readjust the view dimensions. - int minWidth = QtCommon::QtUtil::ComputeMinimumTableWidth(ui.instructionsTreeView, s_MAX_NUM_ROWS, s_COLUMN_PADDING); - emit DisassemblyTableWidthResizeRequested(minWidth); -} - -void rgIsaDisassemblyTableView::UpdateCorrelatedSourceFileLine(int lineNumber) -{ - // Set the highlighted lines in the table model. - bool isCorrelated = m_pIsaTableModel->SetCorrelatedSourceLineIndex(lineNumber); - - // Scroll to the highlighted lines only if the high-level source file's current table has a correlated line with the disassembly table. - if (isCorrelated) - { - const std::vector& disassemblyLineIndices = m_pIsaTableModel->GetCorrelatedLineIndices(); - if (!disassemblyLineIndices.empty()) - { - // Extract the first highlighted Isa row index, and scroll to it. - int firstHighlightedDisassemblyRowIndex = disassemblyLineIndices[0]; - ScrollToLine(firstHighlightedDisassemblyRowIndex); - } - } - - // Trigger a repaint of the treeview. - ui.instructionsTreeView->repaint(); -} - -void rgIsaDisassemblyTableView::UpdateFilteredTable() -{ - // Invalidate the table's filtering model, since column visibility has changed. - m_pIsaTableFilteringModel->invalidate(); - - // Add all label rows into the table after filtering. - InitializeLabelRows(); - - // Add all link labels into the table after filtering. - InitializeLinkLabels(); - - // Adjust the table column widths after populating with data. - QtCommon::QtUtil::AutoAdjustTableColumns(ui.instructionsTreeView, 32, 20); -} - -std::string rgIsaDisassemblyTableView::GetDisassemblyFilePath() const -{ - return m_disassemblyFilePath; -} - -void rgIsaDisassemblyTableView::SetDisassemblyFilePath(const std::string& disassemblyFilePath) -{ - m_disassemblyFilePath = disassemblyFilePath; -} - -bool rgIsaDisassemblyTableView::IsDisassemblyLoaded() const -{ - return m_isDisassemblyCached; -} - -bool rgIsaDisassemblyTableView::IsSourceLineCorrelated(int lineIndex) const -{ - assert(m_pIsaTableModel != nullptr); - return (m_pIsaTableModel != nullptr ? m_pIsaTableModel->IsSourceLineCorrelated(lineIndex) : false); -} - -void rgIsaDisassemblyTableView::HandleBranchLinkClicked(const QString& link) -{ - assert(m_pIsaTableModel != nullptr); - if (m_pIsaTableModel != nullptr) - { - // Obtain the map of all labels within the disassembly table. - std::map labelNameToLineNumber; - m_pIsaTableModel->GetLabelNameToLineIndexMap(labelNameToLineNumber); - - // Find the given link name within the map, and scroll to the line index. - auto lineIndexIter = labelNameToLineNumber.find(link.toStdString()); - if (lineIndexIter != labelNameToLineNumber.end()) - { - int labelLineNumber = lineIndexIter->second; - - // Advance the focused line by 1. That's where the label's first line of code is. - int labelCodeLine = labelLineNumber + 1; - - // Retrieve the source line number associated with the label's ISA line number. - int inputSourceLineNumber = kInvalidCorrelationLineIndex; - m_pIsaTableModel->GetInputSourceLineNumberFromInstructionRow(labelCodeLine, inputSourceLineNumber); - - // Emit the signal used to highlight the label's correlated source code. - emit InputSourceHighlightedLineChanged(inputSourceLineNumber); - - // Scroll the table so that the label is visible. - ScrollToLine(labelLineNumber); - } - } -} - -void rgIsaDisassemblyTableView::HandleCopyDisassemblyClicked() -{ - QVector selectedRowNumbers; - - QItemSelectionModel* pSelectionModel = ui.instructionsTreeView->selectionModel(); - const QItemSelection selection = pSelectionModel->selection(); - if (!selection.isEmpty()) - { - // Get the selected line numbers. - int startRow = 0; - int endRow = 0; - QItemSelectionModel* pTableSelectionModel = ui.instructionsTreeView->selectionModel(); - QModelIndexList selectedRows = pTableSelectionModel->selectedRows(); - for (auto& currentIndex : selectedRows) - { - int rowIndex = currentIndex.row(); - selectedRowNumbers << rowIndex; - } - - // Make sure the row numbers are in descending order since the user could've made selections out of order. - std::sort(selectedRowNumbers.begin(), selectedRowNumbers.end()); - - // Copy the range of row data to the user's clipboard. - m_pIsaTableModel->CopyRowsToClipboard(selectedRowNumbers); - - } -} - -void rgIsaDisassemblyTableView::HandleOpenDisassemblyInFileBrowserClicked() -{ - // Use the path to the loaded CSV file to figure out which folder to open. - std::string buildOutputDirectory; - bool isOk = rgUtils::ExtractFileDirectory(m_disassemblyFilePath, buildOutputDirectory); - assert(isOk); - if (isOk) - { - // Open the directory in the system's file browser. - rgUtils::OpenFolderInFileBrowser(buildOutputDirectory); - } -} - -void rgIsaDisassemblyTableView::HandleCurrentSelectionChanged(const QItemSelection& selected, const QItemSelection& /*deselected*/) -{ - // Use the model's current selection to check what needs to be highlighted. - QItemSelectionModel* pSelectionModel = ui.instructionsTreeView->selectionModel(); - assert(pSelectionModel != nullptr); - if (pSelectionModel != nullptr) - { - const QItemSelection& currentSelection = pSelectionModel->selection(); - - QModelIndexList selectedIndices = currentSelection.indexes(); - if (!selectedIndices.isEmpty()) - { - QModelIndex firstSelectedIndex = selectedIndices[0]; - - if (firstSelectedIndex.isValid()) - { - int firstSelectedRowIndex = firstSelectedIndex.row(); - - // Determine which line in the input source file is correlated with the given Isa row. - int inputSourceLineNumber = kInvalidCorrelationLineIndex; - m_pIsaTableModel->GetInputSourceLineNumberFromInstructionRow(firstSelectedRowIndex, inputSourceLineNumber); - - // Did the user select a line that isn't currently highlighted? - const std::vector& indices = m_pIsaTableModel->GetCorrelatedLineIndices(); - auto correlatedLinesIter = std::find(indices.begin(), indices.end(), firstSelectedRowIndex); - if (correlatedLinesIter == indices.end()) - { - // Invalidate the currently highlighted lines. - m_pIsaTableModel->SetCorrelatedSourceLineIndex(kInvalidCorrelationLineIndex); - } - - // Do the instruction lines in the selected block all contiguously map to the same input source file line? - int correlatedLineIndex = kInvalidCorrelationLineIndex; - bool isContiguousBlockSelected = IsContiguousCorrelatedRangeSelected(correlatedLineIndex); - - if (isContiguousBlockSelected) - { - // Emit a signal indicating that the input source file's correlation highlight line should be updated. - emit InputSourceHighlightedLineChanged(inputSourceLineNumber); - } - else - { - // Clear the correlated lines in the disassembly table. - UpdateCorrelatedSourceFileLine(kInvalidCorrelationLineIndex); - - // Clear the highlighted line in the source editor. - emit InputSourceHighlightedLineChanged(kInvalidCorrelationLineIndex); - } - } - } - } -} - -void rgIsaDisassemblyTableView::HandleOpenContextMenu(const QPoint& widgetClickPosition) -{ - // Convert the widget's local click position to the global screen position. - const QPoint clickPoint = mapToGlobal(widgetClickPosition); - - // Open the context menu at the user's click position. - m_pContextMenu->exec(clickPoint); -} - -void rgIsaDisassemblyTableView::ConnectContextMenuSignals() -{ - // Connect the handler responsible for triggering a copy to clipboard from the table. - bool isConnected = connect(m_pCopySelectedDisassembly, &QAction::triggered, this, &rgIsaDisassemblyTableView::HandleCopyDisassemblyClicked); - assert(isConnected); - - // Connect the handler responsible for opening the current disassembly build output folder in the system file browser. - isConnected = connect(m_pOpenDisassemblyInFileBrowser, &QAction::triggered, this, &rgIsaDisassemblyTableView::HandleOpenDisassemblyInFileBrowserClicked); - assert(isConnected); - - // Use a custom context menu for the table. - this->setContextMenuPolicy(Qt::CustomContextMenu); - - // Connect the handler responsible for showing the table's context menu. - isConnected = connect(this, &QWidget::customContextMenuRequested, this, &rgIsaDisassemblyTableView::HandleOpenContextMenu); - assert(isConnected); -} - -void rgIsaDisassemblyTableView::ConnectSelectionSignals() -{ - QItemSelectionModel* pSelectionModel = ui.instructionsTreeView->selectionModel(); - assert(pSelectionModel != nullptr); - if (pSelectionModel != nullptr) - { - // Connect the table's selection changed handler. - bool isConnected = connect(pSelectionModel, &QItemSelectionModel::selectionChanged, this, &rgIsaDisassemblyTableView::HandleCurrentSelectionChanged); - assert(isConnected); - } -} - -void rgIsaDisassemblyTableView::ConnectSignals() -{ - // Connect the disassembly table's focus in signal. - bool isConnected = connect(ui.instructionsTreeView, &rgIsaDisassemblyCustomTableView::FrameFocusInSignal, this, &rgIsaDisassemblyTableView::FrameFocusInSignal); - assert(isConnected); - - // Connect the disassembly table's focus out signal. - isConnected = connect(ui.instructionsTreeView, &rgIsaDisassemblyCustomTableView::FrameFocusOutSignal, this, &rgIsaDisassemblyTableView::FrameFocusOutSignal); - assert(isConnected); - - // Connect the disassembly table view's enable scroll bar signal. - isConnected = connect(this, &rgIsaDisassemblyTableView::EnableScrollbarSignals, ui.instructionsTreeView, &rgIsaDisassemblyCustomTableView::EnableScrollbarSignals); - assert(isConnected); - - // Connect the disassembly table view's disable scroll bar signal. - isConnected = connect(this, &rgIsaDisassemblyTableView::DisableScrollbarSignals, ui.instructionsTreeView, &rgIsaDisassemblyCustomTableView::DisableScrollbarSignals); - assert(isConnected); - - // Connect the disassembly table's target GPU push button focus in signal. - isConnected = connect(ui.instructionsTreeView, &rgIsaDisassemblyCustomTableView::FocusTargetGpuPushButton, this, &rgIsaDisassemblyTableView::FocusTargetGpuPushButton); - assert(isConnected); - - // Connect the disassembly table's target GPU push button focus in signal. - isConnected = connect(ui.instructionsTreeView, &rgIsaDisassemblyCustomTableView::SwitchDisassemblyContainerSize, this, &rgIsaDisassemblyTableView::SwitchDisassemblyContainerSize); - assert(isConnected); - - // Connect the disassembly table's columns push button focus in signal. - isConnected = connect(ui.instructionsTreeView, &rgIsaDisassemblyCustomTableView::FocusColumnPushButton, this, &rgIsaDisassemblyTableView::FocusColumnPushButton); - assert(isConnected); - - // Connect the disassembly table's source window focus in signal. - isConnected = connect(ui.instructionsTreeView, &rgIsaDisassemblyCustomTableView::FocusSourceWindow, this, &rgIsaDisassemblyTableView::FocusSourceWindow); - assert(isConnected); - - // Connect the disassembly table view's update current sub widget signal. - isConnected = connect(this, &rgIsaDisassemblyTableView::UpdateCurrentSubWidget, ui.instructionsTreeView, &rgIsaDisassemblyCustomTableView::HandleUpdateCurrentSubWidget); - assert(isConnected); - - // Connect the disassembly table's focus cli output window signal. - isConnected = connect(ui.instructionsTreeView, &rgIsaDisassemblyCustomTableView::FocusCliOutputWindow, this, &rgIsaDisassemblyTableView::FocusCliOutputWindow); - assert(isConnected); -} - -bool rgIsaDisassemblyTableView::GetSelectedRowRange(int& minRow, int& maxRow) const -{ - bool gotRange = false; - - QItemSelectionModel* pTableSelectionModel = ui.instructionsTreeView->selectionModel(); - auto rowsSelection = pTableSelectionModel->selectedRows(); - - if (!rowsSelection.isEmpty()) - { - // Find the bounds of the selected row indices. - minRow = INT_MAX; - maxRow = INT_MIN; - for (QModelIndex& currentIndex : rowsSelection) - { - int rowIndex = currentIndex.row(); - minRow = (rowIndex < minRow) ? rowIndex : minRow; - maxRow = (rowIndex > maxRow) ? rowIndex : maxRow; - } - - gotRange = true; - } - - return gotRange; -} - -void rgIsaDisassemblyTableView::InitializeContextMenu() -{ - // Create the context menu instance. - m_pContextMenu = new QMenu(this); - - // Set the cursor for the context menu. - m_pContextMenu->setCursor(Qt::PointingHandCursor); - - // Create the menu items to insert into the context menu. - m_pCopySelectedDisassembly = new QAction(STR_DISASSEMBLY_TABLE_CONTEXT_MENU_COPY, this); - m_pContextMenu->addAction(m_pCopySelectedDisassembly); - - // Create an item allowing the user to browse to the disassembly build output folder. - m_pOpenDisassemblyInFileBrowser = new QAction(STR_DISASSEMBLY_TABLE_CONTEXT_MENU_OPEN_IN_FILE_BROWSER, this); - m_pContextMenu->addAction(m_pOpenDisassemblyInFileBrowser); - - // Connect the context menu signals. - ConnectContextMenuSignals(); -} - -void rgIsaDisassemblyTableView::InitializeLabelRows() -{ - // Clear existing label lines from the model. - m_pIsaTableModel->ClearLabelLines(); - - // Always insert labels into the left-most visible column in the table. - m_pIsaTableModel->InsertLabelRows(); -} - -void rgIsaDisassemblyTableView::InitializeLinkLabels() -{ - // A map of row index to the label's name being linked to in the operands column. - std::map linkLabels; - m_pIsaTableModel->GetLineIndexToLabelNameMap(linkLabels); - - int columnIndex = rgIsaDisassemblyTableModel::GetTableColumnIndex(rgIsaDisassemblyTableColumns::Operands); - - // Hold a vector of all Label links inserted into the table. - std::vector labelLinks; - - auto startLabel = linkLabels.begin(); - auto endLabel = linkLabels.end(); - for (auto labelsIter = startLabel; labelsIter != endLabel; ++labelsIter) - { - // Extract the line number and label text from the map. - int labelLineIndex = labelsIter->first; - std::string& labelText = labelsIter->second; - - QStandardItemModel* pTableModel = m_pIsaTableModel->GetTableModel(); - - // Compute the index in the table where the link needs to get inserted. - QModelIndex labelIndex = pTableModel->index(labelLineIndex, columnIndex); - QModelIndex filteredIndex = m_pIsaTableFilteringModel->mapFromSource(labelIndex); - - if (filteredIndex.isValid()) - { - // Create a label with a richtext link within it. - QLabel* pLinkLabel = new QLabel(ui.instructionsTreeView); - pLinkLabel->setTextFormat(Qt::TextFormat::RichText); - pLinkLabel->setOpenExternalLinks(false); - pLinkLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); - - // Set the richtext markup string to add a clickable URL to the label. - std::stringstream linkMarkup; - linkMarkup << ""; - linkMarkup << labelText; - linkMarkup << ""; - pLinkLabel->setText(linkMarkup.str().c_str()); - pLinkLabel->setFont(ui.instructionsTreeView->font()); - - // Connect the link clicked handler to the new label. - bool isConnected = connect(pLinkLabel, &QLabel::linkActivated, this, &rgIsaDisassemblyTableView::HandleBranchLinkClicked); - assert(isConnected); - - // Insert the link label into the table. - ui.instructionsTreeView->setIndexWidget(filteredIndex, pLinkLabel); - - // Add the new link to the list of label widgets. - labelLinks.push_back(pLinkLabel); - } - } - - // Provide the list of inserted links so that the custom QTreeView knows where they're located within the table. - ui.instructionsTreeView->SetLabelLinkWidgets(labelLinks); -} - -bool rgIsaDisassemblyTableView::IsContiguousCorrelatedRangeSelected(int& correlatedLineIndex) const -{ - bool isNonContiguous = false; - - // Find the bounds of the selected row indices. - int minRow = 0; - int maxRow = 0; - bool gotRange = GetSelectedRowRange(minRow, maxRow); - if (gotRange) - { - // Step through each row in the range and determine which input source file line it's mapped to. - int correlatedLine = kInvalidCorrelationLineIndex; - for (int selectedRowIndex = minRow; selectedRowIndex <= maxRow; ++selectedRowIndex) - { - int inputLineIndex = 0; - bool gotLine = m_pIsaTableModel->GetInputSourceLineNumberFromInstructionRow(selectedRowIndex, inputLineIndex); - if (gotLine) - { - if (correlatedLine != kInvalidCorrelationLineIndex) - { - if (inputLineIndex != correlatedLine) - { - // The instruction was emitted due to a different input source line. This isn't a contiguous block. - isNonContiguous = true; - correlatedLineIndex = kInvalidCorrelationLineIndex; - break; - } - } - else - { - correlatedLine = inputLineIndex; - correlatedLineIndex = inputLineIndex; - } - } - } - } - - return !isNonContiguous; -} - -void rgIsaDisassemblyTableView::ScrollToLine(int lineNumber) -{ - // Find the row of the index at the top left of the table. - int firstVisibleRow = 0; - const QModelIndex firstVisibleIndex = ui.instructionsTreeView->indexAt(ui.instructionsTreeView->rect().topLeft()); - if (firstVisibleIndex.isValid()) - { - firstVisibleRow = firstVisibleIndex.row(); - } - - // When the lastVisibleIndex is invalid, it means that the table is already fully visible. - // Initializing this to a large number ensures that we won't attempt to scroll the table when the lastVisibleIndex is invalid. - int lastVisibleRow = INT_MAX; - - // Find the row of the index at the bottom left of the table. - const QModelIndex lastVisibleIndex = ui.instructionsTreeView->indexAt(ui.instructionsTreeView->rect().bottomLeft()); - if (lastVisibleIndex.isValid()) - { - lastVisibleRow = lastVisibleIndex.row(); - } - - // If the line we're scrolling to is already visible within view, don't scroll the view. - bool isLineVisible = (lineNumber >= firstVisibleRow) && (lineNumber <= lastVisibleRow); - if (!isLineVisible) - { - // Scroll the instruction table's vertical scrollbar to the given line. - QScrollBar* pScrollbar = ui.instructionsTreeView->verticalScrollBar(); - pScrollbar->setValue(lineNumber); - } -} - -void rgIsaDisassemblyTableView::keyPressEvent(QKeyEvent* pEvent) -{ - Qt::KeyboardModifiers keyboardModifiers = QApplication::keyboardModifiers(); - if ((keyboardModifiers & Qt::ControlModifier) && (pEvent->key() == Qt::Key_C)) - { - HandleCopyDisassemblyClicked(); - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyView.cpp b/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyView.cpp deleted file mode 100644 index 3b8f3d1..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyView.cpp +++ /dev/null @@ -1,1232 +0,0 @@ -#ifdef _WIN32 -// This warning relates to a compiler limitation that restricts the length of type names. -// The warning doesn't impose any risk to the code, so it's disabled for this file. -#pragma warning(disable : 4503) -#endif - -// C++. -#include -#include -#include -#include -#include - -// Qt. -#include -#include -#include - -// Infra. -#include -#include -#include -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Names of special widgets within the disassembly view. -static const char* STR_DISASSEMBLY_COLUMN_VISIBILITY_LIST = "DisassemblyColumnVisibilityList"; -static const char* STR_DISASSEMBLY_COLUMN_LIST_ITEM_CHECKBOX = "ListWidgetCheckBox"; -static const char* STR_DISASSEMBLY_COLUMN_LIST_ITEM_ALL_CHECKBOX = "ListWidgetAllCheckBox"; - -// Object name associated with the target GPU dropdown list. -static const char* STR_DISASSEMBLY_TARGET_GPU_LIST = "TargetGpuList"; - -// Columns push button font size. -const int s_PUSH_BUTTON_FONT_SIZE = 11; - -rgIsaDisassemblyView::rgIsaDisassemblyView(QWidget* pParent) : - QWidget(pParent) -{ - ui.setupUi(this); - - ui.verticalSplitterWidget->setStretchFactor(0, 1); - ui.verticalSplitterWidget->setStretchFactor(1, 0); - ui.verticalSplitterWidget->handle(1)->setDisabled(true); - - // Create the widget used to control column visibility. - CreateColumnVisibilityControls(); - - // Fill the column visibility dropdown with all of the possible column names. - PopulateColumnVisibilityList(); - - // Create the dropdown list used to select the current target GPU. - CreateTargetGpuListControls(); - - // Connect the signals for the disassembly view. - ConnectSignals(); - - // Set mouse pointer to pointing hand cursor. - SetCursor(); - - // Block recursively repolishing child tables in the disassembly view. - ui.disassemblyTableHostWidget->setProperty(gs_IS_REPOLISHING_BLOCKED, true); - - // Set the push button font sizes. - SetFontSizes(); - - // Set the focus proxy of the view maximize button to be the title bar. - // This will cause the frame border to change to black when the maximize button loses focus. - // This is because the view title bar already handles its own loss of focus event. - ui.viewMaximizeButton->setFocusProxy(ui.viewTitlebar); -} - -rgIsaDisassemblyView::~rgIsaDisassemblyView() -{ - // Remove the column dropdown focus event filters if they exist. - if (m_pDisassemblyColumnsListWidget != nullptr && m_pDisassemblyColumnsListEventFilter != nullptr) - { - m_pDisassemblyColumnsListWidget->removeEventFilter(m_pDisassemblyColumnsListEventFilter); - qApp->removeEventFilter(m_pDisassemblyColumnsListEventFilter); - } - - // Remove the GPU dropdown event filter. - if (m_pTargetGpusListWidget != nullptr && m_pTargetGpusListEventFilter != nullptr) - { - m_pTargetGpusListWidget->removeEventFilter(m_pTargetGpusListEventFilter); - qApp->removeEventFilter(m_pTargetGpusListEventFilter); - } -} - -void rgIsaDisassemblyView::ClearBuildOutput() -{ - if (!m_gpuTabViews.empty()) - { - // Destroy all existing GPU tabs. - auto firstGpuTab = m_gpuTabViews.begin(); - auto lastGpuTab = m_gpuTabViews.end(); - for (auto gpuTabIter = firstGpuTab; gpuTabIter != lastGpuTab; ++gpuTabIter) - { - ui.disassemblyTableHostWidget->removeWidget(gpuTabIter->second); - } - } - - // Clear all state data in the view. - m_gpuTabViews.clear(); - m_gpuResourceUsageViews.clear(); - m_resourceUsageText.clear(); -} - -void rgIsaDisassemblyView::GetResourceUsageTextBounds(QRect& textBounds) const -{ - QFontMetrics fontMetrics(m_resourceUsageFont); - textBounds = fontMetrics.boundingRect(m_resourceUsageText.c_str()); -} - -bool rgIsaDisassemblyView::IsEmpty() const -{ - return m_gpuTabViews.empty(); -} - -void rgIsaDisassemblyView::RemoveInputFileEntries(const std::string& inputFilePath) -{ - // Clean up disassembly tables associated with the given file. - DestroyDisassemblyViewsForFile(inputFilePath); - - // Clean up resource usage views associated with the given file. - DestroyResourceUsageViewsForFile(inputFilePath); -} - -void rgIsaDisassemblyView::HandleInputFileSelectedLineChanged(const std::string& targetGpu, const std::string& inputFilePath, std::string& entryName, int lineIndex) -{ - // Get the currently active stacked view. - rgIsaDisassemblyTabView* pCurrentTabView = GetTargetGpuTabWidgetByTabName(targetGpu); - - if (pCurrentTabView != nullptr && pCurrentTabView->GetTableCount() > 0) - { - HandleSelectedEntrypointChanged(targetGpu, inputFilePath, entryName); - pCurrentTabView->UpdateCorrelatedSourceFileLine(inputFilePath, lineIndex, entryName); - } -} - -void rgIsaDisassemblyView::HandleSelectedEntrypointChanged(const std::string& targetGpu, const std::string& inputFilePath, const std::string& selectedEntrypointName) -{ - // Get the currently active stacked view. - rgIsaDisassemblyTabView* pTargetTabView = GetTargetGpuTabWidgetByTabName(targetGpu); - - // Switch the target GPU tab if necessary. - if (pTargetTabView != m_pCurrentTabView) - { - SetCurrentTargetGpuTabView(pTargetTabView); - } - - if (pTargetTabView != nullptr) - { - // Switch the table to show the disassembly for the given entrypoint. - pTargetTabView->SwitchToEntryPoint(inputFilePath, selectedEntrypointName); - } - - // Get a reference to the map of input file path to the entry point names map. - InputToEntrypointViews& inputFileToEntrypointMap = m_gpuResourceUsageViews[targetGpu]; - - // Use the input file path to get a reference to a map of entry point names to resource usage views. - EntrypointToResourcesView& entrypointMap = inputFileToEntrypointMap[inputFilePath]; - - // Search the map to find the resource usage view associated with the given entrypoint. - auto resourceViewIter = entrypointMap.find(selectedEntrypointName); - if (resourceViewIter != entrypointMap.end()) - { - // Display the resource usage view associated with the given entrypoint. - rgResourceUsageView* pResourceUsageView = resourceViewIter->second; - ui.resourceUsageHostStackedWidget->setCurrentWidget(pResourceUsageView); - } -} - -void rgIsaDisassemblyView::HandleColumnVisibilityButtonClicked(bool /*clicked*/) -{ - // Make the list widget appear and process user selection from the list widget. - bool visible = m_pDisassemblyColumnsListWidget->isVisible(); - if (visible == true) - { - m_pDisassemblyColumnsListWidget->hide(); - - // Change the up arrow to a down arrow. - ui.columnVisibilityArrowPushButton->SetDirection(ArrowIconWidget::Direction::DownArrow); - } - else - { - // Update the check box values in case they were changed in global settings. - rgConfigManager& configManager = rgConfigManager::Instance(); - std::shared_ptr pGlobalSettings = configManager.GetGlobalConfig(); - ListWidget::SetColumnVisibilityCheckboxes(m_pDisassemblyColumnsListWidget, pGlobalSettings->m_visibleDisassemblyViewColumns); - - // Compute where to place the combo box relative to where the arrow button is. - QWidget* pWidget = ui.columnVisibilityArrowPushButton; - m_pDisassemblyColumnsListWidget->show(); - m_pDisassemblyColumnsListWidget->setFocus(); - QRect rect = pWidget->geometry(); - QPoint pos(0, 0); - pos = pWidget->mapTo(this, pos); - pos.setY(pos.y() + rect.height()); - int height = QtCommon::QtUtil::GetListWidgetHeight(m_pDisassemblyColumnsListWidget); - int width = QtCommon::QtUtil::GetListWidgetWidth(m_pDisassemblyColumnsListWidget); - m_pDisassemblyColumnsListWidget->setGeometry(pos.x(), pos.y(), width + s_CHECK_BOX_WIDTH, height); - - // Change the down arrow to an up arrow. - ui.columnVisibilityArrowPushButton->SetDirection(ArrowIconWidget::Direction::UpArrow); - } -} - -void rgIsaDisassemblyView::HandleColumnVisibilityComboBoxItemClicked(const QString& text, const bool checked) -{ - rgConfigManager& configManager = rgConfigManager::Instance(); - std::shared_ptr pGlobalSettings = configManager.GetGlobalConfig(); - - const int firstColumn = rgIsaDisassemblyTableModel::GetTableColumnIndex(rgIsaDisassemblyTableColumns::Address); - const int lastColumn = rgIsaDisassemblyTableModel::GetTableColumnIndex(rgIsaDisassemblyTableColumns::Count); - - // Get the current checked state of the UI. - // This will include changes from the check/uncheck that triggered this callback. - std::vector columnVisibility = ListWidget::GetColumnVisibilityCheckboxes(m_pDisassemblyColumnsListWidget); - - // Make sure at least one check box is still checked. - bool isAtLeastOneChecked = std::any_of(columnVisibility.begin() + firstColumn, columnVisibility.begin() + lastColumn, [](bool b) { return b == true; }); - - if (checked || isAtLeastOneChecked) - { - // If the user checked the "All" option, Step through each column and set to visible. - if (text.compare(STR_DISASSEMBLY_TABLE_COLUMN_ALL) == 0 && (checked == true)) - { - for (int columnIndex = firstColumn; columnIndex < lastColumn; ++columnIndex) - { - columnVisibility[columnIndex] = checked; - } - - // Update the state of the dropdown check boxes to reflect that all options are checked. - ListWidget::SetColumnVisibilityCheckboxes(m_pDisassemblyColumnsListWidget, columnVisibility); - } - - // Save the changes. - configManager.Instance().SetDisassemblyColumnVisibility(columnVisibility); - configManager.SaveGlobalConfigFile(); - } - else - { - // The user tried to uncheck the last check box, but at least one box - // MUST be checked, so find that item in the ListWidget, and set it back to checked. - for (int row = 0; row < m_pDisassemblyColumnsListWidget->count(); row++) - { - QListWidgetItem* pItem = m_pDisassemblyColumnsListWidget->item(row); - QCheckBox* pCheckBox = (QCheckBox*)m_pDisassemblyColumnsListWidget->itemWidget(pItem); - QString checkBoxText = pCheckBox->text(); - if (checkBoxText.compare(text) == 0) - { - QCheckBox* pCheckBox = (QCheckBox*)m_pDisassemblyColumnsListWidget->itemWidget(pItem); - pCheckBox->setChecked(true); - } - } - } - - // See if the "All" box needs checking/unchecking. - ListWidget::UpdateAllCheckbox(m_pDisassemblyColumnsListWidget); - - // Update the "All" checkbox text color to grey or black. - UpdateAllCheckBoxText(); -} - -void rgIsaDisassemblyView::HandleColumnVisibilityFilterStateChanged(bool checked) -{ - // Figure out the sender and process appropriately. - QObject* pSender = QObject::sender(); - assert(pSender != nullptr); - - // Find out which entry caused the signal. - QWidget* pItem = qobject_cast(pSender); - assert(pItem != nullptr); - - QCheckBox* pCheckBox = qobject_cast(pSender); - assert(pCheckBox != nullptr); - - // Process the click. - HandleColumnVisibilityComboBoxItemClicked(pCheckBox->text(), checked); - - // Emit a signal to trigger a refresh of the disassembly table's filter. - emit DisassemblyColumnVisibilityUpdated(); -} - -void rgIsaDisassemblyView::HandleTargetGpuArrowClicked(bool clicked) -{ - // Make the list widget appear and process user selection from the list widget. - bool visible = m_pTargetGpusListWidget->isVisible(); - if (visible == true) - { - m_pTargetGpusListWidget->hide(); - - // Change the up arrow to a down arrow. - ui.targetGpuPushButton->SetDirection(ArrowIconWidget::Direction::DownArrow); - } - else - { - // Compute where to place the combo box relative to where the arrow button is. - QWidget* pWidget = ui.targetGpuPushButton; - m_pTargetGpusListWidget->show(); - m_pTargetGpusListWidget->setFocus(); - m_pTargetGpusListWidget->setCursor(Qt::PointingHandCursor); - QRect rect = pWidget->geometry(); - QPoint pos(0, 0); - pos = pWidget->mapTo(this, pos); - pos.setY(pos.y() + rect.height()); - int height = QtCommon::QtUtil::GetListWidgetHeight(m_pTargetGpusListWidget); - int width = QtCommon::QtUtil::GetListWidgetWidth(m_pTargetGpusListWidget); - m_pTargetGpusListWidget->setGeometry(pos.x(), pos.y(), width + s_CHECK_BOX_WIDTH, height); - - // Change the down arrow to an up arrow. - ui.targetGpuPushButton->SetDirection(ArrowIconWidget::Direction::UpArrow); - } -} - -void rgIsaDisassemblyView::HandleTargetGpuChanged(int currentIndex) -{ - assert(m_pTargetGpusListWidget != nullptr); - if (m_pTargetGpusListWidget != nullptr) - { - auto pTargetGpuItem = m_pTargetGpusListWidget->item(currentIndex); - assert(pTargetGpuItem != nullptr); - if (pTargetGpuItem != nullptr) - { - // Change the target GPU if it differs from the current target GPU. - std::string currentTargetGpu = ui.targetGpuPushButton->text().toStdString(); - std::string newTargetGpu = pTargetGpuItem->text().toStdString(); - if (currentTargetGpu.compare(newTargetGpu) != 0) - { - // Use the dropdown list's selection model to change the currently selected target GPU. - QItemSelectionModel* pSelectionModel = m_pTargetGpusListWidget->selectionModel(); - assert(pSelectionModel != nullptr); - if (pSelectionModel != nullptr) - { - // Select the new target GPU within the dropdown list widget. - QAbstractItemModel* pListModel = m_pTargetGpusListWidget->model(); - - assert(pListModel != nullptr); - if (pListModel != nullptr) - { - QModelIndex modelIndex = pListModel->index(currentIndex, 0); - pSelectionModel->setCurrentIndex(modelIndex, QItemSelectionModel::SelectionFlag::Select); - } - } - - // Change the target GPU to the newly selected item. - SetTargetGpu(newTargetGpu); - - // Strip the GPU name from the architecture if needed. - std::string strippedGpuName; - size_t bracketPos = newTargetGpu.find("("); - if (bracketPos != std::string::npos && newTargetGpu.size() > 2) - { - strippedGpuName = newTargetGpu.substr(0, bracketPos - 1); - } - else - { - strippedGpuName = newTargetGpu; - } - - // Strip gfx notation if needed. - size_t slashPos = strippedGpuName.find("/"); - if (slashPos != std::string::npos) - { - strippedGpuName = strippedGpuName.substr(slashPos + 1); - } - - // Emit a signal with the name of the target GPU to switch to. - emit SelectedTargetGpuChanged(strippedGpuName); - } - } - } - - // Set focus to disassembly view. - setFocus(); -} - -void rgIsaDisassemblyView::ClearListWidget(ListWidget* &pListWidget) -{ - assert(pListWidget != nullptr); - - // Disconnect slot/signal connection for each check box - for (int row = 0; row < pListWidget->count(); row++) - { - QListWidgetItem* pItem = pListWidget->item(row); - QCheckBox* pCheckBox = (QCheckBox*)pListWidget->itemWidget(pItem); - - if (pListWidget->objectName().compare(STR_DISASSEMBLY_COLUMN_VISIBILITY_LIST) == 0) - { - bool isDisconnected = disconnect(pCheckBox, &QCheckBox::clicked, this, &rgIsaDisassemblyView::HandleColumnVisibilityFilterStateChanged); - assert(isDisconnected); - } - else - { - assert(false); - } - } - - // Clear the list widget. This also deletes each item. - pListWidget->clear(); -} - -void rgIsaDisassemblyView::ConnectDisassemblyTabViewSignals(rgIsaDisassemblyTabView* pEntryView) -{ - // Connect the new disassembly GPU tab's source input file highlight line changed signal. - bool isConnected = connect(pEntryView, &rgIsaDisassemblyTabView::InputSourceHighlightedLineChanged, this, &rgIsaDisassemblyView::InputSourceHighlightedLineChanged); - assert(isConnected); - - // Connect the disassembly table's resized event handler. - isConnected = connect(pEntryView, &rgIsaDisassemblyTabView::DisassemblyTableWidthResizeRequested, this, &rgIsaDisassemblyView::DisassemblyTableWidthResizeRequested); - assert(isConnected); - - // Connect the disassembly view's column visibility updated signal. - isConnected = connect(this, &rgIsaDisassemblyView::DisassemblyColumnVisibilityUpdated, pEntryView, &rgIsaDisassemblyTabView::HandleColumnVisibilityFilterStateChanged); - assert(isConnected); - - // Connect the disassembly view's set frame border red signal. - isConnected = connect(pEntryView, &rgIsaDisassemblyTabView::FrameFocusInSignal, this, &rgIsaDisassemblyView::HandleDisassemblyTabViewClicked); - assert(isConnected); - - // Connect the disassembly view's set frame border black signal. - isConnected = connect(pEntryView, &rgIsaDisassemblyTabView::FrameFocusOutSignal, this, &rgIsaDisassemblyView::HandleDisassemblyTabViewLostFocus); - assert(isConnected); - - // Connect the disassembly view's title bar's set frame border red signal. - isConnected = connect(ui.viewTitlebar, &rgIsaDisassemblyViewTitlebar::FrameFocusInSignal, this, &rgIsaDisassemblyView::HandleDisassemblyTabViewClicked); - assert(isConnected); - - // Connect the disassembly view's enable scroll bar signal. - isConnected = connect(this, &rgIsaDisassemblyView::EnableScrollbarSignals, pEntryView, &rgIsaDisassemblyTabView::EnableScrollbarSignals); - assert(isConnected); - - // Connect the disassembly view's disable scroll bar signal. - isConnected = connect(this, &rgIsaDisassemblyView::DisableScrollbarSignals, pEntryView, &rgIsaDisassemblyTabView::DisableScrollbarSignals); - assert(isConnected); - - // Connect the disassembly table's target GPU push button focus in signal. - isConnected = connect(pEntryView, &rgIsaDisassemblyTabView::FocusTargetGpuPushButton, this, &rgIsaDisassemblyView::HandleFocusTargetGpuPushButton); - assert(isConnected); - - // Connect the disassembly table's switch disassembly view size signal. - isConnected = connect(pEntryView, &rgIsaDisassemblyTabView::SwitchDisassemblyContainerSize, this, &rgIsaDisassemblyView::SwitchDisassemblyContainerSize); - assert(isConnected); - - // Connect the disassembly table's columns push button focus in signal. - isConnected = connect(pEntryView, &rgIsaDisassemblyTabView::FocusColumnPushButton, this, &rgIsaDisassemblyView::HandleFocusColumnsPushButton); - assert(isConnected); - - // Connect the disassembly table's cli output window focus in signal. - isConnected = connect(pEntryView, &rgIsaDisassemblyTabView::FocusSourceWindow, this, &rgIsaDisassemblyView::FocusSourceWindow); - assert(isConnected); - - // Connect the disassembly view's update current sub widget signal. - isConnected = connect(this, &rgIsaDisassemblyView::UpdateCurrentSubWidget, pEntryView, &rgIsaDisassemblyTabView::UpdateCurrentSubWidget); - assert(isConnected); -} - -void rgIsaDisassemblyView::ConnectSignals() -{ - // Connect the column visibility selector arrow button. - bool isConnected = connect(ui.columnVisibilityArrowPushButton, &QPushButton::clicked, this, &rgIsaDisassemblyView::HandleColumnVisibilityButtonClicked); - assert(isConnected); - - // Connect the handler to show/hide the target GPU list when the arrow button is clicked. - isConnected = connect(ui.targetGpuPushButton, &QPushButton::clicked, this, &rgIsaDisassemblyView::HandleTargetGpuArrowClicked); - assert(isConnected); - - // Connect the handler to give focus to frame on view maximize button click. - isConnected = connect(ui.viewMaximizeButton, &QPushButton::clicked, this, &rgIsaDisassemblyView::HandleDisassemblyTabViewClicked); - assert(isConnected); - - // Connect the handler to give focus to frame on disassembly column list widget's gain of focus. - isConnected = connect(m_pDisassemblyColumnsListWidget, &ListWidget::FocusInEvent, this, &rgIsaDisassemblyView::HandleListWidgetFocusInEvent); - assert(isConnected); - - // Connect the handler to remove focus from frame on disassembly column list widget's loss of focus. - isConnected = connect(m_pDisassemblyColumnsListWidget, &ListWidget::FocusOutEvent, this, &rgIsaDisassemblyView::HandleListWidgetFocusOutEvent); - assert(isConnected); - - // Connect the handler to give focus to frame on target GPUs list widget's gain of focus. - isConnected = connect(m_pTargetGpusListWidget, &ListWidget::FocusInEvent, this, &rgIsaDisassemblyView::HandleListWidgetFocusInEvent); - assert(isConnected); - - // Connect the handler to give focus to frame on target GPUs list widget's loss of focus. - isConnected = connect(m_pTargetGpusListWidget, &ListWidget::FocusOutEvent, this, &rgIsaDisassemblyView::HandleListWidgetFocusOutEvent); - assert(isConnected); - - // Connect the handler to give focus to frame on columns push button click. - isConnected = connect(ui.columnVisibilityArrowPushButton, &QPushButton::clicked, this, &rgIsaDisassemblyView::HandleDisassemblyTabViewClicked); - assert(isConnected); - - // Connect the handler to give focus to frame on target GPUs push button click. - isConnected = connect(ui.targetGpuPushButton, &QPushButton::clicked, this, &rgIsaDisassemblyView::HandleDisassemblyTabViewClicked); - assert(isConnected); - - // Connect the handler to remove focus from frame on columns push button loss of focus. - isConnected = connect(ui.columnVisibilityArrowPushButton, &ArrowIconWidget::FocusOutEvent, this, &rgIsaDisassemblyView::HandleListWidgetFocusOutEvent); - assert(isConnected); - - // Connect the handler to give focus to frame on target GPUs push button loss of focus. - isConnected = connect(ui.targetGpuPushButton, &ArrowIconWidget::FocusOutEvent, this, &rgIsaDisassemblyView::HandleListWidgetFocusOutEvent); - assert(isConnected); - - // Select next GPU device action. - m_pSelectNextGPUTarget = new QAction(this); - m_pSelectNextGPUTarget->setShortcutContext(Qt::ApplicationShortcut); - m_pSelectNextGPUTarget->setShortcut(QKeySequence(gs_DISASSEMBLY_VIEW_HOTKEY_GPU_SELECTION)); - addAction(m_pSelectNextGPUTarget); - - isConnected = connect(m_pSelectNextGPUTarget, &QAction::triggered, this, &rgIsaDisassemblyView::HandleSelectNextGPUTargetAction); - assert(isConnected); -} - -void rgIsaDisassemblyView::CreateColumnVisibilityControls() -{ - // Setup the list widget that opens when the user clicks the column visibility arrow. - rgUtils::SetupComboList(this, m_pDisassemblyColumnsListWidget, ui.columnVisibilityArrowPushButton, m_pDisassemblyColumnsListEventFilter, false); - m_pDisassemblyColumnsListWidget->setObjectName(STR_DISASSEMBLY_COLUMN_VISIBILITY_LIST); - - // Handle the open gpu list widget signal and, - // the update current sub widget signal from the hide list widget event filter object. - if (m_pDisassemblyColumnsListEventFilter != nullptr) - { - rgHideListWidgetEventFilter* pEventFilter = static_cast(m_pDisassemblyColumnsListEventFilter); - if (pEventFilter != nullptr) - { - bool isConnected = connect(pEventFilter, &rgHideListWidgetEventFilter::OpenGpuListWidget, this, &rgIsaDisassemblyView::HandleOpenGpuListWidget); - assert(isConnected); - - isConnected = connect(pEventFilter, &rgHideListWidgetEventFilter::UpdateCurrentSubWidget, this, &rgIsaDisassemblyView::UpdateCurrentSubWidget); - assert(isConnected); - - isConnected = connect(pEventFilter, &rgHideListWidgetEventFilter::FocusCliOutputWindow, this, &rgIsaDisassemblyView::FocusCliOutputWindow); - assert(isConnected); - } - } - - // Update scale factor for widgets. - QFont font = ui.columnVisibilityArrowPushButton->font(); - double scaleFactor = ScalingManager::Get().GetScaleFactor(); - font.setPointSize(s_PUSH_BUTTON_FONT_SIZE * scaleFactor); - m_pDisassemblyColumnsListWidget->setStyleSheet(s_LIST_WIDGET_STYLE.arg(font.pointSize())); - - // Reset the current selection in the column visibility list. - m_pDisassemblyColumnsListWidget->setCurrentRow(0); -} - -void rgIsaDisassemblyView::HandleOpenColumnListWidget() -{ - if (m_pDisassemblyColumnsListWidget != nullptr) - { - ui.columnVisibilityArrowPushButton->clicked(); - } -} - -void rgIsaDisassemblyView::CreateTargetGpuListControls() -{ - // Setup the list widget used to select the current target GPU. - rgUtils::SetupComboList(this, m_pTargetGpusListWidget, ui.targetGpuPushButton, m_pTargetGpusListEventFilter, false); - m_pTargetGpusListWidget->setObjectName(STR_DISASSEMBLY_TARGET_GPU_LIST); - - if (m_pTargetGpusListEventFilter != nullptr) - { - rgHideListWidgetEventFilter* pEventFilter = static_cast(m_pTargetGpusListEventFilter); - if (pEventFilter != nullptr) - { - bool isConnected = connect(pEventFilter, &rgHideListWidgetEventFilter::OpenColumnListWidget, this, &rgIsaDisassemblyView::HandleOpenColumnListWidget); - assert(isConnected); - - isConnected = connect(pEventFilter, &rgHideListWidgetEventFilter::UpdateCurrentSubWidget, this, &rgIsaDisassemblyView::UpdateCurrentSubWidget); - assert(isConnected); - } - } - - // Update scale factor for widgets. - QFont font = ui.targetGpuPushButton->font(); - double scaleFactor = ScalingManager::Get().GetScaleFactor(); - font.setPointSize(s_PUSH_BUTTON_FONT_SIZE * scaleFactor); - m_pTargetGpusListWidget->setStyleSheet(s_LIST_WIDGET_STYLE.arg(font.pointSize())); - - // Reset the current selection in the target GPU dropdown list. - m_pTargetGpusListWidget->setCurrentRow(0); - - // Connect the signal used to handle a change in the selected target GPU. - bool isConnected = connect(m_pTargetGpusListWidget, &QListWidget::currentRowChanged, this, &rgIsaDisassemblyView::HandleTargetGpuChanged); - assert(isConnected); -} - -void rgIsaDisassemblyView::HandleOpenGpuListWidget() -{ - if (m_pTargetGpusListWidget != nullptr) - { - ui.targetGpuPushButton->clicked(); - } -} - -std::string rgIsaDisassemblyView::GetDisassemblyColumnName(rgIsaDisassemblyTableColumns column) const -{ - std::string result; - - static std::map kColumnNameMap = - { - { rgIsaDisassemblyTableColumns::Address, STR_DISASSEMBLY_TABLE_COLUMN_ADDRESS }, - { rgIsaDisassemblyTableColumns::Opcode, STR_DISASSEMBLY_TABLE_COLUMN_OPCODE }, - { rgIsaDisassemblyTableColumns::Operands, STR_DISASSEMBLY_TABLE_COLUMN_OPERANDS }, - { rgIsaDisassemblyTableColumns::FunctionalUnit, STR_DISASSEMBLY_TABLE_COLUMN_FUNCTIONAL_UNIT }, - { rgIsaDisassemblyTableColumns::Cycles, STR_DISASSEMBLY_TABLE_COLUMN_CYCLES }, - { rgIsaDisassemblyTableColumns::BinaryEncoding, STR_DISASSEMBLY_TABLE_COLUMN_BINARY_ENCODING }, - }; - - auto columnNameIter = kColumnNameMap.find(column); - if (columnNameIter != kColumnNameMap.end()) - { - result = columnNameIter->second; - } - else - { - // The incoming column doesn't have a name string mapped to it. - assert(false); - } - - return result; -} - -rgIsaDisassemblyTabView* rgIsaDisassemblyView::GetTargetGpuTabWidgetByTabName(const std::string& tabText) const -{ - rgIsaDisassemblyTabView* pResult = nullptr; - - // If a matching view exists return it. - auto gpuTabIter = m_gpuTabViews.find(tabText); - if (gpuTabIter != m_gpuTabViews.end()) - { - pResult = gpuTabIter->second; - } - - return pResult; -} - -void rgIsaDisassemblyView::PopulateTargetGpuList(const rgBuildOutputsMap& buildOutput) -{ - // Get a mapping of the compute capability to architecture. - std::map computeCapabilityToArch; - bool hasArchMapping = rgUtils::GetComputeCapabilityToArchMapping(computeCapabilityToArch); - - // Block signals to stop updates when each new GPU is added to the list. - m_pTargetGpusListWidget->blockSignals(true); - - m_pTargetGpusListWidget->clear(); - - std::vector targets; - - for (auto targetGpuIter = buildOutput.rbegin(); targetGpuIter != buildOutput.rend(); ++targetGpuIter) - { - if (targetGpuIter->second != nullptr) - { - // Add each target GPU from the build outputs to the dropdown list. - auto targetGpu = targetGpuIter->first; - - // Construct the presented name. - std::stringstream presentedName; - - // If applicable, prepend the gfx notation (for example, "gfx802/Tonga" for "Tonga"). - std::string gfxNotation; - bool hasGfxNotation = rgUtils::GetGfxNotation(targetGpu, gfxNotation); - if (hasGfxNotation && !gfxNotation.empty()) - { - presentedName << gfxNotation << "/"; - } - presentedName << targetGpu; - - // If we have a mapping, let's construct a name that includes - // the GPU architecture as well: (). - if (hasArchMapping) - { - auto iter = computeCapabilityToArch.find(targetGpu); - if (iter != computeCapabilityToArch.end()) - { - presentedName << " (" << iter->second << ")"; - } - } - - // Add the name to the list. - targets.push_back(presentedName.str()); - } - } - assert(!targets.empty()); - - // Sort and choose the latest target. - std::sort(targets.begin(), - targets.end(), [&](const std::string& a, const std::string& b) - { - const char* GFX_NOTATION_TOKEN = "gfx"; - bool ret = true; - size_t szA = a.find(GFX_NOTATION_TOKEN); - size_t szB = b.find(GFX_NOTATION_TOKEN); - if (szA == std::string::npos && szB == std::string::npos) - { - // Neither name is in gfx-notation, compare using standard string logic. - ret = a.compare(b) < 0; - } - else if (!(szA != std::string::npos && szB != std::string::npos)) - { - // Only one name has the gfx notation, assume that it is a newer generation. - ret = (szB != std::string::npos); - } - else - { - // Both names are in gfx notation, compare according to the number. - std::vector splitA; - std::vector splitB; - rgUtils::splitString(a, 'x', splitA); - rgUtils::splitString(b, 'x', splitB); - assert(splitA.size() > 1); - assert(splitB.size() > 1); - if (splitA.size() > 1 && splitB.size() > 1) - { - try - { - int numA = std::stoi(splitA[1], nullptr, 16); - int numB = std::stoi(splitB[1], nullptr, 16); - ret = ((numB - numA) > 0); - } - catch (...) - { - ret = false; - } - } - } - return !ret; - }); - - for (const std::string& str : targets) - { - m_pTargetGpusListWidget->addItem(str.c_str()); - } - - // Switch to the first target GPU. - HandleTargetGpuChanged(0); - - // Re-enable signals emitted from the target GPU list. - m_pTargetGpusListWidget->blockSignals(false); -} - -bool rgIsaDisassemblyView::PopulateDisassemblyEntries(const GpuToEntryVector& gpuToDisassemblyCsvEntries) -{ - bool ret = true; - - if (!gpuToDisassemblyCsvEntries.empty()) - { - // Step through each GPU and insert a new rgIsaDisassemblyTabView into a new tab. - for (auto gpuEntryIter = gpuToDisassemblyCsvEntries.begin(); gpuEntryIter != gpuToDisassemblyCsvEntries.end(); ++gpuEntryIter) - { - const std::string& gpuName = gpuEntryIter->first; - const std::vector& gpuEntries = gpuEntryIter->second; - - // Does a tab already exist for the target GPU we're loading results for? - rgIsaDisassemblyTabView* pEntryView = GetTargetGpuTabWidgetByTabName(gpuName); - - // Create a new tab for the target GPU, and add a new disassembly table viewer. - if (pEntryView == nullptr) - { - // Create a new entry view for each unique GPU. - pEntryView = new rgIsaDisassemblyTabView(); - - // Connect signals for the new tab. - ConnectDisassemblyTabViewSignals(pEntryView); - - // Add the new entry view to the map. - m_gpuTabViews[gpuName] = pEntryView; - - // Add the new disassembly table as a tab page in the array of GPU results. - ui.disassemblyTableHostWidget->addWidget(pEntryView); - } - - // Send the CSV file paths to the GPU-specific entry viewer. - bool isTablePopulated = pEntryView->PopulateEntries(gpuEntries); - - // Verify that the table was populated correctly. - assert(isTablePopulated); - if (!isTablePopulated) - { - ret = false; - } - } - } - - return ret; -} - -bool rgIsaDisassemblyView::PopulateResourceUsageEntries(const GpuToEntryVector& gpuToResourceUsageCsvEntries) -{ - bool isLoadFailed = false; - - if (!gpuToResourceUsageCsvEntries.empty()) - { - // Step through each GPU and insert a new rgResourceView underneath the disassembly table. - for (auto gpuEntryIter = gpuToResourceUsageCsvEntries.begin(); gpuEntryIter != gpuToResourceUsageCsvEntries.end(); ++gpuEntryIter) - { - const std::string& gpuName = gpuEntryIter->first; - const std::vector& gpuEntries = gpuEntryIter->second; - - // Create a resource usage disassembly table for each entry, and add it to the layout. - // Only a single entry point table will be visible at a time, and the user can switch between the current entry. - for (const rgEntryOutput& entry : gpuEntries) - { - OutputFileTypeFinder outputFileTypeSearcher(rgCliOutputFileType::HwResourceUsageFile); - auto csvFileIter = std::find_if(entry.m_outputs.begin(), entry.m_outputs.end(), outputFileTypeSearcher); - if (csvFileIter != entry.m_outputs.end()) - { - // Create a CSV parser to read the resource usage file. - rgResourceUsageCsvFileParser resourceUsageFileParser(csvFileIter->m_filePath); - - // Attempt to parse the file. - std::string parseErrorString; - bool parsedSuccessfully = resourceUsageFileParser.Parse(parseErrorString); - if (parsedSuccessfully) - { - // Extract the parsed data, and populate the resource usage view. - const rgResourceUsageData& resourceUsageData = resourceUsageFileParser.GetData(); - rgResourceUsageView* pResourceUsageView = new rgResourceUsageView(); - pResourceUsageView->PopulateView(resourceUsageData); - m_resourceUsageText = pResourceUsageView->GetResourceUsageText(); - m_resourceUsageFont = pResourceUsageView->GetResourceUsageFont(); - - // Register the resource usage view with the scaling manager. - ScalingManager::Get().RegisterObject(pResourceUsageView); - - // Connect resource usage view signals. - ConnectResourceUsageViewSignals(pResourceUsageView); - - // Add the new resource usage view to the host widget. - ui.resourceUsageHostStackedWidget->addWidget(pResourceUsageView); - ui.resourceUsageHostStackedWidget->setContentsMargins(0, 10, 0, 0); - - // Get a reference to the entry point views associated with the parsed device. - InputToEntrypointViews& inputFileToEntrypointMap = m_gpuResourceUsageViews[gpuName]; - - // Get a reference to the resource views map for the source file. - EntrypointToResourcesView& entrypointMap = inputFileToEntrypointMap[entry.m_inputFilePath]; - - // Associate the entrypoint's name with the new rgResourceView. - entrypointMap[entry.m_entrypointName] = pResourceUsageView; - } - else - { - isLoadFailed = true; - } - } - } - } - } - - return !isLoadFailed; -} - -void rgIsaDisassemblyView::ConnectResourceUsageViewSignals(rgResourceUsageView * pResourceUsageView) -{ - // Connect to the resource usage view's mouse press event. - bool isConnected = connect(pResourceUsageView, &rgResourceUsageView::ResourceUsageViewClickedSignal, this, &rgIsaDisassemblyView::HandleDisassemblyTabViewClicked); - assert(isConnected); - - // Connect to the resource usage view's focus out event. - isConnected = connect(pResourceUsageView, &rgResourceUsageView::ResourceUsageViewFocusOutEventSignal, this, &rgIsaDisassemblyView::HandleResourceUsageViewFocusOutEvent); - assert(isConnected); -} - -void rgIsaDisassemblyView::PopulateColumnVisibilityList() -{ - // Set up the function pointer responsible for handling column visibility filter state change. - using std::placeholders::_1; - std::function slotFunctionPointer = std::bind(&rgIsaDisassemblyView::HandleColumnVisibilityFilterStateChanged, this, _1); - - // Remove the existing items first - ClearListWidget(m_pDisassemblyColumnsListWidget); - - // Add the "All" entry - ListWidget::AddListWidgetCheckboxItem(STR_DISASSEMBLY_TABLE_COLUMN_ALL, m_pDisassemblyColumnsListWidget, slotFunctionPointer, this, STR_DISASSEMBLY_COLUMN_VISIBILITY_LIST, STR_DISASSEMBLY_COLUMN_LIST_ITEM_ALL_CHECKBOX); - - // Loop through each column enum member. - int startColumn = rgIsaDisassemblyTableModel::GetTableColumnIndex(rgIsaDisassemblyTableColumns::Address); - int endColumn = rgIsaDisassemblyTableModel::GetTableColumnIndex(rgIsaDisassemblyTableColumns::Count); - - // Add an item for each column in the table. - for (int columnIndex = startColumn; columnIndex < endColumn; ++columnIndex) - { - // Add an item for each possible column in the table. - std::string columnName = GetDisassemblyColumnName(static_cast(columnIndex)); - ListWidget::AddListWidgetCheckboxItem(columnName.c_str(), m_pDisassemblyColumnsListWidget, slotFunctionPointer, this, STR_DISASSEMBLY_COLUMN_VISIBILITY_LIST, STR_DISASSEMBLY_COLUMN_LIST_ITEM_CHECKBOX); - } - - // Populate the check box items by reading the global settings. - rgConfigManager& configManager = rgConfigManager::Instance(); - std::shared_ptr pGlobalSettings = configManager.GetGlobalConfig(); - ListWidget::SetColumnVisibilityCheckboxes(m_pDisassemblyColumnsListWidget, pGlobalSettings->m_visibleDisassemblyViewColumns); - - // Update the "All" checkbox text color to grey or black. - UpdateAllCheckBoxText(); - - // Set list widget's check box's focus proxy to be the frame. - SetCheckBoxFocusProxies(m_pDisassemblyColumnsListWidget); -} - -void rgIsaDisassemblyView::SetCheckBoxFocusProxies(const ListWidget* pListWidget) const -{ - for (int i = 0; i < pListWidget->count(); i++) - { - QListWidgetItem* pItem = pListWidget->item(i); - assert(pItem != nullptr); - - QCheckBox* pCheckBox = qobject_cast(pListWidget->itemWidget(pItem)); - assert(pCheckBox != nullptr); - - pCheckBox->setFocusProxy(ui.frame); - } -} - -void rgIsaDisassemblyView::UpdateAllCheckBoxText() -{ - bool areAllItemsChecked = true; - - // Check to see if all of the boxes are checked. - for (int i = 1; i < m_pDisassemblyColumnsListWidget->count(); i++) - { - QListWidgetItem* pItem = m_pDisassemblyColumnsListWidget->item(i); - assert(pItem != nullptr); - - QCheckBox* pCheckBox = qobject_cast(m_pDisassemblyColumnsListWidget->itemWidget(pItem)); - assert(pCheckBox != nullptr); - - if (pCheckBox->checkState() == Qt::CheckState::Unchecked) - { - areAllItemsChecked = false; - break; - } - } - - // If all boxes are checked, update the text color of the All check box. - QListWidgetItem* pItem = m_pDisassemblyColumnsListWidget->item(0); - if (pItem != nullptr) - { - QCheckBox* pCheckBox = qobject_cast(m_pDisassemblyColumnsListWidget->itemWidget(pItem)); - if (pCheckBox != nullptr) - { - if (areAllItemsChecked) - { - pCheckBox->setStyleSheet("QCheckBox#ListWidgetAllCheckBox {color: grey;}"); - } - else - { - pCheckBox->setStyleSheet("QCheckBox#ListWidgetAllCheckBox {color: black;}"); - } - } - } -} - -void rgIsaDisassemblyView::DestroyDisassemblyViewsForFile(const std::string& inputFilePath) -{ - // Keep a list of tabs that should be destroyed after removing the input file. - std::vector gpuTabsToRemove; - - // Step through each GPU tab and try to remove the entries associated with the given input file. - auto startTab = m_gpuTabViews.begin(); - auto endTab = m_gpuTabViews.end(); - for (auto tabIter = startTab; tabIter != endTab; ++tabIter) - { - // Search the tab for entries to remove. - rgIsaDisassemblyTabView* pGpuTab = tabIter->second; - assert(pGpuTab != nullptr); - if (pGpuTab != nullptr) - { - // Attempt to remove entries associated with the input file from each GPU tab. - pGpuTab->RemoveInputFileEntries(inputFilePath); - - // Does the GPU tab have any tables left in it? If not, destroy the tab too. - int numTablesInTab = pGpuTab->GetTableCount(); - if (numTablesInTab == 0) - { - const std::string& gpuName = tabIter->first; - gpuTabsToRemove.push_back(gpuName); - } - } - } - - // Destroy all tabs that were marked for destruction. - for (auto pGpuTab : gpuTabsToRemove) - { - auto tabIter = m_gpuTabViews.find(pGpuTab); - if (tabIter != m_gpuTabViews.end()) - { - // Destroy the GPU tab. - rgIsaDisassemblyTabView* pGpuTabView = tabIter->second; - - // Remove the GPU tab from the view. - ui.disassemblyTableHostWidget->removeWidget(pGpuTabView); - - // Remove the GPU from the view. - m_gpuTabViews.erase(tabIter); - } - } -} - -void rgIsaDisassemblyView::DestroyResourceUsageViewsForFile(const std::string& inputFilePath) -{ - // Destroy resource views for all GPUs. - for (auto gpuIter = m_gpuResourceUsageViews.begin(); gpuIter != m_gpuResourceUsageViews.end(); ++gpuIter) - { - // Find all resource views related to the given input file. - InputToEntrypointViews& inputFileToViewsIter = gpuIter->second; - auto entrypointResourceUsageviewsIter = inputFileToViewsIter.find(inputFilePath); - if (entrypointResourceUsageviewsIter != inputFileToViewsIter.end()) - { - // Step through each entrypoint's resource usage view, and destroy it. - EntrypointToResourcesView& entrypointResourceViews = entrypointResourceUsageviewsIter->second; - for (auto entrypointIter = entrypointResourceViews.begin(); entrypointIter != entrypointResourceViews.end(); ++entrypointIter) - { - // Destroy the resource usage view. - rgResourceUsageView* pResourceUsageView = entrypointIter->second; - - // Remove the resource usage widget from the view. - ui.resourceUsageHostStackedWidget->removeWidget(pResourceUsageView); - } - - inputFileToViewsIter.erase(entrypointResourceUsageviewsIter); - } - } -} - -void rgIsaDisassemblyView::SetCurrentResourceUsageView(rgResourceUsageView* pResourceUsageView) -{ - // Set the current widget in the stack. - ui.resourceUsageHostStackedWidget->setCurrentWidget(pResourceUsageView); - - // Use the given resource usage view as the focus proxy for this view. - setFocusProxy(pResourceUsageView); -} - -void rgIsaDisassemblyView::SetCurrentTargetGpuTabView(rgIsaDisassemblyTabView* pTabView) -{ - // Set the current widget in the stack. - ui.disassemblyTableHostWidget->setCurrentWidget(pTabView); - - // Store the current target GPU tab being viewed. - m_pCurrentTabView = pTabView; - - // Use the current tab view as the focus proxy for this view. - setFocusProxy(pTabView); -} - -void rgIsaDisassemblyView::SetCursor() -{ - ui.columnVisibilityArrowPushButton->setCursor(Qt::PointingHandCursor); - ui.targetGpuPushButton->setCursor(Qt::PointingHandCursor); - ui.viewMaximizeButton->setCursor(Qt::PointingHandCursor); -} - -void rgIsaDisassemblyView::SetTargetGpu(const std::string& targetGpu) -{ - static const int g_ARROW_WIDGET_EXTRA_WIDTH = 30; - - // Update the button text. - ui.targetGpuPushButton->setText(targetGpu.c_str()); - - // Measure the width of the Target GPU text, and add extra space to account for the width of the arrow. - int scaledArrowWidth = static_cast(g_ARROW_WIDGET_EXTRA_WIDTH * ScalingManager::Get().GetScaleFactor()); - int textWidth = QtCommon::QtUtil::GetTextWidth(ui.targetGpuPushButton->font(), targetGpu.c_str()); - ui.targetGpuPushButton->setMinimumWidth(scaledArrowWidth + textWidth); -} - -void rgIsaDisassemblyView::SetFontSizes() -{ - // Set column visibility push button font. - ArrowIconWidget* pArrowWidget = dynamic_cast(ui.columnVisibilityArrowPushButton); - if (pArrowWidget != nullptr) - { - pArrowWidget->SetFontSize(s_PUSH_BUTTON_FONT_SIZE); - } - - // Set ISA list push button font. - pArrowWidget = dynamic_cast(ui.targetGpuPushButton); - if (pArrowWidget != nullptr) - { - pArrowWidget->SetFontSize(s_PUSH_BUTTON_FONT_SIZE); - } -} - -bool rgIsaDisassemblyView::IsLineCorrelatedInEntry(const std::string& inputFilePath, const std::string& targetGpu, const std::string& entrypoint, int srcLine) const -{ - bool ret = false; - - rgIsaDisassemblyTabView* pTargetGpuTab = GetTargetGpuTabWidgetByTabName(targetGpu.c_str()); - - assert(pTargetGpuTab != nullptr); - if (pTargetGpuTab != nullptr) - { - ret = pTargetGpuTab->IsSourceLineCorrelatedForEntry(inputFilePath, entrypoint, srcLine); - } - - return ret; -} - -void rgIsaDisassemblyView::HandleDisassemblyTabViewClicked() -{ - // Emit a signal to indicate that disassembly view was clicked. - emit DisassemblyViewClicked(); - - // Remove the button focus in the file menu. - emit RemoveFileMenuButtonFocus(); -} - -void rgIsaDisassemblyView::HandleDisassemblyTabViewLostFocus() -{ - // Remove the button focus in the file menu. - emit RemoveFileMenuButtonFocus(); -} - -void rgIsaDisassemblyView::HandleResourceUsageViewFocusOutEvent() -{ - // Remove the button focus in the file menu. - emit RemoveFileMenuButtonFocus(); -} - -void rgIsaDisassemblyView::HandleTitlebarClickedEvent(QMouseEvent* pEvent) -{ - // Emit a signal to indicate that disassembly view was clicked. - emit DisassemblyViewClicked(); - - // Remove the button focus in the file menu. - emit RemoveFileMenuButtonFocus(); -} - -void rgIsaDisassemblyView::HandleListWidgetFocusInEvent() -{ - // Emit a signal to indicate that disassembly view was clicked. - emit DisassemblyViewClicked(); - - // Remove the button focus in the file menu. - emit RemoveFileMenuButtonFocus(); -} - -void rgIsaDisassemblyView::HandleListWidgetFocusOutEvent() -{ -} - -void rgIsaDisassemblyView::HandleFocusOutEvent() -{ - // Remove the button focus in the file menu. - emit RemoveFileMenuButtonFocus(); -} - -void rgIsaDisassemblyView::HandleFocusTargetGpuPushButton() -{ - ui.targetGpuPushButton->clicked(false); -} - -void rgIsaDisassemblyView::HandleFocusColumnsPushButton() -{ - ui.columnVisibilityArrowPushButton->clicked(false); -} - -void rgIsaDisassemblyView::ConnectTitleBarDoubleClick(const rgViewContainer* pDisassemblyViewContainer) -{ - assert(pDisassemblyViewContainer != nullptr); - if (pDisassemblyViewContainer != nullptr) - { - bool isConnected = connect(ui.viewTitlebar, &rgIsaDisassemblyViewTitlebar::ViewTitleBarDoubleClickedSignal, pDisassemblyViewContainer, &rgViewContainer::MaximizeButtonClicked); - assert(isConnected); - } -} - -bool rgIsaDisassemblyView::ReplaceInputFilePath(const std::string& oldFilePath, const std::string& newFilePath) -{ - bool result = true; - - // Replace the file path in all disassembly tab views for all devices. - for (auto& gpuAndTabView : m_gpuTabViews) - { - rgIsaDisassemblyTabView* pTabView = gpuAndTabView.second; - if (!pTabView->ReplaceInputFilePath(oldFilePath, newFilePath)) - { - result = false; - break; - } - } - - // Replace the file path in the resource usage map. - if (result) - { - for (auto& gpuAndResourceUsage : m_gpuResourceUsageViews) - { - auto& fileAndResourceUsage = gpuAndResourceUsage.second; - auto it = fileAndResourceUsage.find(oldFilePath); - if ((result = (it != fileAndResourceUsage.end())) == true) - { - std::map resUsageView = it->second; - fileAndResourceUsage.erase(oldFilePath); - fileAndResourceUsage[newFilePath] = resUsageView; - } - } - } - - return result; -} - -void rgIsaDisassemblyView::HandleSelectNextGPUTargetAction() -{ - int currentRow = m_pTargetGpusListWidget->currentRow(); - - if (currentRow < m_pTargetGpusListWidget->count() - 1) - { - currentRow++; - } - else - { - currentRow = 0; - } - m_pTargetGpusListWidget->setCurrentRow(currentRow); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyViewGraphics.cpp b/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyViewGraphics.cpp deleted file mode 100644 index ba34d27..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyViewGraphics.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// C++. -#include - -// Local. -#include - -rgIsaDisassemblyViewGraphics::rgIsaDisassemblyViewGraphics(QWidget* pParent) - : rgIsaDisassemblyView(pParent) -{ -} - -bool rgIsaDisassemblyViewGraphics::PopulateBuildOutput(const std::shared_ptr pProjectClone, const rgBuildOutputsMap& buildOutputs) -{ - bool ret = false; - - std::shared_ptr pPipelineClone = std::dynamic_pointer_cast(pProjectClone); - assert(pPipelineClone != nullptr); - if (pPipelineClone != nullptr) - { - const ShaderInputFileArray& shaderStageArray = pPipelineClone->m_pipeline.m_shaderStages; - - // Build artifacts may contain disassembly for shader files that are no longer associated - // with any stage in the pipeline. Provide the map of the pipeline's current stages, along - // with the build artifacts that can be loaded. - ret = PopulateDisassemblyView(shaderStageArray, buildOutputs); - } - - return ret; -} - -bool rgIsaDisassemblyViewGraphics::PopulateDisassemblyView(const ShaderInputFileArray& shaderStageArray, const rgBuildOutputsMap& buildOutput) -{ - bool isProblemFound = false; - - // Iterate through each target GPU's output. - for (auto gpuOutputsIter = buildOutput.begin(); gpuOutputsIter != buildOutput.end(); ++gpuOutputsIter) - { - const std::string& targetGpu = gpuOutputsIter->first; - std::shared_ptr pGpuBuildOutput = gpuOutputsIter->second; - bool isValidOutput = pGpuBuildOutput != nullptr; - assert(isValidOutput); - if (isValidOutput) - { - std::shared_ptr pGpuBuildOutputPipeline = - std::dynamic_pointer_cast(pGpuBuildOutput); - - // Step through the outputs map, and load the disassembly data for each input file. - for (auto inputFileOutputsIter = pGpuBuildOutputPipeline->m_perFileOutput.begin(); inputFileOutputsIter != pGpuBuildOutputPipeline->m_perFileOutput.end(); ++inputFileOutputsIter) - { - const std::string& inputFilePath = inputFileOutputsIter->first; - - // Only load build outputs for files in the given list of source files. - auto inputFilePathIter = std::find(shaderStageArray.begin(), shaderStageArray.end(), inputFilePath); - if (inputFilePathIter != shaderStageArray.end()) - { - // Get the list of outputs for the input file. - rgFileOutputs& fileOutputs = inputFileOutputsIter->second; - const std::vector& fileEntryOutputs = fileOutputs.m_outputs; - - // Transform the disassembled entries into a map of GPU -> Entries. - // This will make populating the UI much simpler. - std::map> gpuToDisassemblyCsvEntries; - std::map> gpuToResourceUsageCsvEntries; - for (const rgEntryOutput& entry : fileOutputs.m_outputs) - { - for (const rgOutputItem& outputs : entry.m_outputs) - { - if (outputs.m_fileType == IsaDisassemblyCsv) - { - std::vector& disassemblyCsvFilePaths = gpuToDisassemblyCsvEntries[targetGpu]; - disassemblyCsvFilePaths.push_back(entry); - } - else if (outputs.m_fileType == HwResourceUsageFile) - { - std::vector& entryCsvFilePaths = gpuToResourceUsageCsvEntries[targetGpu]; - entryCsvFilePaths.push_back(entry); - } - } - } - - - // Load the disassembly CSV entries from the build output. - bool isDisassemblyDataLoaded = PopulateDisassemblyEntries(gpuToDisassemblyCsvEntries); - assert(isDisassemblyDataLoaded); - if (!isDisassemblyDataLoaded) - { - isProblemFound = true; - } - - if (!isProblemFound) - { - // Load the resource usage CSV entries from the build output. - bool isResourceUsageDataLoaded = PopulateResourceUsageEntries(gpuToResourceUsageCsvEntries); - assert(isResourceUsageDataLoaded); - if (!isResourceUsageDataLoaded) - { - isProblemFound = true; - } - } - } - } - } - } - - // If the disassembly results loaded correctly, add the target GPU to the dropdown. - if (!isProblemFound) - { - // Populate the target GPU dropdown list with the targets from the build output. - PopulateTargetGpuList(buildOutput); - } - - return !isProblemFound; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyViewOpenCL.cpp b/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyViewOpenCL.cpp deleted file mode 100644 index 3268ab4..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyViewOpenCL.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// C++. -#include - -// Local. -#include -#include - -rgIsaDisassemblyViewOpenCL::rgIsaDisassemblyViewOpenCL(QWidget* pParent) - : rgIsaDisassemblyView(pParent) -{ -} - -bool rgIsaDisassemblyViewOpenCL::PopulateBuildOutput(const std::shared_ptr pProjectClone, const rgBuildOutputsMap& buildOutputs) -{ - bool ret = false; - - assert(pProjectClone != nullptr); - if (pProjectClone != nullptr) - { - std::vector& projectSourceFiles = pProjectClone->m_sourceFiles; - - // Build artifacts may contain disassembly for source files that are no longer - // in the project, so provide a list of files to load, along with the current build output. - ret = PopulateDisassemblyView(projectSourceFiles, buildOutputs); - } - - return ret; -} - -bool rgIsaDisassemblyViewOpenCL::PopulateDisassemblyView(const std::vector& sourceFiles, const rgBuildOutputsMap& buildOutput) -{ - bool isProblemFound = false; - - // Iterate through each target GPU's output. - for (auto gpuOutputsIter = buildOutput.begin(); gpuOutputsIter != buildOutput.end(); ++gpuOutputsIter) - { - const std::string& targetGpu = gpuOutputsIter->first; - std::shared_ptr pGpuBuildOutput = gpuOutputsIter->second; - bool isValidOutput = pGpuBuildOutput != nullptr; - assert(isValidOutput); - if (isValidOutput) - { - std::shared_ptr pGpuBuildOutputOpenCL = - std::dynamic_pointer_cast(pGpuBuildOutput); - - // Step through the outputs map, and load the disassembly data for each input file. - for (auto outputIter = pGpuBuildOutputOpenCL->m_perFileOutput.begin(); outputIter != pGpuBuildOutputOpenCL->m_perFileOutput.end(); ++outputIter) - { - const std::string& sourceFilePath = outputIter->first; - - // Only load build outputs for files in the given list of source files. - rgSourceFilePathSearcher sourceFileSearcher(sourceFilePath); - auto sourceFileIter = std::find_if(sourceFiles.begin(), sourceFiles.end(), sourceFileSearcher); - if (sourceFileIter != sourceFiles.end()) - { - // Get the list of outputs for the input file. - rgFileOutputs& fileOutputs = outputIter->second; - const std::vector& fileEntryOutputs = fileOutputs.m_outputs; - - // Transform the disassembled entries into a map of GPU -> Entries. - // This will make populating the UI much simpler. - std::map> gpuToDisassemblyCsvEntries; - std::map> gpuToResourceUsageCsvEntries; - for (const rgEntryOutput& entry : fileOutputs.m_outputs) - { - for (const rgOutputItem& outputs : entry.m_outputs) - { - if (outputs.m_fileType == IsaDisassemblyCsv) - { - std::vector& disassemblyCsvFilePaths = gpuToDisassemblyCsvEntries[targetGpu]; - disassemblyCsvFilePaths.push_back(entry); - } - else if (outputs.m_fileType == HwResourceUsageFile) - { - std::vector& entryCsvFilePaths = gpuToResourceUsageCsvEntries[targetGpu]; - entryCsvFilePaths.push_back(entry); - } - } - } - - - // Load the disassembly CSV entries from the build output. - bool isDisassemblyDataLoaded = PopulateDisassemblyEntries(gpuToDisassemblyCsvEntries); - assert(isDisassemblyDataLoaded); - if (!isDisassemblyDataLoaded) - { - isProblemFound = true; - } - - if (!isProblemFound) - { - // Load the resource usage CSV entries from the build output. - bool isResourceUsageDataLoaded = PopulateResourceUsageEntries(gpuToResourceUsageCsvEntries); - assert(isResourceUsageDataLoaded); - if (!isResourceUsageDataLoaded) - { - isProblemFound = true; - } - } - } - } - } - } - - // If the disassembly results loaded correctly, add the target GPU to the dropdown. - if (!isProblemFound) - { - // Populate the target GPU dropdown list with the targets from the build output. - PopulateTargetGpuList(buildOutput); - } - - return !isProblemFound; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyViewVulkan.cpp b/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyViewVulkan.cpp deleted file mode 100644 index 9b78325..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgIsaDisassemblyViewVulkan.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// Local. -#include -#include -#include -#include - -rgIsaDisassemblyViewVulkan::rgIsaDisassemblyViewVulkan(QWidget* pParent) - : rgIsaDisassemblyViewGraphics(pParent) -{ -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgLabel.cpp b/RadeonGPUAnalyzerGUI/Src/rgLabel.cpp deleted file mode 100644 index 8347136..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgLabel.cpp +++ /dev/null @@ -1,116 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include - -// Infra. -#include -#include - -// Local. -#include - -// The horizontal location of where to show the edit value. -static const int s_PAINT_LOCATION_X = 5; - -// The height of the label. -static const int s_LABEL_SIZE = 18; - -// The vertical margin of the highlight. -static const int s_HIGHLIGHT_VERTICAL_MARGIN = 3; - -// The margin to leave from the top of the label -// before drawing the text. -static const int s_VERTICAL_MARGIN = 3; - -rgLabel::rgLabel(QWidget* pParent) : QLabel(pParent) -{ -} - -void rgLabel::focusInEvent(QFocusEvent* pEvent) -{ - // Emit an event indicating that this widget got focus. - // This is necessary so that external objects can be signaled when this occurs. - emit LabelFocusInEventSignal(); - - // Pass the event onto the base class. - QLabel::focusInEvent(pEvent); -} - -void rgLabel::focusOutEvent(QFocusEvent* pEvent) -{ - // Emit an event indicating that this widget lost focus. - // This is necessary so that external objects can be signaled when this occurs. - emit LabelFocusOutEventSignal(); - - // Pass the event onto the base class. - QLabel::focusOutEvent(pEvent); -} - -void rgLabel::paintEvent(QPaintEvent* pEvent) -{ - Q_UNUSED(pEvent); - - // Set up the painter. - QPainter painter; - painter.begin(this); - painter.setRenderHint(QPainter::Antialiasing); - - // Set properties for the text. - QPen pen; - pen.setColor(Qt::black); - pen.setWidth(1); - painter.setPen(pen); - - // Draw the text. - QFont font = this->font(); - font.setPointSize(8); - painter.setFont(font); - - // Highlight substring if it is requested. - if (m_highlightSubString) - { - // Go through all highlight locations. - for (const auto& stringHighlightData : m_stringHighlightData) - { - QString current = text().mid(0, stringHighlightData.m_startLocation); - int initialTextWidth = QtCommon::QtUtil::GetTextWidth(font, current); - - assert(stringHighlightData.m_endLocation - stringHighlightData.m_startLocation > 0); - current = text().mid(stringHighlightData.m_startLocation, - stringHighlightData.m_endLocation - stringHighlightData.m_startLocation); - - assert(!current.isNull()); - if (!current.isNull()) - { - int width = QtCommon::QtUtil::GetTextWidth(font, current); - QRect rect = this->rect(); - rect.setX(rect.x() + s_PAINT_LOCATION_X + initialTextWidth); - rect.setHeight(rect.height() - s_HIGHLIGHT_VERTICAL_MARGIN); - rect.setY(rect.y() + s_HIGHLIGHT_VERTICAL_MARGIN); - rect.setWidth(width); - painter.fillRect(rect, stringHighlightData.m_highlightColor); - } - } - } - - // Get the scaling factor. - const double scalingFactor = ScalingManager::Get().GetScaleFactor(); - - // Draw the text. - painter.drawText(s_PAINT_LOCATION_X, (s_LABEL_SIZE / 2 + s_VERTICAL_MARGIN) * scalingFactor, text()); - - painter.end(); -} - -void rgLabel::SetHighlightSubStringData(QVector stringHighlightData) -{ - m_stringHighlightData = stringHighlightData; -} - -void rgLabel::SetHighlightSubString(bool value) -{ - m_highlightSubString = value; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgLineEdit.cpp b/RadeonGPUAnalyzerGUI/Src/rgLineEdit.cpp deleted file mode 100644 index a59d893..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgLineEdit.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include - -// Infra. -#include -#include - -// Local. -#include - -// The horizontal location of where to show the edit value. -static const int s_PAINT_LOCATION_X = 5; - -// The height of the line edit. -static const int s_LINE_EDIT_SIZE = 18; - -// The vertical margin of the highlight. -static const int s_HIGHLIGHT_VERTICAL_MARGIN = 5; - -// The margin to leave from the top of the line edit -// before drawing the text. -static const int s_VERTICAL_MARGIN = 3; - -rgLineEdit::rgLineEdit(QWidget* pParent) : QLineEdit(pParent) -{ -} - -void rgLineEdit::focusInEvent(QFocusEvent* pEvent) -{ - emit LineEditFocusInEvent(); - - // Pass the event onto the base class. - QLineEdit::focusInEvent(pEvent); - - // Select the text using single shot timer. - QTimer::singleShot(0, this, &QLineEdit::selectAll); -} - -void rgLineEdit::focusOutEvent(QFocusEvent* pEvent) -{ - emit LineEditFocusOutEvent(); - - // Pass the event onto the base class. - QLineEdit::focusOutEvent(pEvent); -} - -void rgLineEdit::paintEvent(QPaintEvent* pEvent) -{ - Q_UNUSED(pEvent); - - // Let the base class draw everything, i.e. text, cursor, border, etc. - QLineEdit::paintEvent(pEvent); - - // Set up the painter. - QPainter painter; - painter.begin(this); - painter.setRenderHint(QPainter::Antialiasing); - - // Set the font size. - QFont font = this->font(); - font.setPointSize(8); - painter.setFont(font); - - // Highlight substring if it is requested. - if (m_highlightSubString) - { - // Go through all highlight locations. - for (const auto& stringHighlightData : m_stringHighlightData) - { - QString current = text().mid(0, stringHighlightData.m_startLocation); - int initialTextWidth = QtCommon::QtUtil::GetTextWidth(font, current); - - current = text().mid(stringHighlightData.m_startLocation, - stringHighlightData.m_endLocation - stringHighlightData.m_startLocation); - int width = QtCommon::QtUtil::GetTextWidth(font, current); - QRect rect = this->rect(); - rect.setX(rect.x() + s_PAINT_LOCATION_X + initialTextWidth); - rect.setHeight(rect.height() - s_HIGHLIGHT_VERTICAL_MARGIN); - rect.setY(rect.y() + s_HIGHLIGHT_VERTICAL_MARGIN); - rect.setWidth(width); - painter.fillRect(rect, stringHighlightData.m_highlightColor); - } - } - - painter.end(); -} - -void rgLineEdit::SetHighlightSubStringData(QVector stringHighlightData) -{ - m_stringHighlightData = stringHighlightData; -} - -void rgLineEdit::SetHighlightSubString(bool value) -{ - m_highlightSubString = value; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgListWidget.cpp b/RadeonGPUAnalyzerGUI/Src/rgListWidget.cpp deleted file mode 100644 index a03435e..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgListWidget.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include - -// Local. -#include - -rgListWidget::rgListWidget(QWidget* pParent) : - QListWidget(pParent) -{ - setMouseTracking(true); -} - -void rgListWidget::mouseMoveEvent(QMouseEvent* pEvent) -{ - setCursor(Qt::ArrowCursor); - if (pEvent != nullptr) - { - const QPoint pos = pEvent->pos(); - - const QModelIndex modelIndex = indexAt(pos); - if (modelIndex.isValid()) - { - const int hoveredRow = modelIndex.row(); - const int currentItemRow = currentRow(); - if (hoveredRow != currentItemRow) - { - setCursor(Qt::PointingHandCursor); - - // Pass the event onto the base class. - QListWidget::mouseMoveEvent(pEvent); - } - } - } - else - { - // Pass the event onto the base class. - QListWidget::mouseMoveEvent(pEvent); - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgMainWindow.cpp b/RadeonGPUAnalyzerGUI/Src/rgMainWindow.cpp deleted file mode 100644 index 5c7717c..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgMainWindow.cpp +++ /dev/null @@ -1,2151 +0,0 @@ -// C++. -#include -#include -#include -#include - -// Qt. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Infra. -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const int s_CUSTOM_STATUS_BAR_HEIGHT = 25; - -rgMainWindow::rgMainWindow(QWidget* pParent) - : QMainWindow(pParent) -{ - // Get the startup mode. - rgConfigManager& configManager = rgConfigManager::Instance(); - rgProjectAPI currentAPI = configManager.GetCurrentAPI(); - - // We must have a known mode at startup. - assert(currentAPI != rgProjectAPI::Unknown); - - // Create the factory through which we create API-specific components. - m_pFactory = rgFactory::CreateFactory(currentAPI); - - // Setup the UI. - ui.setupUi(this); - - // Set the window icon to the product logo. - setWindowIcon(QIcon(gs_ICON_RESOURCE_RGA_LOGO)); - - // Set the background color to white. - QPalette pal = palette(); - pal.setColor(QPalette::Background, Qt::white); - this->setAutoFillBackground(true); - this->setPalette(pal); - - // 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); -} - -void rgMainWindow::InitMainWindow() -{ - // Use the mode to setup API-specific actions. - rgProjectAPI currentApi = rgConfigManager::Instance().GetCurrentAPI(); - ChangeApiMode(currentApi); - - // Enable drops so the main window can handle opening dropped source files. - setAcceptDrops(true); - - // Set the mouse cursor to the pointing hand cursor for various widgets. - SetCursor(); - - // Set the parent widget for the tab bar so the dialogs get shown in the correct location. - ui.mainTabWidget->GetTabBar()->SetParentWidget(this); - - // Set the focus to the tab bar. - ui.mainTabWidget->setFocus(); - - // Increase the double click interval as the default one is too quick. - const int doubleClickInterval = qApp->doubleClickInterval(); - qApp->setDoubleClickInterval(doubleClickInterval * 2); -} - -void rgMainWindow::ConnectSignals() -{ - // Tab changed signal to handle save shortcut updates. - bool isConnected = connect(ui.mainTabWidget, &rgMainWindowTabWidget::currentChanged, this, &rgMainWindow::HandleMainTabWidgetTabChanged); - assert(isConnected); - - // Connect the status bar's message change signal. - isConnected = connect(this->statusBar(), &QStatusBar::messageChanged, this, &rgMainWindow::HandleStatusBarMessageChange); - assert(isConnected); - - // Connect the default API's settings view's handler for pending changes. - isConnected = connect(m_pSettingsTab, &rgSettingsTab::PendingChangesStateChanged, this, &rgMainWindow::HandleHasSettingsPendingStateChanged); - assert(isConnected); - - // Connect the notification message blinking timer signal. - isConnected = connect(m_pAppNotificationBlinkingTimer, &QTimer::timeout, this, &rgMainWindow::HandleAppNotificationMessageTimerFired); - assert(isConnected); -} - -void rgMainWindow::CreateSettingsTab() -{ - // Get settings tab container widget. - assert(ui.mainTabWidget != nullptr); - if (ui.mainTabWidget != nullptr) - { - QWidget* pTabContainer = ui.mainTabWidget->widget(1); - assert(pTabContainer != nullptr); - if (pTabContainer != nullptr) - { - assert(m_pFactory != nullptr); - if (m_pFactory != nullptr) - { - // Delete any existing settings tab first. - DestroySettingsTab(); - - m_pSettingsTab = m_pFactory->CreateSettingsTab(ui.mainTabWidget); - assert(m_pSettingsTab != nullptr); - if (m_pSettingsTab != nullptr) - { - // Initialize the tab before adding to the parent widget. - m_pSettingsTab->Initialize(); - - rgMainWindowTabBar* pTabBar = ui.mainTabWidget->GetTabBar(); - assert(pTabBar != nullptr); - if (pTabBar != nullptr) - { - pTabBar->SetSettingsTab(m_pSettingsTab); - } - - m_pAppState->SetSettingsTab(m_pSettingsTab); - ui.settingsTab->layout()->addWidget(m_pSettingsTab); - - // Handle when the Settings tab signals that it has pending changes. - bool isConnected = connect(m_pSettingsTab, &rgSettingsTab::PendingChangesStateChanged, this, &rgMainWindow::HandleHasSettingsPendingStateChanged); - assert(isConnected); - Q_UNUSED(isConnected); - } - } - } - } -} - -void rgMainWindow::DestroySettingsTab() -{ - if (m_pSettingsTab != nullptr) - { - delete m_pSettingsTab; - m_pSettingsTab = nullptr; - } -} - -void rgMainWindow::CreateStartTab() -{ - assert(m_pFactory != nullptr); - if (m_pFactory != nullptr) - { - rgStartTab* pStartTab = m_pFactory->CreateStartTab(this); - - // Register the start tab with the scaling manager. - ScalingManager::Get().RegisterObject(pStartTab); - - assert(pStartTab != nullptr && m_pAppState != nullptr); - if (pStartTab != nullptr && m_pAppState != nullptr) - { - // Destroy the existing start tab first. - DestroyStartTab(); - - // Set the start page for the mode, and add it to the main window's layout. - m_pAppState->SetStartTab(pStartTab); - ui.startTab->layout()->addWidget(pStartTab); - - // Initialize the start tab view. - pStartTab->Initialize(); - - // Connect signals for the new start tab. - ConnectStartTabSignals(); - } - } -} - -void rgMainWindow::DestroyStartTab() -{ - // Remove the existing widget first, if there is one. - // This is required because when the user switches APIs, - // there'll be duplicate widgets on the home page if we - // don't delete the existing widget here first. - QLayoutItem* pLayoutItem = ui.startTab->layout()->takeAt(0); - if (pLayoutItem != nullptr) - { - QWidget* pWidget = pLayoutItem->widget(); - assert(pWidget != nullptr); - if (pWidget != nullptr) - { - pWidget->deleteLater(); - } - } -} - -void rgMainWindow::ConnectStartTabSignals() -{ - // Connect signals for the mode's start tab. - rgStartTab* pStartTab = m_pAppState->GetStartTab(); - - assert(pStartTab != nullptr); - if (pStartTab != nullptr) - { - // Signal for the Open Program button click. - bool isConnected = connect(pStartTab, &rgStartTab::OpenProjectFileEvent, this, &rgMainWindow::HandleOpenProjectFileEvent); - assert(isConnected); - - // Signal to load the project file at the given path. - isConnected = connect(pStartTab, &rgStartTab::OpenProjectFileAtPath, this, &rgMainWindow::HandleOpenProjectFileAtPath); - assert(isConnected); - - // Signal emitted when the Help->About item is clicked. - isConnected = connect(pStartTab, &rgStartTab::AboutEvent, this, &rgMainWindow::HandleAboutEvent); - assert(isConnected); - - // Signal emitted when the Help->Getting started guide item is clicked. - isConnected = connect(pStartTab, &rgStartTab::GettingStartedGuideEvent, this, &rgMainWindow::HandleGettingStartedGuideEvent); - assert(isConnected); - - // Signal emitted when the Help->Help manual item is clicked. - isConnected = connect(pStartTab, &rgStartTab::HelpManual, this, &rgMainWindow::HandleHelpManual); - assert(isConnected); - } -} - -void rgMainWindow::AddBuildView() -{ - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - // Add the existing rgBuildView instance to the MainWindow's layout. - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - - assert(pBuildView != nullptr); - if (pBuildView != nullptr) - { - // Initialize the rgBuildView instance's interface. - pBuildView->InitializeView(); - - // Connect the menu signals to the rgBuildView and rgMainWindow. - ConnectMenuSignals(); - - // Add the rgBuildView instance to the main window's build page. - ui.buildPage->layout()->addWidget(pBuildView); - - // Register the object with the scaling manager. - ScalingManager::Get().RegisterObject(pBuildView); - - // Adjust the actions to the build view's initial state. - EnableBuildViewActions(); - -#ifdef RGA_GUI_AUTOMATION - emit TEST_BuildViewCreated(pBuildView); -#endif - } - } -} - -void rgMainWindow::ConnectBuildViewSignals() -{ - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - // Get the API-specific rgBuildView instance used by the current mode. - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - - // Verify that the build view exists before using it. - assert(pBuildView != nullptr); - if (pBuildView != nullptr) - { - // Editor text change handler. - bool isConnected = connect(pBuildView, &rgBuildView::CurrentEditorModificationStateChanged, this, &rgMainWindow::OnCurrentEditorModificationStateChanged); - assert(isConnected); - - // Connect the project count changed signal. - isConnected = connect(pBuildView, &rgBuildView::ProjectFileCountChanged, this, &rgMainWindow::HandleProjectFileCountChanged); - assert(isConnected); - - // Connect the project loaded signal. - isConnected = connect(pBuildView, &rgBuildView::ProjectLoaded, this, &rgMainWindow::HandleProjectLoaded); - assert(isConnected); - - // Connect the current file modified signal. - isConnected = connect(pBuildView, &rgBuildView::CurrentFileModified, this, &rgMainWindow::HandleCurrentFileModifiedOutsideEnv); - assert(isConnected); - - // Connect the project build success signal. - isConnected = connect(pBuildView, &rgBuildView::ProjectBuildSuccess, this, &rgMainWindow::HandleProjectBuildSuccess); - assert(isConnected); - - // Connect the project build started signal. - isConnected = connect(pBuildView, &rgBuildView::ProjectBuildStarted, this, &rgMainWindow::HandleProjectBuildStarted); - assert(isConnected); - - // Connect the update application notification message signal. - isConnected = connect(pBuildView, &rgBuildView::UpdateApplicationNotificationMessageSignal, this, &rgMainWindow::HandleUpdateAppNotificationMessage); - assert(isConnected); - - // Connect the project build failure signal. - isConnected = connect(pBuildView, &rgBuildView::ProjectBuildFailure, this, &rgMainWindow::HandleProjectBuildFailure); - assert(isConnected); - - // Connect the project build canceled signal. - isConnected = connect(pBuildView, &rgBuildView::ProjectBuildCanceled, this, &rgMainWindow::HandleProjectBuildCanceled); - assert(isConnected); - - // Connect the rgBuildView's status bar update signal. - isConnected = connect(pBuildView, &rgBuildView::SetStatusBarText, this, &rgMainWindow::HandleStatusBarTextChanged); - assert(isConnected); - - // Connect the main window's Find event with the rgBuildView. - isConnected = connect(this, &rgMainWindow::FindTriggered, pBuildView, &rgBuildView::HandleFindTriggered); - assert(isConnected); - - // Connect the rgMainWindow to the rgBuildView to update the "project is building" flag. - isConnected = connect(this, &rgMainWindow::IsBuildInProgress, pBuildView, &rgBuildView::HandleIsBuildInProgressChanged); - assert(isConnected); - - // Connect the edit mode changed signal. - isConnected = connect(pBuildView, &rgBuildView::EditModeChanged, this, &rgMainWindow::HandleEditModeChanged); - assert(isConnected); - - // Connect the app state to the rgBuildView. - m_pAppState->ConnectBuildViewSignals(pBuildView); - } - } -} - -void rgMainWindow::ConnectMenuSignals() -{ - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - // Get the API-specific rgBuildView instance used by the current mode. - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - - // Verify that the build view exists before using it. - assert(pBuildView != nullptr); - if (pBuildView != nullptr) - { - rgMenu* pMenu = pBuildView->GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - // Connect the file menu with the build start event. - bool isConnected = connect(pBuildView, &rgBuildView::ProjectBuildStarted, pMenu, &rgMenu::HandleBuildStarted); - assert(isConnected); - - // Connect the file menu with the build failure event. - isConnected = connect(pBuildView, &rgBuildView::ProjectBuildFailure, pMenu, &rgMenu::HandleBuildEnded); - assert(isConnected); - - // Connect the file menu with the build success event. - isConnected = connect(pBuildView, &rgBuildView::ProjectBuildSuccess, pMenu, &rgMenu::HandleBuildEnded); - assert(isConnected); - - // Connect the file menu with the build canceled event. - isConnected = connect(pBuildView, &rgBuildView::ProjectBuildCanceled, pMenu, &rgMenu::HandleBuildEnded); - assert(isConnected); - - // Connect the source file change event with the handler. - isConnected = connect(pMenu, &rgMenu::SelectedFileChanged, this, &rgMainWindow::HandleSelectedFileChanged); - assert(isConnected); - - // Connect the file menu's "Build Settings" button to the main window's handler. - isConnected = connect(pMenu, &rgMenu::BuildSettingsButtonClicked, this, &rgMainWindow::HandleBuildSettingsEvent); - assert(isConnected); - } - } - } -} - -void rgMainWindow::CreateFileMenuActions() -{ - // Open a project. - m_pOpenProjectAction = new QAction(tr(STR_MENU_BAR_OPEN_PROJECT), this); - m_pOpenProjectAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_OPEN_PROJECT)); - m_pOpenProjectAction->setStatusTip(tr(STR_MENU_BAR_OPEN_PROJECT_TOOLTIP)); - bool isConnected = connect(m_pOpenProjectAction, &QAction::triggered, this, &rgMainWindow::HandleOpenProjectFileEvent); - assert(isConnected); - - // Save a file. - m_pSaveAction = new QAction(tr(STR_MENU_BAR_SAVE_FILE), this); - m_pSaveAction->setShortcuts(QKeySequence::Save); - m_pSaveAction->setStatusTip(tr(STR_MENU_BAR_SAVE_FILE_TOOLTIP)); - isConnected = connect(m_pSaveAction, &QAction::triggered, this, &rgMainWindow::HandleSaveFileEvent); - assert(isConnected); - - // Back to home. - m_pBackToHomeAction = new QAction(tr(STR_MENU_BAR_BACK_TO_HOME), this); - m_pBackToHomeAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_BACK_TO_HOME)); - m_pBackToHomeAction->setStatusTip(tr(STR_MENU_BAR_BACK_TO_HOME_TOOLTIP)); - isConnected = connect(m_pBackToHomeAction, &QAction::triggered, this, &rgMainWindow::HandleBackToHomeEvent); - assert(isConnected); - - // Exit the project. - m_pExitAction = new QAction(tr(STR_MENU_BAR_EXIT), this); - m_pExitAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_EXIT)); - m_pExitAction->setStatusTip(tr(STR_MENU_BAR_EXIT_TOOLTIP)); - isConnected = connect(m_pExitAction, &QAction::triggered, this, &rgMainWindow::HandleExitEvent); - assert(isConnected); - - // Start with some actions disabled. - m_pSaveAction->setDisabled(true); -} - -void rgMainWindow::CreateAppState(rgProjectAPI api) -{ - // Create a factory matching the new API mode to switch to. - std::shared_ptr pFactory = rgFactory::CreateFactory(api); - assert(pFactory != nullptr); - if (pFactory != nullptr) - { - std::shared_ptr pApplicationState = pFactory->CreateAppState(); - assert(pApplicationState != nullptr); - if (pApplicationState != nullptr) - { - pApplicationState->SetMainWindow(this); - - // Replace the app state with the one for the new mode. - m_pAppState = pApplicationState; - - // Reset the rgBuildView instance used to interact with the project. - m_pAppState->ResetBuildView(); - - // Connect signals for the Build View. - ConnectBuildViewSignals(); - - // Set main window stylesheet. - ApplyMainWindowStylesheet(); - - // Use the factory for the new API mode. - m_pFactory = pFactory; - } - } -} - -void rgMainWindow::ChangeApiMode(rgProjectAPI api) -{ - if (m_pAppState != nullptr) - { - // Clean up the existing mode before switching to the new one. - m_pAppState->Cleanup(m_pMenuBar); - } - - // Update the current API value in config manager. - rgConfigManager& configManager = rgConfigManager::Instance(); - configManager.SetCurrentAPI(api); - - // Create the new app state. - CreateAppState(api); - - // Create the start tab for the new mode. - CreateStartTab(); - - // Create the settings tab for the new mode. - CreateSettingsTab(); - - // Create the custom status bar for the new mode. - CreateCustomStatusBar(); - - // Update the window title to reflect the current API mode. - ResetWindowTitle(); - - // Set application stylesheet. - SetApplicationStylesheet(); - - // Create the menu bar. - CreateMenuBar(); - - // Reset the state of the action to the default state. - ResetActionsState(); - - // Connect the signals. - ConnectSignals(); - - // Create the custom status bar. - CreateCustomStatusBar(); - - // Switch the main window view to the home page. - SwitchToView(MainWindowView::Home); - - // Set focus to the main tab widget so keyboard shortcuts still work. - ui.mainTabWidget->setFocus(); -} - -void rgMainWindow::DestroyFileMenu() -{ - RG_SAFE_DELETE(m_pMenuBar); -} - -void rgMainWindow::CreateMenuBar() -{ - // Clear the existing menu bar and recreate it for the new mode. - menuBar()->clear(); - - // Create the file menu. - CreateFileMenu(); - - // Create the Edit menu. - CreateEditMenu(); - - // Create the Build menu. - CreateBuildMenu(); - - // Create the help menu. - CreateHelpMenu(); -} - -void rgMainWindow::CreateFileMenu() -{ - // Add the File menu to the main window's menu bar. - m_pMenuBar = menuBar()->addMenu(tr(STR_MENU_BAR_FILE)); - - // Add file actions based on the current mode. - m_pAppState->CreateFileActions(m_pMenuBar); - - // Create the actions to be used by the menus. - CreateFileMenuActions(); - m_pMenuBar->addAction(m_pOpenProjectAction); - m_pMenuBar->addAction(m_pSaveAction); - m_pMenuBar->addSeparator(); - m_pMenuBar->addAction(m_pBackToHomeAction); - m_pMenuBar->addSeparator(); - m_pMenuBar->addAction(m_pExitAction); - - // Set the mouse cursor to pointing hand cursor. - m_pMenuBar->setCursor(Qt::PointingHandCursor); - -#ifdef __linux - // Workaround for broken shortcuts on linux - adding the actions to the main window as - // well as the menu bar seems to fix the issue. - // @TODO Remove this if/when we update to a version of Qt without the bug. - addAction(m_pOpenProjectAction); - addAction(m_pSaveAction); - addAction(m_pBackToHomeAction); - addAction(m_pExitAction); -#endif // __linux -} - -void rgMainWindow::CreateEditMenu() -{ - // Create the actions to be used by the menus. - CreateEditMenuActions(); - - m_pMenuBar = menuBar()->addMenu(tr(STR_MENU_BAR_EDIT)); - m_pMenuBar->addAction(m_pGoToLineAction); - m_pMenuBar->addAction(m_pFindAction); - - // Set the mouse cursor to pointing hand cursor. - m_pMenuBar->setCursor(Qt::PointingHandCursor); - -#ifdef __linux - // Workaround for broken shortcuts on linux - adding the actions to the main window as - // well as the menu bar seems to fix the issue. - // @TODO Remove this if/when we update to a version of Qt without the bug. - addAction(m_pGoToLineAction); -#endif // __linux -} - -void rgMainWindow::CreateHelpMenu() -{ - CreateHelpMenuActions(); - - m_pMenuBar = menuBar()->addMenu(tr(STR_MENU_BAR_HELP)); - - // About. - m_pMenuBar->addAction(m_pHelpAboutAction); - - // Help manual. - m_pMenuBar->addAction(m_pHelpManualAction); - - // Getting started guide. - m_pMenuBar->addAction(m_pHelpGettingStartedGuideAction); - - // Set the mouse cursor to pointing hand cursor. - m_pMenuBar->setCursor(Qt::PointingHandCursor); -} - -void rgMainWindow::CreateHelpMenuActions() -{ - // Create and connect the About action. - m_pHelpAboutAction = new QAction(tr(STR_MENU_BAR_HELP_ABOUT), this); - m_pHelpAboutAction->setStatusTip(tr(STR_MENU_BAR_HELP_ABOUT_TOOLTIP)); - m_pHelpAboutAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_ABOUT)); - bool isConnected = connect(m_pHelpAboutAction, &QAction::triggered, this, &rgMainWindow::HandleAboutEvent); - assert(isConnected); - - // Create and connect the help manual guide action. - m_pHelpManualAction = new QAction(tr(STR_MENU_BAR_HELP_MANUAL), this); - m_pHelpManualAction->setStatusTip(tr(STR_MENU_BAR_HELP_MANUAL_TOOLTIP)); - m_pHelpManualAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_HELP_MANUAL)); - isConnected = connect(m_pHelpManualAction, &QAction::triggered, this, &rgMainWindow::HandleHelpManual); - assert(isConnected); - - // Create and connect the getting started guide action. - m_pHelpGettingStartedGuideAction = new QAction(tr(STR_MENU_BAR_HELP_GETTING_STARTED_GUIDE), this); - m_pHelpGettingStartedGuideAction->setStatusTip(tr(STR_MENU_BAR_HELP_GETTING_STARTED_GUIDE_TOOLTIP)); - isConnected = connect(m_pHelpGettingStartedGuideAction, &QAction::triggered, this, &rgMainWindow::HandleGettingStartedGuideEvent); - assert(isConnected); -} - -void rgMainWindow::CreateBuildMenuActions() -{ - // Build current project action. - m_pBuildProjectAction = new QAction(tr(STR_MENU_BAR_BUILD_PROJECT), this); - m_pBuildProjectAction->setStatusTip(tr(STR_MENU_BAR_BUILD_PROJECT_TOOLTIP)); - m_pBuildProjectAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_BUILD_PROJECT)); - bool isConnected = connect(m_pBuildProjectAction, &QAction::triggered, this, &rgMainWindow::HandleBuildProjectEvent); - assert(isConnected); - - // Open the project's build settings. - m_pBuildSettingsAction = new QAction(tr(STR_MENU_BUILD_SETTINGS), this); - m_pBuildSettingsAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_BUILD_SETTINGS)); - m_pBuildSettingsAction->setStatusTip(tr(STR_MENU_BAR_BUILD_SETTINGS_TOOLTIP)); - isConnected = connect(m_pBuildSettingsAction, SIGNAL(triggered()), this, SLOT(HandleBuildSettingsEvent())); - assert(isConnected); - - // Open the project's pipeline state editor. - m_pPipelineStateAction = new QAction(tr(STR_MENU_PIPELINE_STATE_EDITOR), this); - m_pPipelineStateAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_PIPELINE_STATE)); - m_pPipelineStateAction->setStatusTip(tr(STR_MENU_BAR_PIPELINE_STATE_TOOLTIP)); - isConnected = connect(m_pPipelineStateAction, SIGNAL(triggered()), this, SLOT(HandlePipelineStateEvent())); - assert(isConnected); - - // Cancel the current build. - m_pCancelBuildAction = new QAction(tr(STR_MENU_CANCEL_BUILD), this); - m_pCancelBuildAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_BUILD_CANCEL)); - m_pCancelBuildAction->setStatusTip(tr(STR_MENU_BAR_BUILD_CANCEL_TOOLTIP)); - isConnected = connect(m_pCancelBuildAction, SIGNAL(triggered()), this, SLOT(HandleCancelBuildEvent())); - assert(isConnected); -} - -void rgMainWindow::CreateBuildMenu() -{ - CreateBuildMenuActions(); - - m_pMenuBar = menuBar()->addMenu(tr(STR_MENU_BAR_BUILD)); - m_pMenuBar->addAction(m_pBuildProjectAction); - assert(m_pAppState != nullptr); - // For graphics APIs, add the pipeline state action. - if (m_pAppState != nullptr && m_pAppState->IsGraphics()) - { - m_pMenuBar->addAction(m_pPipelineStateAction); - } - m_pMenuBar->addAction(m_pBuildSettingsAction); - m_pMenuBar->addAction(m_pCancelBuildAction); - - // Set the mouse cursor to pointing hand cursor. - m_pMenuBar->setCursor(Qt::PointingHandCursor); -} - -void rgMainWindow::DestroyBuildView() -{ - // Before destroying the rgBuildView, switch the save mode so that save shortcut signals. - // Signals will get forwarded to the rgMainWindow instead of the (dead) rgBuildView. - SwitchSaveShortcut(SaveActionType::SaveFile); - - // Reset the actions state to default. - ResetActionsState(); - - // Remove the rgBuildView instance from the MainWindow layout. - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - // Remove the rgBuildView instance widget from the MainWindow. - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - ui.buildPage->layout()->removeWidget(pBuildView); - - // Reset the app state's rgBuildView instance so that it can be used for a new project. - m_pAppState->ResetBuildView(); - - // Connect signals for the new rgBuildView instance. - ConnectBuildViewSignals(); - - // Remove the app notification label. - this->statusBar()->removeWidget(m_pAppNotificationWidget); - } -} - -void rgMainWindow::EnableBuildMenu(bool isEnabled) -{ - // Toggle the actions associated with the build menu items. - m_pBuildProjectAction->setEnabled(isEnabled); - - // Make sure that the Build and Cancel options are never both enabled. - if (isEnabled) - { - m_pCancelBuildAction->setEnabled(false); - } -} - -void rgMainWindow::CreateEditMenuActions() -{ - // Build current project action. - m_pGoToLineAction = new QAction(tr(STR_MENU_BAR_GO_TO_LINE), this); - m_pGoToLineAction->setStatusTip(tr(STR_MENU_BAR_GO_TO_LINE_TOOLTIP)); - m_pGoToLineAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_GO_TO_LINE)); - bool isConnected = connect(m_pGoToLineAction, &QAction::triggered, this, &rgMainWindow::HandleGoToLineEvent); - assert(isConnected); - - // Find a string in the source editor. - m_pFindAction = new QAction(tr(STR_MENU_BAR_EDIT_QUICK_FIND), this); - m_pFindAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_FIND)); - m_pFindAction->setStatusTip(tr(STR_MENU_BAR_EDIT_QUICK_FIND_TOOLTIP)); - isConnected = connect(m_pFindAction, &QAction::triggered, this, &rgMainWindow::FindTriggered); - assert(isConnected); -} - -void rgMainWindow::EnableEditMenu(bool isEnabled) -{ - // Toggle the actions associated with the Edit menu items. - m_pGoToLineAction->setEnabled(isEnabled); - m_pFindAction->setEnabled(isEnabled); -} - -bool rgMainWindow::OpenProjectFileAtPath(const std::string& projectFilePath) -{ - bool isProjectLoaded = false; - - assert(!projectFilePath.empty()); - if (!projectFilePath.empty()) - { - // 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 pProject = nullptr; - isProjectLoaded = rgXmlConfigFile::ReadProjectConfigFile(projectFilePath, pProject); - - assert(isProjectLoaded); - assert(pProject != nullptr); - if (isProjectLoaded && pProject != nullptr) - { - // Change the API mode if the project API doesn't match the current mode. - rgProjectAPI currentApi = rgConfigManager::Instance().GetCurrentAPI(); - if (pProject->m_api != currentApi) - { - ChangeApiMode(pProject->m_api); - } - } - - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - if (pBuildView != nullptr) - { - // Attempt to load the user's selected project. - isProjectLoaded = pBuildView->LoadProjectFile(projectFilePath); - assert(isProjectLoaded); - - // If the project was loaded correctly, create and populate the rgBuildView with the source files. - if (isProjectLoaded) - { - // Insert the current mode's rgBuildView instance to the main window. - AddBuildView(); - - // Populate the rgBuildView with the loaded project. - bool isPopulated = pBuildView->PopulateBuildView(); - if (isPopulated) - { - // Show the build view as the central widget. - SwitchToView(MainWindowView::BuildView); - - // Get the directory where the project file lives. - std::string projectDirectory; - bool isOk = rgUtils::ExtractFileDirectory(projectFilePath, projectDirectory); - assert(isOk); - if (isOk) - { - // Try to load existing build output within the project directory. - bool isBuildOutputLoaded = pBuildView->LoadBuildOutput(projectDirectory); - if (isBuildOutputLoaded) - { - // Previous build outputs were loaded correctly. - // Emit the signal indicating a build has succeeded, which will re-populate the view. - pBuildView->HandleProjectBuildSuccess(); - - // Restore the rgBuildView to the last-used layout dimensions. - pBuildView->RestoreViewLayout(); - } - } - } - else - { - // The project wasn't loaded properly. Return to the home page. - HandleBackToHomeEvent(); - isProjectLoaded = false; - } - } - } - } - } - - return isProjectLoaded; -} - -void rgMainWindow::SetWindowTitle(const std::string& titleText) -{ - // Add the application name to the title text. - std::stringstream windowTitle; - windowTitle << STR_APP_NAME << " - "; - - // Determine which API is being used. - std::string apiName; - rgProjectAPI projectAPI = rgConfigManager::Instance().GetCurrentAPI(); - bool isOk = rgUtils::ProjectAPIToString(projectAPI, apiName); - assert(isOk); - if (isOk) - { - // Add the current API name to the title text. - windowTitle << apiName << " "; - windowTitle << STR_TITLE_PROJECT << " - "; - } - - // Finally append the incoming string to the title text. - windowTitle << titleText; - this->setWindowTitle(windowTitle.str().c_str()); -} - -void rgMainWindow::ResetWindowTitle() -{ - // Create the default title with the application name. - std::stringstream windowTitle; - windowTitle << STR_APP_NAME; - - // Determine which API is being used. - std::string apiName; - rgProjectAPI projectAPI = rgConfigManager::Instance().GetCurrentAPI(); - bool isOk = rgUtils::ProjectAPIToString(projectAPI, apiName); - assert(isOk); - if (isOk) - { - // Add the current API name to the title text. - windowTitle << " - "; - windowTitle << apiName << " "; - } - - // Add the application name to the title text. - this->setWindowTitle(windowTitle.str().c_str()); -} - -void rgMainWindow::HandleHasSettingsPendingStateChanged(bool hasPendingChanges) -{ - // Update the File->Save enabled state. - OnCurrentEditorModificationStateChanged(hasPendingChanges); -} - -void rgMainWindow::HandleProjectFileCountChanged(bool isProjectEmpty) -{ - // Toggle the actions associated with the build menu items. - m_pBuildProjectAction->setEnabled(!isProjectEmpty); - - // Make sure that the Build and Cancel options are never both enabled. - if (!isProjectEmpty) - { - m_pCancelBuildAction->setEnabled(false); - } - - // In this specific case, make sure that the build settings and, if applicable, - // the pipeline state items are enabled, since we are in a project (and not in the home page). - m_pBuildSettingsAction->setEnabled(true); - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr && m_pAppState->IsGraphics() && - m_pPipelineStateAction != nullptr) - { - m_pPipelineStateAction->setEnabled(true); - } - - // Toggle the availability of the Edit menu. - EnableEditMenu(!isProjectEmpty); -} - -void rgMainWindow::SwitchToView(MainWindowView tab) -{ - QWidget* pWidget = nullptr; - switch (tab) - { - case MainWindowView::Home: - pWidget = ui.homePage; - - // Show the custom status bar so the mode and the API buttons show while on home page. - assert(m_pStatusBar != nullptr); - if (m_pStatusBar != nullptr) - { - m_pStatusBar->SetStatusBarVisibility(true); - rgUtils::SetToolAndStatusTip("", this); - } - - // Update the current view. - m_currentView = tab; - - break; - case MainWindowView::BuildView: - pWidget = ui.buildPage; - - // Hide the custom status bar so the mode and the API buttons do not show while in build view. - assert(m_pStatusBar != nullptr); - if (m_pStatusBar != nullptr) - { - m_pStatusBar->SetStatusBarVisibility(false); - } - - // Set initial focus to file menu. - if (m_pAppState != nullptr) - { - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - if (pBuildView != nullptr) - { - pBuildView->FocusOnFileMenu(); - } - } - - // Update the current view. - m_currentView = tab; - - break; - default: - assert(false); - } - - if (pWidget != nullptr) - { - ui.stackedWidget->setCurrentWidget(pWidget); - - // Enable/disable back to home menu item. - bool isBackToHomeEnabled = (pWidget != ui.homePage); - m_pBackToHomeAction->setEnabled(isBackToHomeEnabled); - } -} - -void rgMainWindow::HandleOpenProjectFileEvent() -{ - // Ask user to save pending settings. - bool didUserConfirm = true; - - if (!IsInputFileNameBlank()) - { - - assert(m_pSettingsTab != nullptr); - if (m_pSettingsTab != nullptr) - { - didUserConfirm = m_pSettingsTab->PromptToSavePendingChanges(); - } - - if (didUserConfirm) - { - if (m_pAppState != nullptr) - { - didUserConfirm = m_pAppState->ShowProjectSaveDialog(); - } - - if (didUserConfirm) - { - std::string selectedFile; - bool isOk = rgUtils::OpenProjectDialog(this, selectedFile); - if (isOk && !selectedFile.empty()) - { - // Destroy current BuildView if it has some project open. - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - if (pBuildView != nullptr && pBuildView->HasProject()) - { - // Ask the user if they want to save all unsaved files. - bool isAccepted = pBuildView->RequestRemoveAllFiles(); - - // Destroy the rgBuildView instance since the project is being closed. - DestroyBuildView(); - } - } - - HandleStatusBarTextChanged(STR_MAIN_WINDOW_LOADING_PROJECT, gs_STATUS_BAR_NOTIFICATION_TIMEOUT_MS); - bool isProjectLoaded = OpenProjectFileAtPath(selectedFile); - assert(isProjectLoaded); - if (isProjectLoaded) - { - HandleStatusBarTextChanged(STR_MAIN_WINDOW_PROJECT_LOAD_SUCCESS, gs_STATUS_BAR_NOTIFICATION_TIMEOUT_MS); - } - else - { - HandleStatusBarTextChanged(STR_ERR_CANNOT_LOAD_PROJECT_FILE, gs_STATUS_BAR_NOTIFICATION_TIMEOUT_MS); - } - } - } - } - } -} - -bool rgMainWindow::IsInputFileNameBlank() const -{ - bool result = false; - - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - if (m_pAppState->IsInputFileNameBlank()) - { - result = true; - } - } - - return result; -} - -void rgMainWindow::HandleOpenProjectFileAtPath(const std::string& programFilePath) -{ - // Add a loading message to the status bar. - HandleStatusBarTextChanged(STR_MAIN_WINDOW_LOADING_PROJECT, gs_STATUS_BAR_NOTIFICATION_TIMEOUT_MS); - - bool isOk = OpenProjectFileAtPath(programFilePath); - - assert(isOk); - if (isOk) - { - HandleStatusBarTextChanged(STR_MAIN_WINDOW_PROJECT_LOAD_SUCCESS, gs_STATUS_BAR_NOTIFICATION_TIMEOUT_MS); - } - else - { - HandleStatusBarTextChanged(STR_ERR_CANNOT_LOAD_PROJECT_FILE, gs_STATUS_BAR_NOTIFICATION_TIMEOUT_MS); - } -} - -void rgMainWindow::HandleSaveFileEvent() -{ - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - const int currentIndex = ui.mainTabWidget->currentIndex(); - if (currentIndex == 0) - { - // If the rgBuildView exists, forward the save signal. - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - if (pBuildView != nullptr) - { - // Save the current source file or build settings. - pBuildView->HandleSaveSettingsButtonClicked(); - } - else - { - if (m_pSettingsTab != nullptr) - { - m_pSettingsTab->SavePendingChanges(); - } - } - } - else if (currentIndex == 1) - { - if (m_pSettingsTab != nullptr) - { - if (!IsInputFileNameBlank()) - { - m_pSettingsTab->SavePendingChanges(); - } - } - } - } -} - -void rgMainWindow::HandleBackToHomeEvent() -{ - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - if (pBuildView != nullptr) - { - pBuildView->SaveProjectConfigFile(); - - // Refresh the recent projects list upon returning to the start tab. - rgStartTab* pStartTab = m_pAppState->GetStartTab(); - - assert(pStartTab != nullptr); - if (pStartTab != nullptr) - { - pStartTab->PopulateRecentProjectsList(); - } - - // Ask the user if they want to save all unsaved files. - bool isAccepted = pBuildView->RequestRemoveAllFiles(); - - // Only exit if the dialog was accepted (ie. the user didn't press cancel). - if (isAccepted) - { - // Switch the view back to the home page. - SwitchToView(MainWindowView::Home); - - // Destroy the rgBuildView instance since the project is being closed. - DestroyBuildView(); - - // Reset the window title. - ResetWindowTitle(); - - // Reset the status bar. - this->statusBar()->showMessage(""); - } - } - } -} - -void rgMainWindow::HandleExitEvent() -{ - static const int s_TOP_MARGIN = 8; - bool isSaveSettingsAccepted = true; - - // Prompt the user to save any pending changes on SETTINGS tab. - - if (!IsInputFileNameBlank()) - { - assert(m_pSettingsTab != nullptr); - if (m_pSettingsTab != nullptr) - { - isSaveSettingsAccepted = m_pSettingsTab->PromptToSavePendingChanges(); - } - - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - if (pBuildView != nullptr) - { - // Ask the user if they want to save all unsaved files. - bool isAccepted = pBuildView->ShowSaveDialog(rgBuildView::rgFilesToSave::All, true); - - // Only exit if the dialog was accepted (ie. the user didn't press cancel). - if (isAccepted && isSaveSettingsAccepted) - { - // Save the window geometry. - rgConfigManager::Instance().SetWindowGeometry(pos().x(), pos().y() + statusBar()->height() + s_TOP_MARGIN, size().width(), size().height(), windowState()); - - QApplication::exit(0); - } - } - else - { - // Exit out of the application only if the user did NOT press cancel. - if (isSaveSettingsAccepted) - { - - // Save the window geometry. - rgConfigManager::Instance().SetWindowGeometry(pos().x(), pos().y() + statusBar()->height() + s_TOP_MARGIN, size().width(), size().height(), windowState()); - - QApplication::exit(0); - } - } - } - } -} - -void rgMainWindow::closeEvent(QCloseEvent* pEvent) -{ - // Ignore the close event so we can handle shutdown ourself. - pEvent->ignore(); - - HandleExitEvent(); -} - -void rgMainWindow::dragEnterEvent(QDragEnterEvent* pEvent) -{ - // Do not let the user drag and drop a file onto the "SETTINGS" tab. - if (ui.mainTabWidget->currentIndex() == 1 || m_currentView == MainWindowView::BuildView) - { - pEvent->ignore(); - } - else - { - const QMimeData* pMimeData = pEvent->mimeData(); - - // Make sure the drop data has a list of file urls. - if (pMimeData->hasUrls()) - { - // Check to make sure at least one of the files is valid. - for (QUrl& url : pMimeData->urls()) - { - if (url.isLocalFile()) - { - std::string filePath = url.toLocalFile().toStdString(); - if (rgUtils::IsSourceFileTypeValid(filePath)) - { - // Accept the action, making it so we receive a dropEvent when the items are released. - pEvent->setDropAction(Qt::DropAction::CopyAction); - pEvent->accept(); - } - } - } - } - } -} - -void rgMainWindow::dropEvent(QDropEvent *pEvent) -{ - // Get list of all file urls. - QList fileUrls = pEvent->mimeData()->urls(); - // If there is only one file and it is a project file (.rga), - // call OpenProjectFileAtPath. - if (fileUrls.size() == 1 && fileUrls.at(0).isLocalFile() && fileUrls.at(0).toLocalFile().endsWith(STR_PROJECT_FILE_EXTENSION)) - { - bool isLoadSuccessful = OpenProjectFileAtPath(fileUrls.at(0).toLocalFile().toStdString()); - assert(isLoadSuccessful); - if (isLoadSuccessful) - { - this->statusBar()->showMessage(STR_MAIN_WINDOW_PROJECT_LOAD_SUCCESS); - } - else - { - this->statusBar()->showMessage(STR_ERR_CANNOT_LOAD_PROJECT_FILE); - } - } - else - { - // Convert url list to a string list of local file paths. - QStringList filenameStrings; - for (QUrl& fileUrl : fileUrls) - { - if (fileUrl.isLocalFile()) - { - QString filename = fileUrl.toLocalFile(); - // Filter out all files that aren't valid source files. - if (rgUtils::IsSourceFileTypeValid(filename.toStdString())) - { - filenameStrings.push_back(filename); - } - } - } - // Disable additional drops and open the desired files in the build view. - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - setAcceptDrops(false); - m_pAppState->OpenFilesInBuildView(filenameStrings); - setAcceptDrops(true); - } - } - // Set the focus to main window so the user can use keyboard shortcuts. - setFocus(); -} - -void rgMainWindow::OnCurrentEditorModificationStateChanged(bool isModified) -{ - m_pSaveAction->setEnabled(isModified); - - if (m_pSaveAction->text().compare(STR_MENU_BAR_SAVE_FILE) == 0) - { - // Save the current state of save file shortcut. - m_saveFileActionActive = isModified; - } - else if (m_pSaveAction->text().compare(STR_MENU_BAR_SAVE_SETTINGS) == 0) - { - // Save the current state of save settings shortcut. - m_saveSettingsActionActive = isModified; - } - else - { - // Should not get here. - assert(false); - } -} - -void rgMainWindow::HandleAboutEvent() -{ - rgAboutDialog aboutDialog(this); - - // Display the About dialog. - aboutDialog.exec(); -} - -void rgMainWindow::HandleGettingStartedGuideEvent() -{ - // Build the path to the quickstart guide document. - static const char* QUICKSTART_GUIDE_RELATIVE_PATH = "/docs/help/rga/html/quickstart.html"; - QString quickstartFilePath = "file:///"; - QString appDirPath = qApp->applicationDirPath(); - quickstartFilePath.append(appDirPath); - quickstartFilePath.append(QUICKSTART_GUIDE_RELATIVE_PATH); - QDesktopServices::openUrl(QUrl(quickstartFilePath, QUrl::TolerantMode)); -} - -void rgMainWindow::HandleHelpManual() -{ - // Build the path to the help manual document. - static const char* HELP_MANUAL_RELATIVE_PATH = "/docs/help/rga/html/help_manual.html"; - QString helpManualFilePath = "file:///"; - QString appDirPath = qApp->applicationDirPath(); - helpManualFilePath.append(appDirPath); - helpManualFilePath.append(HELP_MANUAL_RELATIVE_PATH); - QDesktopServices::openUrl(QUrl(helpManualFilePath, QUrl::TolerantMode)); -} - -void rgMainWindow::HandleBuildProjectEvent() -{ - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - // Emit a signal to indicate view change. - emit HotKeyPressedSignal(); - - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - if (pBuildView != nullptr) - { - // Save all source files and settings when a new build is started. - if (pBuildView->SaveCurrentState()) - { - // Now build the project. - pBuildView->BuildCurrentProject(); - } - } - } -} - -void rgMainWindow::HandleBuildSettingsEvent() -{ - // Emit a signal to indicate view change. - emit HotKeyPressedSignal(); - - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - if (pBuildView != nullptr) - { - pBuildView->OpenBuildSettings(); - } - } - - // Disable the find functionality. - m_pFindAction->setEnabled(false); - - // Disable the Go-to-line functionality. - m_pGoToLineAction->setEnabled(false); - - // Switch the file menu save file action to save build settings action. - SwitchSaveShortcut(SaveActionType::SaveSettings); - - // Update the file menu save action visibility. - OnCurrentEditorModificationStateChanged(m_saveSettingsActionActive); - - // Give focus to "Build settings" button and remove focus from others. - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - if (pBuildView != nullptr) - { - rgMenu* pMenu = pBuildView->GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - pMenu->DeselectItems(); - auto pBuildSettingsItem = pMenu->GetBuildSettingsItem(); - assert(pBuildSettingsItem != nullptr); - if (pBuildSettingsItem != nullptr) - { - pBuildSettingsItem->SetCurrent(true); - if (pBuildSettingsItem->GetBuildSettingsButton() != nullptr) - { - pBuildSettingsItem->GetBuildSettingsButton()->setStyleSheet(s_BUTTON_FOCUS_IN_STYLESHEET); - } - } - } - } -} - -void rgMainWindow::HandlePipelineStateEvent() -{ - // Switch to the pipeline state view. - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - std::shared_ptr pGraphicsAppState = - std::static_pointer_cast(m_pAppState); - - assert(pGraphicsAppState != nullptr); - if (pGraphicsAppState != nullptr) - { - pGraphicsAppState->HandlePipelineStateEvent(); - } - } -} - -void rgMainWindow::HandleCancelBuildEvent() -{ - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - if (pBuildView != nullptr) - { - // Ask the build view to cancel the current build. - pBuildView->CancelCurrentBuild(); - } - } -} - -void rgMainWindow::HandleSelectedFileChanged(const std::string& oldFile, const std::string& newFile) -{ - // Enable the find functionality. - m_pFindAction->setEnabled(true); - - // Enable the Go-to-line functionality. - m_pGoToLineAction->setEnabled(true); -} - -void rgMainWindow::HandleProjectCreated() -{ - // Add the rgBuildView instance to the window layout. - AddBuildView(); -} - -void rgMainWindow::HandleProjectLoaded(std::shared_ptr pProject) -{ - assert(pProject != nullptr); - if (pProject != nullptr) - { - // Update the application title with the project's name. - SetWindowTitle(pProject->m_projectName); - assert(pProject->m_clones[0] != nullptr); - - // If there are no files in the project, disable source and build related menu items. - if ((pProject->m_clones[0] != nullptr) && (pProject->IsEmpty())) - { - // Disable the build-related actions, except for the build settings action. - m_pBuildProjectAction->setEnabled(false); - m_pBuildSettingsAction->setEnabled(true); - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr && m_pAppState->IsGraphics() && - m_pPipelineStateAction != nullptr) - { - m_pPipelineStateAction->setEnabled(true); - } - m_pCancelBuildAction->setEnabled(false); - - // Disable the source-file related actions. - EnableEditMenu(false); - } - emit TEST_ProjectLoaded(); - } -} - -void rgMainWindow::HandleCurrentFileModifiedOutsideEnv() -{ - // Notify the user about the file modification through the status bar. - HandleStatusBarTextChanged(STR_STATUS_BAR_FILE_MODIFIED_OUTSIDE_ENV, gs_STATUS_BAR_NOTIFICATION_TIMEOUT_MS); -} - -// Manual handling of focus switching because qt doesn't allow the shortcut to be anything other than "Tab". -void rgMainWindow::HandleFocusNextWidget() -{ - QWidget* pFocusWidget = QApplication::focusWidget(); - - if (pFocusWidget != nullptr) - { - QWidget* pTestWidget = QApplication::focusWidget()->nextInFocusChain(); - - // Step through focus widgets until one is found which accepts focus. - while (pTestWidget != nullptr) - { - // Check that the widget accepts focus and is visible to the current focus widget. - if (pTestWidget->focusPolicy() != Qt::NoFocus && - pTestWidget->isVisibleTo(pFocusWidget)) - { - pFocusWidget = pTestWidget; - break; - } - - // Test next widget. - pTestWidget = pTestWidget->nextInFocusChain(); - } - - // Set focus on the new widget. - pFocusWidget->setFocus(Qt::TabFocusReason); - } -} - -// Manual handling of focus switching because qt doesn't allow the shortcut to be anything other than "Tab". -void rgMainWindow::HandleFocusPrevWidget() -{ - QWidget* pFocusWidget = QApplication::focusWidget(); - - if (pFocusWidget != nullptr) - { - QWidget* pTestWidget = QApplication::focusWidget()->previousInFocusChain(); - - // Step through focus widgets until one is found which accepts focus. - while (pTestWidget != nullptr) - { - // Check that the widget accepts focus and is visible to the current focus widget. - if (pTestWidget->focusPolicy() != Qt::NoFocus && - pTestWidget->isVisibleTo(pFocusWidget)) - { - pFocusWidget = pTestWidget; - break; - } - - // Test previous widget. - pTestWidget = pTestWidget->previousInFocusChain(); - } - - // Set focus on the new widget. - pFocusWidget->setFocus(Qt::TabFocusReason); - } -} - -void rgMainWindow::HandleProjectBuildFailure() -{ - rgUtils::SetStatusTip(STR_STATUS_BAR_BUILD_FAILED, this); - - // Show the build failure message. - this->statusBar()->showMessage(STR_STATUS_BAR_BUILD_FAILED); - - // Reset the view's state. - ResetViewStateAfterBuild(); -} - -void rgMainWindow::HandleProjectBuildCanceled() -{ - rgUtils::SetStatusTip(STR_STATUS_BAR_BUILD_CANCELED, this); - - // Show the build cancellation message. - this->statusBar()->showMessage(STR_STATUS_BAR_BUILD_CANCELED); - - // Reset the view's state. - ResetViewStateAfterBuild(); -} - -void rgMainWindow::ResetViewStateAfterBuild() -{ - // Reset the build-in-progress flag. - emit IsBuildInProgress(false); - - // Use the App State interface to reset the view state. - m_pAppState->ResetViewStateAfterBuild(); - - // Re-enable all menu items, since the build is over. - m_pBuildProjectAction->setEnabled(true); - m_pCancelBuildAction->setEnabled(false); - m_pOpenProjectAction->setEnabled(true); - m_pBackToHomeAction->setEnabled(true); - m_pBuildSettingsAction->setEnabled(true); - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr && m_pAppState->IsGraphics() && - m_pPipelineStateAction != nullptr) - { - m_pPipelineStateAction->setEnabled(true); - } - - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - if (pBuildView != nullptr) - { - rgMenu* pMenu = pBuildView->GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - // Set the focus back to the source view. - rgSourceCodeEditor* pSourceCodeEditor = pBuildView->GetEditorForFilepath(pMenu->GetSelectedFilePath()); - if (pSourceCodeEditor != nullptr && pSourceCodeEditor->isVisible()) - { - pSourceCodeEditor->setFocus(); - } - - // Make sure that none of the buttons are highlighted. - pMenu->SetButtonsNoFocus(); - } - } - } -} - -void rgMainWindow::HandleProjectBuildSuccess() -{ - rgUtils::SetStatusTip(STR_STATUS_BAR_BUILD_SUCCEEDED, this); - - this->statusBar()->showMessage(STR_STATUS_BAR_BUILD_SUCCEEDED); - - // Reset the view's state. - ResetViewStateAfterBuild(); -} - -void rgMainWindow::HandleProjectBuildStarted() -{ - // Mark that a build is now in progress. - emit IsBuildInProgress(true); - - // Update the status bar. - this->statusBar()->removeWidget(m_pAppNotificationWidget); - rgUtils::SetStatusTip(STR_STATUS_BAR_BUILD_STARTED, this); - - // Do not allow another build while a build is already in progress. - m_pBuildProjectAction->setEnabled(false); - m_pCancelBuildAction->setEnabled(true); - - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - m_pAppState->HandleProjectBuildStarted(); - } - - // Do not allow creating a project. - m_pOpenProjectAction->setEnabled(false); - - // Do not allow going back to the home page. - m_pBackToHomeAction->setEnabled(false); - - // Do not allow going to the build settings or pipeline state view. - m_pBuildSettingsAction->setEnabled(false); - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr && m_pAppState->IsGraphics() && - m_pPipelineStateAction != nullptr) - { - m_pPipelineStateAction->setEnabled(false); - } - - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - if (pBuildView != nullptr) - { - // Hide the disassembly view. - pBuildView->ToggleDisassemblyViewVisibility(false); - } - } -} - -void rgMainWindow::HandleUpdateAppNotificationMessage(const std::string& message, const std::string& tooltip) -{ - // First remove the previously added permanent widget. - if (m_pAppNotificationWidget != nullptr) - { - this->statusBar()->removeWidget(m_pAppNotificationWidget); - } - - // Add the new location only if it exists. - if (!message.empty()) - { - // Set the notification message. - CreateAppNotificationMessageLabel(message, tooltip); - - // Insert the notification widget to the status bar. - this->statusBar()->addPermanentWidget(m_pAppNotificationWidget, 0); - - // Show the notification label. - m_pAppNotificationWidget->show(); - - // Start the blinking timer. - const int INITIAL_BLINKING_TIMEOUT_MS = 500; - m_pAppNotificationBlinkingTimer->start(INITIAL_BLINKING_TIMEOUT_MS); - } -} - -void rgMainWindow::HandleAppNotificationMessageTimerFired() -{ - // Static counter to count the number of times that this timer has fired. - static uint32_t count = 0; - if (count++ % 2 == 0) - { - // Even counter: remove notification. - this->statusBar()->removeWidget(m_pAppNotificationWidget); - } - else - { - // Odd count: insert the notification widget to the status bar. - this->statusBar()->addPermanentWidget(m_pAppNotificationWidget, 0); - - // Show the notification label. - m_pAppNotificationWidget->show(); - } - - // Stop condition. - if (count % 8 == 0) - { - // Condition met: stop blinking. - count = 0; - m_pAppNotificationBlinkingTimer->stop(); - } - else - { - // Continue blinking. - const int BLINKING_INTERVAL_MS = 800; - m_pAppNotificationBlinkingTimer->start(BLINKING_INTERVAL_MS); - } -} - -void rgMainWindow::CreateAppNotificationMessageLabel(const std::string& message, const std::string& tooltip) -{ - // Delete the existing widgets. - if (m_pAppNotificationWidget != nullptr) - { - RG_SAFE_DELETE(m_pAppNotificationWidget); - } - - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - // Create a widget to hold the labels. - m_pAppNotificationWidget = new QWidget(); - m_pAppNotificationWidget->setToolTip(QString::fromStdString(tooltip)); - - // Create icon and text labels. - QIcon* pIcon = new QIcon(gs_ICON_RESOURCE_REMOVE_NOTIFICATION); - QPixmap pixmap = pIcon->pixmap(QSize(24, 24)); - QLabel* pIconLabel = new QLabel(m_pAppNotificationWidget); - pIconLabel->setPixmap(pixmap); - QLabel* pTextLabel = new QLabel(QString::fromStdString(message), m_pAppNotificationWidget); - pTextLabel->setStyleSheet("color: white"); - - // Set label sizes. - pTextLabel->setFixedSize(190, 18); - pIconLabel->setFixedSize(24, 18); - - // Add labels to a widget and set layout. - QHBoxLayout* pHLayout = new QHBoxLayout(m_pAppNotificationWidget); - pHLayout->addWidget(pIconLabel); - pHLayout->addWidget(pTextLabel); - pHLayout->setContentsMargins(0, 0, 0, 0); - m_pAppNotificationWidget->setLayout(pHLayout); - m_pAppNotificationWidget->setContentsMargins(0, 0, 25, 0); - } -} - -void rgMainWindow::HandleStatusBarTextChanged(const std::string& statusBarText, int timeoutMs) -{ - this->statusBar()->showMessage(statusBarText.c_str(), timeoutMs); -} - -void rgMainWindow::SetCursor() -{ - // Set the cursor to pointing hand cursor. - menuBar()->setCursor(Qt::PointingHandCursor); -} - -void rgMainWindow::HandleGoToLineEvent() -{ - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - if (pBuildView != nullptr) - { - rgMenu* pMenu = pBuildView->GetMenu(); - assert(pMenu != nullptr); - if (pMenu != nullptr) - { - // Get the max number of lines. - rgSourceCodeEditor* pSourceCodeEditor = pBuildView->GetEditorForFilepath(pMenu->GetSelectedFilePath()); - if (pSourceCodeEditor != nullptr && pSourceCodeEditor->isVisible()) - { - int maxLineNumber = pSourceCodeEditor->document()->lineCount(); - - // Create a modal Go To line dialog. - rgGoToLineDialog* pGoToLineDialog = new rgGoToLineDialog(maxLineNumber, this); - pGoToLineDialog->setModal(true); - pGoToLineDialog->setWindowTitle(STR_GO_TO_LINE_DIALOG_TITLE); - - // Register the dialog with the scaling manager. - ScalingManager::Get().RegisterObject(pGoToLineDialog); - - // Center the dialog on the view (registering with the scaling manager - // shifts it out of the center so we need to manually center it). - rgUtils::CenterOnWidget(pGoToLineDialog, this); - - // Execute the dialog and get the result. - rgGoToLineDialog::rgGoToLineDialogResult result; - result = static_cast(pGoToLineDialog->exec()); - - switch (result) - { - case rgGoToLineDialog::Ok: - { - // Go to the indicated line number. - int lineNumber = pGoToLineDialog->GetLineNumber(); - - // Scroll the editor to the indicated line. - pSourceCodeEditor->ScrollToLine(lineNumber); - - // Set the highlighted line. - QList lineNumbers; - lineNumbers << lineNumber; - pSourceCodeEditor->SetHighlightedLines(lineNumbers); - - // Move the cursor as well. - QTextCursor cursor(pSourceCodeEditor->document()->findBlockByLineNumber(lineNumber - 1)); - pSourceCodeEditor->setTextCursor(cursor); - break; - } - case rgGoToLineDialog::Cancel: - { - // Dialog rejected. - break; - } - default: - { - // Shouldn't get here. - assert(false); - } - } - - // Free the memory. - delete pGoToLineDialog; - } - } - } - } -} - -void rgMainWindow::HandleSaveSettingsButtonClicked() -{ - assert(m_pSettingsTab != nullptr); - if (m_pSettingsTab != nullptr) - { - m_pSettingsTab->SavePendingChanges(); - } -} - -void rgMainWindow::HandleTabBarTabChanged(bool saveChanges) -{ - if (saveChanges) - { - HandleSaveSettingsButtonClicked(); - } - else - { - assert(m_pSettingsTab != nullptr); - if (m_pSettingsTab != nullptr) - { - m_pSettingsTab->RevertPendingChanges(); - } - } -} - -void rgMainWindow::HandleStatusBarMessageChange(const QString& msg) -{ - // If a build is in progress, the status bar should not be empty, - // but rather notify the user about the fact that a build is in progress. - if (msg.isEmpty()) - { - // Use the rgBuildView to check if there's a build in progress. - bool isBuildInProgress = false; - - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - if (pBuildView != nullptr) - { - isBuildInProgress = pBuildView->IsBuildInProgress(); - } - } - - this->statusBar()->showMessage(isBuildInProgress ? STR_STATUS_BAR_BUILD_STARTED : msg); - } -} - -void rgMainWindow::HandleMainTabWidgetTabChanged(int currentIndex) -{ - // If the user selected "Settings" tab, change the Ctrl+S shortcut - // to save the settings. - if (currentIndex == 0) - { - // Switch the save shortcut. - SwitchSaveShortcut(SaveActionType::SaveFile); - - // Update the file menu save action visibility. - OnCurrentEditorModificationStateChanged(m_saveFileActionActive); - } - else if (currentIndex == 1) - { - // Switch the save shortcut. - SwitchSaveShortcut(SaveActionType::SaveSettings); - - // Update the file menu save action visibility. - OnCurrentEditorModificationStateChanged(m_saveSettingsActionActive); - } - - // Hide the API list widget. - m_pStatusBar->SetApiListVisibility(false); -} - -void rgMainWindow::HandleEditModeChanged(EditMode mode) -{ - switch (mode) - { - case (EditMode::SourceCode): - { - // Switch the save shortcut. - SwitchSaveShortcut(SaveActionType::SaveFile); - - break; - } - case (EditMode::BuildSettings): - { - // Switch the save shortcut. - SwitchSaveShortcut(SaveActionType::SaveSettings); - - // Disable the edit menu when viewing the build settings. - EnableEditMenu(false); - - break; - } - case (EditMode::PipelineSettings): - { - // Switch the save shortcut. - SwitchSaveShortcut(SaveActionType::SaveSettings); - - // Enable the find functionality. - m_pFindAction->setEnabled(true); - - // Disable the Go-to-line functionality. - m_pGoToLineAction->setEnabled(false); - - break; - } - default: - // We shouldn't get here. - assert(false); - break; - } -} - -void rgMainWindow::SwitchSaveShortcut(SaveActionType saveActionType) -{ - switch (saveActionType) - { - case (SaveActionType::SaveFile): - { - if (m_pSaveAction != nullptr && m_pSaveAction->text().compare(STR_MENU_BAR_SAVE_SETTINGS) == 0) - { - // Change the action text and tooltip and restore the "enabled" state. - m_pSaveAction->setText(tr(STR_MENU_BAR_SAVE_FILE)); - m_pSaveAction->setStatusTip(tr(STR_MENU_BAR_SAVE_FILE_TOOLTIP)); - m_pSaveAction->setEnabled(m_saveFileActionActive); - } - break; - } - case (SaveActionType::SaveSettings): - { - if (m_pSaveAction != nullptr && m_pSaveAction->text().compare(STR_MENU_BAR_SAVE_FILE) == 0) - { - // Change the action text and tooltip and restore the "enabled" state. - m_pSaveAction->setText(tr(STR_MENU_BAR_SAVE_SETTINGS)); - m_pSaveAction->setStatusTip(tr(STR_MENU_BAR_SAVE_SETTINGS_TOOLTIP)); - m_pSaveAction->setEnabled(m_saveSettingsActionActive); - } - break; - } - default: - // We shouldn't get here. - assert(false); - break; - } -} - -void rgMainWindow::ResetActionsState() -{ - assert(m_pAppState != nullptr); - if ((m_pAppState != nullptr)) - { - // Block build-related and source-file-related actions. - EnableBuildMenu(false); - m_pBuildSettingsAction->setEnabled(false); - if (m_pAppState->IsGraphics() && m_pPipelineStateAction != nullptr) - { - m_pPipelineStateAction->setEnabled(false); - } - m_pCancelBuildAction->setEnabled(false); - EnableEditMenu(false); - } -} - -void rgMainWindow::EnableBuildViewActions() -{ - // Enable the build menu options after the build view has been opened. - rgBuildView* pBuildView = m_pAppState->GetBuildView(); - assert(pBuildView != nullptr); - if (pBuildView != nullptr) - { - bool isProjectEmpty = pBuildView->GetMenu()->IsEmpty(); - EnableBuildMenu(!isProjectEmpty); - m_pBuildSettingsAction->setEnabled(true); - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr && m_pPipelineStateAction != nullptr) - { - m_pPipelineStateAction->setEnabled(true); - } - m_pCancelBuildAction->setEnabled(false); - - // Set container switch size action. - bool isConnected = connect(this, &rgMainWindow::SwitchContainerSize, pBuildView, &rgBuildView::HandleSwitchContainerSize); - assert(isConnected); - } -} - -void rgMainWindow::SetApplicationStylesheet() -{ - // Set application-wide stylesheet. - std::vector stylesheetFileNames; - m_pAppState->GetApplicationStylesheet(stylesheetFileNames); - rgUtils::LoadAndApplyStyle(stylesheetFileNames, qApp); -} - -void rgMainWindow::ApplyMainWindowStylesheet() -{ - // Apply main window stylesheet. - assert(m_pAppState != nullptr); - if (m_pAppState != nullptr) - { - std::vector stylesheetFileNames; - m_pAppState->GetMainWindowStylesheet(stylesheetFileNames); - rgUtils::LoadAndApplyStyle(stylesheetFileNames, this); - } -} - -void rgMainWindow::CreateCustomStatusBar() -{ - assert(m_pFactory != nullptr); - if (m_pFactory != nullptr) - { - // Delete any existing custom status bar first. - if (m_pStatusBar != nullptr) - { - delete m_pStatusBar; - m_pStatusBar = nullptr; - } - - m_pStatusBar = m_pFactory->CreateStatusBar(statusBar(), this); - assert(m_pStatusBar != nullptr); - if (m_pStatusBar != nullptr) - { - // Set status bar dimensions. - QSize size; - size.setHeight(s_CUSTOM_STATUS_BAR_HEIGHT); - size.setWidth(QWIDGETSIZE_MAX); - statusBar()->setFixedSize(size); - m_pStatusBar->setFixedSize(size); - - // Register the status bar with the scaling manager. - ScalingManager& scalingManager = ScalingManager::Get(); - scalingManager.RegisterObject(statusBar()); - scalingManager.RegisterObject(m_pStatusBar); - statusBar()->addWidget(m_pStatusBar); - - // Disable the resize grip. - statusBar()->setSizeGripEnabled(false); - - // Show the custom widget. - m_pStatusBar->show(); - - // Connect the custom status bar's change API mode signal. - bool isConnected = connect(m_pStatusBar, &rgStatusBar::ChangeAPIModeSignal, this, &rgMainWindow::HandleChangeAPIMode); - assert(isConnected); - - // Connect the custom status bar's save pending settings changes signal. - isConnected = connect(m_pStatusBar, &rgStatusBar::SavePendingChanges, this, &rgMainWindow::HandleSavePendingChanges); - assert(isConnected); - } - } -} - -bool rgMainWindow::HandleSavePendingChanges() -{ - bool isNotCancelled = false; - assert(m_pSettingsTab != nullptr); - if (m_pSettingsTab != nullptr) - { - isNotCancelled = m_pSettingsTab->PromptToSavePendingChanges(); - } - - return isNotCancelled; -} - -void rgMainWindow::HandleChangeAPIMode(rgProjectAPI switchToApi) -{ - ChangeApiMode(switchToApi); -} - -bool rgMainWindow::eventFilter(QObject* pObject, QEvent* pEvent) -{ - if (pEvent != nullptr) - { - if (pEvent->type() == QEvent::MouseButtonPress) - { - // Hide the API list widget when the user clicks somewhere else. - m_pStatusBar->SetApiListVisibility(false); - - return true; - } - else if (pEvent->type() == QEvent::KeyPress) - { - QKeyEvent* pKeyEvent = static_cast(pEvent); - const int key = pKeyEvent->key(); - Qt::KeyboardModifiers keyboardModifiers = QApplication::keyboardModifiers(); - if ((pKeyEvent->key() != Qt::Key_Up) && (pKeyEvent->key() != Qt::Key_Down)) - { - // Hide the API list widget when the user presses a key. - m_pStatusBar->SetApiListVisibility(false); - - if ((keyboardModifiers & Qt::ControlModifier) && (pKeyEvent->key() == Qt::Key_R)) - { - emit SwitchContainerSize(); - } - return true; - } - else - { - return false; - } - } - else - { - return QObject::eventFilter(pObject, pEvent); - } - } - else - { - // Continue default processing. - return QObject::eventFilter(pObject, pEvent); - } -} - diff --git a/RadeonGPUAnalyzerGUI/Src/rgMainWindowTabBar.cpp b/RadeonGPUAnalyzerGUI/Src/rgMainWindowTabBar.cpp deleted file mode 100644 index 13df73a..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgMainWindowTabBar.cpp +++ /dev/null @@ -1,280 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include -#include -#include -#include -#include -#include - -// Local. -#include -#include -#include -#include -#include - -// Infra. -#include - -static const int s_TAB_BAR_HEIGHT = 47; -static const int s_TAB_BAR_WIDTH = 100; - -rgMainWindowTabBar::rgMainWindowTabBar(QWidget* pParent) : - QTabBar(pParent), - m_spacerIndex(-1), - m_mouseHoverLastTabIndex(-1), - m_pParent(pParent), - m_pSettingsTab(nullptr) -{ - setMouseTracking(true); - setObjectName("rgMainWindowTabBar"); - - // Install an app-level event filter so that this widget can process - // [Shift+]Ctrl+Tab key press events before other widgets steal them. - // In particular this is needed for the Tab key, since the tab key - // on its own causes focus to step between widgets on other parts of the UI. - qApp->installEventFilter(this); - - // Set the font stylesheet. - setStyleSheet("font: bold 14px;"); -} - -void rgMainWindowTabBar::mouseMoveEvent(QMouseEvent* pEvent) -{ - int tabIndex = QTabBar::tabAt(pEvent->pos()); - - // Only change mouse cursor if the mouse is hovering over a different tab. - if (m_mouseHoverLastTabIndex != tabIndex) - { - if (isTabEnabled(tabIndex)) - { - setCursor(Qt::PointingHandCursor); - } - else - { - setCursor(Qt::ArrowCursor); - } - m_mouseHoverLastTabIndex = tabIndex; - } -} - -void rgMainWindowTabBar::mousePressEvent(QMouseEvent* pEvent) -{ - int tabIndex = QTabBar::tabAt(pEvent->pos()); - - // Check if the user is switching to the "START" tab. - switch (tabIndex) - { - case (TabItem::Start): - { - bool userMadeSelection = true; - - assert(m_pSettingsTab != nullptr); - if (m_pSettingsTab != nullptr) - { - userMadeSelection = m_pSettingsTab->PromptToSavePendingChanges(); - } - - if (userMadeSelection) - { - // User did not cancel the prompt, so let the tab switch occur. - // Pass the event onto the base class. - QTabBar::mousePressEvent(pEvent); - } - break; - } - case (TabItem::Settings): - { - // The user is switching to settings tab, allow it. - QTabBar::mousePressEvent(pEvent); - break; - } - default: - { - // Should not get here. - assert(false); - } - } -} - -bool rgMainWindowTabBar::eventFilter(QObject* pObject, QEvent* pEvent) -{ - bool filtered = false; - - if (pEvent != nullptr) - { - if (pEvent->type() == QEvent::KeyPress) - { - // Only process the events if the SettingsTab is the current tab. - if (currentIndex() == TabItem::Settings) - { - if (m_pSettingsTab != nullptr) - { - QKeyEvent* pKeyEvent = static_cast(pEvent); - if (pKeyEvent != nullptr) - { - // If Ctrl+Shift+Tab or Ctrl+Tab is switching tabs, prompt to save pending - // settings changes first. - // Note: The [Shift] is just a way to choose prev or next direction, but - // we only have two tabs, so they both behave the same way. - const int keyPressed = pKeyEvent->key(); - if ((keyPressed == Qt::Key_Tab || keyPressed == Qt::Key_Backtab) && - (pKeyEvent->modifiers() & Qt::ControlModifier)) - { - // Prompt user to save pending changes. - bool userMadeSelection = m_pSettingsTab->PromptToSavePendingChanges(); - if (userMadeSelection == false) - { - // User cancelled the prompt, so the event should be filtered out. - filtered = true; - } - } - else if ((keyPressed == Qt::Key_Up || keyPressed == Qt::Key_Down) && - (pKeyEvent->modifiers() & Qt::ControlModifier)) - { - m_pSettingsTab->SelectNextListWidgetItem(keyPressed); - filtered = true; - } - } - } - } - } - } - - // Allow base class to filter the event if needed. - if (!filtered) - { - filtered = QTabBar::eventFilter(pObject, pEvent); - } - - return filtered; -} - -void rgMainWindowTabBar::SetTabEnabled(int index, bool enable) -{ - // Force next mouseMoveEvent to set mouse cursor even if mouse is hovering over - // the same tab as the last event call. - m_mouseHoverLastTabIndex = -1; - - QTabBar::setTabEnabled(index, enable); -} - -QSize rgMainWindowTabBar::minimumTabSizeHint(int index) const -{ - if (index == SpacerIndex() || tabText(index).isEmpty()) - { - return QSize(0, QTabBar::tabSizeHint(index).height()); - } - else - { - return QTabBar::minimumTabSizeHint(index); - } -} - -QSize rgMainWindowTabBar::tabSizeHint(int index) const -{ - const int height = s_TAB_BAR_HEIGHT * ScalingManager::Get().GetScaleFactor(); - const int width = s_TAB_BAR_WIDTH * ScalingManager::Get().GetScaleFactor(); - - if (index == SpacerIndex()) - { - return QSize(CalcSpacerWidth(), height); - } - else if (tabText(index).isEmpty()) - { - int width = 0; - QWidget* pWidget = tabButton(index, QTabBar::ButtonPosition::LeftSide); - if (pWidget) - { - width += pWidget->width(); - } - - pWidget = tabButton(index, QTabBar::ButtonPosition::RightSide); - if (pWidget) - { - width += pWidget->width(); - } - return QSize(width, height); - } - else - { - return QSize(width, height); - } -} - -void rgMainWindowTabBar::paintEvent(QPaintEvent* pEvent) -{ - QTabBar::paintEvent(pEvent); - if (count() > 0) - { - QPainter painter; - painter.begin(this); - painter.setPen(tabTextColor(0)); - painter.drawLine(pEvent->rect().topLeft(), pEvent->rect().topRight()); - painter.end(); - } -} - -void rgMainWindowTabBar::SetSpacerIndex(int index) -{ - if (index != -1) - { - setTabEnabled(index, false); - setTabText(index, ""); - } - m_spacerIndex = index; -} - -void rgMainWindowTabBar::SetTabTool(int index, QWidget* pWidget) -{ - setTabText(index, ""); - setTabEnabled(index, false); - setTabButton(index, QTabBar::LeftSide, pWidget); -} - -int rgMainWindowTabBar::SpacerIndex() const -{ - return m_spacerIndex; -} - -int rgMainWindowTabBar::CalcSpacerWidth() const -{ - int spacerWidth = -1; - - if ( (count() == 0) || (m_spacerIndex < 0) ) - { - spacerWidth = 0; - } - else - { - // Figure out the length of the spacer between the last left tab - // and the right tab. - QRect leftTabRect; - int tabMargin = contentsMargins().left(); - if (count() > 1) - { - leftTabRect = tabRect(m_spacerIndex - 1); - tabMargin = ScalingManager::Get().Scaled(4); - } - - int rightTabsWidth = leftTabRect.width() * (count() - (m_spacerIndex + 1)); - spacerWidth = parentWidget()->width() - (leftTabRect.right() + rightTabsWidth); - spacerWidth -= (tabMargin * 2); - } - - return spacerWidth; -} - -void rgMainWindowTabBar::SetParentWidget(QWidget* pParent) -{ - m_pParent = pParent; -} - -void rgMainWindowTabBar::SetSettingsTab(rgSettingsTab* pSettingsTab) -{ - m_pSettingsTab = pSettingsTab; -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgMainWindowTabWidget.cpp b/RadeonGPUAnalyzerGUI/Src/rgMainWindowTabWidget.cpp deleted file mode 100644 index 3ee6028..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgMainWindowTabWidget.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// Qt. -#include - -// Local. -#include - -rgMainWindowTabWidget::rgMainWindowTabWidget(QWidget* pParent) : - QTabWidget(pParent) -{ - m_pTabBar = new rgMainWindowTabBar(); - - m_pTabBar->setParent(this); - - // Replace the rgMainWindowTabWidget's QTabBar with a custom one. - setTabBar(m_pTabBar); - - // Set the focus policy. - setFocusPolicy(Qt::FocusPolicy::NoFocus); -} - -QTabBar* rgMainWindowTabWidget::tabBar() const -{ - return QTabWidget::tabBar(); -} - -rgMainWindowTabBar* rgMainWindowTabWidget::GetTabBar() -{ - return m_pTabBar; -} - -int rgMainWindowTabWidget::TabHeight() const -{ - return tabBar()->sizeHint().height(); -} - -void rgMainWindowTabWidget::resizeEvent(QResizeEvent* pResizeEvent) -{ - if (m_pTabBar != nullptr) - { - m_pTabBar->resize(pResizeEvent->size()); - QTabWidget::resizeEvent(pResizeEvent); - } -} - -void rgMainWindowTabWidget::SetTabEnabled(int index, bool enable) -{ - if (m_pTabBar != nullptr) - { - m_pTabBar->setTabEnabled(index, enable); - } -} - -void rgMainWindowTabWidget::SetSpacerIndex(const int index) -{ - if (m_pTabBar != nullptr) - { - m_pTabBar->SetSpacerIndex(index); - } -} - -void rgMainWindowTabWidget::SetTabTool(int index, QWidget* pToolWidget) -{ - if (m_pTabBar != nullptr) - { - m_pTabBar->SetTabTool(index, pToolWidget); - } -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgMaximizeSplitter.cpp b/RadeonGPUAnalyzerGUI/Src/rgMaximizeSplitter.cpp deleted file mode 100644 index ccaed7c..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgMaximizeSplitter.cpp +++ /dev/null @@ -1,225 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include -#include -#include - -// Infra. -#include - -// Local. -#include -#include -#include - -rgMaximizeSplitter::rgMaximizeSplitter(QWidget* pParent) : - QSplitter(pParent) -{ -} - -void rgMaximizeSplitter::AddMaximizableWidget(rgViewContainer* pViewContainer) -{ - if (pViewContainer != nullptr) - { - ScalingManager& scalingManager = ScalingManager::Get(); - - // Ensure the container is scaling registered. - scalingManager.RegisterObject(pViewContainer); - - // Add the container to the list. - m_maximizeContainers.push_back(pViewContainer); - - // Handle the corner button press on the maximization container. - bool isConnected = connect(pViewContainer, &rgViewContainer::MaximizeButtonClicked, this, &rgMaximizeSplitter::HandleCornerButtonClicked); - assert(isConnected); - - // Add the container to the splitter. - addWidget(pViewContainer); - - pViewContainer->SetMaximizedState(false); - } -} - -QWidget* rgMaximizeSplitter::GetMaximizedWidget() const -{ - return m_pMaximizedWidget; -} - -void rgMaximizeSplitter::MaximizeWidget(QWidget* pWidget) -{ - // Signal the view container to have the maximum width. - emit ViewMaximized(); - - // Give the border focus. - emit FrameInFocusSignal(); - - // If this splitter has a maximization container for the given widget, maximize the container instead. - for (rgViewContainer* pContainer : m_maximizeContainers) - { - assert(pContainer != nullptr); - if (pContainer != nullptr) - { - if (pContainer->GetMainWidget() == pWidget) - { - pWidget = pContainer; - break; - } - } - } - - // Confirm the widget is a child of this splitter. - if (pWidget != nullptr && pWidget->parentWidget() == this) - { - // Ensure the widget is visible. - pWidget->show(); - - // Hide all other widgets in this splitter. - for (QObject* pChild : children()) - { - QWidget* pChildWidget = static_cast(pChild); - - if (pChildWidget != pWidget) - { - pChildWidget->hide(); - } - } - - // Handle cases when this splitter's parent is an rgMaximizeSplitter. - rgMaximizeSplitter* pParentSplitter = qobject_cast(parentWidget()); - if (pParentSplitter != nullptr) - { - // Maximize this splitter within the parent splitter. This will recursively propagate - // through all nested rgMaximizeSplitters. - pParentSplitter->MaximizeWidget(this); - } - - // Remember the maximized widget. - m_pMaximizedWidget = pWidget; - } -} - -void rgMaximizeSplitter::Restore() -{ - // Signal the view container to have minimum required width. - emit ViewRestored(); - - if (m_pMaximizedWidget != nullptr) - { - // Show all widgets in this splitter. - for (QObject* pChild : children()) - { - QWidget* pChildWidget = static_cast(pChild); - pChildWidget->show(); - - // If this widget is an rgViewContainer, - // set the hidden state to false. - rgViewContainer* pViewContainer = qobject_cast(pChildWidget); - if(pViewContainer != nullptr) - { - pViewContainer->SetHiddenState(false); - } - } - - // Handle cases when this splitter's parent is an rgMaximizeSplitter. - rgMaximizeSplitter* pParentSplitter = qobject_cast(parentWidget()); - if (pParentSplitter != nullptr) - { - // Restore the parent splitter. This will recursively propagate through all nested rgMaximizeSplitters. - pParentSplitter->Restore(); - } - - // Clear the maximized widget. - m_pMaximizedWidget = nullptr; - } -} - -void rgMaximizeSplitter::HandleCornerButtonClicked() -{ - // Get rgViewContainer which sent the signal. - rgViewContainer* pContainer = qobject_cast(sender()); - - // This should always be true, no other object type should be connected to this slot. - bool isMaximizeContainer = (pContainer != nullptr); - assert(isMaximizeContainer); - - if (isMaximizeContainer && pContainer->IsMaximizable()) - { - if (m_pMaximizedWidget != pContainer) - { - // Maximize the container. - MaximizeWidget(pContainer); - - pContainer->SetMaximizedState(true); - pContainer->SetHiddenState(false); - - for (auto it = m_maximizeContainers.begin(); it != m_maximizeContainers.end(); it++) - { - rgViewContainer* pItem = *it; - if (pItem != pContainer) - { - if (pContainer->objectName().compare(STR_RG_ISA_DISASSEMBLY_VIEW_CONTAINER) == 0) - { - if (pItem->objectName().compare(STR_RG_SOURCE_VIEW_CONTAINER) == 0) - { - pItem->SetHiddenState(true); - break; - } - } - else if (pContainer->objectName().compare(STR_RG_SOURCE_VIEW_CONTAINER) == 0) - { - if (pItem->objectName().compare(STR_RG_ISA_DISASSEMBLY_VIEW_CONTAINER) == 0) - { - pItem->SetHiddenState(true); - break; - } - } - } - } - } - else - { - // Restore to default layout. - Restore(); - - pContainer->SetMaximizedState(false); - } - } -} - -void rgMaximizeSplitter::HandleChildDestroyed(QObject* pChild) -{ - QWidget* pDestroyedWidget = qobject_cast(pChild); - bool isWidget = (pDestroyedWidget != nullptr); - assert(isWidget); - - // This is just a safe guard, it should never be untrue. - if (isWidget) - { - // If the destroyed widget is the maximized one, restore the maximization state. - if (m_pMaximizedWidget == pDestroyedWidget) - { - Restore(); - } - - // Check if the object is an rgViewContainer. - rgViewContainer* pContainer = qobject_cast(pDestroyedWidget); - bool isMaximizeContainer = (pContainer != nullptr); - - // If the object is a container, remove it from the container list. - if (isMaximizeContainer) - { - for (auto it = m_maximizeContainers.begin(); it != m_maximizeContainers.end(); it++) - { - rgViewContainer* pContainer = *it; - if (pContainer == pDestroyedWidget) - { - m_maximizeContainers.erase(it); - break; - } - } - } - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgMenu.cpp b/RadeonGPUAnalyzerGUI/Src/rgMenu.cpp deleted file mode 100644 index ad3c492..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgMenu.cpp +++ /dev/null @@ -1,573 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include -#include -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -rgMenu::rgMenu(QWidget* pParent) : - QFrame(pParent), - m_focusIndex(0), - m_tabFocusIndex(0) -{ - // Initialize the view object. - ui.setupUi(this); - - // Initialize the menu layout, which all file items will be added to. - m_pLayout = ui.fileMenuVerticalLayout; - - // Create file menu actions. - CreateActions(); - - // Install filter to ignore tab input for switching focus. - installEventFilter(&rgHandleTabFocusEventFilter::Get()); -} - -void rgMenu::DeselectItems() -{ - DeselectCurrentFile(); - auto pBuildSettingsItem = GetBuildSettingsItem(); - assert(pBuildSettingsItem != nullptr); - if (pBuildSettingsItem != nullptr) - { - pBuildSettingsItem->SetCurrent(false); - if (pBuildSettingsItem->GetBuildSettingsButton() != nullptr) - { - pBuildSettingsItem->GetBuildSettingsButton()->setStyleSheet(s_BUTTON_FOCUS_OUT_STYLESHEET); - } - } -} - -void rgMenu::CreateActions() -{ - // File menu next item. - m_pNextItemAction = new QAction(this); - m_pNextItemAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_FILE_MENU_NEXT_ITEM)); - m_pNextItemAction->setShortcutContext(Qt::WidgetShortcut); - - addAction(m_pNextItemAction); - bool isConnected = connect(m_pNextItemAction, &QAction::triggered, this, &rgMenu::HandleTabFocusPressed); - assert(isConnected); - - // File menu previous item. - m_pPrevItemAction = new QAction(this); - m_pPrevItemAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_FILE_MENU_PREV_ITEM)); - m_pPrevItemAction->setShortcutContext(Qt::WidgetShortcut); - - addAction(m_pPrevItemAction); - isConnected = connect(m_pPrevItemAction, &QAction::triggered, this, &rgMenu::HandleShiftTabFocusPressed); - assert(isConnected); - - // File menu context menu shortcut. - m_pOpenContextMenuAction = new QAction(this); - m_pOpenContextMenuAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_FILE_MENU_CONTEXT_MENU)); - m_pOpenContextMenuAction->setShortcutContext(Qt::WidgetShortcut); - - addAction(m_pOpenContextMenuAction); - isConnected = connect(m_pOpenContextMenuAction, &QAction::triggered, this, &rgMenu::HandleOpenContextMenuAction); - assert(isConnected); - - // File menu activate item (used to trigger add/create buttons when in focus). - m_pActivateItemAction = new QAction(this); - QList shortcutActions; - shortcutActions.push_back(QKeySequence(gs_ACTION_HOTKEY_FILE_MENU_ACTIVATE_RETURN)); - shortcutActions.push_back(QKeySequence(gs_ACTION_HOTKEY_FILE_MENU_ACTIVATE_ENTER)); - shortcutActions.push_back(QKeySequence(gs_ACTION_HOTKEY_FILE_MENU_ACTIVATE_SPACE)); - m_pActivateItemAction->setShortcuts(shortcutActions); - m_pActivateItemAction->setShortcutContext(Qt::WidgetShortcut); - - addAction(m_pActivateItemAction); - isConnected = connect(m_pActivateItemAction, &QAction::triggered, this, &rgMenu::HandleActivateItemAction); - assert(isConnected); - - // File menu rename selected file. - m_pRenameSelectedFileAction = new QAction(this); - m_pRenameSelectedFileAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_FILE_MENU_RENAME)); - m_pRenameSelectedFileAction->setShortcutContext(Qt::WidgetShortcut); - - addAction(m_pRenameSelectedFileAction); - isConnected = connect(m_pRenameSelectedFileAction, &QAction::triggered, this, &rgMenu::HandleRenameSelectedFileAction); - assert(isConnected); - - // File menu tab key navigation. - m_pTabKeyAction = new QAction(this); - m_pTabKeyAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_FILE_MENU_ACTIVATE_TAB)); - m_pTabKeyAction->setShortcutContext(Qt::WidgetShortcut); - - addAction(m_pTabKeyAction); - isConnected = connect(m_pTabKeyAction, &QAction::triggered, this, &rgMenu::HandleTabFocusPressed); - assert(isConnected); - - // File menu shift+tab key navigation. - m_pShiftTabKeyAction = new QAction(this); - m_pShiftTabKeyAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_FILE_MENU_ACTIVATE_SHIFT_TAB)); - m_pShiftTabKeyAction->setShortcutContext(Qt::WidgetShortcut); - - addAction(m_pShiftTabKeyAction); - isConnected = connect(m_pShiftTabKeyAction, &QAction::triggered, this, &rgMenu::HandleShiftTabFocusPressed); - assert(isConnected); -} - -void rgMenu::ClearFiles() -{ - // Deselect any currently selected file, because it's about to be removed. - DeselectCurrentFile(); - - // Collect a list of keys for each file path with an item in the file menu. - std::vector openFiles; - for (auto currentItem = m_fullFilepathToMenuItem.begin(); currentItem != m_fullFilepathToMenuItem.end(); ++currentItem) - { - openFiles.push_back(currentItem->first); - } - - // Step through each path and remove the item from the file menu. - for (const std::string& currentFilePath : openFiles) - { - RemoveItem(currentFilePath); - } - - // Reset the build settings item to reflect no pending changes. - if (m_pBuildSettingsMenuItem != nullptr) - { - m_pBuildSettingsMenuItem->SetHasPendingChanges(false); - } -} - -rgMenuBuildSettingsItem* rgMenu::GetBuildSettingsItem() const -{ - return m_pBuildSettingsMenuItem; -} - -rgMenuFileItem* rgMenu::GetFileItemFromPath(const std::string& sourceFilePath) const -{ - rgMenuFileItem* pResultItem = nullptr; - - // Step through each file item and find the one that matches the given path. - for (size_t fileItemIndex = 0; fileItemIndex < m_menuItems.size(); fileItemIndex++) - { - if (m_menuItems[fileItemIndex]->GetFilename() == sourceFilePath) - { - pResultItem = m_menuItems[fileItemIndex]; - break; - } - } - - return pResultItem; -} - -rgMenuFileItem* rgMenu::GetSelectedFileItem() const -{ - return m_pSelectedFileItem; -} - -std::string rgMenu::GetSelectedFilePath() const -{ - std::string selectedFilePath; - if (m_pSelectedFileItem != nullptr) - { - selectedFilePath = m_pSelectedFileItem->GetFilename(); - } - return selectedFilePath; -} - -std::vector rgMenu::GetAllFileItems() const -{ - return m_menuItems; -} - -bool rgMenu::IsCurrentlySelectedFileItem(rgMenuFileItem* pFileItem) const -{ - return (pFileItem == m_pSelectedFileItem); -} - -bool rgMenu::IsEmpty() const -{ - return m_fullFilepathToMenuItem.empty(); -} - -bool rgMenu::IsFileInMenu(const std::string& fullPath) const -{ - bool ret = false; - - // Standardize the path of the given full path. - std::string fullPathStandardized = fullPath; - rgUtils::StandardizePathSeparator(fullPathStandardized); - - // Check if the full path already has an item in the menu. - for (const rgMenuFileItem* pItem : m_menuItems) - { - assert(pItem != nullptr); - if (pItem != nullptr) - { - // Retrieve and standardize the file name for this item. - std::string itemFullPath = pItem->GetFilename(); - rgUtils::StandardizePathSeparator(itemFullPath); - - // If the paths match - we found it. - if (itemFullPath.compare(fullPathStandardized) == 0) - { - ret = true; - break; - } - } - } - return ret; -} - -void rgMenu::RemoveItem(const std::string& fullFilename) -{ - if (!fullFilename.empty()) - { - // Remove the item from the map. - auto filepathIter = m_fullFilepathToMenuItem.find(fullFilename); - if (filepathIter != m_fullFilepathToMenuItem.end()) - { - rgMenuFileItem* pMenuItem = filepathIter->second; - - m_fullFilepathToMenuItem.erase(filepathIter); - - // Remove the item from the list. - for (auto it = m_menuItems.begin(); it != m_menuItems.end(); it++) - { - if (*it == pMenuItem) - { - m_menuItems.erase(it); - break; - } - } - - if (m_menuItems.size() == 0) - { - // The file menu is empty. - emit FileMenuItemCountChanged(true); - } - - // Remove the item from the GUI. - m_pLayout->removeWidget(pMenuItem); - - // The widget was removed from the layout, but still exists and will be rendered. - // It is therefore also necessary to hide the widget to make it disappear entirely. - pMenuItem->hide(); - - // Clear the "last selected item" variable if it's the item we are removing. - if (m_pLastSelectedItem == pMenuItem) - { - m_pLastSelectedItem = nullptr; - } - } - } -} - -void rgMenu::DeselectCurrentFile() -{ - // If a file was already selected, deselect it. - if (m_pSelectedFileItem != nullptr) - { - m_pSelectedFileItem->SetHovered(false); - m_pSelectedFileItem->SetCurrent(false); - m_pSelectedFileItem->setCursor(Qt::PointingHandCursor); - m_pSelectedFileItem = nullptr; - } -} - -void rgMenu::SetItemIsSaved(const std::string& fullFilename, bool isSaved) -{ - // Find the item in the map. - auto filepathIter = m_fullFilepathToMenuItem.find(fullFilename); - if (filepathIter != m_fullFilepathToMenuItem.end()) - { - rgMenuFileItem* pMenuItem = filepathIter->second; - bool isItemValid = (pMenuItem != nullptr); - assert(isItemValid); - - if (isItemValid) - { - // Set item saved state. - pMenuItem->SetIsSaved(isSaved); - } - } -} - -void rgMenu::SelectFirstItem() -{ - auto firstItemIter = m_menuItems.cbegin(); - if (firstItemIter != m_menuItems.cend() && *firstItemIter != nullptr) - { - HandleSelectedFileChanged(static_cast(*firstItemIter)); - } -} - -void rgMenu::SelectLastRemainingItem() -{ - auto lastItemIter = m_menuItems.crbegin(); - if (lastItemIter != m_menuItems.crend() && *lastItemIter != nullptr) - { - HandleSelectedFileChanged(static_cast(*lastItemIter)); - } -} - -void rgMenu::SwitchToLastSelectedItem() -{ - if (m_pLastSelectedItem != nullptr) - { - HandleSelectedFileChanged(m_pLastSelectedItem); - } -} - -void rgMenu::HandleBuildStarted() -{ - m_pBuildSettingsMenuItem->setEnabled(false); -} - -void rgMenu::HandleBuildEnded() -{ - m_pBuildSettingsMenuItem->setEnabled(true); -} - -void rgMenu::HandleSwitchToFile(const std::string & filePath, int lineNum) -{ - // Set focus index to newly selected item. - bool found = false; - for (size_t i = 0; i < m_menuItems.size(); i++) - { - if (m_menuItems[i]->GetFilename() == filePath) - { - found = true; - m_focusIndex = i; - m_tabFocusIndex = i; - break; - } - } - - if (found) - { - // Refresh the focus selection so it selects the current focus index. - SelectFocusItem(FileMenuActionType::TabAction); - - // Scroll the source code editor to required line. - emit ScrollCodeEditorToLine(lineNum); - } -} - -void rgMenu::HandleRenamedFile(const std::string& oldFilepath, const std::string& newFilepath) -{ - auto menuItemIter = m_fullFilepathToMenuItem.find(oldFilepath); - bool foundOldFilepath = menuItemIter != m_fullFilepathToMenuItem.end(); - - // If the old path was found, remove it. - assert(foundOldFilepath); - if (foundOldFilepath) - { - rgMenuFileItem* pMenuItem = menuItemIter->second; - - // Erase the existing file path, and make the new path point to the existing menu item. - m_fullFilepathToMenuItem.erase(menuItemIter); - m_fullFilepathToMenuItem[newFilepath] = pMenuItem; - } - - // Signal to the BuildView that a file has been renamed. - emit FileRenamed(oldFilepath, newFilepath); -} - -void rgMenu::SelectFile(rgMenuFileItem* pSelected) -{ - if (pSelected != nullptr) - { - std::string oldFilename; - if (m_pSelectedFileItem != nullptr) - { - m_pSelectedFileItem->SetHovered(false); - oldFilename = m_pSelectedFileItem->GetFilename(); - } - - // Assign the new selection as the currently-selected file item. - m_pSelectedFileItem = pSelected; - m_pLastSelectedItem = pSelected; - - // Set the file item as the new selection, and expand the entry point list. - m_pSelectedFileItem->SetHovered(true); - - // Update the cursor type. - UpdateCursor(m_pSelectedFileItem); - - // Set the file item as the new highlighted item. - UpdateHighlight(pSelected); - - // Set the file item as the current item. - UpdateCurrentItem(pSelected); - - const std::string& newFilename = pSelected->GetFilename(); - StringToFileItemMap::iterator fullFilenameIter = m_fullFilepathToMenuItem.find(newFilename); - if (fullFilenameIter != m_fullFilepathToMenuItem.end()) - { - emit SelectedFileChanged(oldFilename, newFilename); - } - } -} - -void rgMenu::DisplayFileInEditor(rgMenuFileItem* pSelected) -{ - std::string oldFilename; - if (m_pSelectedFileItem != nullptr) - { - m_pSelectedFileItem->SetHovered(false); - oldFilename = m_pSelectedFileItem->GetFilename(); - } - - const std::string& newFilename = pSelected->GetFilename(); - StringToFileItemMap::iterator fullFilenameIter = m_fullFilepathToMenuItem.find(newFilename); - if (fullFilenameIter != m_fullFilepathToMenuItem.end()) - { - // Set the file item as the new highlighted item. - UpdateHighlight(pSelected); - - // Set this item as the current one. - UpdateCurrentItem(pSelected); - - // Update the cursors. - UpdateCursor(pSelected); - - // Assign the new selection as the currently-selected file item. - m_pSelectedFileItem = pSelected; - m_pLastSelectedItem = pSelected; - - emit SelectedFileChanged(oldFilename, newFilename); - } -} - -void rgMenu::HandleNextItemAction() -{ - // Compute the index of the next button to focus on. Take the extra non-file items into account. - int offset = GetButtonCount() - 1; - size_t endIndex = m_menuItems.size() + offset; - - // Increment focus index and wrap around. - m_focusIndex++; - if (m_focusIndex > endIndex) - { - m_focusIndex = 0; - } - - // Update the tab focus index. - m_tabFocusIndex = m_focusIndex; - - // Refresh focus. - SelectFocusItem(FileMenuActionType::ArrowAction); -} - -void rgMenu::HandlePreviousItemAction() -{ - // Compute the index of the next button to focus on. Take the extra non-file items into account. - int offset = GetButtonCount() - 1; - size_t endIndex = m_menuItems.size() + offset; - - // Decrement focus index and wrap around. - if (m_focusIndex != 0) - { - m_focusIndex--; - } - else - { - m_focusIndex = endIndex; - } - - // Update the tab focus index. - m_tabFocusIndex = m_focusIndex; - - // Refresh focus. - SelectFocusItem(FileMenuActionType::ArrowAction); -} - -void rgMenu::HandleOpenContextMenuAction() -{ - if (m_pSelectedFileItem != nullptr) - { - m_pSelectedFileItem->OpenContextMenu(); - } -} - -void rgMenu::HandleRenameSelectedFileAction() -{ - if (m_pSelectedFileItem != nullptr) - { - m_pSelectedFileItem->ShowRenameControls(true); - } -} - -void rgMenu::UpdateCursor(rgMenuFileItem* pCurrentStageItem) -{ - // Reset cursor to pointing hand cursor for all items. - foreach(auto pItem, m_menuItems) - { - pItem->setCursor(Qt::PointingHandCursor); - } - - // Set the cursor to arrow cursor for the selected item. - pCurrentStageItem->setCursor(Qt::ArrowCursor); -} - -void rgMenu::UpdateHighlight(rgMenuFileItem* pSelected) -{ - // Reset the highlight for all items. - foreach(auto pItem, m_menuItems) - { - pItem->SetHovered(false); - } - - pSelected->SetHovered(true); -} - -void rgMenu::mousePressEvent(QMouseEvent* pEvent) -{ - emit FileMenuFocusInEvent(); - - QFrame::mousePressEvent(pEvent); -} - -void rgMenu::UpdateCurrentItem(rgMenuFileItem* pSelected) -{ - for (auto pItem : m_menuItems) - { - pItem->SetCurrent(false); - } - - pSelected->SetCurrent(true); -} - -void rgMenu::ClearFileMenuHighlight() -{ - for (auto pItem : m_menuItems) - { - pItem->SetHovered(false); - } -} - -void rgMenu::ClearFileMenuItemSelection() -{ - // Set the stylesheet for each file menu item to be not selected (grayed out), - // along with the mouse cursor to pointing hand cursor. - for (rgMenuFileItem* pItem : m_menuItems) - { - pItem->SetHovered(false); - pItem->SetCurrent(false); - pItem->setCursor(Qt::PointingHandCursor); - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgMenuBuildSettingsItem.cpp b/RadeonGPUAnalyzerGUI/Src/rgMenuBuildSettingsItem.cpp deleted file mode 100644 index 582e0bb..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgMenuBuildSettingsItem.cpp +++ /dev/null @@ -1,132 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include - -// Local. -#include -#include - -static const char* s_BUTTON_FOCUS_IN_STYLESHEET_GRAPHICS = "QPushButton { background: rgb(253,255,174); border-style: solid; border-width: 2px; border-color: rgb(135, 20, 16);}"; -static const char* s_BUTTON_FOCUS_OUT_STYLESHEET = "QPushButton { margin: 1px; background: rgb(214, 214, 214);}"; -static const char* s_BUILD_SETTINGS_BUTTON_NAME = "buildSettingsButton"; - -rgMenuBuildSettingsItem::rgMenuBuildSettingsItem(rgMenu* pParent) : - rgMenuItem(pParent) -{ - ui.setupUi(this); - - // Set the status bar tip. - this->setStatusTip(STR_MENU_BAR_BUILD_SETTINGS_TOOLTIP); - - // Set the tool tip. - this->setToolTip(STR_MENU_BAR_BUILD_SETTINGS_TOOLTIP); - - // Set the mouse cursor to pointing hand cursor. - SetCursor(Qt::PointingHandCursor); - - // Connect the file menu signals. - ConnectSignals(); - - // Set object name. - setObjectName(s_BUILD_SETTINGS_BUTTON_NAME); -} - -void rgMenuBuildSettingsItem::ConnectSignals() -{ - // Connect the "Build settings" push button clicked signal. - bool isConnected = connect(ui.buildSettingsButton, &QPushButton::clicked, this, &rgMenuBuildSettingsItem::HandleBuildSettingsButton); - assert(isConnected); - - // Connect the "Build settings" button to forward the click externally for the file menu to handle. - isConnected = connect(ui.buildSettingsButton, &QPushButton::clicked, this, &rgMenuBuildSettingsItem::BuildSettingsButtonClicked); - assert(isConnected); -} - -void rgMenuBuildSettingsItem::HandleBuildSettingsButton(bool checked) -{ - Q_UNUSED(checked); - - ui.buildSettingsButton->setCursor(Qt::ArrowCursor); - - SetCurrent(true); -} - -QPushButton* rgMenuBuildSettingsItem::GetBuildSettingsButton() const -{ - return ui.buildSettingsButton; -} - -void rgMenuBuildSettingsItem::SetHasPendingChanges(bool hasPendingChanges) -{ - std::stringstream itemText; - - itemText << STR_MENU_BUILD_SETTINGS; - - if (hasPendingChanges) - { - itemText << STR_UNSAVED_FILE_SUFFIX; - } - - SetItemText(itemText.str().c_str()); -} - -void rgMenuBuildSettingsItem::SetItemText(const std::string& itemText) -{ - ui.buildSettingsButton->setText(itemText.c_str()); -} - -void rgMenuBuildSettingsItem::GotFocus() -{ - // Set arrow cursor so it doesn't appear that the user can click on the button again. - ui.buildSettingsButton->setCursor(Qt::ArrowCursor); - - // Set stylesheet. - ui.buildSettingsButton->setStyleSheet(s_BUTTON_FOCUS_IN_STYLESHEET_GRAPHICS); -} - -void rgMenuBuildSettingsItem::LostFocus() -{ - // Set pointing hand cursor so it looks like the user can click on it. - ui.buildSettingsButton->setCursor(Qt::PointingHandCursor); - - // Set stylesheet. - ui.buildSettingsButton->setStyleSheet(s_BUTTON_FOCUS_OUT_STYLESHEET); -} - -void rgMenuBuildSettingsItem::SetCursor(const QCursor& cursor) -{ - // Set the mouse cursor to the specified type. - ui.buildSettingsButton->setCursor(cursor); -} - -void rgMenuBuildSettingsItem::SetCurrent(bool isCurrent) -{ - m_current = isCurrent; - - if (m_current) - { - GotFocus(); - } - else - { - LostFocus(); - } -} - -bool rgMenuBuildSettingsItem::IsCurrent() const -{ - return m_current; -} - -void rgMenuBuildSettingsItem::ClickMenuItem() const -{ - QPushButton* pBuildSettingsButton = GetBuildSettingsButton(); - assert(pBuildSettingsButton != nullptr); - if (pBuildSettingsButton != nullptr) - { - pBuildSettingsButton->click(); - } -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgMenuEntryPointTree.cpp b/RadeonGPUAnalyzerGUI/Src/rgMenuEntryPointTree.cpp deleted file mode 100644 index 569ddae..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgMenuEntryPointTree.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// C++. -#include - -// Local. -#include -#include - -// Qt. -#include -#include -#include - -rgMenuEntryPointTree::rgMenuEntryPointTree(QWidget* pParent) : - QTreeView(pParent) -{ - setMouseTracking(true); - setCursor(Qt::PointingHandCursor); - - // Initialize the context menu. - InitializeContextMenu(); - - // Connect the signals. - ConnectSignals(); - - // Set context menu policy. - this->setContextMenuPolicy(Qt::CustomContextMenu); -} - -void rgMenuEntryPointTree::mouseMoveEvent(QMouseEvent* pEvent) -{ -} - -void rgMenuEntryPointTree::mousePressEvent(QMouseEvent* pEvent) -{ - assert(pEvent != nullptr); - if (pEvent != nullptr) - { - // Do not highlight the item if the right mouse button is clicked. - if (pEvent->buttons() != Qt::RightButton) - { - QTreeView::mousePressEvent(pEvent); - } - } -} - -void rgMenuEntryPointTree::ConnectSignals() -{ - // Connect the handler responsible for showing the item's context menu. - bool isConnected = connect(this, &QTreeView::customContextMenuRequested, this, &rgMenuEntryPointTree::HandleOpenContextMenu); - assert(isConnected); - - // Connect the item's "Copy" menu item. - isConnected = connect(m_pCopyKernelNameAction, &QAction::triggered, this, &rgMenuEntryPointTree::HandleCopyKernelNameSelection); - assert(isConnected); -} - -void rgMenuEntryPointTree::AdjustTreeSize(QStandardItemModel* pModel) -{ - assert(pModel != nullptr); - if (pModel != nullptr) - { - // Calculate the entry point table view height. - int height = (rowHeight(pModel->index(0, 0))) * pModel->rowCount() + 2; - - // Update the entry point table view height. - setMinimumHeight(height); - setMaximumHeight(height); - } -} - -void rgMenuEntryPointTree::InitializeContextMenu() -{ - // Create the context menu instance. - m_pContextMenu = new QMenu(this); - - // Create the menu items to insert into the context menu. - m_pCopyKernelNameAction = new QAction(STR_FILE_CONTEXT_MENU_COPY_FILE_NAME, this); - m_pContextMenu->addAction(m_pCopyKernelNameAction); -} - -void rgMenuEntryPointTree::HandleOpenContextMenu(const QPoint& widgetClickPosition) -{ - // Get and save the kernel name clicked on. - QModelIndex modelIndex = this->indexAt(widgetClickPosition); - m_kernelName = modelIndex.data().toString(); - - // Convert the widget's local click position to the global screen position. - const QPoint clickPoint = mapToGlobal(widgetClickPosition); - - // Open the context menu at the user's click position. - m_pContextMenu->exec(clickPoint); -} - -void rgMenuEntryPointTree::HandleCopyKernelNameSelection() -{ - // Copy the name of the file to clipboard. - QClipboard* pClipboard = QApplication::clipboard(); - assert(pClipboard != nullptr); - if (pClipboard != nullptr) - { - pClipboard->setText(m_kernelName); - } -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgMenuFileItem.cpp b/RadeonGPUAnalyzerGUI/Src/rgMenuFileItem.cpp deleted file mode 100644 index bbdb97d..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgMenuFileItem.cpp +++ /dev/null @@ -1,308 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include -#include -#include -#include -#include -#include - -// Local. -#include -#include -#include - -rgMenuFileItem::rgMenuFileItem(const std::string& fullFilePath, rgMenu* pParent) - : rgMenuItem(pParent) - , m_fullFilepath(fullFilePath) -{ - // Initialize the context menu for right-clicks on the item. - InitializeContextMenu(); - - // Connect signals to slots. - ConnectSignals(); -} - -void rgMenuFileItem::ConnectSignals() -{ - // Connect a FocusChanged handler so we know when a filename change is completed. - bool isConnected = connect(qApp, &QApplication::focusChanged, this, &rgMenuFileItem::HandleFocusChanged); - assert(isConnected); - - // Connect the item's "Open in file browser" menu item. - isConnected = connect(m_contextMenuActions.pOpenContainingFolder, &QAction::triggered, this, &rgMenuFileItem::HandleOpenInFileBrowserClicked); - assert(isConnected); - - // Connect the item's "Rename" menu item. - isConnected = connect(m_contextMenuActions.pRenameFile, &QAction::triggered, this, &rgMenuFileItem::HandleRenameClicked); - assert(isConnected); - - // Connect the handler responsible for showing the item's context menu. - isConnected = connect(this, &QWidget::customContextMenuRequested, this, &rgMenuFileItem::HandleOpenContextMenu); - assert(isConnected); - - this->setContextMenuPolicy(Qt::CustomContextMenu); -} - -const std::string& rgMenuFileItem::GetFilename() const -{ - return m_fullFilepath; -} - -void rgMenuFileItem::OpenContextMenu() -{ - QPoint centerPoint(width() / 2, height() / 2); - - // Open the context menu on a default centered point. - HandleOpenContextMenu(centerPoint); -} - -void rgMenuFileItem::ShowRenameControls(bool isRenaming) -{ - QLineEdit* pLineEdit = GetRenameLineEdit(); - QLabel* pItemLabel = GetItemLabel(); - - // Disable signals from the file name line edit and the application for now, - // so updating line edit and setting focus to it do not cause another - // signal to fire, causing an infinite loop. - QSignalBlocker signalBlockerLineEdit(pLineEdit); - QSignalBlocker signalBlockerApplication(qApp); - - // Swap the visibility of the filename label and line edit. - if (isRenaming) - { - pItemLabel->setVisible(false); - pLineEdit->setText(m_filename.c_str()); - pLineEdit->setVisible(true); - - std::string filenameOnly; - bool gotFilename = rgUtils::ExtractFileName(m_filename, filenameOnly, false); - assert(gotFilename); - - // Focus on the widget with the filename selected so the user can start typing immediately. - pLineEdit->setFocus(); - pLineEdit->setSelection(0, static_cast(filenameOnly.length())); - - // Set cursor to IBeam cursor. - setCursor(Qt::IBeamCursor); - } - else - { - pItemLabel->setVisible(true); - pLineEdit->setVisible(false); - - // Set cursor to Arrow cursor. - setCursor(Qt::ArrowCursor); - } -} - -void rgMenuFileItem::SetIsSaved(bool isSaved) -{ - // Only refresh if there is a change. - if (m_isSaved != isSaved) - { - m_isSaved = isSaved; - UpdateFilenameLabelText(); - } - else - { - m_isSaved = isSaved; - } -} - -void rgMenuFileItem::UpdateFilepath(const std::string& newFilepath) -{ - m_fullFilepath = newFilepath; - - if (!newFilepath.empty()) - { - // Only display the filename in the interface- not the full path to the file. - bool isOk = rgUtils::ExtractFileName(newFilepath, m_filename); - assert(isOk); - } - else - { - // When the full path to the file is cleared, also clear the filename string. - m_filename.clear(); - } - - // Update the view to display the latest filename. - UpdateFilenameLabelText(); -} - -void rgMenuFileItem::HandleEnterPressed() -{ - // Handle the file name change. - RenameFile(); -} - -void rgMenuFileItem::HandleFocusChanged(QWidget* pOld, QWidget* pNow) -{ - Q_UNUSED(pNow); - - if (pOld != nullptr) - { - // If the control that lost focus was the renaming QLineEdit, finish the item rename. - if (pOld == GetRenameLineEdit()) - { - RenameFile(); - } - } -} - -void rgMenuFileItem::HandleOpenInFileBrowserClicked() -{ - std::string fileDirectory; - bool gotDirectory = rgUtils::ExtractFileDirectory(GetFilename(), fileDirectory); - assert(gotDirectory); - - if (gotDirectory) - { - // Open a system file browser window pointing to the given directory. - rgUtils::OpenFolderInFileBrowser(fileDirectory); - } -} - -void rgMenuFileItem::HandleRenameClicked() -{ - // Show the file item renaming controls. - ShowRenameControls(true); -} - -void rgMenuFileItem::HandleOpenContextMenu(const QPoint& widgetClickPosition) -{ - // Only open the context menu for file items that aren't empty. - if (!m_fullFilepath.empty()) - { - // Convert the widget's local click position to the global screen position. - const QPoint clickPoint = mapToGlobal(widgetClickPosition); - - // Open the context menu at the user's click position. - m_pContextMenu->exec(clickPoint); - } -} - -void rgMenuFileItem::InitializeContextMenu() -{ - // Create the context menu instance. - m_pContextMenu = new QMenu(this); - - // Set the cursor for the context menu. - m_pContextMenu->setCursor(Qt::PointingHandCursor); - - // Create the menu items to insert into the context menu. - m_contextMenuActions.pOpenContainingFolder = new QAction(STR_FILE_CONTEXT_MENU_OPEN_CONTAINING_FOLDER, this); - m_pContextMenu->addAction(m_contextMenuActions.pOpenContainingFolder); - - // Add a separator between the current menu items. - m_pContextMenu->addSeparator(); - - // Create the rename action and add it to the menu. - m_contextMenuActions.pRenameFile = new QAction(STR_FILE_CONTEXT_MENU_RENAME_FILE, this); - m_pContextMenu->addAction(m_contextMenuActions.pRenameFile); - - // Create the remove action and add it to the menu. - m_contextMenuActions.pRemoveFile = new QAction(STR_FILE_CONTEXT_MENU_REMOVE_FILE, this); - m_pContextMenu->addAction(m_contextMenuActions.pRemoveFile); -} - -bool rgMenuFileItem::RenameFile() -{ - bool isFileRenamed = false; - - if (!m_isEscapePressed) - { - QLineEdit* pLineEdit = GetRenameLineEdit(); - - // The new filename is whatever the user left in the renaming QLineEdit. - const std::string newFilename = pLineEdit->text().toStdString(); - - // Only attempt a rename if the user has altered the filename string. - bool filenameChanged = m_filename.compare(newFilename) != 0; - - // If the current filename differs from what the user left in the QLineEdit, update the filename. - if (filenameChanged) - { - // The renamed file will live in the same location as the old one. - std::string fileFolderPath; - bool gotFolder = rgUtils::ExtractFileDirectory(m_fullFilepath, fileFolderPath); - assert(gotFolder); - - // Generate the full path to where the new file lives. - std::string newFilepath; - rgUtils::AppendFileNameToPath(fileFolderPath, newFilename, newFilepath); - - // Disable signals from the file name line edit and the application for now, - // so updating line edit and setting focus to it do not cause another - // signal to fire, causing an infinite loop. - QSignalBlocker signalBlockerLineEdit(pLineEdit); - QSignalBlocker signalBlockerApplication(qApp); - if (rgUtils::IsValidFileName(newFilename)) - { - if (!rgUtils::IsFileExists(newFilepath)) - { - // Rename the file on disk. - rgUtils::RenameFile(m_fullFilepath, newFilepath); - - // Signal to the file menu that the file path has changed. - emit FileRenamed(m_fullFilepath, newFilepath); - - // Update the file path so the item will display the correct filename in the menu. - UpdateFilepath(newFilepath); - - // The file on disk was successfully renamed. - isFileRenamed = true; - } - else - { - // Show an error message stating that the rename failed because a - // file with the same name already exists in the same location. - std::stringstream msg; - msg << STR_ERR_CANNOT_RENAME_FILE_A; - msg << newFilename; - msg << STR_ERR_CANNOT_RENAME_FILE_B_ALREADY_EXISTS; - - rgUtils::ShowErrorMessageBox(msg.str().c_str(), this); - } - } - else - { - std::stringstream msg; - // Show an error message stating that the rename failed because - // the given name is invalid. - if (newFilename.empty()) - { - msg << STR_ERR_CANNOT_RENAME_FILE_BLANK_FILENAME; - } - else - { - msg << STR_ERR_CANNOT_RENAME_FILE_A; - msg << newFilename; - msg << STR_ERR_CANNOT_RENAME_FILE_B_ILLEGAL_FILENAME; - } - - rgUtils::ShowErrorMessageBox(msg.str().c_str(), this); - } - } - - // Re-enable the filename editing controls, since the user gets another chance to attempt a rename. - if (!isFileRenamed && filenameChanged) - { - // Toggle the item back to editing mode, showing the original filename. - ShowRenameControls(true); - } - else - { - // Toggle the item back to being read-only, showing the updated filename. - ShowRenameControls(false); - } - } - else - { - m_isEscapePressed = false; - } - return isFileRenamed; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgMenuFileItemGraphics.cpp b/RadeonGPUAnalyzerGUI/Src/rgMenuFileItemGraphics.cpp deleted file mode 100644 index 10bf2ca..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgMenuFileItemGraphics.cpp +++ /dev/null @@ -1,534 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include -#include -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include - -static const char* s_STR_SUB_BUTTON_NO_FOCUS_STYLESHEET = "rgMenuFileItemGraphics #addFilePushButton:hover\ -{ \ -border-style: solid;\ -border-width: 2px;\ -border-color: rgb(135,20,16)\ -}\ -rgMenuFileItemGraphics #removeButton:hover\ -{\ -border-style: solid;\ -border-width: 2px;\ -border-color: rgb(135,20,16)}"; -static const char* s_STR_SUB_BUTTON_IN_FOCUS_STYLESHEET = "border: 2px inset rgb(135, 20, 16);"; -static const char* s_STR_FILE_MENU_ITEM_NAME_GRAPHICS = "fileMenuItemGraphics"; - -rgMenuFileItemGraphics::rgMenuFileItemGraphics(rgMenu* pParent, rgPipelineStage stage) - : rgMenuFileItem("", pParent) - , m_stage(stage) -{ - ui.setupUi(this); - - // Disable the renaming controls upon creation. - ShowRenameControls(false); - - // Set the mouse cursor to pointing hand cursor. - SetCursor(Qt::PointingHandCursor); - - // Initialize the graphics-specific part of context menu. - InitializeContextMenuGraphics(); - - // Connect the file menu signals. - ConnectSignals(); - - // Show the add/create buttons by default since the stage is empty. - SetButtonsMode(StageButtonsMode::AddCreate); - - // Initialize all strings within the widget. - SetStringConstants(); - - // Enable drops so the graphics file item can handle opening dropped files. - setAcceptDrops(true); - - // Set the cursor for this file item to arrow cursor. - setCursor(Qt::ArrowCursor); - - // Set object name. - setObjectName(s_STR_FILE_MENU_ITEM_NAME_GRAPHICS); -} - -void rgMenuFileItemGraphics::SetCursor(const QCursor& cursor) -{ - // Set the mouse cursor to the specified type. - ui.addFilePushButton->setCursor(cursor); - ui.removeFilePushButton->setCursor(cursor); -} - -// Set the shader file for the stage. -void rgMenuFileItemGraphics::SetShaderFile(const std::string& filename, rgVulkanInputType fileType) -{ - UpdateFilepath(filename); - m_fileType = fileType; - - StageButtonsMode mode = !m_fullFilepath.empty() ? StageButtonsMode::Remove : StageButtonsMode::AddCreate; - - // Display the close button to remove the shader from the stage. - SetButtonsMode(mode); -} - -void rgMenuFileItemGraphics::SetButtonsEnabled(bool isEnabled) -{ - // Set the enabled state of the add/create buttons, and the close button. - ui.addFilePushButton->setEnabled(isEnabled); - ui.removeFilePushButton->setEnabled(isEnabled); -} - -void rgMenuFileItemGraphics::SetButtonsMode(StageButtonsMode buttonMode) -{ - bool isAddCreateVisible = (buttonMode == StageButtonsMode::AddCreate); - - // Set the visibility of the add button. - ui.addFilePushButton->setVisible(isAddCreateVisible); - - // The close button is visible when a source file has been attached to the stage. - ui.removeFilePushButton->setVisible(!isAddCreateVisible); -} - -void rgMenuFileItemGraphics::HandleAddExistingFileButtonClicked() -{ - // Emit a signal to add an existing file, and provide the target stage. - emit AddExistingFileButtonClicked(m_stage); -} - -void rgMenuFileItemGraphics::HandleCreateSourceFileButtonClicked() -{ - // Emit a signal to add an existing file, and provide the target stage. - emit CreateSourceFileButtonClicked(m_stage); -} - -void rgMenuFileItemGraphics::HandleRemoveSourceFileButtonClicked() -{ - // Emit a signal to remove the source file from the stage. - emit RemoveSourceFileButtonClicked(m_stage); -} - -void rgMenuFileItemGraphics::HandleRestoreOriginalSpvClicked() -{ - emit RestoreOriginalSpvButtonClicked(m_stage); -} - -void rgMenuFileItemGraphics::InitializeContextMenuGraphics() -{ - // Create the Restore Original SPIR-V Binary action. - // (Do not add it to the menu here because it's not always present). - m_contextMenuActionsGraphics.pRestoreSpv = new QAction(STR_FILE_CONTEXT_MENU_RESTORE_SPV, this); -} - -void rgMenuFileItemGraphics::ConnectSignals() -{ - // Connect the "Add existing file" push button clicked signal. - bool isConnected = connect(ui.addFilePushButton, &QPushButton::clicked, this, &rgMenuFileItemGraphics::HandleAddExistingFileButtonClicked); - assert(isConnected); - - // Connect the "Remove file" push button clicked signal. - isConnected = connect(ui.removeFilePushButton, &QPushButton::clicked, this, &rgMenuFileItemGraphics::HandleRemoveSourceFileButtonClicked); - assert(isConnected); - - // Connect the item's "Remove" context menu item. - isConnected = connect(m_contextMenuActions.pRemoveFile, &QAction::triggered, this, &rgMenuFileItemGraphics::HandleRemoveSourceFileButtonClicked); - assert(isConnected); - - // Connect the handler responsible for restoring backup (original) spir-v binary file. - isConnected = connect(m_contextMenuActionsGraphics.pRestoreSpv, &QAction::triggered, this, &rgMenuFileItemGraphics::HandleRestoreOriginalSpvClicked); - assert(isConnected); - - // Connect the filename QLineEdit signals, so the user can confirm a rename by pressing Return. - isConnected = connect(ui.filenameLineEdit, &QLineEdit::returnPressed, this, &rgMenuFileItem::HandleEnterPressed); - assert(isConnected); -} - -void rgMenuFileItemGraphics::AddContextMenuActionRestoreSpv() -{ - assert(m_pContextMenu != nullptr); - if (m_pContextMenu != nullptr) - { - m_contextMenuActionsGraphics.pSeparator = m_pContextMenu->addSeparator(); - m_pContextMenu->addAction(m_contextMenuActionsGraphics.pRestoreSpv); - } -} - -void rgMenuFileItemGraphics::RemoveContextMenuActionRestoreSpv() -{ - assert(m_pContextMenu != nullptr); - if (m_pContextMenu != nullptr) - { - m_pContextMenu->removeAction(m_contextMenuActionsGraphics.pSeparator); - m_pContextMenu->removeAction(m_contextMenuActionsGraphics.pRestoreSpv); - } -} - -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 currentApi = rgConfigManager::Instance().GetCurrentAPI(); - std::shared_ptr pGraphicsUtil = rgUtilsGraphics::CreateUtility(currentApi); - - assert(pGraphicsUtil != nullptr); - if (pGraphicsUtil != nullptr) - { - // Update the stage item's label. The label displays the stage type, and the source filename - // for the stage, if one exists. - UpdateFilenameLabelText(); - - // Build the tooltip text for the Add button. - std::stringstream addButtonTooltipText; - addButtonTooltipText << STR_GRAPHICS_MENU_SHADER_STAGE_ADD_BUTTON_TOOLTIP_A; - addButtonTooltipText << pGraphicsUtil->PipelineStageToString(m_stage); - addButtonTooltipText << STR_GRAPHICS_MENU_SHADER_STAGE_ADD_BUTTON_TOOLTIP_B; - - // Set the status bar tip for the add button. - ui.addFilePushButton->setStatusTip(addButtonTooltipText.str().c_str()); - - // Set the tool tip for the add button. - ui.addFilePushButton->setToolTip(addButtonTooltipText.str().c_str()); - - // Build the tooltip text for the Create button. - std::stringstream createButtonTooltipText; - createButtonTooltipText << STR_GRAPHICS_MENU_SHADER_STAGE_CREATE_BUTTON_TOOLTIP_A; - createButtonTooltipText << pGraphicsUtil->PipelineStageToString(m_stage); - createButtonTooltipText << STR_GRAPHICS_MENU_SHADER_STAGE_CREATE_BUTTON_TOOLTIP_B; - - // Build the tooltip text for the Delete button. - std::stringstream removeButtonTooltipText; - removeButtonTooltipText << STR_GRAPHICS_MENU_SHADER_STAGE_CLOSE_BUTTON_TOOLTIP; - - // Set the status bar tip for the Delete button. - ui.removeFilePushButton->setStatusTip(removeButtonTooltipText.str().c_str()); - - // Set the tool tip for the Delete button. - ui.removeFilePushButton->setToolTip(removeButtonTooltipText.str().c_str()); - } -} - -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 currentApi = rgConfigManager::Instance().GetCurrentAPI(); - std::shared_ptr pGraphicsUtil = rgUtilsGraphics::CreateUtility(currentApi); - - assert(pGraphicsUtil != nullptr); - if (pGraphicsUtil != nullptr) - { - std::string stageNameAbbreviation = pGraphicsUtil->PipelineStageToAbbreviation(m_stage); - if (m_fullFilepath.empty()) - { - // Set the name of the stage in the item's label. - ui.stageNameLabel->setText(stageNameAbbreviation.c_str()); - } - else - { - std::string text = m_filename; - std::string displayText; - - // Determine suffix based on whether or not the file is saved. - if (!m_isSaved) - { - text += STR_UNSAVED_FILE_SUFFIX; - } - - // Get available space and subtract 2 for the parentheses around the file name, - // four for the stage name, and 1 for the space after the name. - const int availableSpace = ui.filenameDisplayLayout->contentsRect().width(); - rgUtils::GetDisplayText(text, displayText, availableSpace - 7, ui.stageNameLabel, gs_TEXT_TRUNCATE_LENGTH_BACK_VULKAN); - - // Construct the filename label for the stage. - std::stringstream stageSourceText; - stageSourceText << stageNameAbbreviation; - stageSourceText << " ("; - stageSourceText << displayText; - stageSourceText << ")"; - - // Set the name of the stage in the item's label, and include the source file name. - ui.stageNameLabel->setText(stageSourceText.str().c_str()); - - // Set the full path as a tooltip. - this->setToolTip(m_fullFilepath.c_str()); - } - } -} - -QLineEdit* rgMenuFileItemGraphics::GetRenameLineEdit() -{ - return ui.filenameLineEdit; -} - -QLabel* rgMenuFileItemGraphics::GetItemLabel() -{ - return ui.stageNameLabel; -} - -void rgMenuFileItemGraphics::enterEvent(QEvent* pEvent) -{ - if (!m_fullFilepath.empty()) - { - ui.removeFilePushButton->show(); - - // Change the item color. - SetHovered(true); - } -} - -void rgMenuFileItemGraphics::leaveEvent(QEvent* pEvent) -{ - if (!m_fullFilepath.empty()) - { - ui.removeFilePushButton->hide(); - - // Change the item color. - SetHovered(false); - } -} - -void rgMenuFileItemGraphics::mouseDoubleClickEvent(QMouseEvent* pEvent) -{ - // Don't allow renaming a pipeline stage item that's empty. - if (!m_fullFilepath.empty()) - { - // On double-click, allow the user to re-name the item's filename. - ShowRenameControls(true); - } -} - -void rgMenuFileItemGraphics::mousePressEvent(QMouseEvent* pEvent) -{ - // Don't process a pipeline stage click if the stage is empty. - if (!m_fullFilepath.empty()) - { - emit MenuItemSelected(this); - } -} - -void rgMenuFileItemGraphics::resizeEvent(QResizeEvent *pEvent) -{ - UpdateFilenameLabelText(); -} - -void rgMenuFileItemGraphics::showEvent(QShowEvent *pEvent) -{ - UpdateFilenameLabelText(); -} - -void rgMenuFileItemGraphics::keyPressEvent(QKeyEvent* pEvent) -{ - if (pEvent->key() == Qt::Key_Escape) - { - m_isEscapePressed = true; - - // Hide the rename box, and display the labels - ShowRenameControls(false); - } - else - { - // Pass the event onto the base class - QWidget::keyPressEvent(pEvent); - } -} - -void rgMenuFileItemGraphics::SetHovered(bool isHovered) -{ - // Set "hovered" property to be utilized by this widget's stylesheet. - ui.itemBackground->setProperty(STR_FILE_MENU_PROPERTY_HOVERED, isHovered); - - // Repolish the widget to ensure the style gets updated. - ui.itemBackground->style()->unpolish(ui.itemBackground); - ui.itemBackground->style()->polish(ui.itemBackground); -} - -void rgMenuFileItemGraphics::SetCurrent(bool isCurrent) -{ - // Set "current" property to be utilized by this widget's stylesheet. - ui.itemBackground->setProperty(STR_FILE_MENU_PROPERTY_CURRENT, isCurrent); - - // Repolish the widget to ensure the style gets updated. - ui.itemBackground->style()->unpolish(ui.itemBackground); - ui.itemBackground->style()->polish(ui.itemBackground); -} - -void rgMenuFileItemGraphics::SetStageIsOccupied(bool isOccupied) -{ - // Set "occupied" property to be utilized by this widget's stylesheet. - ui.itemBackground->setProperty(STR_FILE_MENU_PROPERTY_OCCUPIED, isOccupied); - - // Re-polish the widget to ensure the style gets updated. - ui.itemBackground->style()->unpolish(ui.itemBackground); - ui.itemBackground->style()->polish(ui.itemBackground); -} - -void rgMenuFileItemGraphics::dragEnterEvent(QDragEnterEvent* pEvent) -{ - // Change the item's background color. - SetHovered(true); - SetCurrent(true); - - assert(pEvent != nullptr); - if (pEvent != nullptr) - { - const QMimeData* pMimeData = pEvent->mimeData(); - assert(pMimeData != nullptr); - if (pMimeData != nullptr) - { - const int numFiles = pMimeData->urls().size(); - - // Make sure the drop data has only one file url. - if (pMimeData->hasUrls() && (numFiles == 1)) - { - // Check to make sure the file is valid. - QUrl url = pMimeData->urls().at(0); - - // Do not allow the user to use PSO files. - bool validFile = true; - QString extension; - const QString filePath = url.toLocalFile(); - QStringList nameExtension = filePath.split(STR_FILE_EXTENSION_DELIMITER); - assert(nameExtension.size() == 2); - if (nameExtension.size() == 2) - { - extension = filePath.split(".").at(1); - if (extension.compare(STR_DEFAULT_PIPELINE_FILE_EXTENSION_NAME_GRAPHICS) == 0) - { - validFile = false; - } - else if (extension.compare(STR_DEFAULT_PIPELINE_FILE_EXTENSION_NAME_COMPUTE) == 0) - { - validFile = false; - } - } - - if (url.isLocalFile() && validFile) - { - // @TODO: Validate the file for correct type. - // Accept the action, making it so we receive a dropEvent when the items are released. - pEvent->setDropAction(Qt::DropAction::CopyAction); - pEvent->accept(); - } - else - { - pEvent->ignore(); - - // Change the item's background color. - SetHovered(false); - SetCurrent(false); - } - } - else - { - pEvent->ignore(); - - // Change the item's background color. - SetHovered(false); - SetCurrent(false); - } - } - } -} - -void rgMenuFileItemGraphics::dragLeaveEvent(QDragLeaveEvent* pEvent) -{ - // Change the item's background color. - SetHovered(false); - SetCurrent(false); -} - -void rgMenuFileItemGraphics::dragMoveEvent(QDragMoveEvent *event) -{ - // If there is already a file present in this stage, - // do not allow the user to drop here. - if (m_fullFilepath.empty()) - { - event->setDropAction(Qt::CopyAction); - event->accept(); - } - else - { - event->ignore(); - } -} - -void rgMenuFileItemGraphics::dropEvent(QDropEvent* pEvent) -{ - const QMimeData* pMimeData = pEvent->mimeData(); - - // Make sure the drop data has a file. - if (pMimeData->hasUrls()) - { - // Check to make sure the file is valid. - QUrl url = pMimeData->urls().at(0); - if (url.isLocalFile()) - { - // Get the file path. - std::string filePath = url.toLocalFile().toStdString(); - - // Emit a signal to add an existing file, and provide the target stage. - emit DragAndDropExistingFile(m_stage, filePath); - } - } - else - { - pEvent->ignore(); - } -} - -void rgMenuFileItemGraphics::SetButtonHighlighted(const GraphicsMenuTabFocusItems button) -{ - switch (button) - { - case GraphicsMenuTabFocusItems::RemoveButton: - ui.removeFilePushButton->show(); - ui.removeFilePushButton->setStyleSheet(s_STR_SUB_BUTTON_IN_FOCUS_STYLESHEET); - break; - case GraphicsMenuTabFocusItems::AddExistingFileButton: - ui.addFilePushButton->setStyleSheet(s_STR_SUB_BUTTON_IN_FOCUS_STYLESHEET); - break; - default: - assert(false); - break; - } -} - -void rgMenuFileItemGraphics::RemoveSubButtonFocus() -{ - ui.removeFilePushButton->setStyleSheet(s_STR_SUB_BUTTON_NO_FOCUS_STYLESHEET); - ui.addFilePushButton->setStyleSheet(s_STR_SUB_BUTTON_NO_FOCUS_STYLESHEET); -} - -void rgMenuFileItemGraphics::HideRemoveFilePushButton() -{ - ui.removeFilePushButton->hide(); -} - -void rgMenuFileItemGraphics::ProcessRemoveButtonClick() -{ - ui.removeFilePushButton->click(); -} - -void rgMenuFileItemGraphics::ProcessAddExistingFileButtonClick() -{ - ui.addFilePushButton->click(); -} - -rgPipelineStage rgMenuFileItemGraphics::GetStage() const -{ - return m_stage; -} - -rgVulkanInputType rgMenuFileItemGraphics::GetFileType() const -{ - return m_fileType; -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgMenuFileItemOpenCL.cpp b/RadeonGPUAnalyzerGUI/Src/rgMenuFileItemOpenCL.cpp deleted file mode 100644 index f666555..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgMenuFileItemOpenCL.cpp +++ /dev/null @@ -1,573 +0,0 @@ -// C++. -#include -#include - -// Infra. -#include - -// Qt. -#include -#include -#include -#include -#include - -// Local. -#include -#include -#include -#include - -static const char* s_FILE_MENU_ITEM_COLOR = "#itemBackground[current = true] {background-color: rgb(253, 255, 215); border-style: solid; border-width: 1px; border-color: rgb(18, 152, 0);}"; -static const int s_FILE_MENU_KERNEL_ITEM_HEIGHT = 20; - -// A delegate used to style a file item's entry point list. -class rgEntrypointItemStyleDelegate : public QStyledItemDelegate -{ -public: - rgEntrypointItemStyleDelegate(QObject* pParent = nullptr) - : QStyledItemDelegate(pParent) {} - - // A custom row painter for the entry point list. - void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const - { - QStyleOptionViewItem itemOption(option); - - if (index.isValid()) - { - initStyleOption(&itemOption, index); - } - - // Invoke the item paint implementation with the updated item options. - QStyledItemDelegate::paint(pPainter, itemOption, index); - } -}; - -rgMenuItemEntryListModel::rgMenuItemEntryListModel(QWidget* pParent) - : QObject(pParent) -{ - // Initialize the item model. - m_pEntrypointItemModel = new QStandardItemModel(pParent); - - // Figure out which API is being used. This will determine which text is used for the item's entrypoints list. - rgProjectAPI currentAPI = rgConfigManager::Instance().GetCurrentAPI(); - const std::string entrypointLabelText = rgUtils::GetEntrypointsNameString(currentAPI); - - // Add the column header text. - m_pEntrypointItemModel->setHorizontalHeaderItem(0, new QStandardItem(entrypointLabelText.c_str())); -} - -QStandardItemModel* rgMenuItemEntryListModel::GetEntryItemModel() const -{ - return m_pEntrypointItemModel; -} - -void rgMenuItemEntryListModel::AddEntry(const std::string& entrypointName) -{ - std::string displayText; - - int currentRowCount = m_pEntrypointItemModel->rowCount(); - int newRowCount = currentRowCount + 1; - - // Truncate long entry point names. - rgUtils::GetDisplayText(entrypointName, displayText, m_entryPointWidgetWidth, m_pEntryPointTree, gs_TEXT_TRUNCATE_LENGTH_BACK_OPENCL); - - // Save the entry point name and the possibly truncated display name. - m_entryPointNames.push_back(entrypointName); - m_displayNames.push_back(displayText); - - // Update the number of row items in the model. - m_pEntrypointItemModel->setRowCount(newRowCount); - - // Set the data for the new item row, and left-align the entry point name string. - QModelIndex modelIndex = m_pEntrypointItemModel->index(currentRowCount, 0); - m_pEntrypointItemModel->setData(modelIndex, QString(displayText.c_str())); - m_pEntrypointItemModel->setData(modelIndex, Qt::AlignLeft, Qt::TextAlignmentRole); - m_pEntrypointItemModel->dataChanged(modelIndex, modelIndex); - - // Set the tooltip for the new entry point item. - std::stringstream tooltipText; - tooltipText << STR_MENU_ITEM_ENTRYPOINT_TOOLTIP_TEXT; - tooltipText << entrypointName; - m_pEntrypointItemModel->setData(modelIndex, tooltipText.str().c_str(), Qt::ToolTipRole); - - // Set the scaled height for size hint. - QSize size = m_pEntrypointItemModel->data(modelIndex, Qt::SizeHintRole).toSize(); - size.setHeight(ScalingManager::Get().Scaled(s_FILE_MENU_KERNEL_ITEM_HEIGHT)); - m_pEntrypointItemModel->setData(modelIndex, size, Qt::SizeHintRole); -} - -void rgMenuItemEntryListModel::ClearEntries() -{ - // Clear the model data by removing all existing rows. - int numRows = m_pEntrypointItemModel->rowCount(); - m_pEntrypointItemModel->removeRows(0, numRows); - - // Clear the entry point names as well. - m_entryPointNames.clear(); - m_displayNames.clear(); -} - -void rgMenuItemEntryListModel::SetEntryPointWidgetWidth(const int width) -{ - m_entryPointWidgetWidth = width; -} - -void rgMenuItemEntryListModel::SetEntryPointTreeWidget(rgMenuEntryPointTree* pTree) -{ - m_pEntryPointTree = pTree; -} - -void rgMenuItemEntryListModel::GetEntryPointNames(std::vector& entrypointNames) -{ - entrypointNames = m_entryPointNames; -} - -std::string rgMenuItemEntryListModel::GetEntryPointName(const int index) const -{ - return m_entryPointNames[index]; -} - -std::string rgMenuItemEntryListModel::GetEntryPointName(const std::string& displayEntrypointName) const -{ - int index = 0; - - std::string value; - if (!displayEntrypointName.empty()) - { - auto iter = std::find(m_displayNames.begin(), m_displayNames.end(), displayEntrypointName); - if (iter != m_displayNames.end()) - { - value = *iter; - } - } - return value; -} - -rgMenuFileItemOpenCL::rgMenuFileItemOpenCL(const std::string& fileFullPath, rgMenu* pParent) : - rgMenuFileItem(fileFullPath, pParent) -{ - ui.setupUi(this); - - UpdateFilepath(m_fullFilepath); - - // Start as a saved item. - SetIsSaved(true); - - // Don't show QLineEdit item renaming control when an item is first created. - ShowRenameControls(false); - - // The close button is hidden by default, and is made visible on item mouseover. - ui.closeButton->hide(); - - // Set tool and status tip for close button. - std::string tooltip = STR_FILE_MENU_REMOVE_FILE_TOOLTIP_PREFIX + m_fullFilepath + STR_FILE_MENU_REMOVE_FILE_TOOLTIP_SUFFIX; - rgUtils::SetToolAndStatusTip(tooltip, ui.closeButton); - - // Initialize the entry point list. - InitializeEntrypointsList(); - - // Connect signals for the file item. - ConnectSignals(); - - // Enable mouse tracking for the entry point list view. - ui.entrypointListView->setMouseTracking(true); - - // Set mouse pointer to pointing hand cursor. - SetCursor(); -} - -void rgMenuFileItemOpenCL::enterEvent(QEvent* pEvent) -{ - ui.closeButton->show(); - - // Change the item color. - SetHovered(true); -} - -void rgMenuFileItemOpenCL::leaveEvent(QEvent* pEvent) -{ - ui.closeButton->hide(); - - // Change the item color. - SetHovered(false); -} - -void rgMenuFileItemOpenCL::mouseDoubleClickEvent(QMouseEvent* pEvent) -{ - // On double-click, allow the user to re-name the item's filename. - ShowRenameControls(true); -} - -void rgMenuFileItemOpenCL::mousePressEvent(QMouseEvent* pEvent) -{ - emit MenuItemSelected(this); -} - -void rgMenuFileItemOpenCL::resizeEvent(QResizeEvent *pEvent) -{ - UpdateFilenameLabelText(); -} - -void rgMenuFileItemOpenCL::showEvent(QShowEvent *pEvent) -{ - UpdateFilenameLabelText(); -} - -void rgMenuFileItemOpenCL::keyPressEvent(QKeyEvent* pEvent) -{ - if (pEvent->key() == Qt::Key_Escape) - { - m_isEscapePressed = true; - // Hide the rename box, and display the labels - ShowRenameControls(false); - } - else - { - // Pass the event onto the base class - QWidget::keyPressEvent(pEvent); - } -} - -void rgMenuFileItemOpenCL::ClearEntrypointsList() -{ - assert(m_pEntryListModel != nullptr); - if (m_pEntryListModel != nullptr) - { - m_pEntryListModel->ClearEntries(); - } -} - -void rgMenuFileItemOpenCL::GetEntrypointNames(std::vector& entrypointNames) const -{ - m_pEntryListModel->GetEntryPointNames(entrypointNames); -} - -bool rgMenuFileItemOpenCL::GetSelectedEntrypointName(std::string& entrypointName) const -{ - bool gotEntrypointName = false; - - // Find the selected entry point in the list's selection model. - QItemSelectionModel* pSelectionModel = ui.entrypointListView->selectionModel(); - assert(pSelectionModel != nullptr); - if (pSelectionModel != nullptr) - { - // 1. Look for currently selected entry in the Selection Model. - QModelIndex selectedEntrypointIndex = pSelectionModel->currentIndex(); - if (selectedEntrypointIndex.isValid()) - { - // Extract and return the entry point name from the list. - QVariant entrypointNameData = m_pEntryListModel->GetEntryItemModel()->data(selectedEntrypointIndex); - entrypointName = entrypointNameData.toString().toStdString(); - gotEntrypointName = true; - } - else - { - // 2. If the Selection Model is empty (it may have been cleared after the build), check the last selected entry name. - if (!m_lastSelectedEntryName.empty()) - { - entrypointName = m_lastSelectedEntryName; - gotEntrypointName = true; - } - } - } - - return gotEntrypointName; -} - -void rgMenuFileItemOpenCL::SetHovered(bool isHovered) -{ - // Set "hovered" property to be utilized by this widget's stylesheet. - ui.itemBackground->setProperty(STR_FILE_MENU_PROPERTY_HOVERED, isHovered); - - // Repolish the widget to ensure the style gets updated. - ui.itemBackground->style()->unpolish(ui.itemBackground); - ui.itemBackground->style()->polish(ui.itemBackground); -} - -void rgMenuFileItemOpenCL::SetCurrent(bool isCurrent) -{ - // Set "current" property to be utilized by this widget's stylesheet. - ui.itemBackground->setProperty(STR_FILE_MENU_PROPERTY_CURRENT, isCurrent); - - // Repolish the widget to ensure the style gets updated. - ui.itemBackground->style()->unpolish(ui.itemBackground); - ui.itemBackground->style()->polish(ui.itemBackground); - - // Toggle the visibility of the entrypoints list based on if the item is current or not. - ShowEntrypointsList(isCurrent); -} - -void rgMenuFileItemOpenCL::UpdateFilenameLabelText() -{ - std::string text = m_filename; - std::string displayText; - - // Determine suffix based on whether or not the file is saved. - if (!m_isSaved) - { - text += STR_UNSAVED_FILE_SUFFIX; - } - - // Get available space. - const int availableSpace = ui.filenameDisplayLayout->contentsRect().width(); - - // Get and set display text. - rgUtils::GetDisplayText(text, displayText, availableSpace, ui.filenameLabel, gs_TEXT_TRUNCATE_LENGTH_BACK_OPENCL); - ui.filenameLabel->setText(displayText.c_str()); - - // Set the full path as a tooltip. - this->setToolTip(m_fullFilepath.c_str()); -} - -QLineEdit* rgMenuFileItemOpenCL::GetRenameLineEdit() -{ - return ui.filenameLineEdit; -} - -QLabel* rgMenuFileItemOpenCL::GetItemLabel() -{ - return ui.filenameLabel; -} - -void rgMenuFileItemOpenCL::UpdateFilepath(const std::string& newFilepath) -{ - m_fullFilepath = newFilepath; - - // Only display the filename in the interface- not the full path to the file. - bool isOk = rgUtils::ExtractFileName(newFilepath, m_filename); - if (isOk == false) - { - // Attempt to display as much of the full file path as possible. - m_filename = newFilepath; - } - - // Update the view to display the latest filename. - UpdateFilenameLabelText(); -} - -void rgMenuFileItemOpenCL::ConnectSignals() -{ - // Connect the item's close button. - bool isConnected = connect(ui.closeButton, &QPushButton::clicked, this, &rgMenuFileItemOpenCL::HandleRemoveItemRequest); - assert(isConnected); - - // Connect the filename QLineEdit signals, so the user can confirm a rename by pressing Return. - isConnected = connect(ui.filenameLineEdit, &QLineEdit::returnPressed, this, &rgMenuFileItemOpenCL::HandleEnterPressed); - assert(isConnected); - - // Connect the entry point list selected item changed signal. - isConnected = connect(ui.entrypointListView, &QTreeView::clicked, this, &rgMenuFileItemOpenCL::HandleEntrypointClicked); - assert(isConnected); - - // Slot/signal for the tree view. - isConnected = connect(ui.entrypointListView, &QTreeView::entered, this, &rgMenuFileItemOpenCL::HandleTableItemEntered); - assert(isConnected); - - // Connect the remove file context menu with the remove item request signal. - isConnected = connect(m_contextMenuActions.pRemoveFile, &QAction::triggered, this, &rgMenuFileItemOpenCL::HandleRemoveItemRequest); - assert(isConnected); -} - -void rgMenuFileItemOpenCL::InitializeEntrypointsList() -{ - // Initialize the Expand/Contract icons. Use the expand icon by default. - m_pEntryListModel = new rgMenuItemEntryListModel(this); - ui.entrypointListView->setModel(m_pEntryListModel->GetEntryItemModel()); - ui.entrypointListView->hide(); - - // Set the widget width so the entry point names get truncated correctly. - m_pEntryListModel->SetEntryPointWidgetWidth(ui.entrypointListView->contentsRect().width()); - - // Set the widget. - m_pEntryListModel->SetEntryPointTreeWidget(ui.entrypointListView); - - m_pEntrypointStyleDelegate = new rgEntrypointItemStyleDelegate(ui.entrypointListView); - ui.entrypointListView->setItemDelegate(m_pEntrypointStyleDelegate); -} - -void rgMenuFileItemOpenCL::ShowEntrypointsList(bool showList) -{ - // Toggle the visibility of the entry point list. - if (showList) - { - QStandardItemModel* pEntrypointListModel = m_pEntryListModel->GetEntryItemModel(); - if (pEntrypointListModel != nullptr) - { - bool isEntrypointListEnabled = false; - - // Will the parent menu allow expanding a file item's entry point list? - rgMenuOpenCL* pParentFileMenu = static_cast(GetParentMenu()); - assert(pParentFileMenu != nullptr); - if (pParentFileMenu != nullptr) - { - isEntrypointListEnabled = pParentFileMenu->GetIsShowEntrypointListEnabled(); - } - - // Show the entry point list if it's allowed. - if (isEntrypointListEnabled) - { - // Show the entrypoints list only when it's non-empty. - if (pEntrypointListModel->rowCount() > 0) - { - ui.entrypointListView->show(); - } - } - } - } - else - { - ui.entrypointListView->hide(); - } -} - -void rgMenuFileItemOpenCL::SwitchToEntrypointByName(const std::string& displayName) -{ - // Get the list of entry point names for this file item. - std::vector entrypointNames; - GetEntrypointNames(entrypointNames); - - int selectedEntrypointIndex = 0; - bool foundEntryPoint = false; - for (const std::string& currentEntry : entrypointNames) - { - if (displayName.compare(currentEntry) == 0) - { - foundEntryPoint = true; - break; - } - selectedEntrypointIndex++; - } - - // Compute the model index for the selected entrypoint's row, and set the selection in the selection model. - if (foundEntryPoint) - { - QItemSelectionModel* pSelectionModel = ui.entrypointListView->selectionModel(); - assert(pSelectionModel != nullptr); - if (pSelectionModel != nullptr) - { - QModelIndex selectedRowIndex = m_pEntryListModel->GetEntryItemModel()->index(selectedEntrypointIndex, 0); - pSelectionModel->setCurrentIndex(selectedRowIndex, QItemSelectionModel::SelectCurrent); - m_lastSelectedEntryName = entrypointNames[selectedEntrypointIndex]; - } - } -} - -void rgMenuFileItemOpenCL::UpdateBuildOutputs(const std::vector& entryOutputs) -{ - std::string currentDisplayEntrypointName; - bool isEntrypointSelected = GetSelectedEntrypointName(currentDisplayEntrypointName); - - assert(m_pEntryListModel != nullptr); - if (m_pEntryListModel != nullptr) - { - // Clear the existing list of outputs. - m_pEntryListModel->ClearEntries(); - - if (!entryOutputs.empty()) - { - // Add a new item in the list for each build output entry. - for (const rgEntryOutput& entryOutput : entryOutputs) - { - m_pEntryListModel->AddEntry(entryOutput.m_entrypointName); - } - - // Update the entry point table view height. - ui.entrypointListView->AdjustTreeSize(m_pEntryListModel->GetEntryItemModel()); - - std::vector entrypointNames; - GetEntrypointNames(entrypointNames); - if (!entrypointNames.empty()) - { - bool selectFirstEntrypoint = false; - if (isEntrypointSelected) - { - // Attempt to re-select the same entry point from the new build outputs. - auto entryIter = std::find(entrypointNames.begin(), entrypointNames.end(), currentDisplayEntrypointName); - if (entryIter != entrypointNames.end()) - { - // Re-select the previously selected entrypoint. - SwitchToEntrypointByName(m_pEntryListModel->GetEntryPointName(currentDisplayEntrypointName)); - } - else - { - // Select the first entry point by default since the previous selection no longer exists. - selectFirstEntrypoint = true; - } - } - else - { - // Select the first entry point by default since there was no selection previously. - selectFirstEntrypoint = true; - } - - // Fall back to selecting the first entrypoint. - if (selectFirstEntrypoint) - { - // If the user didn't have an entry point selected previously, automatically select the first entrypoint. - currentDisplayEntrypointName = entrypointNames[0]; - - const std::string& inputFilePath = GetFilename(); - emit SelectedEntrypointChanged(inputFilePath, currentDisplayEntrypointName); - } - } - } - } -} - -void rgMenuFileItemOpenCL::HandleRemoveItemRequest() -{ - emit MenuItemCloseButtonClicked(this->GetFilename()); -} - -void rgMenuFileItemOpenCL::HandleEntrypointClicked() -{ - // Signal to the menu that the user has clicked within this item. This will switch the current file. - emit MenuItemSelected(this); - - // Is the selected item valid? - QItemSelectionModel* pSelectionModel = ui.entrypointListView->selectionModel(); - if (pSelectionModel->currentIndex().isValid()) - { - // Pull the filename out of the selected item. - const std::string& filePath = GetFilename(); - int selectedRow = pSelectionModel->currentIndex().row(); - - // Get a list of all the entry point names for the input file. - std::vector entrypointNames; - GetEntrypointNames(entrypointNames); - - bool isValidRow = selectedRow < entrypointNames.size(); - assert(isValidRow); - if (isValidRow) - { - // Emit a signal indicating that the selected entry point has changed. - emit SelectedEntrypointChanged(filePath, entrypointNames[selectedRow]); - } - } -} - -void rgMenuFileItemOpenCL::HandleTableItemEntered(const QModelIndex& modelIndex) -{ - // Set the cursor if modelIndex valid. - if (modelIndex.isValid()) - { - ui.entrypointListView->setCursor(Qt::PointingHandCursor); - } - else - { - ui.entrypointListView->setCursor(Qt::ArrowCursor); - } -} - -void rgMenuFileItemOpenCL::SetCursor() -{ - // Set the cursor to pointing hand cursor. - ui.closeButton->setCursor(Qt::PointingHandCursor); -} - -void rgMenuFileItemOpenCL::HandleProjectBuildSuccess() -{ - // Change the style sheet when the project built successfully. - setStyleSheet(s_FILE_MENU_ITEM_COLOR); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgMenuGraphics.cpp b/RadeonGPUAnalyzerGUI/Src/rgMenuGraphics.cpp deleted file mode 100644 index ce80f46..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgMenuGraphics.cpp +++ /dev/null @@ -1,1055 +0,0 @@ -// C++. -#include - -// Qt. -#include - -// Infra. -#include - -// Local. -#include -#include -#include -#include - -static const char* s_BUTTON_FOCUS_IN_STYLESHEET_GRAPHICS = "QPushButton { background: rgb(253,255,174); border-style: solid; border-width: 2px; border-color: rgb(135, 20, 16);}"; -static const char* s_BUTTON_TABBED_STYLESHEET = "QPushButton { border: 2px solid rgb(135,20,16); margin: 1px; background: rgb(214,214,214);}"; -static const char* s_FILE_MENU_NAME_GRAPHICS = "fileMenuGraphics"; - -static const int s_PIPELINE_STATE_BUTTON_INDEX = 1; -static const int s_BUILD_SETTINGS_BUTTON_INDEX = 2; - -static const int s_NUMBER_OF_GRAPHICS_PIPELINE_STAGES = 5; -static const int s_NUMBER_OF_COMPUTE_PIPELINE_STAGES = 1; - -rgMenuGraphics::rgMenuGraphics(QWidget* pParent) - : rgMenu(pParent) -{ - // Set the object name. - setObjectName(s_FILE_MENU_NAME_GRAPHICS); -} - -void rgMenuGraphics::SelectFocusItem(FileMenuActionType actionType) -{ - assert(m_pPipelineStateItem != nullptr); - assert(m_pBuildSettingsMenuItem != nullptr); - if (m_pPipelineStateItem != nullptr && m_pBuildSettingsMenuItem != nullptr) - { - ClearButtonStylesheets(); - - // Find out total stages and which vector to use. - const size_t totalPipelineStages = GetNumberPipelineStagesToCycleThrough(actionType); - const std::vector menuFileItems = GetFileMenuItemsToProcess(actionType); - - // If focus index is in the range of the menu file items, select the appropriate file item. - if (m_focusIndex < totalPipelineStages) - { - rgMenuFileItemGraphics* pItem = static_cast(menuFileItems[m_focusIndex]); - assert(pItem != nullptr); - if (pItem != nullptr) - { - UpdateHighlight(pItem); - } - } - else - { - // Deselect graphics menu items. - DeselectFileItems(); - - // Out of range, so special case handle the last focus items. - // Get index excluding file items. - size_t index = m_focusIndex - totalPipelineStages; - - // Handle special cases for pipeline state and build settings buttons. - SelectButton(index); - } - } -} - -void rgMenuGraphics::SelectButton(size_t index) -{ - // Handle special cases for pipeline state and build settings buttons. - switch (index) - { - case static_cast(GraphicsMenuFocusItems::BuildSettingsButton) : - if (!m_pBuildSettingsMenuItem->IsCurrent()) - { - m_pBuildSettingsMenuItem->GetBuildSettingsButton()->setStyleSheet(s_BUTTON_TABBED_STYLESHEET); - m_hasTabFocus = GraphicsMenuTabFocusItems::NoButton; - } - break; - case static_cast(GraphicsMenuFocusItems::PipelineStateButton) : - if (!m_pPipelineStateItem->IsCurrent()) - { - m_pPipelineStateItem->GetPipelineStateButton()->setStyleSheet(s_BUTTON_TABBED_STYLESHEET); - m_hasTabFocus = GraphicsMenuTabFocusItems::NoButton; - } - break; - default: - // Should never get here. - assert(false); - break; - } -} - -void rgMenuGraphics::SelectTabFocusItem(bool shiftTabFocus) -{ - assert(m_pPipelineStateItem != nullptr); - assert(m_pBuildSettingsMenuItem != nullptr); - if (m_pPipelineStateItem != nullptr && m_pBuildSettingsMenuItem != nullptr) - { - ClearButtonStylesheets(); - - // If focus index is in the range of the menu file items, select the appropriate file item. - if (m_tabFocusIndex < m_totalPipelineStages) - { - rgMenuFileItemGraphics* pItem = GetCurrentFileMenuItem(); - assert(pItem != nullptr); - if (pItem != nullptr) - { - if (!pItem->GetFilename().empty()) - { - UpdateHighlight(pItem); - } - else - { - - pItem->SetButtonHighlighted(GraphicsMenuTabFocusItems::AddExistingFileButton); - m_hasTabFocus = GraphicsMenuTabFocusItems::AddExistingFileButton; - } - } - } - else - { - // Deselect graphics menu items. - DeselectFileItems(); - - // Out of range, so special case handle the last focus items. - // Get index excluding file items. - size_t index = m_focusIndex - m_totalPipelineStages; - - // Handle special cases for pipeline state and build settings buttons. - SelectButton(index); - } - } -} - -void rgMenuGraphics::DeselectFileItems() -{ - // Deselect graphics menu file items. - for (rgMenuFileItem* pItem : m_menuItems) - { - rgMenuFileItemGraphics* pItemGraphics = static_cast(pItem); - assert(pItem != nullptr); - if (pItem != nullptr) - { - pItem->SetHovered(false); - } - } -} - -void rgMenuGraphics::ClearButtonStylesheets() -{ - // Clear button style sheets. - if (!m_pBuildSettingsMenuItem->IsCurrent()) - { - m_pBuildSettingsMenuItem->GetBuildSettingsButton()->setStyleSheet(""); - } - - if (!m_pPipelineStateItem->IsCurrent()) - { - m_pPipelineStateItem->GetPipelineStateButton()->setStyleSheet(""); - } -} - -void rgMenuGraphics::InitializeDefaultMenuItems(const std::shared_ptr pProjectClone) -{ - // Initialize the default shader stage items. - InitializeDefaultShaderStageItems(pProjectClone); - - // Get the index for the last widget added. - int lastStage; - std::shared_ptr pGraphicsClone = std::dynamic_pointer_cast(pProjectClone); - assert(pGraphicsClone != nullptr); - if (pGraphicsClone != nullptr) - { - if (pGraphicsClone->m_pipeline.m_type == rgPipelineType::Graphics) - { - lastStage = static_cast(rgPipelineStage::Fragment); - } - else if (pGraphicsClone->m_pipeline.m_type == rgPipelineType::Compute) - { - lastStage = 0; - } - else - { - // If the pipeline type isn't Graphics or Compute, something is very wrong. - assert(false); - } - - // Insert a horizontal line before adding buttons. - QHBoxLayout* pHorizontalLineLayout = CreateHorizontalLine(); - m_pLayout->insertLayout(lastStage + 1, pHorizontalLineLayout); - - // Insert the pipeline state menu item to the top of the menu. - m_pPipelineStateItem = new rgMenuPipelineStateItem(pGraphicsClone->m_pipeline.m_type, this); - m_pLayout->insertWidget(lastStage + 2, m_pPipelineStateItem); - - // Insert a horizontal line. - pHorizontalLineLayout = CreateHorizontalLine(); - m_pLayout->insertLayout(lastStage + 3, pHorizontalLineLayout); - - // Insert the "Build Settings" item into the top of the menu. - m_pBuildSettingsMenuItem = new rgMenuBuildSettingsItem(); - m_pLayout->insertWidget(lastStage + 4, m_pBuildSettingsMenuItem); - - // Connect signals for each individual shader stage item in the menu. - ConnectStageItemSignals(); - - // Connect menu item signals. - ConnectDefaultItemSignals(); - - // Connect the signals for Build settings and Pipeline state buttons. - ConnectButtonSignals(); - - // Make the menu as wide as the items. - const int width = m_pBuildSettingsMenuItem->width(); - const int height = m_pBuildSettingsMenuItem->height(); - this->resize(width, 2 * height); - - // Set cursor. - SetCursor(Qt::ArrowCursor); - - // Register the buttons with the scaling manager. - ScalingManager::Get().RegisterObject(m_pBuildSettingsMenuItem); - ScalingManager::Get().RegisterObject(m_pPipelineStateItem); - } -} - -QHBoxLayout* rgMenuGraphics::CreateHorizontalLine() const -{ - // Margin constants. - static const int s_LEFT_MARGIN = 10; - static const int s_TOP_MARGIN = 8; - static const int s_RIGHT_MARGIN = 10; - static const int s_BOTTOM_MARGIN = 8; - - QHBoxLayout* pHLayout = new QHBoxLayout(); - QFrame* pFrame = new QFrame; - pFrame->setFrameShape(QFrame::HLine); - pFrame->setFrameShadow(QFrame::Plain); - pFrame->setStyleSheet("color: gray"); - pHLayout->addWidget(pFrame); - pHLayout->setContentsMargins(s_LEFT_MARGIN, s_TOP_MARGIN, s_RIGHT_MARGIN, s_BOTTOM_MARGIN); - pHLayout->setSizeConstraint(QLayout::SetDefaultConstraint); - - return pHLayout; -} - -void rgMenuGraphics::InitializeDefaultShaderStageItems(const std::shared_ptr pProjectClone) -{ - // Zero out the stage items array. - m_shaderStageItems = {}; - - // Create an item for each shader stage. - std::shared_ptr pGraphicsClone = std::dynamic_pointer_cast(pProjectClone); - assert(pGraphicsClone != nullptr); - if (pGraphicsClone != nullptr) - { - m_pipelineType = pGraphicsClone->m_pipeline.m_type; - m_totalPipelineStages = GetTotalPipelineStages(); - if (pGraphicsClone->m_pipeline.m_type == rgPipelineType::Graphics) - { - // Step through each stage of the graphics pipeline and create a new menu item used to add files to the stage. - char firstStage = static_cast(rgPipelineStage::Vertex); - char lastStage = static_cast(rgPipelineStage::Fragment); - for (int stageIndex = firstStage; stageIndex <= lastStage; ++stageIndex) - { - rgPipelineStage stage = static_cast(stageIndex); - - // Create a new stage item and add it to the menu. - rgMenuFileItemGraphics* pGraphicsPipelineStageItem = new rgMenuFileItemGraphics(this, stage); - m_pLayout->insertWidget(stageIndex, pGraphicsPipelineStageItem); - m_shaderStageItems[stageIndex] = pGraphicsPipelineStageItem; - - // Register the stage with the scaling manager. - ScalingManager::Get().RegisterObject(pGraphicsPipelineStageItem); - - // Connect to file item's drag and drop signal. - bool isConnected = connect(pGraphicsPipelineStageItem, &rgMenuFileItemGraphics::DragAndDropExistingFile, - this, &rgMenuGraphics::HandleDragAndDropExistingFile); - assert(isConnected); - } - } - else if (pGraphicsClone->m_pipeline.m_type == rgPipelineType::Compute) - { - // Create the compute shader stage item. - rgPipelineStage computeStage = rgPipelineStage::Compute; - rgMenuFileItemGraphics* pComputePipelineStageItem = new rgMenuFileItemGraphics(this, computeStage); - m_pLayout->insertWidget(0, pComputePipelineStageItem); - m_shaderStageItems[static_cast(computeStage)] = pComputePipelineStageItem; - - // Register the stage with the scaling manager. - ScalingManager::Get().RegisterObject(pComputePipelineStageItem); - - // Connect to file item's drag and drop signal. - bool isConnected = connect(pComputePipelineStageItem, &rgMenuFileItemGraphics::DragAndDropExistingFile, - this, &rgMenuGraphics::HandleDragAndDropExistingFile); - assert(isConnected); - } - else - { - // If the pipeline type isn't Graphics or Compute, something is very wrong. - assert(false); - } - } -} - -void rgMenuGraphics::SetStageButtonsEnabled(bool isEnabled) -{ - // Loop through each available stage in the pipeline - // and update the enabledness of the buttons. - for (auto stageItemIter = m_shaderStageItems.begin(); - stageItemIter != m_shaderStageItems.end(); ++stageItemIter) - { - // If a stage item is nullptr, it's not a problem. It just means that the - // stage is not actively being used within the project. - rgMenuFileItemGraphics* pStageItem = *stageItemIter; - if (pStageItem != nullptr) - { - pStageItem->SetButtonsEnabled(isEnabled); - } - } -} - -void rgMenuGraphics::SetCursor(Qt::CursorShape shape) -{ - for (rgMenuFileItemGraphics* pItem : m_shaderStageItems) - { - // The stage items array is fixed-size, and slots may be set to nullptr if the stage is not - // used. Only update the cursor for valid pipeline stage slots. - if (pItem != nullptr) - { - pItem->setCursor(shape); - } - } -} - -void rgMenuGraphics::HandleBuildStarted() -{ - // Call the base class implementation. - rgMenu::HandleBuildStarted(); - - // Disable the Add/Create buttons for each stage item. - SetStageButtonsEnabled(false); -} - -void rgMenuGraphics::HandleBuildEnded() -{ - // Call the base class implementation. - rgMenu::HandleBuildEnded(); - - // Re-enable the Add/Create buttons for each stage item. - SetStageButtonsEnabled(true); -} - -void rgMenuGraphics::ConnectStageItemSignals() -{ - for (size_t stageIndex = 0; stageIndex < m_shaderStageItems.size(); ++stageIndex) - { - rgMenuFileItemGraphics* pStageItem = m_shaderStageItems[stageIndex]; - if (pStageItem != nullptr) - { - // Connect the stage item's "Add existing file" button to remove sub button focus. - bool isConnected = connect(pStageItem, &rgMenuFileItemGraphics::AddExistingFileButtonClicked, this, &rgMenuGraphics::HandleAddExistingFileButtonClicked); - assert(isConnected); - - // Connect the stage item's "Add existing file" button. - isConnected = connect(pStageItem, &rgMenuFileItemGraphics::AddExistingFileButtonClicked, this, &rgMenuGraphics::AddExistingFileButtonClicked); - assert(isConnected); - - // Connect the stage item's drag and drop event. - isConnected = connect(pStageItem, &rgMenuFileItemGraphics::DragAndDropExistingFile, this, &rgMenuGraphics::DragAndDropExistingFile); - assert(isConnected); - - // Connect the stage item's "Create new file" button. - isConnected = connect(pStageItem, &rgMenuFileItemGraphics::CreateSourceFileButtonClicked, this, &rgMenuGraphics::CreateNewFileButtonClicked); - assert(isConnected); - - // Connect the stage item's "Remove source file" button. - isConnected = connect(pStageItem, &rgMenuFileItemGraphics::RemoveSourceFileButtonClicked, this, &rgMenuGraphics::RemoveFileButtonClicked); - assert(isConnected); - - // Connect the stage item's "Restore original SPIR-V binary" button. - isConnected = connect(pStageItem, &rgMenuFileItemGraphics::RestoreOriginalSpvButtonClicked, this, &rgMenuGraphics::RestoreOriginalSpirvClicked); - assert(isConnected); - } - } -} - -void rgMenuGraphics::ConnectButtonSignals() -{ - // Connect the Build settings button's clicked signal. - bool isConnected = connect(m_pBuildSettingsMenuItem, &rgMenuBuildSettingsItem::BuildSettingsButtonClicked, this, &rgMenuGraphics::HandleBuildSettingsButtonClicked); - assert(isConnected); - - // Connect the pipeline state button's drag and drop file signal. - isConnected = connect(m_pPipelineStateItem, &rgMenuPipelineStateItem::DragAndDropExistingFile, this, &rgMenuGraphics::DragAndDropExistingPsoFile); - assert(isConnected); -} - -int rgMenuGraphics::GetButtonCount() const -{ - // There are 2 extra buttons besides the file items: - // Build settings - // Pipeline state - static const int s_EXTRA_GRAPHICS_BUTTON_COUNT = 2; - return s_EXTRA_GRAPHICS_BUTTON_COUNT; -} - -void rgMenuGraphics::HandleDragAndDropExistingFile() -{ - SetButtonsNoFocus(); -} - -void rgMenuGraphics::SetButtonsNoFocus() -{ - assert(m_pBuildSettingsMenuItem != nullptr); - assert(m_pPipelineStateItem != nullptr); - - // Set the pipeline state and build settings buttons to have focus out style sheets. - if (m_pBuildSettingsMenuItem != nullptr && m_pPipelineStateItem != nullptr) - { - m_pBuildSettingsMenuItem->SetCurrent(false); - m_pPipelineStateItem->SetCurrent(false); - } -} - -rgMenuFileItemGraphics* rgMenuGraphics::GetStageItem(rgPipelineStage stage) const -{ - rgMenuFileItemGraphics* pResultWidget = nullptr; - switch (stage) - { - case rgPipelineStage::Vertex: - case rgPipelineStage::TessellationControl: - case rgPipelineStage::TessellationEvaluation: - case rgPipelineStage::Geometry: - case rgPipelineStage::Fragment: - pResultWidget = m_shaderStageItems[static_cast(stage)]; - break; - case rgPipelineStage::Compute: - { - pResultWidget = m_shaderStageItems[static_cast(rgPipelineStage::Compute)]; - } - break; - default: - assert(false); - break; - } - - return pResultWidget; -} - -void rgMenuGraphics::RebuildMenuItemsList() -{ - // Erase, and then reconstruct the menu item list in order by stage. - m_menuItems.clear(); - - for (auto pStageItem : m_shaderStageItems) - { - if (pStageItem != nullptr) - { - // If a stage item has a filename, add the item to the ordered list. - if (!pStageItem->GetFilename().empty()) - { - m_menuItems.push_back(pStageItem); - } - } - } -} - -rgMenuPipelineStateItem* rgMenuGraphics::GetPipelineStateItem() const -{ - return m_pPipelineStateItem; -} - -void rgMenuGraphics::HandleTabFocusPressed() -{ - // Remove focus from the sub buttons. - RemoveSubButtonFocus(); - - // Hide the remove file push button. - HideRemoveFilePushButton(); - - // Clear style sheets for all buttons. - ClearButtonStylesheets(); - - // Refresh focus. - if (m_tabFocusIndex < m_totalPipelineStages) - { - if ((m_hasTabFocus == GraphicsMenuTabFocusItems::RemoveButton) || - (m_hasTabFocus == GraphicsMenuTabFocusItems::AddExistingFileButton)) - { - IncrementTabFocusIndex(); - - // Reset the sub-button tab focus. - m_hasTabFocus = GraphicsMenuTabFocusItems::NoButton; - if (m_tabFocusIndex < m_totalPipelineStages) - { - rgMenuFileItemGraphics* pItem = GetCurrentFileMenuItem(); - if (pItem != nullptr) - { - if (!pItem->GetFilename().empty()) - { - SelectTabFocusItem(false); - } - else - { - pItem->SetButtonHighlighted(GraphicsMenuTabFocusItems::AddExistingFileButton); - m_hasTabFocus = GraphicsMenuTabFocusItems::AddExistingFileButton; - } - } - } - else - { - // Figure out the correct button index. - m_focusIndex = m_tabFocusIndex; - SelectTabFocusItem(false); - } - } - else if (m_hasTabFocus == GraphicsMenuTabFocusItems::NoButton) - { - // Select the next item in the file menu. - SelectNextItem(FileMenuActionType::TabAction); - } - } - else - { - IncrementTabFocusIndex(); - - // Select the next item in the file menu. - SelectTabFocusItem(false); - } -} - -void rgMenuGraphics::SelectNextItem(FileMenuActionType actionType) -{ - // Figure out the correct button index. - if (m_tabFocusIndex < m_totalPipelineStages) - { - rgMenuFileItemGraphics* pItem = GetCurrentFileMenuItem(); - - assert(pItem != nullptr); - if (pItem != nullptr && !pItem->GetFilename().empty()) - { - if (m_hasTabFocus == GraphicsMenuTabFocusItems::RemoveButton || - m_hasTabFocus == GraphicsMenuTabFocusItems::AddExistingFileButton) - { - SelectTabFocusItem(false); - m_hasTabFocus = GraphicsMenuTabFocusItems::NoButton; - } - else if (m_hasTabFocus == GraphicsMenuTabFocusItems::NoButton) - { - pItem->SetButtonHighlighted(GraphicsMenuTabFocusItems::RemoveButton); - m_hasTabFocus = GraphicsMenuTabFocusItems::RemoveButton; - } - } - else - { - pItem->SetButtonHighlighted(GraphicsMenuTabFocusItems::AddExistingFileButton); - m_hasTabFocus = GraphicsMenuTabFocusItems::AddExistingFileButton; - } - } - else - { - SelectFocusItem(actionType); - } -} - -void rgMenuGraphics::SelectPreviousItem(FileMenuActionType actionType) -{ - // Figure out the correct button index. - if (m_tabFocusIndex < m_totalPipelineStages) - { - rgMenuFileItemGraphics* pItem = GetCurrentFileMenuItem(); - assert(pItem != nullptr); - if (pItem != nullptr) - { - if (!pItem->GetFilename().empty()) - { - if (m_hasTabFocus == GraphicsMenuTabFocusItems::RemoveButton) - { - SelectTabFocusItem(true); - m_hasTabFocus = GraphicsMenuTabFocusItems::NoButton; - } - else - { - pItem->SetButtonHighlighted(GraphicsMenuTabFocusItems::RemoveButton); - m_hasTabFocus = GraphicsMenuTabFocusItems::RemoveButton; - } - } - else - { - pItem->SetButtonHighlighted(GraphicsMenuTabFocusItems::AddExistingFileButton); - m_hasTabFocus = GraphicsMenuTabFocusItems::AddExistingFileButton; - } - } - } - else - { - SelectFocusItem(actionType); - } -} - -void rgMenuGraphics::IncrementTabFocusIndex() -{ - // Clear highlight for all file menu items. - ClearFileMenuHighlight(); - - // Advance the tab focus index. - int offset = GetButtonCount() - 1; - size_t endIndex = m_totalPipelineStages + offset + 1; - - // Increment focus index and wrap around. - m_tabFocusIndex++; - if (m_tabFocusIndex >= endIndex) - { - m_tabFocusIndex = 0; - m_focusIndex = 0; - - // We've reached the end of file menu, so now - // give focus to the next view. - emit FocusNextView(); - } - - // Update the focus index. - UpdateFocusIndex(); - -} - -void rgMenuGraphics::DecrementTabFocusIndex() -{ - // Clear highlight for all file menu items. - ClearFileMenuHighlight(); - - // Decrement the tab focus index. - int offset = GetButtonCount() - 1; - size_t endIndex = m_totalPipelineStages + offset; - - // Decrement focus index and wrap around. - if (m_tabFocusIndex > 0) - { - m_tabFocusIndex--; - } - else - { - m_tabFocusIndex = 0; - - // We've reached the beginning of file menu, so now - // give focus to the previous view. - emit FocusPrevView(); - } - - // Update the focus index. - UpdateFocusIndex(); -} - -void rgMenuGraphics::UpdateFocusIndex() -{ - if (m_tabFocusIndex < m_totalPipelineStages) - { - // Update m_focusIndex only if m_tabFocusIndex points to an occupied stage. - rgMenuFileItemGraphics* pItem = GetCurrentFileMenuItem(); - assert(pItem != nullptr); - if (pItem != nullptr) - { - int count = 0; - for (const auto& pGraphicsItem : m_menuItems) - { - if (pGraphicsItem == pItem) - { - m_focusIndex = count; - break; - } - count++; - } - } - } - else - { - // Update the focus index. - m_focusIndex = m_tabFocusIndex; - } -} - -void rgMenuGraphics::SelectFocusSubButton(rgMenuFileItemGraphics* pItem) -{ - assert(pItem != nullptr); - - if ((pItem != nullptr) && (!pItem->GetFilename().empty())) - { - if (m_hasTabFocus == GraphicsMenuTabFocusItems::NoButton) - { - if (pItem != nullptr) - { - // Give focus to the remove file button. - pItem->SetButtonHighlighted(GraphicsMenuTabFocusItems::RemoveButton); - m_hasTabFocus = GraphicsMenuTabFocusItems::RemoveButton; - } - } - } - else - { - if (pItem != nullptr) - { - pItem->SetButtonHighlighted(GraphicsMenuTabFocusItems::AddExistingFileButton); - m_hasTabFocus = GraphicsMenuTabFocusItems::AddExistingFileButton; - } - } -} - -void rgMenuGraphics::HandleShiftTabFocusPressed() -{ - // Remove focus from the sub buttons. - RemoveSubButtonFocus(); - - // Clear style sheets for all buttons. - ClearButtonStylesheets(); - - // Hide the remove file push button. - HideRemoveFilePushButton(); - - // Refresh focus. - if (m_tabFocusIndex < m_totalPipelineStages) - { - if (m_hasTabFocus == GraphicsMenuTabFocusItems::AddExistingFileButton) - { - DecrementTabFocusIndex(); - - // Reset the sub-button tab focus. - m_hasTabFocus = GraphicsMenuTabFocusItems::NoButton; - if (m_tabFocusIndex < m_totalPipelineStages) - { - rgMenuFileItemGraphics* pItem = GetCurrentFileMenuItem(); - assert(pItem != nullptr); - if (pItem != nullptr) - { - if (!pItem->GetFilename().empty()) - { - if (m_hasTabFocus == GraphicsMenuTabFocusItems::NoButton) - { - UpdateHighlight(pItem); - pItem->SetButtonHighlighted(GraphicsMenuTabFocusItems::RemoveButton); - m_hasTabFocus = GraphicsMenuTabFocusItems::RemoveButton; - } - else if (m_hasTabFocus == GraphicsMenuTabFocusItems::RemoveButton) - { - SelectTabFocusItem(true); - m_hasTabFocus = GraphicsMenuTabFocusItems::NoButton; - } - } - else if (pItem->GetFilename().empty()) - { - if (m_hasTabFocus == GraphicsMenuTabFocusItems::NoButton) - { - pItem->SetButtonHighlighted(GraphicsMenuTabFocusItems::AddExistingFileButton); - m_hasTabFocus = GraphicsMenuTabFocusItems::AddExistingFileButton; - } - else - { - DecrementTabFocusIndex(); - m_hasTabFocus = GraphicsMenuTabFocusItems::NoButton; - } - } - } - } - else - { - // Update the focus index. - m_focusIndex = m_tabFocusIndex; - SelectTabFocusItem(true); - } - } - else if (m_hasTabFocus == GraphicsMenuTabFocusItems::RemoveButton) - { - SelectTabFocusItem(true); - m_hasTabFocus = GraphicsMenuTabFocusItems::NoButton; - } - else if (m_hasTabFocus == GraphicsMenuTabFocusItems::NoButton) - { - DecrementTabFocusIndex(); - - // Select the previous item in the file menu. - SelectPreviousItem(FileMenuActionType::TabAction); - } - } - else - { - DecrementTabFocusIndex(); - - // Select the previous item in the file menu. - SelectTabFocusItem(true); - } -} - -void rgMenuGraphics::HandleBuildSettingsButtonClicked(bool /* checked */) -{ - // Clear the file menu item selection. - ClearFileMenuItemSelection(); - - // Clear the sub button highlights. - RemoveSubButtonFocus(); - - assert(m_pBuildSettingsMenuItem != nullptr); - assert(m_pPipelineStateItem != nullptr); - if (m_pBuildSettingsMenuItem != nullptr && m_pPipelineStateItem != nullptr) - { - // Set the focus index. - m_focusIndex = m_menuItems.size() + GetButtonCount() - s_PIPELINE_STATE_BUTTON_INDEX; - - // Update button selection values. - m_pPipelineStateItem->SetCurrent(false); - m_pBuildSettingsMenuItem->SetCurrent(true); - } -} - -void rgMenuGraphics::HandlePipelineStateButtonClicked(bool /* checked */) -{ - // Clear the file menu item selection. - ClearFileMenuItemSelection(); - - // Clear the sub button highlights. - RemoveSubButtonFocus(); - - assert(m_pBuildSettingsMenuItem != nullptr); - assert(m_pPipelineStateItem != nullptr); - if (m_pBuildSettingsMenuItem != nullptr && m_pPipelineStateItem != nullptr) - { - // Set the focus index. - m_focusIndex = m_menuItems.size() + GetButtonCount() - s_BUILD_SETTINGS_BUTTON_INDEX; - - // Update button selection values. - m_pPipelineStateItem->SetCurrent(true); - m_pBuildSettingsMenuItem->SetCurrent(false); - } -} - -void rgMenuGraphics::RemoveSubButtonFocus() -{ - // Remove sub button focus from all file items. - for (rgMenuFileItemGraphics* pItem : m_shaderStageItems) - { - // Do not assert here since pItem could be null - // if this is compute pipeline item while in graphics pipeline, - // and vice versa. - if (pItem != nullptr) - { - pItem->RemoveSubButtonFocus(); - } - } -} - -void rgMenuGraphics::HideRemoveFilePushButton() -{ - // Hide the remove file push button for all file items. - for (rgMenuFileItemGraphics* pItem : m_shaderStageItems) - { - // Do not assert here since pItem could be null - // if this is compute pipeline item while in graphics pipeline, - // and vice versa. - if (pItem != nullptr) - { - pItem->HideRemoveFilePushButton(); - } - } -} - -rgMenuFileItemGraphics* rgMenuGraphics::GetCurrentFileMenuItem() const -{ - rgMenuFileItemGraphics* pItem = nullptr; - switch (m_pipelineType) - { - case (rgPipelineType::Graphics): - { - if (m_tabFocusIndex < s_NUMBER_OF_GRAPHICS_PIPELINE_STAGES) - { - pItem = static_cast(m_shaderStageItems[m_tabFocusIndex]); - } - } - break; - case (rgPipelineType::Compute): - { - if (m_tabFocusIndex < s_NUMBER_OF_COMPUTE_PIPELINE_STAGES) - { - pItem = static_cast(m_shaderStageItems[static_cast(rgPipelineStage::Compute)]); - } - } - break; - default: - assert(false); - break; - } - - return pItem; -} - -rgPipelineStage rgMenuGraphics::GetCurrentStage() const -{ - return m_currentStage; -} - -void rgMenuGraphics::HandleAddExistingFileButtonClicked(rgPipelineStage stage) -{ - // Remove focus from all sub buttons. - RemoveSubButtonFocus(); - - // Now add back the focus for the current stage's "Add existing file" button. - rgMenuFileItemGraphics* pStageItem = GetStageItem(stage); - assert(pStageItem != nullptr); - if (pStageItem != nullptr) - { - pStageItem->SetButtonHighlighted(GraphicsMenuTabFocusItems::AddExistingFileButton); - } - - // Also update focus indexes. - UpdateFocusIndex(stage); -} - -void rgMenuGraphics::UpdateFocusIndex(rgPipelineStage stage) -{ - if (m_pipelineType == rgPipelineType::Compute) - { - m_focusIndex = 0; - m_tabFocusIndex = 0; - } - else if (m_pipelineType == rgPipelineType::Graphics) - { - m_focusIndex = static_cast(stage); - m_tabFocusIndex = static_cast(stage); - } - else - { - // Should not be here. - assert(false); - } -} - -size_t rgMenuGraphics::GetTotalPipelineStages() const -{ - size_t totalPipelineStages = 0; - - if (m_pipelineType == rgPipelineType::Compute) - { - totalPipelineStages = s_NUMBER_OF_COMPUTE_PIPELINE_STAGES; - } - else if (m_pipelineType == rgPipelineType::Graphics) - { - totalPipelineStages = s_NUMBER_OF_GRAPHICS_PIPELINE_STAGES; - } - else - { - // Should not be here. - assert(false); - } - - return totalPipelineStages; -} - -size_t rgMenuGraphics::GetNumberPipelineStagesToCycleThrough(FileMenuActionType actionType) const -{ - size_t totalOccupiedPipelineStages = 0; - - switch (actionType) - { - case FileMenuActionType::ArrowAction: - case FileMenuActionType::TabAction: - { - if (m_pipelineType == rgPipelineType::Compute) - { - totalOccupiedPipelineStages = s_NUMBER_OF_COMPUTE_PIPELINE_STAGES; - } - else if (m_pipelineType == rgPipelineType::Graphics) - { - totalOccupiedPipelineStages = s_NUMBER_OF_GRAPHICS_PIPELINE_STAGES; - } - else - { - // Should not be here. - assert(false); - } - break; - } - default: - // We shouldn't get here. - assert(false); - break; - } - - return totalOccupiedPipelineStages; -} - -std::vector rgMenuGraphics::GetFileMenuItemsToProcess(FileMenuActionType actionType) const -{ - std::vector vectorToProcess; - - switch (actionType) - { - case FileMenuActionType::ArrowAction: - case FileMenuActionType::TabAction: - { - std::vector vectorToProcess(std::begin(m_shaderStageItems), std::end(m_shaderStageItems)); - break; - } - default: - // We shouldn't get here. - assert(false); - break; - } - - return vectorToProcess; -} - -void rgMenuGraphics::HandleRemoveFileMenuButtonFocus() -{ - RemoveSubButtonFocus(); - RemoveFileMenuButtonFocus(); -} - -void rgMenuGraphics::SetCurrent(rgPipelineStage stage, bool isCurrent) -{ - rgMenuFileItemGraphics* pStage = GetStageItem(stage); - if (pStage != nullptr) - { - pStage->SetCurrent(isCurrent); - pStage->SetHovered(isCurrent); - } -} - -void rgMenuGraphics::RemoveFileMenuButtonFocus() -{ - assert(m_pBuildSettingsMenuItem != nullptr); - assert(m_pPipelineStateItem != nullptr); - if (m_pBuildSettingsMenuItem != nullptr && m_pPipelineStateItem != nullptr) - { - // Set the pipeline state and build settings buttons to have focus out style sheets. - // Verify that the button isn't currently selected before removing the focus. - if (!m_pBuildSettingsMenuItem->IsCurrent()) - { - m_pBuildSettingsMenuItem->GetBuildSettingsButton()->setStyleSheet(s_BUTTON_FOCUS_OUT_STYLESHEET); - m_pBuildSettingsMenuItem->GetBuildSettingsButton()->setCursor(Qt::PointingHandCursor); - } - - if (!m_pPipelineStateItem->IsCurrent()) - { - m_pPipelineStateItem->GetPipelineStateButton()->setStyleSheet(s_BUTTON_FOCUS_OUT_STYLESHEET); - m_pPipelineStateItem->GetPipelineStateButton()->setCursor(Qt::PointingHandCursor); - } - } -} - -void rgMenuGraphics::mousePressEvent(QMouseEvent* pEvent) -{ - emit MenuClicked(); - emit FileMenuFocusInEvent(); -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgMenuItem.cpp b/RadeonGPUAnalyzerGUI/Src/rgMenuItem.cpp deleted file mode 100644 index 170c56c..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgMenuItem.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// Local. -#include -#include - -rgMenuItem::rgMenuItem(rgMenu* pParent) : - QWidget(pParent), - m_pParentMenu(pParent) -{ - setAttribute(Qt::WA_LayoutUsesWidgetRect); -} - -rgMenu* rgMenuItem::GetParentMenu() const -{ - return m_pParentMenu; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgMenuOpenCL.cpp b/RadeonGPUAnalyzerGUI/Src/rgMenuOpenCL.cpp deleted file mode 100644 index 29aefc5..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgMenuOpenCL.cpp +++ /dev/null @@ -1,643 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const char* s_BUTTON_FOCUS_IN_STYLESHEET_OPENCL = "QPushButton { background: rgb(253,255,174); border: 2px inset rgb(18, 152, 0); }"; - -rgMenuOpenCL::rgMenuOpenCL(QWidget* pParent) - : rgMenu(pParent) -{ -} - -void rgMenuOpenCL::InitializeDefaultMenuItems(const std::shared_ptr) -{ - // Insert the "Build Settings" item into the top of the menu. - m_pBuildSettingsMenuItem = new rgMenuBuildSettingsItem(); - m_pLayout->insertWidget(0, m_pBuildSettingsMenuItem); - - // Insert the "Add/Create" menu item to the top of the menu. - m_pAddCreateMenuItem = new rgAddCreateMenuItem(this); - m_pLayout->insertWidget(0, m_pAddCreateMenuItem); - - ConnectDefaultItemSignals(); - - ConnectButtonSignals(); - - // Make the menu as wide as the items. - const int height = m_pAddCreateMenuItem->height(); - this->resize(m_pAddCreateMenuItem->width(), 2 * (height)); - - // Register the buttons with the scaling manager. - ScalingManager::Get().RegisterObject(m_pBuildSettingsMenuItem); - ScalingManager::Get().RegisterObject(m_pAddCreateMenuItem); -} - -void rgMenuOpenCL::ConnectDefaultItemSignals() -{ - // Handler invoked when the "Add File" button is clicked within an API item. - bool isConnected = connect(m_pAddCreateMenuItem->GetAddButton(), &QPushButton::clicked, this, &rgMenu::OpenFileButtonClicked); - assert(isConnected); - - // Handler invoked when the "Create File" button is clicked within an API item. - isConnected = connect(m_pAddCreateMenuItem->GetCreateButton(), &QPushButton::clicked, this, &rgMenu::CreateFileButtonClicked); - assert(isConnected); -} - -void rgMenuOpenCL::ConnectButtonSignals() -{ - // Handler invoked when the "Build settings" button is clicked. - bool isConnected = connect(m_pBuildSettingsMenuItem->GetBuildSettingsButton(), &QPushButton::clicked, this, &rgMenu::BuildSettingsButtonClicked); - assert(isConnected); - - isConnected = connect(m_pBuildSettingsMenuItem->GetBuildSettingsButton(), &QPushButton::clicked, this, &rgMenu::HandleBuildSettingsButtonClicked); - assert(isConnected); -} - -void rgMenuOpenCL::ConnectMenuFileItemSignals(rgMenuFileItem* pMenuItem) -{ - rgMenuFileItemOpenCL* pOpenCLItem = static_cast(pMenuItem); - - assert(pOpenCLItem != nullptr); - if (pOpenCLItem != nullptr) - { - // Connect the close button for the file's menu item. - bool isConnected = connect(pOpenCLItem, &rgMenuFileItemOpenCL::MenuItemCloseButtonClicked, this, &rgMenu::MenuItemCloseButtonClicked); - assert(isConnected); - - // Connect the file menu item selection handler for each new item. - isConnected = connect(pOpenCLItem, &rgMenuFileItemOpenCL::MenuItemSelected, this, &rgMenu::MenuItemClicked); - assert(isConnected); - - // Connect the file menu item selection handler to update build settings button. - isConnected = connect(pMenuItem, &rgMenuFileItemOpenCL::MenuItemSelected, this, &rgMenu::HandleActivateItemAction); - assert(isConnected); - - // Connect the file menu item rename handler for each new item. - isConnected = connect(pOpenCLItem, &rgMenuFileItemOpenCL::FileRenamed, this, &rgMenu::HandleRenamedFile); - assert(isConnected); - - // Connect the file menu item's entry point changed handler. - isConnected = connect(pOpenCLItem, &rgMenuFileItemOpenCL::SelectedEntrypointChanged, this, &rgMenuOpenCL::SelectedEntrypointChanged); - assert(isConnected); - } -} - -bool rgMenuOpenCL::AddItem(const std::string& fullPath, bool isNewFileItem) -{ - bool wasAdded = false; - - // Extract the file name from the full file path. - std::string fileName; - bool isOk = rgUtils::ExtractFileName(fullPath, fileName); - assert(isOk); - if (isOk) - { - // If a file with that name hasn't been added. - if (m_fullFilepathToMenuItem.find(fullPath) == m_fullFilepathToMenuItem.end()) - { - // Create the menu item widget and add it to the UI and to the list. - rgMenuFileItemOpenCL* pNewMenuItem = new rgMenuFileItemOpenCL(fullPath, this); - m_menuItems.push_back(pNewMenuItem); - - // Connect to this file item to change the stylesheet when the build is successful. - bool isConnected = connect(this, &rgMenuOpenCL::ProjectBuildSuccess, pNewMenuItem, &rgMenuFileItemOpenCL::HandleProjectBuildSuccess); - assert(isConnected); - - // Emit a signal that indicates that the number of items in the menu change, - // and specify that the menu is not empty. - emit FileMenuItemCountChanged(false); - - // Add the file name and its full path to the map. - m_fullFilepathToMenuItem[fullPath] = pNewMenuItem; - - // Insert the item just above the default "CL" menu item. - const size_t index = (!m_menuItems.empty()) ? (m_menuItems.size() - 1) : 0; - m_pLayout->insertWidget(static_cast(index), pNewMenuItem, Qt::AlignTop); - - // Register the object with the scaling manager. - ScalingManager::Get().RegisterObject(pNewMenuItem); - - // Connect signals for the new file menu item. - ConnectMenuFileItemSignals(pNewMenuItem); - - // Select the file that was just opened. - HandleSelectedFileChanged(pNewMenuItem); - - if (isNewFileItem) - { - // If a file was newly-created (as opposed to being opened), display the - // item's renaming control immediately so the user can choose a new filename. - pNewMenuItem->ShowRenameControls(true); - } - - wasAdded = true; - } - else - { - // Report the error. - std::stringstream msg; - msg << STR_ERR_CANNOT_ADD_FILE_A << fileName << STR_ERR_CANNOT_ADD_FILE_B; - rgUtils::ShowErrorMessageBox(msg.str().c_str(), this); - } - } - - return wasAdded; -} - -void rgMenuOpenCL::ClearBuildOutputs() -{ - // Step through each file item in menu and clear the entry point list. - for (rgMenuFileItem* pFileItem : m_menuItems) - { - rgMenuFileItemOpenCL* pFileItemOpenCL = static_cast(pFileItem); - assert(pFileItemOpenCL != nullptr); - if (pFileItemOpenCL != nullptr) - { - pFileItemOpenCL->ClearEntrypointsList(); - } - } -} - -bool rgMenuOpenCL::GetIsShowEntrypointListEnabled() const -{ - return m_isShowEntrypointListEnabled; -} - -bool rgMenuOpenCL::OffsetCurrentFileEntrypoint(int offset) -{ - bool ret = false; - - // The offset should be a positive or negative integer. If it's not, something is wrong. - assert(offset != 0); - - // If focus index is in the range of the menu file items, select the appropriate file item. - bool isFocusInFileItemRange = m_focusIndex < m_menuItems.size(); - assert(isFocusInFileItemRange); - if (isFocusInFileItemRange) - { - rgMenuFileItem* pFileItem = m_menuItems[m_focusIndex]; - - rgMenuFileItemOpenCL* pOpenCLItem = static_cast(pFileItem); - - assert(pOpenCLItem != nullptr); - if (pOpenCLItem != nullptr) - { - // Get the list of entry point names in the current file. - std::vector entrypointNames; - pOpenCLItem->GetEntrypointNames(entrypointNames); - - if (!entrypointNames.empty()) - { - // Get the name of the currently selected entrypoint. - std::string selectedEntrypointName; - bool isEntrypointSelected = pOpenCLItem->GetSelectedEntrypointName(selectedEntrypointName); - if (isEntrypointSelected && !selectedEntrypointName.empty()) - { - // Compute the index of the currently selected entrypoint. - auto currentIndexIter = std::find(entrypointNames.begin(), entrypointNames.end(), selectedEntrypointName); - int selectedIndex = currentIndexIter - entrypointNames.begin(); - - // Offset the index, and check that it's still a valid index in the name list. - selectedIndex += offset; - if (selectedIndex >= 0 && selectedIndex < entrypointNames.size()) - { - // Emit a signal indicating that the selected entry point has changed. - auto nextEntrypointIter = entrypointNames.begin() + selectedIndex; - emit SelectedEntrypointChanged(pOpenCLItem->GetFilename(), *nextEntrypointIter); - ret = true; - } - } - } - } - } - - return ret; -} - -void rgMenuOpenCL::SetIsShowEntrypointListEnabled(bool isEnabled) -{ - m_isShowEntrypointListEnabled = isEnabled; - - // Disable the ability to expand file items' entry point list. - if (!isEnabled && m_pSelectedFileItem != nullptr) - { - rgMenuFileItemOpenCL* pMenuItemOpenCL = static_cast(m_pSelectedFileItem); - assert(pMenuItemOpenCL != nullptr); - if (pMenuItemOpenCL != nullptr) - { - pMenuItemOpenCL->ShowEntrypointsList(false); - } - } -} - -void rgMenuOpenCL::UpdateBuildOutput(const rgBuildOutputsMap& buildOutputs) -{ - std::string gpuWithOutputs; - std::shared_ptr pGpuOutputs = nullptr; - bool isOutputValid = rgUtils::GetFirstValidOutputGpu(buildOutputs, gpuWithOutputs, pGpuOutputs); - if (isOutputValid && (pGpuOutputs != nullptr)) - { - std::shared_ptr pGpuOutputsOpenCL = - std::dynamic_pointer_cast(pGpuOutputs); - - assert(pGpuOutputsOpenCL != nullptr); - if (pGpuOutputsOpenCL != nullptr) - { - // Step through each file item in the menu. - for (rgMenuFileItem* pFileItem : m_menuItems) - { - rgMenuFileItemOpenCL* pFileItemOpenCL = static_cast(pFileItem); - - // Find the build output with the current item's filename. - const std::string& itemFilename = pFileItem->GetFilename(); - auto outputIter = pGpuOutputsOpenCL->m_perFileOutput.find(itemFilename); - if (outputIter != pGpuOutputsOpenCL->m_perFileOutput.end()) - { - // Update the menu item with the outputs for the matching input file. - rgFileOutputs& fileOutputs = outputIter->second; - const std::vector& entryOutputs = fileOutputs.m_outputs; - pFileItemOpenCL->UpdateBuildOutputs(entryOutputs); - } - } - - // Does the user have a file selected in the menu? - rgMenuFileItemOpenCL* pFileItemOpenCL = static_cast(m_pSelectedFileItem); - if (pFileItemOpenCL != nullptr) - { - // Auto-expand the list of entrypoints in the selected file item. - const std::string& selectedFilename = pFileItemOpenCL->GetFilename(); - pFileItemOpenCL->ShowEntrypointsList(true); - } - } - } -} - -void rgMenuOpenCL::HandleBuildStarted() -{ - // Call the base class implementation. - rgMenu::HandleBuildStarted(); - - // Don't allow the user to expand the entry point list for file items. - SetIsShowEntrypointListEnabled(false); - - // While a build is in progress, disable adding/creating files or changing the build settings. - m_pAddCreateMenuItem->GetAddButton()->setEnabled(false); - m_pAddCreateMenuItem->GetCreateButton()->setEnabled(false); -} - -void rgMenuOpenCL::HandleBuildEnded() -{ - // Call the base class implementation. - rgMenu::HandleBuildEnded(); - - // Re-enable allowing the user to expand the entry point list for file items. - SetIsShowEntrypointListEnabled(true); - - // After the build is over, re-enable the menu items. - m_pAddCreateMenuItem->GetAddButton()->setEnabled(true); - m_pAddCreateMenuItem->GetCreateButton()->setEnabled(true); -} - -void rgMenuOpenCL::SelectFocusItem(FileMenuActionType actionType) -{ - assert(m_pBuildSettingsMenuItem != nullptr); - if (m_pBuildSettingsMenuItem != nullptr) - { - // Clear button style sheets. - if (!m_pBuildSettingsMenuItem->IsCurrent()) - { - m_pBuildSettingsMenuItem->GetBuildSettingsButton()->setStyleSheet(""); - } - QPushButton* pAddButton = m_pAddCreateMenuItem->GetAddButton(); - QPushButton* pCreateButton = m_pAddCreateMenuItem->GetCreateButton(); - assert(pAddButton != nullptr); - assert(pCreateButton != nullptr); - if (pAddButton != nullptr) - { - pAddButton->setStyleSheet(""); - } - if (pCreateButton != nullptr) - { - pCreateButton->setStyleSheet(""); - } - - // If focus index is in the range of the menu file items, select the appropriate file item. - if (m_focusIndex < m_menuItems.size()) - { - rgMenuFileItemOpenCL* pItem = static_cast(m_menuItems[m_focusIndex]); - assert(pItem != nullptr); - if (pItem != nullptr) - { - UpdateHighlight(pItem); - } - - // Update the cursor. - UpdateCursor(pItem); - } - else - { - // Deselect OpenCL menu file items. - for (rgMenuFileItem* pItem : m_menuItems) - { - rgMenuFileItemOpenCL* pItemOpenCL = static_cast(pItem); - assert(pItem != nullptr); - if (pItem != nullptr) - { - pItem->SetHovered(false); - } - } - - // If out of range, special case handle the last focus items. - // Get index excluding file items. - size_t index = m_focusIndex - m_menuItems.size(); - - // Handle special cases for Add, Create and Build settings buttons. - switch (index) - { - case static_cast(FileMenuFocusItems::AddButton) : - { - if (pAddButton != nullptr) - { - pAddButton->setStyleSheet(s_BUTTON_FOCUS_IN_STYLESHEET_OPENCL); - } - break; - } - case static_cast(FileMenuFocusItems::CreateButton): - { - if (pCreateButton != nullptr) - { - pCreateButton->setStyleSheet(s_BUTTON_FOCUS_IN_STYLESHEET_OPENCL); - } - break; - } - case static_cast(FileMenuFocusItems::BuildSettingsButton): - m_pBuildSettingsMenuItem->GetBuildSettingsButton()->setStyleSheet(s_BUTTON_FOCUS_IN_STYLESHEET_OPENCL); - break; - default: - // Should never get here. - assert(false); - break; - } - } - } -} - -void rgMenuOpenCL::HandleActivateItemAction() -{ - assert(m_pAddCreateMenuItem != nullptr); - if (m_pAddCreateMenuItem != nullptr) - { - // If focus index is in the range of the menu file items, select the appropriate file item. - if (m_focusIndex < m_menuItems.size()) - { - SelectFile(m_menuItems[m_focusIndex]); - - // Set the build settings button to have focus out style sheets. - assert(m_pBuildSettingsMenuItem != nullptr); - if (m_pBuildSettingsMenuItem != nullptr) - { - m_pBuildSettingsMenuItem->SetCurrent(false); - m_pBuildSettingsMenuItem->GetBuildSettingsButton()->setStyleSheet(s_BUTTON_FOCUS_OUT_STYLESHEET); - - // Set the cursors. - m_pBuildSettingsMenuItem->GetBuildSettingsButton()->setCursor(Qt::PointingHandCursor); - } - } - else - { - // Deselect menu file items. - for (rgMenuFileItem* pItem : m_menuItems) - { - rgMenuFileItemOpenCL* pItemOpenCL = static_cast(pItem); - assert(pItemOpenCL != nullptr); - if (pItemOpenCL != nullptr) - { - pItemOpenCL->SetHovered(false); - pItemOpenCL->SetCurrent(false); - } - } - - // If out of range, special case handle the last focus items. - // Get index excluding file items. - size_t index = m_focusIndex - m_menuItems.size(); - - // Handle special cases for Add, Create and Build settings buttons. - switch (index) - { - case static_cast(FileMenuFocusItems::AddButton): - { - QPushButton * pAddButton = m_pAddCreateMenuItem->GetAddButton(); - assert(pAddButton != nullptr); - if (pAddButton != nullptr) - { - pAddButton->click(); - } - break; - } - case static_cast(FileMenuFocusItems::CreateButton): - { - QPushButton * pCreateButton = m_pAddCreateMenuItem->GetCreateButton(); - assert(pCreateButton != nullptr); - if (pCreateButton != nullptr) - { - pCreateButton->click(); - } - break; - } - case static_cast(FileMenuFocusItems::BuildSettingsButton): - assert(m_pBuildSettingsMenuItem != nullptr); - if (m_pBuildSettingsMenuItem != nullptr) - { - m_pBuildSettingsMenuItem->GetBuildSettingsButton()->setStyleSheet(s_BUTTON_FOCUS_IN_STYLESHEET); - m_pBuildSettingsMenuItem->GetBuildSettingsButton()->click(); - } - break; - default: - // Should never get here. - assert(false); - break; - } - } - } -} - -void rgMenuOpenCL::HandleBuildSettingsButtonClicked(bool /*checked*/) -{ - // Set the stylesheet for each file menu item to be not selected (grayed out), - // along with the mouse cursor to pointing hand cursor. - for (rgMenuFileItem* pItem : m_menuItems) - { - pItem->SetHovered(false); - pItem->SetCurrent(false); - pItem->setCursor(Qt::PointingHandCursor); - } - - // Set the focus index. - m_focusIndex = m_menuItems.size() + GetButtonCount() - 1; - - // Set the "current" property value to true for build settings button. - m_pBuildSettingsMenuItem->SetCurrent(true); - - // Set the focus for the build settings button stylesheet. - m_pBuildSettingsMenuItem->GetBuildSettingsButton()->setStyleSheet(s_BUTTON_FOCUS_IN_STYLESHEET_OPENCL); - - // Set the mouse cursor for the build settings button. - m_pBuildSettingsMenuItem->GetBuildSettingsButton()->setCursor(Qt::ArrowCursor); -} - -void rgMenuOpenCL::HandleSelectedEntrypointChanged(const std::string& inputFilePath, const std::string& selectedEntrypointName) -{ - // Find the given input file and select the incoming entry point name. - for (rgMenuFileItem* pFileItem : m_menuItems) - { - if (pFileItem->GetFilename().compare(inputFilePath) == 0) - { - rgMenuFileItemOpenCL* pFileItemOpenCL = static_cast(pFileItem); - assert(pFileItemOpenCL != nullptr); - if (pFileItemOpenCL != nullptr) - { - // Switch to the given entry point in the file item's entry point list. - pFileItemOpenCL->SwitchToEntrypointByName(selectedEntrypointName); - } - } - } -} - -void rgMenuOpenCL::HandleNextItemAction() -{ - size_t endIndex = m_menuItems.size() + 2; - - // If a file item is currently selected, switch to the next available entrypoint. - bool nextEntrypointSelected = false; - if (m_focusIndex < m_menuItems.size()) - { - nextEntrypointSelected = OffsetCurrentFileEntrypoint(1); - } - - if (!nextEntrypointSelected) - { - // Increment focus index and wrap around. - m_focusIndex++; - if (m_focusIndex > endIndex) - { - m_focusIndex = 0; - } - - // Refresh focus. - SelectFocusItem(FileMenuActionType::ArrowAction); - } -} - -void rgMenuOpenCL::HandlePreviousItemAction() -{ - size_t endIndex = m_menuItems.size() + 2; - - // If a file item is currently selected, switch to the next available entrypoint. - bool previousEntrypointSelected = false; - if (m_focusIndex < m_menuItems.size()) - { - previousEntrypointSelected = OffsetCurrentFileEntrypoint(-1); - } - - if (!previousEntrypointSelected) - { - // Decrement focus index and wrap around. - if (m_focusIndex != 0) - { - m_focusIndex--; - } - else - { - m_focusIndex = endIndex; - } - - // Refresh focus. - SelectFocusItem(FileMenuActionType::ArrowAction); - } -} - -void rgMenuOpenCL::HandleSourceFileAdded() -{ - rgMenuBuildSettingsItem* pBuildSettingsButton = GetBuildSettingsItem(); - assert(pBuildSettingsButton != nullptr); - if (pBuildSettingsButton != nullptr) - { - pBuildSettingsButton->SetCurrent(false); - } -} - -int rgMenuOpenCL::GetButtonCount() const -{ - // There are 3 extra buttons besides the file items: - // Add existing file - // Create new file - // Build settings - static const int s_EXTRA_OPENCL_BUTTON_COUNT = 3; - return s_EXTRA_OPENCL_BUTTON_COUNT; -} - -void rgMenuOpenCL::HandleSelectedFileChanged(rgMenuFileItem* pSelected) -{ - // Set focus index to newly selected item. - for (size_t i = 0; i < m_menuItems.size(); i++) - { - if (m_menuItems[i] == pSelected) - { - m_focusIndex = i; - m_tabFocusIndex = i; - break; - } - } - - // Display the currently selected file in the source editor. - DisplayFileInEditor(m_menuItems[m_focusIndex]); -} - -void rgMenuOpenCL::SetButtonsNoFocus() -{ - assert(m_pBuildSettingsMenuItem != nullptr); - - // Set the build settings button to have focus out style sheets. - if (m_pBuildSettingsMenuItem != nullptr) - { - QPushButton* pBuildSettingsButton = m_pBuildSettingsMenuItem->GetBuildSettingsButton(); - assert(pBuildSettingsButton != nullptr); - if (pBuildSettingsButton != nullptr) - { - pBuildSettingsButton->setStyleSheet(s_BUTTON_FOCUS_OUT_STYLESHEET); - } - } -} - -void rgMenuOpenCL::SelectTabFocusItem(bool shiftTabFocus) -{ - // @TODO: Need to add tabbing functionality in OpenCL file menu. -} - -void rgMenuOpenCL::HandleTabFocusPressed() -{ - // @TODO: Need to add tabbing functionality in OpenCL file menu. -} - -void rgMenuOpenCL::HandleShiftTabFocusPressed() -{ - // @TODO: Need to add tabbing functionality in OpenCL file menu. -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgMenuPipelineStateItem.cpp b/RadeonGPUAnalyzerGUI/Src/rgMenuPipelineStateItem.cpp deleted file mode 100644 index 334cb09..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgMenuPipelineStateItem.cpp +++ /dev/null @@ -1,219 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include -#include -#include - -// Local. -#include -#include - -static const char* s_BUTTON_FOCUS_IN_STYLESHEET_GRAPHICS = "QPushButton { background: rgb(253,255,174); border-style: solid; border-width: 2px; border-color: rgb(135, 20, 16);}"; -static const char* s_BUTTON_FOCUS_OUT_STYLESHEET = "QPushButton { margin: 1px; background: rgb(214, 214, 214);}"; -static const char* s_STR_DEFAULT_PIPELINE_FILE_EXTENSION_GRAPHICS = "gpso"; -static const char* s_STR_DEFAULT_PIPELINE_FILE_EXTENSION_COMPUTE = "cpso"; -static const char* s_FILE_EXTENSION_DELIMITER = "."; - -rgMenuPipelineStateItem::rgMenuPipelineStateItem(rgPipelineType pipelineType, rgMenu* pParent) - : m_pipelineType(pipelineType), - rgMenuItem(pParent) -{ - ui.setupUi(this); - - // Set the status bar tip. - this->setStatusTip(STR_GRAPHICS_MENU_PIPELINE_STATE_TOOLTIP); - - // Set the tool tip. - this->setToolTip(STR_GRAPHICS_MENU_PIPELINE_STATE_TOOLTIP); - - // Set the mouse cursor to arrow cursor. - SetCursor(Qt::PointingHandCursor); - - // Connect the file menu signals. - ConnectSignals(); - - // Enable drag and drop. - setAcceptDrops(true); -} - -void rgMenuPipelineStateItem::ConnectSignals() -{ - // Connect the "Pipeline State" button to a handler to convert the parameter. - bool isConnected = connect(ui.pipelineStateButton, &QPushButton::clicked, this, &rgMenuPipelineStateItem::HandlePipelineStateButtonClicked); - assert(isConnected); -} - -void rgMenuPipelineStateItem::HandlePipelineStateButtonClicked(bool checked) -{ - Q_UNUSED(checked); - - emit PipelineStateButtonClicked(this); -} - -void rgMenuPipelineStateItem::SetItemText(const std::string& itemText) -{ - ui.pipelineStateButton->setText(itemText.c_str()); -} - -QPushButton* rgMenuPipelineStateItem::GetPipelineStateButton() const -{ - return ui.pipelineStateButton; -} - -void rgMenuPipelineStateItem::GotFocus() -{ - // Set arrow cursor so it doesn't appear that the user can click on the button again. - ui.pipelineStateButton->setCursor(Qt::ArrowCursor); - - // Set stylesheet. - ui.pipelineStateButton->setStyleSheet(s_BUTTON_FOCUS_IN_STYLESHEET_GRAPHICS); -} - -void rgMenuPipelineStateItem::LostFocus() -{ - // Set pointing hand cursor so it looks like the user can click on it. - ui.pipelineStateButton->setCursor(Qt::PointingHandCursor); - - // Set stylesheet. - ui.pipelineStateButton->setStyleSheet(s_BUTTON_FOCUS_OUT_STYLESHEET); -} - -void rgMenuPipelineStateItem::SetCursor(const QCursor& cursor) -{ - // Set the mouse cursor to the specified type. - ui.pipelineStateButton->setCursor(cursor); -} - -void rgMenuPipelineStateItem::SetCurrent(bool isCurrent) -{ - m_current = isCurrent; - - if (m_current) - { - GotFocus(); - } - else - { - LostFocus(); - } -} - -bool rgMenuPipelineStateItem::IsCurrent() const -{ - return m_current; -} - -void rgMenuPipelineStateItem::ClickMenuItem() const -{ - QPushButton* pPipelineStateButton = GetPipelineStateButton(); - assert(pPipelineStateButton != nullptr); - if (pPipelineStateButton != nullptr) - { - pPipelineStateButton->click(); - } -} - -void rgMenuPipelineStateItem::dragEnterEvent(QDragEnterEvent* pEvent) -{ - assert(pEvent != nullptr); - if (pEvent != nullptr) - { - const QMimeData* pMimeData = pEvent->mimeData(); - assert(pMimeData != nullptr); - if (pMimeData != nullptr) - { - const int numFiles = pMimeData->urls().size(); - - // Make sure the drop data has only one file url, and is a valid file. - if (pMimeData->hasUrls() && (numFiles == 1)) - { - // Check to make sure the file is valid. - QUrl url = pMimeData->urls().at(0); - - // Verify we have the correct file for the current pipeline type. - bool validFile = false; - QString extension; - const QString filePath = url.toLocalFile(); - QStringList nameExtension = filePath.split(s_FILE_EXTENSION_DELIMITER); - assert(nameExtension.size() == 2); - if (nameExtension.size() == 2) - { - extension = filePath.split(".").at(1); - if (m_pipelineType == rgPipelineType::Graphics && extension.compare(s_STR_DEFAULT_PIPELINE_FILE_EXTENSION_GRAPHICS) == 0) - { - validFile = true; - } - else if (m_pipelineType == rgPipelineType::Compute && extension.compare(s_STR_DEFAULT_PIPELINE_FILE_EXTENSION_COMPUTE) == 0) - { - validFile = true; - } - - if (url.isLocalFile() && validFile) - { - // Accept the action, making it so we receive a dropEvent when the items are released. - pEvent->setDropAction(Qt::DropAction::CopyAction); - pEvent->accept(); - - // Change the item's background color. - SetCurrent(true); - } - else - { - pEvent->ignore(); - } - } - else - { - pEvent->ignore(); - } - } - else - { - pEvent->ignore(); - } - } - } -} - -void rgMenuPipelineStateItem::dropEvent(QDropEvent* pEvent) -{ - assert(pEvent != nullptr); - if (pEvent != nullptr) - { - const QMimeData* pMimeData = pEvent->mimeData(); - assert(pMimeData != nullptr); - if (pMimeData != nullptr) - { - // Make sure the drop data has a file. - if (pMimeData->hasUrls()) - { - // Check to make sure the file is valid. - QUrl url = pMimeData->urls().at(0); - if (url.isLocalFile()) - { - // Get the file path. - std::string filePath = url.toLocalFile().toStdString(); - - // Click the button. - HandlePipelineStateButtonClicked(false); - - // Emit a signal to open an existing PSO file. - emit DragAndDropExistingFile(filePath); - } - } - else - { - pEvent->ignore(); - } - } - } -} - -void rgMenuPipelineStateItem::dragLeaveEvent(QDragLeaveEvent* pEvent) -{ - // Change the item's background color. - SetCurrent(false); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgMenuTitlebar.cpp b/RadeonGPUAnalyzerGUI/Src/rgMenuTitlebar.cpp deleted file mode 100644 index d8bdc05..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgMenuTitlebar.cpp +++ /dev/null @@ -1,220 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include -#include -#include -#include -#include - -// Infra. -#include - -// Local -#include -#include -#include - -// Fixed height of the project title item. -static const int s_PROJECT_TITLE_ITEM_HEIGHT = 28; - -// File menu bar stylesheets. -static const char* s_STR_FILEMENU_TITLE_BAR_TOOLTIP_WIDTH = "min-width: %1px; width: %2px;"; -static const char* s_STR_FILEMENU_TITLE_BAR_TOOLTIP_HEIGHT = "min-height: %1px; height: %2px; max-height: %3px;"; - -rgMenuTitlebar::rgMenuTitlebar(QWidget* pParent) : - QWidget(pParent) -{ - // Create basic layout to hold the background. - QVBoxLayout* pLayout = new QVBoxLayout(); - pLayout->setContentsMargins(0, 0, 0, 0); - setLayout(pLayout); - - // Create the background widget. - QWidget* pBackground = new QWidget(); - pBackground->setObjectName("itemBackground"); - pLayout->addWidget(pBackground); - - // Create main layout. - m_pMainLayout = new QVBoxLayout(); - m_pMainLayout->setContentsMargins(6, 6, 6, 6); - pBackground->setLayout(m_pMainLayout); - - // Create stacked layout. - m_pStackedLayout = new QStackedLayout(); - m_pMainLayout->addLayout(m_pStackedLayout); - - // Create label and editor. - m_pTitleLabel = new QLabel(); - m_pTitleTextEdit = new QLineEdit(); - - // Add widgets to layout. - m_pStackedLayout->addWidget(m_pTitleLabel); - m_pStackedLayout->addWidget(m_pTitleTextEdit); - - // Connect the handler for when texting editing is finished. - bool isConnected = connect(m_pTitleTextEdit, &QLineEdit::editingFinished, this, &rgMenuTitlebar::StopEditing); - assert(isConnected); - isConnected = connect(m_pTitleTextEdit, &QLineEdit::returnPressed, this, &rgMenuTitlebar::HandleReturnPressed); - assert(isConnected); - - // Force size for this item. - setMinimumSize(0, s_PROJECT_TITLE_ITEM_HEIGHT); - setMaximumSize(QWIDGETSIZE_MAX, s_PROJECT_TITLE_ITEM_HEIGHT); - - // Set mouse cursor to pointing hand cursor. - SetCursor(); -} - -rgMenuTitlebar::~rgMenuTitlebar() -{ - m_pTitleLabel->deleteLater(); - m_pTitleTextEdit->deleteLater(); - m_pStackedLayout->deleteLater(); -} - -void rgMenuTitlebar::SetTitle(const std::string& title) -{ - // Set widget text. - m_pTitleLabel->setText(title.c_str()); - m_pTitleTextEdit->setText(title.c_str()); - - // Refresh the tooltip. - RefreshTooltip(title.c_str()); -} - -void rgMenuTitlebar::StartEditing() -{ - // Set the initial line edit text from the title label text. - std::string labelText = m_pTitleLabel->text().toStdString(); - labelText = labelText.substr(labelText.find("") + 4); - - m_pTitleTextEdit->setText(labelText.c_str()); - - // Show the line edit widget. - m_pStackedLayout->setCurrentWidget(m_pTitleTextEdit); - - // Default focus on the line edit. - m_pTitleTextEdit->setFocus(); - m_pTitleTextEdit->setSelection(0, static_cast(m_pTitleLabel->text().length())); -} - -void rgMenuTitlebar::StopEditing() -{ - m_pTitleTextEdit->blockSignals(true); - - // Trim the leading and trailing whitespace characters from the project name. - std::string updatedProjectName = m_pTitleTextEdit->text().toStdString(); - rgUtils::TrimLeadingAndTrailingWhitespace(updatedProjectName, updatedProjectName); - - if (rgUtils::IsValidProjectName(updatedProjectName)) - { - // Check if the text has changed during editing. - std::string labelText = m_pTitleLabel->text().toStdString(); - labelText = labelText.substr(labelText.find("") + 4); - - if (labelText.compare(updatedProjectName) != 0) - { - // Set the new title text from the edited line text. - std::stringstream updatedTitle; - updatedTitle << rgUtils::GetProjectTitlePrefix(rgProjectAPI::OpenCL) << updatedProjectName; - m_pTitleLabel->setText(updatedTitle.str().c_str()); - - // Indicate the title text has been changed. - emit TitleChanged(updatedProjectName); - - // Update the tooltip. - std::stringstream updatedToolTip; - updatedToolTip << STR_FILE_MENU_PROJECT_TITLE_TOOLTIP_A << updatedProjectName; - - // Refresh the tooltip. - RefreshTooltip(updatedToolTip.str()); - } - - // Show the title label widget. - m_pStackedLayout->setCurrentWidget(m_pTitleLabel); - } - else - { - // Notify the user that the project name is illegal. - std::stringstream msg; - msg << STR_ERR_ILLEGAL_PROJECT_NAME << " \""; - msg << updatedProjectName << "\"."; - rgUtils::ShowErrorMessageBox(msg.str().c_str()); - - // Keep focus on the line edit. - m_pTitleTextEdit->setFocus(); - m_pTitleTextEdit->setSelection(0, static_cast(m_pTitleLabel->text().length())); - } - - m_pTitleTextEdit->blockSignals(false); -} - -void rgMenuTitlebar::mouseDoubleClickEvent(QMouseEvent* pEvent) -{ - if (pEvent != nullptr && pEvent->button() == Qt::LeftButton) - { - StartEditing(); - } -} - -void rgMenuTitlebar::keyPressEvent(QKeyEvent* pEvent) -{ - if (pEvent->key() == Qt::Key_Escape) - { - // Block signals from the text edit before - // switching the index on the stacked widget. - // Not blocking the signals here will cause - // an editingFinished/StopEditing signal/slot - // to execute when the text edit loses focus, - // causing undesired behavior. - const QSignalBlocker signalBlocker(m_pTitleTextEdit); - - // Switch the stacked widget to the title label. - assert(m_pStackedLayout != nullptr); - if (m_pStackedLayout != nullptr) - { - m_pStackedLayout->setCurrentWidget(m_pTitleLabel); - } - } - else - { - // Pass the event onto the base class - QWidget::keyPressEvent(pEvent); - } -} - -void rgMenuTitlebar::RefreshTooltip(const std::string& updatedTooltip) -{ - // Make full tooltip string. - std::string tooltip = updatedTooltip + STR_FILE_MENU_PROJECT_TITLE_TOOLTIP_B; - - // Set tooltip. - QString tooltipFormatted = "

"; - tooltipFormatted += QString::fromStdString(tooltip); - tooltipFormatted += "

"; - - // Set tool and status tip. - rgUtils::SetToolAndStatusTip(tooltipFormatted.toStdString(), this); - - // Set status tip since we do not want the formatted string for the status bar. - rgUtils::SetStatusTip(tooltip, this); -} - -void rgMenuTitlebar::HandleReturnPressed() -{ - m_pTitleTextEdit->blockSignals(true); - - // When return is pressed to end editing, redirect the focus. - rgUtils::FocusOnFirstValidAncestor(this); - - m_pTitleTextEdit->blockSignals(false); -} - -void rgMenuTitlebar::SetCursor() -{ - // Set mouse cursor to pointing hand cursor. - setCursor(Qt::PointingHandCursor); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgMenuVulkan.cpp b/RadeonGPUAnalyzerGUI/Src/rgMenuVulkan.cpp deleted file mode 100644 index 2d13dc6..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgMenuVulkan.cpp +++ /dev/null @@ -1,420 +0,0 @@ -// C++. -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include - -rgMenuVulkan::rgMenuVulkan(QWidget* pParent) - : rgMenuGraphics(pParent) -{ -} - -void rgMenuVulkan::ConnectDefaultItemSignals() -{ - // Handler invoked when the "Build settings" button is clicked. - assert(m_pBuildSettingsMenuItem != nullptr); - if (m_pBuildSettingsMenuItem != nullptr) - { - bool isConnected = connect(m_pBuildSettingsMenuItem->GetBuildSettingsButton(), &QPushButton::clicked, this, &rgMenu::HandleBuildSettingsButtonClicked); - assert(isConnected); - } -} - -void rgMenuVulkan::ConnectMenuFileItemSignals(rgMenuFileItem* pMenuItem) -{ - // Connect the file menu item selection handler for each new item. - bool isConnected = connect(pMenuItem, &rgMenuFileItemGraphics::MenuItemSelected, this, &rgMenu::MenuItemClicked); - assert(isConnected); - - // Connect the file menu item rename handler for each new item. - isConnected = connect(pMenuItem, &rgMenuFileItem::FileRenamed, this, &rgMenu::HandleRenamedFile); - assert(isConnected); -} - -void rgMenuVulkan::DeselectItems() -{ - rgMenu::DeselectItems(); - - assert(m_pPipelineStateItem); - if (m_pPipelineStateItem != nullptr) - { - m_pPipelineStateItem->SetCurrent(false); - } -} - -void rgMenuVulkan::ClearStageSourceFile(rgPipelineStage stage) -{ - // Find the target stage item and update the attached shader file. - rgMenuFileItemGraphics* pStageItem = GetStageItem(stage); - - assert(pStageItem != nullptr); - if (pStageItem != nullptr) - { - // Erase the file path from the path to menu item map. - const std::string& pathBeingRemoved = pStageItem->GetFilename(); - auto filePathToItemMapIter = m_fullFilepathToMenuItem.find(pathBeingRemoved); - if (filePathToItemMapIter != m_fullFilepathToMenuItem.end()) - { - m_fullFilepathToMenuItem.erase(filePathToItemMapIter); - } - - // Clear out the filepath for the stage item. - pStageItem->SetShaderFile("", rgVulkanInputType::Unknown); - - // Set the "occupied" property for this file item. - pStageItem->SetStageIsOccupied(false); - - // Set the "current" property for this file item. - pStageItem->SetCurrent(false); - - // Set the cursor type to arrow cursor. - pStageItem->SetCursor(Qt::ArrowCursor); - - // Set the "+" sub button as selected. - RemoveSubButtonFocus(); - HideRemoveFilePushButton(); - pStageItem->SetButtonHighlighted(GraphicsMenuTabFocusItems::AddExistingFileButton); - m_hasTabFocus = GraphicsMenuTabFocusItems::AddExistingFileButton; - - // Also set the tab focus index and focus index. - // Find out if one of the buttons is currently selected. - // If so, do not update the focus index. - if (!IsButtonPressed()) - { - if (stage == rgPipelineStage::Compute) - { - m_focusIndex = 0; - } - else - { - m_focusIndex = static_cast(stage); - } - m_tabFocusIndex = m_focusIndex; - } - - // Remove the item from the list. - for (auto it = m_menuItems.begin(); it != m_menuItems.end(); it++) - { - if (*it == pStageItem) - { - m_menuItems.erase(it); - break; - } - } - } - - // Emit a signal that indicates that the number of items in the menu change, - // and specify that the menu is not empty. - emit FileMenuItemCountChanged(false); -} - -bool rgMenuVulkan::IsButtonPressed() const -{ - bool buttonPressed = false; - - assert(m_pBuildSettingsMenuItem != nullptr); - assert(m_pPipelineStateItem != nullptr); - if (m_pBuildSettingsMenuItem != nullptr && m_pPipelineStateItem != nullptr) - { - buttonPressed = m_pBuildSettingsMenuItem->IsCurrent() || m_pPipelineStateItem->IsCurrent(); - } - - return buttonPressed; -} - -bool rgMenuVulkan::SetStageSourceFile(rgPipelineStage stage, const std::string& fullPath, rgVulkanInputType fileType, bool isNewFileItem) -{ - bool ret = false; - - // If a file with that name hasn't been added. - if (!IsFileInMenu(fullPath)) - { - // Find the target stage item and update the attached shader file. - rgMenuFileItemGraphics* pStageItem = GetStageItem(stage); - - assert(pStageItem != nullptr); - if (pStageItem != nullptr) - { - pStageItem->SetShaderFile(fullPath, fileType); - - // Since users may add shader files to the pipeline stages in any order they choose, in - // order to use the Up/Down arrow keys to navigate through shader stage items, a linear - // list of menu items must be reconstructed. - RebuildMenuItemsList(); - - // Set the "occupied" property for this file item. - pStageItem->SetStageIsOccupied(true); - - // Set the cursor for this item. - UpdateCursor(pStageItem); - - // Hide the "Remove" button. - pStageItem->RemoveSubButtonFocus(); - pStageItem->HideRemoveFilePushButton(); - - ret = true; - } - - // Emit a signal that indicates that the number of items in the menu change, - // and specify that the menu is not empty. - emit FileMenuItemCountChanged(false); - - // Add the file name and its full path to the map. - m_fullFilepathToMenuItem[fullPath] = pStageItem; - - // Connect signals for the new file menu item. - ConnectMenuFileItemSignals(pStageItem); - - // Select the file that was just opened. - HandleSelectedFileChanged(pStageItem); - - if (isNewFileItem) - { - // If a file was newly-created (as opposed to being opened), display the - // item's renaming control immediately so the user can choose a new filename. - pStageItem->ShowRenameControls(true); - } - - } - else - { - // Report the error. - std::stringstream msg; - msg << STR_ERR_CANNOT_ADD_FILE_A << fullPath << STR_ERR_CANNOT_ADD_FILE_B; - rgUtils::ShowErrorMessageBox(msg.str().c_str(), this); - - // Remove the highlight. - rgMenuFileItemGraphics* pStageItem = GetStageItem(stage); - - assert(pStageItem != nullptr); - if (pStageItem != nullptr) - { - pStageItem->SetCurrent(false); - pStageItem->SetHovered(false); - } - - // Set the highlight for the current stage. - pStageItem = GetCurrentFileMenuItem(); - assert(pStageItem != nullptr); - if (pStageItem != nullptr) - { - pStageItem->SetCurrent(true); - pStageItem->SetHovered(true); - } - } - - return ret; -} - -bool rgMenuVulkan::ReplaceStageFile(rgPipelineStage stage, const std::string& newFilePath, rgVulkanInputType fileType) -{ - bool ret = false; - rgMenuFileItemGraphics* pFileItem = GetStageItem(stage); - assert(pFileItem != nullptr); - if (pFileItem != nullptr) - { - // Replace the file path in the file to item map. - const std::string& oldFilePath = pFileItem->GetFilename(); - auto it = m_fullFilepathToMenuItem.find(oldFilePath); - if (it != m_fullFilepathToMenuItem.end()) - { - assert(it->second == pFileItem); - if (it->second == pFileItem) - { - m_fullFilepathToMenuItem.erase(it); - m_fullFilepathToMenuItem[newFilePath] = pFileItem; - ret = true; - } - } - - // Replace the file path in the item. - pFileItem->SetShaderFile(newFilePath, fileType); - } - - return ret; -} - -void rgMenuVulkan::HandleActivateItemAction() -{ - // If focus index is in the range of the menu file items, select the appropriate file item. - const size_t totalStages = GetTotalPipelineStages(); - if (m_pipelineType == rgPipelineType::Graphics && m_tabFocusIndex < totalStages || - m_pipelineType == rgPipelineType::Compute && m_tabFocusIndex <= totalStages) - { - // See if a sub button is selected, - // and then execute accordingly. - if (m_hasTabFocus != GraphicsMenuTabFocusItems::NoButton) - { - // If the user hit enter when one of the sub-buttons were highlighted, - // process accordingly. - ProcessSubButtonAction(); - } - else if (m_focusIndex < m_menuItems.size()) - { - SelectFile(m_menuItems[m_focusIndex]); - m_pBuildSettingsMenuItem->SetCurrent(false); - m_pPipelineStateItem->SetCurrent(false); - } - else - { - // Local index: this is the index of the relevant - // item within the menu items after filtering out - // the file items (leaving only the other buttons: - // pipeline state and build settings). - const int PIPELINE_STATE_ITEM_LOCAL_INDEX = 0; - const int BUILD_SETTINGS_ITEM_LOCAL_INDEX = 1; - - // Calculate the index of the relevant item. - const int buttonCount = GetButtonCount(); - const size_t numOfFileItems = m_menuItems.size(); - size_t targetItemIndex = static_cast(m_tabFocusIndex) - numOfFileItems; - assert(targetItemIndex == 0 || targetItemIndex == 1); - if (targetItemIndex == PIPELINE_STATE_ITEM_LOCAL_INDEX) - { - // This is the pipeline state button - simulate a click. - m_pPipelineStateItem->ClickMenuItem(); - } - else if(targetItemIndex == BUILD_SETTINGS_ITEM_LOCAL_INDEX) - { - // This is the build settings button - simulate a click. - m_pBuildSettingsMenuItem->ClickMenuItem(); - } - else - { - // We shouldn't get here. - assert(false); - } - } - - RemoveFileMenuButtonFocus(); - } - else - { - // Deselect graphics menu file items. - for (rgMenuFileItem* pItem : m_menuItems) - { - rgMenuFileItemGraphics* pItemGraphics = static_cast(pItem); - assert(pItemGraphics != nullptr); - if (pItemGraphics != nullptr) - { - pItemGraphics->SetHovered(false); - pItemGraphics->SetCurrent(false); - } - } - - // If out of range, special case handle the last focus items. - // Get index excluding file items. - size_t index = m_focusIndex - totalStages; - - // Handle special cases for pipeline state and build settings item. - switch (index) - { - case static_cast(GraphicsMenuFocusItems::BuildSettingsButton) : - m_pBuildSettingsMenuItem->GetBuildSettingsButton()->setStyleSheet(s_BUTTON_FOCUS_IN_STYLESHEET); - m_pBuildSettingsMenuItem->GetBuildSettingsButton()->click(); - break; - case static_cast(GraphicsMenuFocusItems::PipelineStateButton) : - GetPipelineStateItem()->GetPipelineStateButton()->setStyleSheet(s_BUTTON_FOCUS_IN_STYLESHEET); - GetPipelineStateItem()->GetPipelineStateButton()->click(); - break; - default: - // Should never get here. - assert(false); - break; - } - } -} - -void rgMenuVulkan::ProcessSubButtonAction() -{ - const size_t totalStages = GetTotalPipelineStages(); - assert(m_tabFocusIndex < totalStages); - if (m_tabFocusIndex < totalStages) - { - rgMenuFileItemGraphics* pItem = GetCurrentFileMenuItem(); - assert(pItem != nullptr); - if (pItem != nullptr) - { - switch (m_hasTabFocus) - { - case (GraphicsMenuTabFocusItems::RemoveButton): - pItem->ProcessRemoveButtonClick(); - break; - case (GraphicsMenuTabFocusItems::AddExistingFileButton): - pItem->ProcessAddExistingFileButtonClick(); - break; - default: - // Do not assert here. - // Doing so will cause asserts any time the user - // clicks on a file menu item, or hits enter when - // a file menu item has the focus. - break; - } - } - } -} - -void rgMenuVulkan::HandleSelectedFileChanged(rgMenuFileItem* pSelected) -{ - rgMenuFileItemGraphics* pGraphicsItem = qobject_cast(pSelected); - assert(pGraphicsItem != nullptr); - - // Set focus index to newly selected item. - for (size_t i = 0; i < m_menuItems.size() && pGraphicsItem != nullptr; i++) - { - if (m_menuItems[i] == pSelected) - { - // Update the focus and tab indices. Compute indices are always - // 0 because there's only 1 item in the compute pipeline menu. - rgPipelineStage stageType = pGraphicsItem->GetStage(); - if (stageType != rgPipelineStage::Compute) - { - m_focusIndex = static_cast(stageType); - m_tabFocusIndex = static_cast(stageType); - } - else - { - m_focusIndex = 0; - m_tabFocusIndex = 0; - } - break; - } - } - - // Update the current stage value. - if (pGraphicsItem != nullptr) - { - m_currentStage = pGraphicsItem->GetStage(); - } - - // Display the currently selected file in the source editor. - DisplayFileInEditor(pSelected); - - // Update button selection values. - m_pPipelineStateItem->SetCurrent(false); - m_pBuildSettingsMenuItem->SetCurrent(false); - - // Set the pipeline state and build settings buttons to have focus out style sheets. - assert(m_pBuildSettingsMenuItem); - assert(m_pPipelineStateItem); - if (m_pBuildSettingsMenuItem != nullptr && m_pPipelineStateItem != nullptr) - { - m_pBuildSettingsMenuItem->GetBuildSettingsButton()->setStyleSheet(s_BUTTON_FOCUS_OUT_STYLESHEET); - m_pBuildSettingsMenuItem->GetBuildSettingsButton()->setCursor(Qt::PointingHandCursor); - - m_pPipelineStateItem->GetPipelineStateButton()->setStyleSheet(s_BUTTON_FOCUS_OUT_STYLESHEET); - m_pPipelineStateItem->GetPipelineStateButton()->setCursor(Qt::PointingHandCursor); - } -} - -void rgMenuVulkan::UpdateFocusIndex() -{ - m_focusIndex = static_cast(m_currentStage); - m_tabFocusIndex = static_cast(m_currentStage); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgModePushButton.cpp b/RadeonGPUAnalyzerGUI/Src/rgModePushButton.cpp deleted file mode 100644 index af9d795..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgModePushButton.cpp +++ /dev/null @@ -1,180 +0,0 @@ -// Qt. -#include -#include -#include -#include -#include -#include - -// Infra. -#include - -// Local. -#include - -static const int s_TEXT_OFFSET_X = 20; -static const int s_TEXT_OFFSET_Y = 14; -static const int s_CENTER_UP_ARROW = 10; -static const int s_CENTER_DOWN_ARROW = 9; -static const int s_BUTTON_BASE_SIZE = 18; -static const int s_ARROW_SIZE = 12; -static const int s_ARROW_X_OFFSET = 13; -static const int s_PEN_WIDTH = 3; -static const int s_FONT_SIZE = 11; -static const int s_GEAR_ICON_OFFSET_Y = 4; -static const int s_GEAR_ICON_OFFSET_X = 5; -static const char* s_GEAR_ICON_FILE = ":/icons/gearIconWhite.svg"; - -rgModePushButton::rgModePushButton(QWidget* pParent) : - QPushButton(pParent) -{ - // Set default values. - m_size = s_BUTTON_BASE_SIZE; - m_color = Qt::GlobalColor::gray; - m_fontColor = Qt::GlobalColor::black; - m_penWidth = s_PEN_WIDTH; - m_fontSize = s_FONT_SIZE; - - // Create the vertices. - CreateVertices(); -} - -void rgModePushButton::paintEvent(QPaintEvent *pEvent) -{ - Q_UNUSED(pEvent); - - // Set up the painter. - QPainter painter; - painter.begin(this); - painter.setRenderHint(QPainter::Antialiasing); - painter.save(); - - // Create the gear icon. - QIcon gearIcon(s_GEAR_ICON_FILE); - - // Draw the gear icon. - QRect rect = this->rect(); - rect.setY(s_GEAR_ICON_OFFSET_Y); - rect.setX(s_GEAR_ICON_OFFSET_X); - style()->drawItemPixmap(&painter, rect, Qt::AlignLeft, gearIcon.pixmap(this->rect().height() * 0.50)); - - // If the widget is hovered over, or gets focus through tabbing, set the color to hover color. - if (underMouse() || hasFocus()) - { - m_color = m_hoverColor; - } - else - { - m_color = m_nonHoverColor; - } - QPalette pal = palette(); - pal.setColor(QPalette::Button, m_color); - setAutoFillBackground(true); - setPalette(pal); - - // Get the scaling factor. - const double scalingFactor = ScalingManager::Get().GetScaleFactor(); - - // Draw the text. - QFont font = this->font(); - font.setPixelSize(m_fontSize * scalingFactor); - painter.setFont(font); - QPen pen; - pen.setColor(m_fontColor); - painter.setPen(pen); - QString textQStr = QString::fromStdString(m_text); - painter.drawText(s_TEXT_OFFSET_X * scalingFactor, s_TEXT_OFFSET_Y * scalingFactor, textQStr); - - // Calculate new points using the current scale factor. - QPoint scaledPoints[s_NUMBER_OF_VERTICES]; - for (int i = 0; i < s_NUMBER_OF_VERTICES; i++) - { - scaledPoints[i].setX(m_vertices[i].x() * scalingFactor); - scaledPoints[i].setY(m_vertices[i].y() * scalingFactor); - } - - // Calculate text width. - QFontMetrics fm(font); - int endOfText = fm.width(textQStr) + s_TEXT_OFFSET_X * scalingFactor; - - // Position the paint object. - painter.translate(endOfText, -s_CENTER_UP_ARROW * scalingFactor); - - // Rotate the paint object to generate an up arrow. - painter.rotate(180); - - // Also translate the paint object towards the bottom of the rect. - painter.translate(0, -3); - painter.translate(-s_ARROW_X_OFFSET * scalingFactor, (-m_size - s_CENTER_DOWN_ARROW) * scalingFactor); - - // Create the upward arrow. - QPolygon polygon; - polygon << scaledPoints[0] - << scaledPoints[1] - << scaledPoints[2] - << scaledPoints[0]; - - // Draw filled arrow. - QPainterPath path; - path.addPolygon(polygon); - painter.fillPath(path, QBrush(Qt::white)); - - // Restore the painter object. - painter.restore(); - - // End the painter. - painter.end(); -} - -void rgModePushButton::keyPressEvent(QKeyEvent* pEvent) -{ - // Process the enter key. - if ((pEvent->key() == Qt::Key_Enter) || (pEvent->key() == Qt::Key_Return)) - { - emit clicked(false); - } - else - { - QPushButton::keyPressEvent(pEvent); - } -} - -void rgModePushButton::CreateVertices() -{ - // Generate the vertices from the size input. - // Vertex zero is at the top left. - m_vertices[0].setX(s_ARROW_SIZE *.8); - m_vertices[0].setY(s_ARROW_SIZE * .6); - - // Vertex 1 is halfway down the bottom side. - m_vertices[1].setX(s_ARROW_SIZE / 2); - m_vertices[1].setY(s_ARROW_SIZE * .9); - - // Vertex 2 is the top right. - m_vertices[2].setX(s_ARROW_SIZE *.2); - m_vertices[2].setY(s_ARROW_SIZE * .6); -} - -void rgModePushButton::SetText(const std::string& text) -{ - m_text = text; - - update(); -} - -void rgModePushButton::SetColor(const QColor& color) -{ - m_fontColor = color; - - update(); -} - -void rgModePushButton::SetHoverColor(const QColor& hoverColor) -{ - m_hoverColor = hoverColor; -} - -void rgModePushButton::SetNonHoverColor(const QColor& nonHoverColor) -{ - m_nonHoverColor = nonHoverColor; -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgOrderedListDialog.cpp b/RadeonGPUAnalyzerGUI/Src/rgOrderedListDialog.cpp deleted file mode 100644 index 1152787..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgOrderedListDialog.cpp +++ /dev/null @@ -1,449 +0,0 @@ -// C++. -#include - -// Qt. -#include - -// Infra. -#include - -// Local. -#include -#include -#include -#include - -rgOrderedListDialog::rgOrderedListDialog(const char* pDelimiter, QWidget* pParent) : - QDialog(pParent), - m_pDelimiter(pDelimiter) -{ - const int WIDGET_FIXED_WIDTH = 600; - const int WIDGET_FIXED_HEIGHT = 150; - - // Verify that the given delimiter is valid. - assert(m_pDelimiter != nullptr); - - // Setup the UI. - ui.setupUi(this); - - // Set the background to white. - QPalette pal = palette(); - pal.setColor(QPalette::Background, Qt::white); - this->setAutoFillBackground(true); - this->setPalette(pal); - - // Set the window icon. - setWindowIcon(QIcon(":/icons/rgaIcon.png")); - - // Set the size of the window. - QSize size; - size.setWidth(WIDGET_FIXED_WIDTH * ScalingManager::Get().GetScaleFactor()); - size.setHeight(WIDGET_FIXED_HEIGHT * ScalingManager::Get().GetScaleFactor()); - setMinimumSize(size); - - // Disable the help button in the title bar. - setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); - - // Connect the signals. - ConnectSignals(); - - // Set the mouse cursor to the pointing hand cursor for various widgets. - SetCursor(); - - // Set the button fonts. - SetButtonFonts(); - - // Set push button shortcuts. - SetButtonShortcuts(); - - // Start off with various buttons disabled. - ui.moveUpPushButton->setEnabled(false); - ui.moveDownPushButton->setEnabled(false); - ui.editPushButton->setEnabled(false); -} - -void rgOrderedListDialog::SetListItems(const QString& entries) -{ - // Clear any existing data. - m_itemsList.clear(); - ui.itemsList->clear(); - - if (!entries.isEmpty()) - { - // Process the incoming text. - QStringList entryList = entries.split(m_pDelimiter); - - // Remove trailing and leading whitespace, and then only add non-empty strings. - // This could happen if the user manually typed invalid entries. - for (int i = 0; i < entryList.count(); ++i) - { - QString item = entryList[i].trimmed(); - - if (item != "") - { - m_itemsList.append(item); - } - } - - // Update the list widget. - UpdateListWidget(); - } - - // Insert an empty item to the list widget and select it. - InsertBlankItem(); -} - -void rgOrderedListDialog::ConnectSignals() -{ - // Cancel button. - bool isConnected = connect(ui.cancelPushButton, &QPushButton::clicked, this, &rgOrderedListDialog::HandleExit); - assert(isConnected); - - // Add new entry button. - isConnected = connect(this->ui.newPushButton, &QPushButton::clicked, this, &rgOrderedListDialog::HandleNewButtonClick); - assert(isConnected); - - // Edit button. - isConnected = connect(this->ui.editPushButton, &QPushButton::clicked, this, &rgOrderedListDialog::HandleEditButtonClick); - assert(isConnected); - - // "OK" button. - isConnected = connect(this->ui.okPushButton, &QPushButton::clicked, this, &rgOrderedListDialog::HandleOKButtonClick); - assert(isConnected); - - // "Move up" button. - isConnected = connect(this->ui.moveUpPushButton, &QPushButton::clicked, this, &rgOrderedListDialog::HandleMoveUpButtonClick); - assert(isConnected); - - // "Move down" button. - isConnected = connect(this->ui.moveDownPushButton, &QPushButton::clicked, this, &rgOrderedListDialog::HandleMoveDownButtonClick); - assert(isConnected); - - // "Delete" button. - isConnected = connect(this->ui.deletePushButton, &QPushButton::clicked, this, &rgOrderedListDialog::HandleDeleteButtonClick); - assert(isConnected); - - // Items tree widget. - isConnected = connect(ui.itemsList, &QListWidget::itemChanged, this, &rgOrderedListDialog::HandleListItemChanged); - assert(isConnected); - - isConnected = connect(ui.itemsList, &QListWidget::itemSelectionChanged, this, &rgOrderedListDialog::HandleListItemSelectionChanged); - assert(isConnected); -} - -void rgOrderedListDialog::SetCursor() -{ - // Set the cursor to pointing hand cursor. - ui.cancelPushButton->setCursor(Qt::PointingHandCursor); - ui.deletePushButton->setCursor(Qt::PointingHandCursor); - ui.moveDownPushButton->setCursor(Qt::PointingHandCursor); - ui.moveUpPushButton->setCursor(Qt::PointingHandCursor); - ui.newPushButton->setCursor(Qt::PointingHandCursor); - ui.okPushButton->setCursor(Qt::PointingHandCursor); -} - -void rgOrderedListDialog::SetButtonFonts() -{ - // Create font. - QFont font = ui.deletePushButton->font(); - font.setPointSize(gs_BUTTON_POINT_FONT_SIZE); - - // Update font size for all the buttons. - ui.cancelPushButton->setFont(font); - ui.deletePushButton->setFont(font); - ui.moveDownPushButton->setFont(font); - ui.moveUpPushButton->setFont(font); - ui.newPushButton->setFont(font); - ui.okPushButton->setFont(font); -} - -void rgOrderedListDialog::HandleExit(bool /* checked */) -{ - // Clear any existing data. - m_itemsList.clear(); - ui.itemsList->clear(); - - close(); -} - -void rgOrderedListDialog::HandleOKButtonClick(bool /* checked */) -{ - // Remove any empty entries. - m_itemsList.removeAll(""); - - // Emit a signal to indicate "OK" button clicked so the data can be saved. - emit OKButtonClicked(m_itemsList); - - // Close the dialog. - close(); -} - -void rgOrderedListDialog::UpdateListWidget() -{ - // Clear any existing data. - ui.itemsList->clear(); - - int counter = 0; - - // Update the list widget. - foreach(auto entry, m_itemsList) - { - QListWidgetItem* pItem = new QListWidgetItem; - pItem->setText(entry); - pItem->setFlags(pItem->flags() | Qt::ItemIsEditable); - ui.itemsList->insertItem(counter, pItem); - counter++; - } -} - - -void rgOrderedListDialog::HandleMoveDownButtonClick(bool /* checked */) -{ - // Get the current index. - int currentIndex = ui.itemsList->currentRow(); - - // Do not do anything if this is the last item. - if (currentIndex < ui.itemsList->count() - 1) - { - // If the next item is empty, do not do anything. - QString nextItem = ui.itemsList->item(currentIndex + 1)->text(); - if (!nextItem.isEmpty()) - { - QListWidgetItem* pCurrentItem = ui.itemsList->takeItem(currentIndex); - if (pCurrentItem != nullptr) - { - ui.itemsList->insertItem(currentIndex + 1, pCurrentItem); - ui.itemsList->setCurrentRow(currentIndex + 1); - - // Update local data with this change. - m_itemsList.swap(currentIndex, currentIndex + 1); - } - } - } - - // Update buttons. - UpdateButtons(); -} - -void rgOrderedListDialog::HandleMoveUpButtonClick(bool /* checked */) -{ - // Get the current index. - int currentIndex = ui.itemsList->currentRow(); - - // Make sure the index is not out of bounds. - if (currentIndex < ui.itemsList->count()) - { - // Do not do anything if this is the first item, or the text field is empty. - if (currentIndex > 0 && !ui.itemsList->item(currentIndex)->text().isEmpty()) - { - QListWidgetItem* pCurrentItem = ui.itemsList->takeItem(currentIndex); - if (pCurrentItem != nullptr) - { - ui.itemsList->insertItem(currentIndex - 1, pCurrentItem); - ui.itemsList->setCurrentRow(currentIndex - 1); - - // Update local data with this change. - m_itemsList.swap(currentIndex - 1, currentIndex); - } - } - } - - // Update buttons. - UpdateButtons(); -} - -void rgOrderedListDialog::HandleDeleteButtonClick(bool /* checked */) -{ - // Display a confirmation message box. - bool isConfirmation = rgUtils::ShowConfirmationMessageBox(STR_INCLUDE_DIR_DIALOG_DELETE_BOX_TITLE, STR_INCLUDE_DIR_DIALOG_DELETE_BOX_MESSAGE, this); - - if (isConfirmation) - { - // Remove the selected item from the list widget. - int currentIndex = ui.itemsList->currentRow(); - QListWidgetItem* pCurrentItem = ui.itemsList->takeItem(currentIndex); - - // Remove the selected item from the string list. - if (pCurrentItem != nullptr) - { - m_itemsList.removeAt(currentIndex); - - // Update buttons. - UpdateButtons(); - } - - // If this was the last item in the list widget, - // add a blank place holder. - if (ui.itemsList->count() == 0) - { - // Insert an empty item to the list widget and highlight it. - InsertBlankItem(); - } - } -} - -void rgOrderedListDialog::SetButtonShortcuts() -{ - // Add button keyboard shortcut. - m_pAddAction = new QAction(this); - m_pAddAction->setShortcut(QKeySequence(Qt::Key_Alt | Qt::Key_N)); - - bool isConnected = connect(m_pAddAction, &QAction::triggered, this, &rgOrderedListDialog::HandleNewButtonClick); - assert(isConnected); - - // Delete button keyboard shortcut. - m_pDeleteAction = new QAction(this); - m_pDeleteAction->setShortcut(QKeySequence(Qt::Key_Alt | Qt::Key_D)); - - isConnected = connect(m_pDeleteAction, &QAction::triggered, this, &rgOrderedListDialog::HandleDeleteButtonClick); - assert(isConnected); - - // "Move up" button shortcut. - m_pMoveUpAction = new QAction(this); - m_pMoveUpAction->setShortcut(QKeySequence(Qt::Key_Alt | Qt::Key_U)); - - isConnected = connect(m_pMoveUpAction, &QAction::triggered, this, &rgOrderedListDialog::HandleMoveUpButtonClick); - assert(isConnected); - - // "Move down" button shortcut. - m_pMoveDownAction = new QAction(this); - m_pMoveDownAction->setShortcut(QKeySequence(Qt::Key_Alt | Qt::Key_O)); - - isConnected = connect(m_pMoveDownAction, &QAction::triggered, this, &rgOrderedListDialog::HandleMoveDownButtonClick); - assert(isConnected); -} - -void rgOrderedListDialog::HandleListItemChanged(QListWidgetItem* pItem) -{ - OnListItemChanged(pItem); -} - -void rgOrderedListDialog::HandleNewButtonClick(bool /* checked */) -{ - // Get the last item in the list widget. - QListWidgetItem* pItem = nullptr; - if (ui.itemsList->count() > 0) - { - pItem = ui.itemsList->item(ui.itemsList->count() - 1); - } - if (pItem != nullptr && pItem->text().isEmpty()) - { - QListWidgetItem* pItem = ui.itemsList->item(ui.itemsList->count() - 1); - ui.itemsList->setCurrentItem(pItem); - ui.itemsList->editItem(pItem); - } - else - { - QListWidgetItem* pItem = new QListWidgetItem; - pItem->setText(""); - pItem->setFlags(pItem->flags() | Qt::ItemIsEditable); - ui.itemsList->setCurrentItem(pItem); - ui.itemsList->insertItem(ui.itemsList->count(), pItem); - ui.itemsList->editItem(pItem); - } - - // Update buttons. - UpdateButtons(); -} - -void rgOrderedListDialog::HandleEditButtonClick(bool /* checked */) -{ - // Get the current row. - const int row = ui.itemsList->currentRow(); - - // Make the current row editable. - QListWidgetItem* pItem = ui.itemsList->item(row); - ui.itemsList->editItem(pItem); -} - -void rgOrderedListDialog::UpdateButtons() -{ - // Enable/disable move up/down buttons. - if (ShouldDisableMoveUpDownButtons()) - { - ui.moveUpPushButton->setEnabled(false); - ui.moveDownPushButton->setEnabled(false); - } - else - { - // Get the current row. - const int currentRow = ui.itemsList->currentRow(); - - // Set both up/down buttons to disabled for now. - ui.moveUpPushButton->setEnabled(false); - ui.moveDownPushButton->setEnabled(false); - - // Figure out which up/down buttons to enable. - if (currentRow > 0) - { - ui.moveUpPushButton->setEnabled(true); - } - if (currentRow >= 0 && currentRow < m_itemsList.count() - 1) - { - ui.moveDownPushButton->setEnabled(true); - } - } - - // Enable/Disable the Edit and Delete buttons. - if (ui.itemsList->count() == 0) - { - ui.editPushButton->setEnabled(false); - ui.deletePushButton->setEnabled(false); - } - else - { - ui.editPushButton->setEnabled(true); - ui.deletePushButton->setEnabled(true); - } -} - -bool rgOrderedListDialog::ShouldDisableMoveUpDownButtons() -{ - bool shouldDisableButtons = false; - - if (ui.itemsList->count() < 2) - { - shouldDisableButtons = true; - } - else if (ui.itemsList->count() == 2) - { - if (ui.itemsList->item(1)->text().isEmpty()) - { - shouldDisableButtons = true; - } - } - else if (ui.itemsList->currentRow() >= 0 && - ui.itemsList->item(ui.itemsList->currentRow())->text().isEmpty()) - { - shouldDisableButtons = true; - } - - return shouldDisableButtons; -} - -void rgOrderedListDialog::UpdateToolTips() -{ - for (int i = 0; i < ui.itemsList->count(); i++) - { - QListWidgetItem* pItem = ui.itemsList->item(i); - if (pItem != nullptr) - { - pItem->setToolTip(pItem->text()); - } - } -} - -void rgOrderedListDialog::InsertBlankItem() -{ - // Create a blank item and insert it in the list widget. - QListWidgetItem* pItem = new QListWidgetItem(); - pItem->setFlags(pItem->flags() | Qt::ItemIsEditable); - ui.itemsList->addItem(pItem); - ui.itemsList->setCurrentItem(pItem); - ui.itemsList->setFocus(); -} - -void rgOrderedListDialog::HandleListItemSelectionChanged() -{ - UpdateButtons(); -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidget.cpp b/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidget.cpp deleted file mode 100644 index ff053f0..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidget.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// C++. -#include - -// Qt. -#include - -// Local. -#include - -rgPipelineStateEditorWidget::rgPipelineStateEditorWidget(QWidget* pParent) - : QWidget(pParent) - , m_type(rgEditorDataType::Void) -{ -} - -void rgPipelineStateEditorWidget::keyPressEvent(QKeyEvent* pEvent) -{ - assert(pEvent != nullptr); - if (pEvent != nullptr && pEvent->key() == Qt::Key_Escape) - { - // If the user pressed Escape while the widget is focused, finish editing and lose focus. - emit FocusOutSignal(); - } - - // Invoke the base implementation. - QWidget::keyPressEvent(pEvent); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidgetArrayElementAdd.cpp b/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidgetArrayElementAdd.cpp deleted file mode 100644 index 53b2cd0..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidgetArrayElementAdd.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// C++. -#include - -// Local. -#include -#include - -rgPipelineStateEditorWidgetArrayElementAdd::rgPipelineStateEditorWidgetArrayElementAdd(rgEditorElementArrayElementAdd* pParent) - : rgPipelineStateEditorWidget(pParent) - , m_pArrayRootElement(pParent) -{ - ui.setupUi(this); - - // Update the cursor for the delete button. - ui.addElementButton->setCursor(Qt::PointingHandCursor); - - // Set the Plus button as the focus proxy. - setFocusProxy(ui.addElementButton); - - // Connect the internal widget signals. - ConnectSignals(); - - // If the array is resized, update the size label. - m_pArrayRootElement->SetResizeCallback([=] { UpdateArraySizeLabel(); }); -} - -void rgPipelineStateEditorWidgetArrayElementAdd::HandleAddButtonClicked() -{ - assert(m_pArrayRootElement != nullptr); - if (m_pArrayRootElement != nullptr) - { - // Add a new element to the array. - m_pArrayRootElement->AddNewElement(); - - // Update the array size label to match the new element count. - UpdateArraySizeLabel(); - } -} - -void rgPipelineStateEditorWidgetArrayElementAdd::ConnectSignals() -{ - // Connect the add element button's signal to be forwarded to a local public signal. - bool isConnected = connect(ui.addElementButton, &QPushButton::clicked, this, &rgPipelineStateEditorWidgetArrayElementAdd::HandleAddButtonClicked); - assert(isConnected); -} - -void rgPipelineStateEditorWidgetArrayElementAdd::UpdateArraySizeLabel() -{ - // Extract the array size element from the array root element. - rgEditorElementNumeric* pSizeElement = m_pArrayRootElement->GetArraySizeElement(); - assert(pSizeElement != nullptr); - if (pSizeElement != nullptr) - { - // Extract the array dimension from the size element, and set the count label. - uint32_t currentSize = pSizeElement->GetValue(); - ui.countLabel->setText(QString::number(currentSize)); - - // Hide/show the count label depending on the number of items. - if (currentSize > 0) - { - ui.countLabel->show(); - } - else - { - ui.countLabel->hide(); - } - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidgetArrayElementRemove.cpp b/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidgetArrayElementRemove.cpp deleted file mode 100644 index 21bda3b..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidgetArrayElementRemove.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// C++. -#include -#include - -// Local. -#include -#include - -rgPipelineStateEditorWidgetArrayElementRemove::rgPipelineStateEditorWidgetArrayElementRemove(QWidget* pParent) - : rgPipelineStateEditorWidget(pParent) -{ - ui.setupUi(this); - - // Always show the delete element button. - ui.deleteElementButton->setVisible(true); - - // Update the cursor for the delete button. - ui.deleteElementButton->setCursor(Qt::PointingHandCursor); - - // Set the trashcan button as the focus proxy widget. - setFocusProxy(ui.deleteElementButton); - - // Connect the internal widget signals. - ConnectSignals(); -} - -void rgPipelineStateEditorWidgetArrayElementRemove::SetTrashCanIconTooltip(const std::string& tooltipStr) -{ - ui.deleteElementButton->setToolTip(tooltipStr.c_str()); -} - -void rgPipelineStateEditorWidgetArrayElementRemove::ConnectSignals() -{ - // Connect the add element button's signal to be forwarded to a local public signal. - bool isConnected = connect(ui.deleteElementButton, &QPushButton::clicked, this, &rgPipelineStateEditorWidgetArrayElementRemove::DeleteButtonClicked); - assert(isConnected); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidgetBool.cpp b/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidgetBool.cpp deleted file mode 100644 index 1049c0c..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidgetBool.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// C++. -#include - -// Local. -#include -#include - -rgPipelineStateEditorWidgetBool::rgPipelineStateEditorWidgetBool(QWidget* pParent) - : rgPipelineStateEditorWidget(pParent) -{ - ui.setupUi(this); - - // Set the bool checkbox as the focus proxy widget. - setFocusProxy(ui.valueCheckbox); - - // Connect internal signals. - ConnectSignals(); -} - -bool rgPipelineStateEditorWidgetBool::GetValue() const -{ - // Return the control's check state to determine the updated model value. - return ui.valueCheckbox->isChecked(); -} - -void rgPipelineStateEditorWidgetBool::SetValue(bool value) -{ - // Set the control's check state based on the incoming model value. - Qt::CheckState checkState = value ? Qt::CheckState::Checked : Qt::CheckState::Unchecked; - ui.valueCheckbox->setCheckState(checkState); -} - -void rgPipelineStateEditorWidgetBool::ConnectSignals() -{ - // Connect the checkbox check state changed handler. - bool isConnected = connect(ui.valueCheckbox, &QCheckBox::stateChanged, this, &rgPipelineStateEditorWidgetBool::EditingFinished); - assert(isConnected); - - // Connect the checkbox focus in handler. - isConnected = connect(ui.valueCheckbox, &rgCheckBox::CheckBoxFocusInEvent, this, &rgPipelineStateEditorWidget::FocusInSignal); - assert(isConnected); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidgetEnum.cpp b/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidgetEnum.cpp deleted file mode 100644 index d80c117..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidgetEnum.cpp +++ /dev/null @@ -1,526 +0,0 @@ -// C++. -#include - -// Qt. -#include - -// Infra. -#include -#include -#include -#include - -// Local. -#include -#include -#include - -// Names of special widgets. -static const char* STR_ENUM_LIST = "EnumList"; -static const char* STR_ENUM_LIST_ITEM_CHECKBOX = "EnumListWidgetCheckBox"; -static const char* s_STR_ENUM_LIST_PUSH_BUTTON = "ListPushButton"; - -// Enumeration push button font size. -const int s_PUSH_BUTTON_FONT_SIZE = 11; - -// Initialize the static enum push button count. -int rgPipelineStateEditorWidgetEnum::s_enumComboPushButtonCounter = 0; - -rgPipelineStateEditorWidgetEnum::rgPipelineStateEditorWidgetEnum(bool isBitFlagsEnum, QWidget* pParent) - : m_isBitFlagsEnum(isBitFlagsEnum) - , m_pParent(pParent) - , rgPipelineStateEditorWidget(pParent) -{ - ui.setupUi(this); - - // Create the enum drop down. - CreateEnumControls(); - - // Set the dropdown arrow button as the focus proxy widget. - setFocusProxy(ui.enumComboPushButton); - - // Connect internal signals. - ConnectSignals(); -} - -rgPipelineStateEditorWidgetEnum::~rgPipelineStateEditorWidgetEnum() -{ - // Remove the event filter from the main window. - if (m_pEnumListWidget != nullptr) - { - qApp->removeEventFilter(m_pEnumListEventFilter); - } -} - -uint32_t rgPipelineStateEditorWidgetEnum::GetValue() const -{ - uint32_t result = 0; - - if (m_isBitFlagsEnum) - { - assert(m_pEnumListWidget != nullptr); - if (m_pEnumListWidget != nullptr) - { - // Combine all flags into a single integer. - for (int i = 0; i < m_pEnumListWidget->count(); i++) - { - QListWidgetItem* pItem = m_pEnumListWidget->item(i); - assert(pItem != nullptr); - if (pItem != nullptr) - { - QCheckBox* pCheckBox = qobject_cast(m_pEnumListWidget->itemWidget(pItem)); - assert(pCheckBox != nullptr); - if (pCheckBox != nullptr) - { - if (pCheckBox->checkState() == Qt::CheckState::Checked) - { - uint32_t currentFlag = m_enumerators[i].m_value; - result |= currentFlag; - } - } - } - } - } - } - else - { - // Read the push button text and return the appropriate value for it. - assert(m_currentIndex >= 0 && m_currentIndex < m_enumerators.size()); - if (m_currentIndex >= 0 && m_currentIndex < m_enumerators.size()) - { - result = m_enumerators[m_currentIndex].m_value; - } - } - - return result; -} - -void rgPipelineStateEditorWidgetEnum::SetEnumerators(const rgEnumValuesVector& enumerators) -{ - m_enumerators = enumerators; - - // Set up the function pointer responsible for handling column visibility filter state change. - using std::placeholders::_1; - std::function slotFunctionPointer = std::bind(&rgPipelineStateEditorWidgetEnum::HandleFlagCheckStateChanged, this, _1); - - assert(m_pEnumListWidget != nullptr); - if (m_pEnumListWidget != nullptr) - { - // Add an item for each column in the table. - for (const rgEnumNameValuePair& currentEnum : enumerators) - { - // Add an item for each possible enum. - // If this item needs a check box, make the item checkable. - if (m_isBitFlagsEnum) - { - ListWidget::AddListWidgetCheckboxItem(currentEnum.m_name.c_str(), m_pEnumListWidget, slotFunctionPointer, this, m_pEnumListWidget->objectName(), STR_ENUM_LIST_ITEM_CHECKBOX); - } - else - { - m_pEnumListWidget->addItem(currentEnum.m_name.c_str()); - } - } - } -} - -void rgPipelineStateEditorWidgetEnum::GetFlagBitsString(std::string& flagBits) -{ - uint32_t currentValue = GetValue(); - - uint32_t flagsValue = 0; - assert(m_pEnumListWidget != nullptr); - if (m_pEnumListWidget != nullptr) - { - int itemCount = m_pEnumListWidget->count(); - - // Bitwise OR together all the checked values and display that number for push button text. - for (int i = 0; i < m_enumerators.size(); ++i) - { - bool isChecked = (m_enumerators[i].m_value & currentValue) == m_enumerators[i].m_value; - if (isChecked) - { - assert(i >= 0 && i < itemCount); - if (i >= 0 && i < itemCount) - { - QListWidgetItem* pItem = m_pEnumListWidget->item(i); - assert(pItem != nullptr); - if (pItem != nullptr) - { - QCheckBox* pCheckBoxItem = static_cast(m_pEnumListWidget->itemWidget(pItem)); - assert(pCheckBoxItem != nullptr); - if (pCheckBoxItem != nullptr) - { - uint32_t currentFlag = m_enumerators[i].m_value; - flagsValue |= currentFlag; - } - } - } - } - } - } - - // Return a string that displays individual flag bits. - int numEnumerators = static_cast(m_enumerators.size()); - QString outputFlagBits = "(" + QString::number(flagsValue) + ") " + QString::number(flagsValue, 2).rightJustified(numEnumerators, '0'); - flagBits = outputFlagBits.toStdString(); -} - -void rgPipelineStateEditorWidgetEnum::GetTooltipString(std::string& tooltipText) -{ - uint32_t currentValue = GetValue(); - - // Bitwise OR together all the checked values and display that number for push button text. - QString tooltip; - assert(m_pEnumListWidget != nullptr); - if (m_pEnumListWidget != nullptr) - { - int itemCount = m_pEnumListWidget->count(); - for (int i = 0; i < m_enumerators.size(); ++i) - { - bool isChecked = (m_enumerators[i].m_value & currentValue) == m_enumerators[i].m_value; - if (isChecked) - { - assert(i >= 0 && i < itemCount); - if (i >= 0 && i < itemCount) - { - // Append a bitwise OR pipe between each enumerator. - if (!tooltip.isEmpty()) - { - tooltip += " | "; - } - - QListWidgetItem* pItem = m_pEnumListWidget->item(i); - assert(pItem != nullptr); - if (pItem != nullptr) - { - QCheckBox* pCheckBoxItem = static_cast(m_pEnumListWidget->itemWidget(pItem)); - assert(pCheckBoxItem != nullptr); - if (pCheckBoxItem != nullptr) - { - const QString& enumString = pCheckBoxItem->text(); - tooltip += enumString; - } - } - } - } - } - } - - // Return the tooltip text used to show each enumerator name. - tooltipText = tooltip.toStdString(); -} - -void rgPipelineStateEditorWidgetEnum::HandleUpdateEnumButtonText(const QString& text, bool checked) -{ - std::string tooltipText; - GetTooltipString(tooltipText); - - std::string flagBits; - GetFlagBitsString(flagBits); - - // Set the tooltip to display all the checked values as a text. - ui.enumComboPushButton->setToolTip(tooltipText.c_str()); - - // Set the flag bits string. - UpdateSelectedEnum(flagBits); - - // The user altered the current value- signal to the parent row that editing is finished. - emit EditingFinished(); -} - -void rgPipelineStateEditorWidgetEnum::SetValue(uint32_t value) -{ - if (m_isBitFlagsEnum) - { - for (int enumeratorIndex = 0; enumeratorIndex < static_cast(m_enumerators.size()); ++enumeratorIndex) - { - // Set the push button's text to the item with the given value. - auto pEnumItem = m_pEnumListWidget->item(enumeratorIndex); - assert(pEnumItem != nullptr); - if (pEnumItem != nullptr) - { - bool isChecked = (value & m_enumerators[enumeratorIndex].m_value) == m_enumerators[enumeratorIndex].m_value; - - QCheckBox* pCheckbox = qobject_cast(m_pEnumListWidget->itemWidget(pEnumItem)); - assert(pCheckbox != nullptr); - if (pCheckbox != nullptr) - { - pCheckbox->setCheckState(isChecked ? Qt::CheckState::Checked : Qt::CheckState::Unchecked); - } - } - } - - // Set the tooltip to display all the checked values as a text. - std::string tooltipText; - GetTooltipString(tooltipText); - ui.enumComboPushButton->setToolTip(tooltipText.c_str()); - - // Set the flag bits string. - std::string flagBits; - GetFlagBitsString(flagBits); - UpdateSelectedEnum(flagBits); - } - else - { - // Find the given value in the list of enumerators, and set it as the - // current value in the combo box containing all enumerator options. - rgEnumeratorSearcher searcher(value); - auto enumeratorIter = std::find_if(m_enumerators.begin(), m_enumerators.end(), searcher); - if (enumeratorIter != m_enumerators.end()) - { - // Set the push button's text to the item with the given value. - int itemIndex = enumeratorIter - m_enumerators.begin(); - auto pEnumItem = m_pEnumListWidget->item(itemIndex); - assert(pEnumItem != nullptr); - if (pEnumItem != nullptr) - { - // Set the push button's text to the item with the given value. - int itemIndex = enumeratorIter - m_enumerators.begin(); - auto pEnumItem = m_pEnumListWidget->item(itemIndex); - assert(pEnumItem != nullptr); - if (pEnumItem != nullptr) - { - std::string enumString = pEnumItem->text().toStdString(); - UpdateSelectedEnum(enumString); - - // Update the current index member variable. - SetSelectedListRow(itemIndex); - } - } - } - - // Update the button text with the selected entry. - auto pEnumItem = m_pEnumListWidget->item(m_currentIndex); - assert(pEnumItem != nullptr); - if (pEnumItem != nullptr) - { - std::string enumString = pEnumItem->text().toStdString(); - UpdateSelectedEnum(enumString); - } - } -} - -void rgPipelineStateEditorWidgetEnum::ConnectSignals() -{ - // Connect the enum arrow widget button clicked handler. - bool isConnected = connect(this->ui.enumComboPushButton, &QPushButton::clicked, this, &rgPipelineStateEditorWidgetEnum::HandleEnumPushButtonClick); - assert(isConnected); - - // Connect the arrow widget button focus in handler. - isConnected = connect(ui.enumComboPushButton, &ArrowIconWidget::FocusInEvent, this, &rgPipelineStateEditorWidget::FocusInSignal); - assert(isConnected); - - // Connect the signal used to handle a change in the selected enum. - isConnected = connect(m_pEnumListWidget, &QListWidget::currentRowChanged, this, &rgPipelineStateEditorWidgetEnum::HandleEnumChanged); - assert(isConnected); - - // Connect the handler to close list widget on application's loss of focus. - isConnected = connect(qApp, &QGuiApplication::applicationStateChanged, this, &rgPipelineStateEditorWidgetEnum::HandleApplicationFocusOutEvent); - assert(isConnected); -} - -void rgPipelineStateEditorWidgetEnum::HandleHotKeyPressedSignal() -{ - HideListWidget(); -} - -void rgPipelineStateEditorWidgetEnum::HideListWidget() -{ - assert(m_pEnumListWidget != nullptr); - if (m_pEnumListWidget != nullptr) - { - // List widget push button lost focus so hide the list widget. - if (!m_pEnumListWidget->isHidden()) - { - m_pEnumListWidget->hide(); - - // Change the up arrow to a down arrow. - ui.enumComboPushButton->SetDirection(ArrowIconWidget::Direction::DownArrow); - - // Emit the list widget status signal. - emit EnumListWidgetStatusSignal(false); - } - } -} - -void rgPipelineStateEditorWidgetEnum::HandleApplicationFocusOutEvent(Qt::ApplicationState state) -{ - assert(m_pEnumListWidget != nullptr); - if (m_pEnumListWidget != nullptr && state != Qt::ApplicationState::ApplicationActive) - { - HideListWidget(); - } -} - -void rgPipelineStateEditorWidgetEnum::HandleEnumChanged(int currentIndex) -{ - assert(m_pEnumListWidget != nullptr); - if (m_pEnumListWidget != nullptr) - { - auto pEnumItem = m_pEnumListWidget->item(currentIndex); - assert(pEnumItem != nullptr); - if (pEnumItem != nullptr) - { - // Change the enum value if it differs from the current enum value. - std::string currentEnum = ui.enumComboPushButton->text().toStdString(); - std::string newEnum = pEnumItem->text().toStdString(); - if (currentEnum.compare(newEnum) != 0) - { - // Use the dropdown list's selection model to change the currently selected enum. - QItemSelectionModel* pSelectionModel = m_pEnumListWidget->selectionModel(); - assert(pSelectionModel != nullptr); - if (pSelectionModel != nullptr) - { - // Select the new enum within the dropdown list widget. - QAbstractItemModel* pListModel = m_pEnumListWidget->model(); - - assert(pListModel != nullptr); - if (pListModel != nullptr) - { - QModelIndex modelIndex = pListModel->index(currentIndex, 0); - pSelectionModel->setCurrentIndex(modelIndex, QItemSelectionModel::SelectionFlag::Select); - } - } - - // Change the push button to the newly selected item. - UpdateSelectedEnum(newEnum); - - // Update the current index member variable. - m_currentIndex = currentIndex; - - emit EditingFinished(); - } - } - } -} - -void rgPipelineStateEditorWidgetEnum::UpdateSelectedEnum(const std::string& newValue) -{ - static const int g_ARROW_WIDGET_EXTRA_WIDTH = 100; - - // Update the button text. - ui.enumComboPushButton->setText(newValue.c_str()); - - // Measure the width of the enum text, and add extra space to account for the width of the arrow. - int scaledArrowWidth = static_cast(g_ARROW_WIDGET_EXTRA_WIDTH * ScalingManager::Get().GetScaleFactor()); - int textWidth = QtCommon::QtUtil::GetTextWidth(ui.enumComboPushButton->font(), newValue.c_str()); - ui.enumComboPushButton->setMinimumWidth(scaledArrowWidth + textWidth); -} - -void rgPipelineStateEditorWidgetEnum::HandleEnumPushButtonClick(bool /* checked */) -{ - // Make the list widget appear and process user selection from the list widget. - bool visible = m_pEnumListWidget->isVisible(); - if (visible) - { - m_pEnumListWidget->hide(); - - // Change the up arrow to a down arrow. - ui.enumComboPushButton->SetDirection(ArrowIconWidget::Direction::DownArrow); - - // Emit the list widget status signal. - emit EnumListWidgetStatusSignal(false); - } - else - { - // Compute where to place the combo box relative to where the arrow button is. - QWidget* pWidget = ui.enumComboPushButton; - QRect rect = pWidget->geometry(); - QPoint pos(0, 0); - QMainWindow* pMainWindow = qobject_cast(QApplication::activeWindow()); - pos = pWidget->mapTo(pMainWindow, pos); - pos.setY(pos.y() + rect.height()); - int height = QtCommon::QtUtil::GetListWidgetHeight(m_pEnumListWidget); - int width = QtCommon::QtUtil::GetListWidgetWidth(m_pEnumListWidget); - m_pEnumListWidget->setGeometry(pos.x(), pos.y(), width + s_CHECK_BOX_WIDTH, height); - m_pEnumListWidget->show(); - - // Change the down arrow to an up arrow. - ui.enumComboPushButton->SetDirection(ArrowIconWidget::Direction::UpArrow); - - // Emit the list widget status signal. - emit EnumListWidgetStatusSignal(true); - } -} - -void rgPipelineStateEditorWidgetEnum::SetSelectedListRow(int rowIndex) -{ - // Update the current index member variable. - m_currentIndex = rowIndex; - - // Reset the current selection in the enum list. - m_pEnumListWidget->setCurrentRow(m_currentIndex); -} - -void rgPipelineStateEditorWidgetEnum::CreateEnumControls() -{ - // Limit the maximum height of the popup ListWidget. - // A vertical scrollbar will automatically be inserted if it's needed. - static const int s_MAX_LIST_HEIGHT = 250; - - // Setup the list widget that opens when the user clicks the enum arrow. - QMainWindow* pMainWindow = qobject_cast(QApplication::activeWindow()); - rgUtils::SetupComboList(m_pParent, m_pEnumListWidget, ui.enumComboPushButton, m_pEnumListEventFilter, false); - m_pEnumListWidget->setMaximumHeight(s_MAX_LIST_HEIGHT); - m_pEnumListWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - - // Set a unique object name for the enum combo push button. - QString enumComboPushButtonObjectName = s_STR_ENUM_LIST_PUSH_BUTTON + QString::number(s_enumComboPushButtonCounter); - ui.enumComboPushButton->setObjectName(enumComboPushButtonObjectName); - - // Add the enum combo push button object to the list widget event filter. - rgHideListWidgetEventFilter* pEventFilter = qobject_cast(m_pEnumListEventFilter); - assert(pEventFilter != nullptr); - if (pEventFilter != nullptr) - { - pEventFilter->AddObjectName(enumComboPushButtonObjectName); - - // Connect to event filter's list widget status signal. - bool isConnected = connect(pEventFilter, &rgHideListWidgetEventFilter::EnumListWidgetStatusSignal, this, &rgPipelineStateEditorWidgetEnum::EnumListWidgetStatusSignal); - assert(isConnected); - } - - // Bump up the enum combo push button counter. - UpdateEnumPushButtonCounter(); - - // Update scale factor for widgets. - QFont font = ui.enumComboPushButton->font(); - double scaleFactor = ScalingManager::Get().GetScaleFactor(); - font.setPointSize(s_PUSH_BUTTON_FONT_SIZE * scaleFactor); - m_pEnumListWidget->setStyleSheet(s_LIST_WIDGET_STYLE.arg(font.pointSize())); - - SetSelectedListRow(0); - - // Set the list cursor to pointing hand cursor. - m_pEnumListWidget->setCursor(Qt::PointingHandCursor); -} - -void rgPipelineStateEditorWidgetEnum::HandleFlagCheckStateChanged(bool checked) -{ - // Figure out the sender and process appropriately. - QObject* pSender = QObject::sender(); - assert(pSender != nullptr); - - // Find out which entry caused the signal. - QWidget* pItem = qobject_cast(pSender); - assert(pItem != nullptr); - - QCheckBox* pCheckBox = qobject_cast(pSender); - assert(pCheckBox != nullptr); - - // Process the click. - if (pCheckBox != nullptr) - { - HandleUpdateEnumButtonText(pCheckBox->text(), checked); - } -} - -void rgPipelineStateEditorWidgetEnum::UpdateEnumPushButtonCounter() -{ - s_enumComboPushButtonCounter++; -} - -int rgPipelineStateEditorWidgetEnum::GetEnumPushButtonCounter() -{ - return s_enumComboPushButtonCounter; -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidgetNumeric.cpp b/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidgetNumeric.cpp deleted file mode 100644 index 4de16a4..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateEditorWidgetNumeric.cpp +++ /dev/null @@ -1,181 +0,0 @@ -// C++. -#include -#include -#include - -// Local. -#include -#include - -rgPipelineStateEditorWidgetNumeric::rgPipelineStateEditorWidgetNumeric(QWidget* pParent) - : rgPipelineStateEditorWidget(pParent) -{ - ui.setupUi(this); - - // Set the numeric line edit as the focus proxy widget. - setFocusProxy(ui.lineEdit); - - // Connect internal signals. - ConnectSignals(); -} - -QVariant rgPipelineStateEditorWidgetNumeric::GetValue() const -{ - return QVariant::fromValue(ui.lineEdit->text()); -} - -void rgPipelineStateEditorWidgetNumeric::SetType(rgEditorDataType type) -{ - m_type = type; - - switch (m_type) - { - case rgEditorDataType::Int8: - m_pValidator = new QIntValidator(std::numeric_limits::min(), std::numeric_limits::max(), this); - break; - case rgEditorDataType::Int16: - m_pValidator = new QIntValidator(std::numeric_limits::min(), std::numeric_limits::max(), this); - break; - case rgEditorDataType::Int32: - m_pValidator = new QIntValidator(std::numeric_limits::min(), std::numeric_limits::max(), this); - break; - case rgEditorDataType::UInt8: - m_pValidator = new rgUnsignedIntValidator(0, std::numeric_limits::max(), this); - break; - case rgEditorDataType::UInt16: - m_pValidator = new rgUnsignedIntValidator(0, std::numeric_limits::max(), this); - break; - case rgEditorDataType::UInt32: - m_pValidator = new rgUnsignedIntValidator(0, std::numeric_limits::max(), this); - break; - case rgEditorDataType::Float: - m_pValidator = new QDoubleValidator(std::numeric_limits::min(), std::numeric_limits::max(), 4, this); - break; - case rgEditorDataType::Double: - m_pValidator = new QDoubleValidator(std::numeric_limits::min(), std::numeric_limits::max(), 4, this); - break; - default: - // If we get here, the editor is attempting to edit - // a value type it doesn't know how to edit. - assert(false); - break; - } - - // Verify that a validator was created and assign it to the line edit control. - assert(m_pValidator != nullptr); - if (m_pValidator != nullptr) - { - ui.lineEdit->setValidator(m_pValidator); - } -} - -void rgPipelineStateEditorWidgetNumeric::SetValue(QVariant value) -{ - bool isOk = false; - switch (m_type) - { - case rgEditorDataType::Int8: - case rgEditorDataType::Int16: - case rgEditorDataType::Int32: - { - int integer = value.toInt(&isOk); - if (isOk) - { - std::stringstream stream; - stream << integer; - ui.lineEdit->setText(stream.str().c_str()); - } - } - break; - case rgEditorDataType::UInt8: - case rgEditorDataType::UInt16: - case rgEditorDataType::UInt32: - { - uint unsignedInteger = value.toUInt(&isOk); - if (isOk) - { - std::stringstream stream; - stream << unsignedInteger; - ui.lineEdit->setText(stream.str().c_str()); - } - } - break; - case rgEditorDataType::Float: - case rgEditorDataType::Double: - { - std::stringstream stream; - stream << value.toDouble(); - ui.lineEdit->setText(stream.str().c_str()); - } - break; - default: - // If we get here, the editor is attempting to display - // a value type it doesn't know how to edit. - assert(false); - break; - } -} - -void rgPipelineStateEditorWidgetNumeric::ConnectSignals() -{ - // Connect the line editing finished signal. - bool isConnected = connect(ui.lineEdit, &QLineEdit::editingFinished, this, &rgPipelineStateEditorWidget::EditingFinished); - assert(isConnected); - - // Connect the line edit widget focus in signal. - isConnected = connect(ui.lineEdit, &rgLineEdit::LineEditFocusInEvent, this, &rgPipelineStateEditorWidget::FocusInSignal); - assert(isConnected); -} - -void rgPipelineStateEditorWidgetNumeric::HighlightSubString(int startLocation, const std::string& searchString) -{ - // Update search string location. - UpdateStringMatchingLocation(startLocation, static_cast(searchString.size()), searchString); - ui.lineEdit->SetHighlightSubStringData(m_stringHighlightData); - ui.lineEdit->SetHighlightSubString(true); - ui.lineEdit->update(); -} - -void rgPipelineStateEditorWidgetNumeric::UpdateStringMatchingLocation(int startLocation, int length, const std::string& searchString) -{ - bool found = false; - - // Remove any entries that do not match the search string anymore. - int count = 0; - std::vector removeEntries; - for (auto& stringData : m_stringHighlightData) - { - if (stringData.m_highlightString != searchString) - { - removeEntries.push_back(count); - } - count++; - } - for (std::vector::reverse_iterator it = removeEntries.rbegin(); it != removeEntries.rend(); ++it) - { - m_stringHighlightData.remove(*it); - } - - // Update existing locations, if any. - for (auto& stringData : m_stringHighlightData) - { - if (stringData.m_startLocation == startLocation) - { - stringData.m_endLocation = startLocation + length; - stringData.m_highlightString = searchString; - found = true; - break; - } - } - - // Create a new entry if a matching entry not found. - if (!found) - { - StringHighlightData stringHighlightData = {}; - stringHighlightData.m_startLocation = startLocation; - stringHighlightData.m_endLocation = startLocation + length; - stringHighlightData.m_highlightString = searchString; - stringHighlightData.m_highlightColor = Qt::yellow; - m_stringHighlightData.push_back(stringHighlightData); - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateModel.cpp b/RadeonGPUAnalyzerGUI/Src/rgPipelineStateModel.cpp deleted file mode 100644 index 6669bec..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateModel.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// C++. -#include - -// Local. -#include -#include -#include -#include - -rgPipelineStateModel::rgPipelineStateModel(QWidget* pParent) - : QObject(pParent) - , m_pParent(pParent) -{ -} - -rgEditorElement* rgPipelineStateModel::GetRootElement() const -{ - return m_pRootItem; -} - -void rgPipelineStateModel::InitializeDefaultPipelineState(QWidget* pParent, rgPipelineType pipelineType) -{ - // Set the type of pipeline being edited with this model instance. - m_pipelineType = pipelineType; - - // The CreateInfo root element in the tree. - rgEditorElement* pPipelineCreateInfoRootItem = nullptr; - - switch (pipelineType) - { - case rgPipelineType::Graphics: - { - // Initialize the default graphics pipeline state configuration. - InitializeDefaultGraphicsPipeline(); - - // Initialize the model root element. - pPipelineCreateInfoRootItem = InitializeGraphicsPipelineCreateInfo(pParent); - } - break; - case rgPipelineType::Compute: - { - // Initialize the default compute pipeline state configuration. - InitializeDefaultComputePipeline(); - - // Initialize the model root element. - pPipelineCreateInfoRootItem = InitializeComputePipelineCreateInfo(pParent); - } - break; - default: - // The pipeline type should not be anything other than Graphics or Compute. - assert(false); - break; - } - - // Destroy the existing element tree from the root item. - RG_SAFE_DELETE(m_pRootItem); - - // Assign the root item in the model. - m_pRootItem = pPipelineCreateInfoRootItem; -} - -void rgPipelineStateModel::Search(const QString& searchString, rgPipelineStateSearcher::SearchResultData& searchResults, rgEditorElement* pRootElement) -{ - // If no root element is provided, start at the model root element. - if (pRootElement == nullptr) - { - assert(m_pRootItem != nullptr); - if (m_pRootItem != nullptr) - { - QString searchStringCopy = searchString; - - // If we don't care about matching upper/lower case, convert everything to lower case. - if (!searchResults.m_searchOptions.m_matchCase) - { - searchStringCopy = searchStringCopy.toLower(); - } - - searchResults.m_searchString = searchStringCopy.toStdString(); - - // Start searching the tree at the root element. - Search(searchStringCopy, searchResults, m_pRootItem); - } - } - else - { - // Search all child elements. - const int childCount = pRootElement->ChildCount(); - for (int childIndex = 0; childIndex < childCount; ++childIndex) - { - rgEditorElement* pChildElement = pRootElement->GetChild(childIndex); - if (pChildElement != nullptr) - { - // Search each column in the child for the search string. - int columnIndex = static_cast(rgRowData::RowDataMemberName); - const int lastColumnIndex = static_cast(rgRowData::RowDataMemberValue); - for (; columnIndex <= lastColumnIndex; ++columnIndex) - { - QString fieldToSearch = pChildElement->Data(columnIndex).toString(); - - // If casing doesn't matter, compare everything in lower case. - if (!searchResults.m_searchOptions.m_matchCase) - { - fieldToSearch = fieldToSearch.toLower(); - } - - int startIndex = 0; - while ((startIndex = fieldToSearch.indexOf(searchString, startIndex)) != -1) - { - rgPipelineStateSearcher::OccurrenceLocation indices = { pChildElement, columnIndex, startIndex }; - searchResults.m_resultOccurrences.push_back(indices); - startIndex += searchString.length(); - } - } - - // Recursively iterate to each child element to look for search results. - if (pChildElement->ChildCount() > 0) - { - // Search the child's children for the string. - Search(searchString, searchResults, pChildElement); - } - } - } - } -} - -rgPipelineType rgPipelineStateModel::GetPipelineType() const -{ - return m_pipelineType; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateModelVulkan.cpp b/RadeonGPUAnalyzerGUI/Src/rgPipelineStateModelVulkan.cpp deleted file mode 100644 index 3d15b01..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateModelVulkan.cpp +++ /dev/null @@ -1,3639 +0,0 @@ -// C++. -#include -#include - -// Infra. -#include - -// Utils. -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const rgEnumValuesVector& GetFormatEnumerators() -{ - static rgEnumValuesVector formatValues = { - ENUM_VALUE(VK_FORMAT_UNDEFINED), - ENUM_VALUE(VK_FORMAT_R4G4_UNORM_PACK8), - ENUM_VALUE(VK_FORMAT_R4G4B4A4_UNORM_PACK16), - ENUM_VALUE(VK_FORMAT_B4G4R4A4_UNORM_PACK16), - ENUM_VALUE(VK_FORMAT_R5G6B5_UNORM_PACK16), - ENUM_VALUE(VK_FORMAT_B5G6R5_UNORM_PACK16), - ENUM_VALUE(VK_FORMAT_R5G5B5A1_UNORM_PACK16), - ENUM_VALUE(VK_FORMAT_B5G5R5A1_UNORM_PACK16), - ENUM_VALUE(VK_FORMAT_A1R5G5B5_UNORM_PACK16), - ENUM_VALUE(VK_FORMAT_R8_UNORM), - ENUM_VALUE(VK_FORMAT_R8_SNORM), - ENUM_VALUE(VK_FORMAT_R8_USCALED), - ENUM_VALUE(VK_FORMAT_R8_SSCALED), - ENUM_VALUE(VK_FORMAT_R8_UINT), - ENUM_VALUE(VK_FORMAT_R8_SINT), - ENUM_VALUE(VK_FORMAT_R8_SRGB), - ENUM_VALUE(VK_FORMAT_R8G8_UNORM), - ENUM_VALUE(VK_FORMAT_R8G8_SNORM), - ENUM_VALUE(VK_FORMAT_R8G8_USCALED), - ENUM_VALUE(VK_FORMAT_R8G8_SSCALED), - ENUM_VALUE(VK_FORMAT_R8G8_UINT), - ENUM_VALUE(VK_FORMAT_R8G8_SINT), - ENUM_VALUE(VK_FORMAT_R8G8_SRGB), - ENUM_VALUE(VK_FORMAT_R8G8B8_UNORM), - ENUM_VALUE(VK_FORMAT_R8G8B8_SNORM), - ENUM_VALUE(VK_FORMAT_R8G8B8_USCALED), - ENUM_VALUE(VK_FORMAT_R8G8B8_SSCALED), - ENUM_VALUE(VK_FORMAT_R8G8B8_UINT), - ENUM_VALUE(VK_FORMAT_R8G8B8_SINT), - ENUM_VALUE(VK_FORMAT_R8G8B8_SRGB), - ENUM_VALUE(VK_FORMAT_B8G8R8_UNORM), - ENUM_VALUE(VK_FORMAT_B8G8R8_SNORM), - ENUM_VALUE(VK_FORMAT_B8G8R8_USCALED), - ENUM_VALUE(VK_FORMAT_B8G8R8_SSCALED), - ENUM_VALUE(VK_FORMAT_B8G8R8_UINT), - ENUM_VALUE(VK_FORMAT_B8G8R8_SINT), - ENUM_VALUE(VK_FORMAT_B8G8R8_SRGB), - ENUM_VALUE(VK_FORMAT_R8G8B8A8_UNORM), - ENUM_VALUE(VK_FORMAT_R8G8B8A8_SNORM), - ENUM_VALUE(VK_FORMAT_R8G8B8A8_USCALED), - ENUM_VALUE(VK_FORMAT_R8G8B8A8_SSCALED), - ENUM_VALUE(VK_FORMAT_R8G8B8A8_UINT), - ENUM_VALUE(VK_FORMAT_R8G8B8A8_SINT), - ENUM_VALUE(VK_FORMAT_R8G8B8A8_SRGB), - ENUM_VALUE(VK_FORMAT_B8G8R8A8_UNORM), - ENUM_VALUE(VK_FORMAT_B8G8R8A8_SNORM), - ENUM_VALUE(VK_FORMAT_B8G8R8A8_USCALED), - ENUM_VALUE(VK_FORMAT_B8G8R8A8_SSCALED), - ENUM_VALUE(VK_FORMAT_B8G8R8A8_UINT), - ENUM_VALUE(VK_FORMAT_B8G8R8A8_SINT), - ENUM_VALUE(VK_FORMAT_B8G8R8A8_SRGB), - ENUM_VALUE(VK_FORMAT_A8B8G8R8_UNORM_PACK32), - ENUM_VALUE(VK_FORMAT_A8B8G8R8_SNORM_PACK32), - ENUM_VALUE(VK_FORMAT_A8B8G8R8_USCALED_PACK32), - ENUM_VALUE(VK_FORMAT_A8B8G8R8_SSCALED_PACK32), - ENUM_VALUE(VK_FORMAT_A8B8G8R8_UINT_PACK32), - ENUM_VALUE(VK_FORMAT_A8B8G8R8_SINT_PACK32), - ENUM_VALUE(VK_FORMAT_A8B8G8R8_SRGB_PACK32), - ENUM_VALUE(VK_FORMAT_A2R10G10B10_UNORM_PACK32), - ENUM_VALUE(VK_FORMAT_A2R10G10B10_SNORM_PACK32), - ENUM_VALUE(VK_FORMAT_A2R10G10B10_USCALED_PACK32), - ENUM_VALUE(VK_FORMAT_A2R10G10B10_SSCALED_PACK32), - ENUM_VALUE(VK_FORMAT_A2R10G10B10_UINT_PACK32), - ENUM_VALUE(VK_FORMAT_A2R10G10B10_SINT_PACK32), - ENUM_VALUE(VK_FORMAT_A2B10G10R10_UNORM_PACK32), - ENUM_VALUE(VK_FORMAT_A2B10G10R10_SNORM_PACK32), - ENUM_VALUE(VK_FORMAT_A2B10G10R10_USCALED_PACK32), - ENUM_VALUE(VK_FORMAT_A2B10G10R10_SSCALED_PACK32), - ENUM_VALUE(VK_FORMAT_A2B10G10R10_UINT_PACK32), - ENUM_VALUE(VK_FORMAT_A2B10G10R10_SINT_PACK32), - ENUM_VALUE(VK_FORMAT_R16_UNORM), - ENUM_VALUE(VK_FORMAT_R16_SNORM), - ENUM_VALUE(VK_FORMAT_R16_USCALED), - ENUM_VALUE(VK_FORMAT_R16_SSCALED), - ENUM_VALUE(VK_FORMAT_R16_UINT), - ENUM_VALUE(VK_FORMAT_R16_SINT), - ENUM_VALUE(VK_FORMAT_R16_SFLOAT), - ENUM_VALUE(VK_FORMAT_R16G16_UNORM), - ENUM_VALUE(VK_FORMAT_R16G16_SNORM), - ENUM_VALUE(VK_FORMAT_R16G16_USCALED), - ENUM_VALUE(VK_FORMAT_R16G16_SSCALED), - ENUM_VALUE(VK_FORMAT_R16G16_UINT), - ENUM_VALUE(VK_FORMAT_R16G16_SINT), - ENUM_VALUE(VK_FORMAT_R16G16_SFLOAT), - ENUM_VALUE(VK_FORMAT_R16G16B16_UNORM), - ENUM_VALUE(VK_FORMAT_R16G16B16_SNORM), - ENUM_VALUE(VK_FORMAT_R16G16B16_USCALED), - ENUM_VALUE(VK_FORMAT_R16G16B16_SSCALED), - ENUM_VALUE(VK_FORMAT_R16G16B16_UINT), - ENUM_VALUE(VK_FORMAT_R16G16B16_SINT), - ENUM_VALUE(VK_FORMAT_R16G16B16_SFLOAT), - ENUM_VALUE(VK_FORMAT_R16G16B16A16_UNORM), - ENUM_VALUE(VK_FORMAT_R16G16B16A16_SNORM), - ENUM_VALUE(VK_FORMAT_R16G16B16A16_USCALED), - ENUM_VALUE(VK_FORMAT_R16G16B16A16_SSCALED), - ENUM_VALUE(VK_FORMAT_R16G16B16A16_UINT), - ENUM_VALUE(VK_FORMAT_R16G16B16A16_SINT), - ENUM_VALUE(VK_FORMAT_R16G16B16A16_SFLOAT), - ENUM_VALUE(VK_FORMAT_R32_UINT), - ENUM_VALUE(VK_FORMAT_R32_SINT), - ENUM_VALUE(VK_FORMAT_R32_SFLOAT), - ENUM_VALUE(VK_FORMAT_R32G32_UINT), - ENUM_VALUE(VK_FORMAT_R32G32_SINT), - ENUM_VALUE(VK_FORMAT_R32G32_SFLOAT), - ENUM_VALUE(VK_FORMAT_R32G32B32_UINT), - ENUM_VALUE(VK_FORMAT_R32G32B32_SINT), - ENUM_VALUE(VK_FORMAT_R32G32B32_SFLOAT), - ENUM_VALUE(VK_FORMAT_R32G32B32A32_UINT), - ENUM_VALUE(VK_FORMAT_R32G32B32A32_SINT), - ENUM_VALUE(VK_FORMAT_R32G32B32A32_SFLOAT), - ENUM_VALUE(VK_FORMAT_R64_UINT), - ENUM_VALUE(VK_FORMAT_R64_SINT), - ENUM_VALUE(VK_FORMAT_R64_SFLOAT), - ENUM_VALUE(VK_FORMAT_R64G64_UINT), - ENUM_VALUE(VK_FORMAT_R64G64_SINT), - ENUM_VALUE(VK_FORMAT_R64G64_SFLOAT), - ENUM_VALUE(VK_FORMAT_R64G64B64_UINT), - ENUM_VALUE(VK_FORMAT_R64G64B64_SINT), - ENUM_VALUE(VK_FORMAT_R64G64B64_SFLOAT), - ENUM_VALUE(VK_FORMAT_R64G64B64A64_UINT), - ENUM_VALUE(VK_FORMAT_R64G64B64A64_SINT), - ENUM_VALUE(VK_FORMAT_R64G64B64A64_SFLOAT), - ENUM_VALUE(VK_FORMAT_B10G11R11_UFLOAT_PACK32), - ENUM_VALUE(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32), - ENUM_VALUE(VK_FORMAT_D16_UNORM), - ENUM_VALUE(VK_FORMAT_X8_D24_UNORM_PACK32), - ENUM_VALUE(VK_FORMAT_D32_SFLOAT), - ENUM_VALUE(VK_FORMAT_S8_UINT), - ENUM_VALUE(VK_FORMAT_D16_UNORM_S8_UINT), - ENUM_VALUE(VK_FORMAT_D24_UNORM_S8_UINT), - ENUM_VALUE(VK_FORMAT_D32_SFLOAT_S8_UINT), - ENUM_VALUE(VK_FORMAT_BC1_RGB_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_BC1_RGB_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_BC1_RGBA_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_BC1_RGBA_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_BC2_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_BC2_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_BC3_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_BC3_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_BC4_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_BC4_SNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_BC5_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_BC5_SNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_BC6H_UFLOAT_BLOCK), - ENUM_VALUE(VK_FORMAT_BC6H_SFLOAT_BLOCK), - ENUM_VALUE(VK_FORMAT_BC7_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_BC7_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_EAC_R11_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_EAC_R11_SNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_EAC_R11G11_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_EAC_R11G11_SNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_4x4_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_4x4_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_5x4_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_5x4_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_5x5_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_5x5_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_6x5_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_6x5_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_6x6_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_6x6_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_8x5_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_8x5_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_8x6_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_8x6_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_8x8_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_8x8_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_10x5_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_10x5_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_10x6_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_10x6_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_10x8_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_10x8_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_10x10_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_10x10_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_12x10_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_12x10_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_12x12_UNORM_BLOCK), - ENUM_VALUE(VK_FORMAT_ASTC_12x12_SRGB_BLOCK), - ENUM_VALUE(VK_FORMAT_G8B8G8R8_422_UNORM), - ENUM_VALUE(VK_FORMAT_B8G8R8G8_422_UNORM), - ENUM_VALUE(VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM), - ENUM_VALUE(VK_FORMAT_G8_B8R8_2PLANE_420_UNORM), - ENUM_VALUE(VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM), - ENUM_VALUE(VK_FORMAT_G8_B8R8_2PLANE_422_UNORM), - ENUM_VALUE(VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM), - ENUM_VALUE(VK_FORMAT_R10X6_UNORM_PACK16), - ENUM_VALUE(VK_FORMAT_R10X6G10X6_UNORM_2PACK16), - ENUM_VALUE(VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16), - ENUM_VALUE(VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16), - ENUM_VALUE(VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16), - ENUM_VALUE(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16), - ENUM_VALUE(VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16), - ENUM_VALUE(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16), - ENUM_VALUE(VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16), - ENUM_VALUE(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16), - ENUM_VALUE(VK_FORMAT_R12X4_UNORM_PACK16), - ENUM_VALUE(VK_FORMAT_R12X4G12X4_UNORM_2PACK16), - ENUM_VALUE(VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16), - ENUM_VALUE(VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16), - ENUM_VALUE(VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16), - ENUM_VALUE(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16), - ENUM_VALUE(VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16), - ENUM_VALUE(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16), - ENUM_VALUE(VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16), - ENUM_VALUE(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16), - ENUM_VALUE(VK_FORMAT_G16B16G16R16_422_UNORM), - ENUM_VALUE(VK_FORMAT_B16G16R16G16_422_UNORM), - ENUM_VALUE(VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM), - ENUM_VALUE(VK_FORMAT_G16_B16R16_2PLANE_420_UNORM), - ENUM_VALUE(VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM), - ENUM_VALUE(VK_FORMAT_G16_B16R16_2PLANE_422_UNORM), - ENUM_VALUE(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM), - ENUM_VALUE(VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG), - ENUM_VALUE(VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG), - ENUM_VALUE(VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG), - ENUM_VALUE(VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG), - ENUM_VALUE(VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG), - ENUM_VALUE(VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG), - ENUM_VALUE(VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG), - ENUM_VALUE(VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG), - - // NOTE: All declarations below use values repeated from the declarations above. - ENUM_VALUE(VK_FORMAT_G8B8G8R8_422_UNORM_KHR), - ENUM_VALUE(VK_FORMAT_B8G8R8G8_422_UNORM_KHR), - ENUM_VALUE(VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR), - ENUM_VALUE(VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR), - ENUM_VALUE(VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR), - ENUM_VALUE(VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR), - ENUM_VALUE(VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR), - ENUM_VALUE(VK_FORMAT_R10X6_UNORM_PACK16_KHR), - ENUM_VALUE(VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR), - ENUM_VALUE(VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR), - ENUM_VALUE(VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR), - ENUM_VALUE(VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR), - ENUM_VALUE(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR), - ENUM_VALUE(VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR), - ENUM_VALUE(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR), - ENUM_VALUE(VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR), - ENUM_VALUE(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR), - ENUM_VALUE(VK_FORMAT_R12X4_UNORM_PACK16_KHR), - ENUM_VALUE(VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR), - ENUM_VALUE(VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR), - ENUM_VALUE(VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR), - ENUM_VALUE(VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR), - ENUM_VALUE(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR), - ENUM_VALUE(VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR), - ENUM_VALUE(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR), - ENUM_VALUE(VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR), - ENUM_VALUE(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR), - ENUM_VALUE(VK_FORMAT_G16B16G16R16_422_UNORM_KHR), - ENUM_VALUE(VK_FORMAT_B16G16R16G16_422_UNORM_KHR), - ENUM_VALUE(VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR), - ENUM_VALUE(VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR), - ENUM_VALUE(VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR), - ENUM_VALUE(VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR), - ENUM_VALUE(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR), - }; - - return formatValues; -} - -static const rgEnumValuesVector& GetPipelineCreateFlagEnumerators() -{ - static rgEnumValuesVector pipelineCreateFlagEnumerators = { - ENUM_VALUE(VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT), - ENUM_VALUE(VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT), - ENUM_VALUE(VK_PIPELINE_CREATE_DERIVATIVE_BIT), - ENUM_VALUE(VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT), - ENUM_VALUE(VK_PIPELINE_CREATE_DISPATCH_BASE), - ENUM_VALUE(VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NV), - ENUM_VALUE(VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR), - ENUM_VALUE(VK_PIPELINE_CREATE_DISPATCH_BASE_KHR), - }; - - return pipelineCreateFlagEnumerators; -} - -static const rgEnumValuesVector& GetDescriptorSetLayoutCreateFlagEnumerators() -{ - static rgEnumValuesVector descriptorSetLayoutCreateFlagEnumerators = { - ENUM_VALUE(VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR), - ENUM_VALUE(VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT) - }; - - return descriptorSetLayoutCreateFlagEnumerators; -} - -static const rgEnumValuesVector& GetAttachmentDescriptionFlagEnumerators() -{ - static rgEnumValuesVector attachmentDescriptionFlagEnumerators = { - ENUM_VALUE(VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT), - }; - - return attachmentDescriptionFlagEnumerators; -} - -static const rgEnumValuesVector& GetPrimitiveTopologyEnumerators() -{ - static rgEnumValuesVector primitiveTopologyEnumerators = { - ENUM_VALUE(VK_PRIMITIVE_TOPOLOGY_POINT_LIST), - ENUM_VALUE(VK_PRIMITIVE_TOPOLOGY_LINE_LIST), - ENUM_VALUE(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP), - ENUM_VALUE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST), - ENUM_VALUE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP), - ENUM_VALUE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN), - ENUM_VALUE(VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY), - ENUM_VALUE(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY), - ENUM_VALUE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY), - ENUM_VALUE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY), - ENUM_VALUE(VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) - }; - - return primitiveTopologyEnumerators; -} - -static const rgEnumValuesVector& GetAttachmentLoadOpEnumerators() -{ - static rgEnumValuesVector loadOpEnumerators = { - ENUM_VALUE(VK_ATTACHMENT_LOAD_OP_LOAD), - ENUM_VALUE(VK_ATTACHMENT_LOAD_OP_CLEAR), - ENUM_VALUE(VK_ATTACHMENT_LOAD_OP_DONT_CARE) - }; - - return loadOpEnumerators; -} - -static const rgEnumValuesVector& GetAttachmentStoreOpEnumerators() -{ - static rgEnumValuesVector storeOpEnumerators = { - ENUM_VALUE(VK_ATTACHMENT_STORE_OP_STORE), - ENUM_VALUE(VK_ATTACHMENT_STORE_OP_DONT_CARE), - }; - - return storeOpEnumerators; -} - -static const rgEnumValuesVector& GetImageLayoutEnumerators() -{ - static rgEnumValuesVector imageLayoutEnumerators = { - ENUM_VALUE(VK_IMAGE_LAYOUT_UNDEFINED), - ENUM_VALUE(VK_IMAGE_LAYOUT_GENERAL), - ENUM_VALUE(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL), - ENUM_VALUE(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), - ENUM_VALUE(VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL), - ENUM_VALUE(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL), - ENUM_VALUE(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL), - ENUM_VALUE(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL), - ENUM_VALUE(VK_IMAGE_LAYOUT_PREINITIALIZED), - ENUM_VALUE(VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL), - ENUM_VALUE(VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL), - ENUM_VALUE(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR), - ENUM_VALUE(VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR), - ENUM_VALUE(VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR), - ENUM_VALUE(VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR), - }; - - return imageLayoutEnumerators; -} - -static const rgEnumValuesVector& GetPolygonModeEnumerators() -{ - static rgEnumValuesVector polygonModeEnumerators = { - ENUM_VALUE(VK_POLYGON_MODE_FILL), - ENUM_VALUE(VK_POLYGON_MODE_LINE), - ENUM_VALUE(VK_POLYGON_MODE_POINT), - ENUM_VALUE(VK_POLYGON_MODE_FILL_RECTANGLE_NV), - }; - - return polygonModeEnumerators; -} - -static const rgEnumValuesVector& GetCullModeFlagEnumerators() -{ - static rgEnumValuesVector cullModeFlagEnumerators = { - ENUM_VALUE(VK_CULL_MODE_NONE), - ENUM_VALUE(VK_CULL_MODE_FRONT_BIT), - ENUM_VALUE(VK_CULL_MODE_BACK_BIT), - ENUM_VALUE(VK_CULL_MODE_FRONT_AND_BACK), - }; - - return cullModeFlagEnumerators; -} - -static const rgEnumValuesVector& GetFrontFaceEnumerators() -{ - static rgEnumValuesVector frontFaceEnumerators = { - ENUM_VALUE(VK_FRONT_FACE_COUNTER_CLOCKWISE), - ENUM_VALUE(VK_FRONT_FACE_CLOCKWISE), - }; - - return frontFaceEnumerators; -} - -static const rgEnumValuesVector& GetRasterizationSamplesEnumerators() -{ - static rgEnumValuesVector rasterizationSamplesFlags = { - ENUM_VALUE(VK_SAMPLE_COUNT_1_BIT), - ENUM_VALUE(VK_SAMPLE_COUNT_2_BIT), - ENUM_VALUE(VK_SAMPLE_COUNT_4_BIT), - ENUM_VALUE(VK_SAMPLE_COUNT_8_BIT), - ENUM_VALUE(VK_SAMPLE_COUNT_16_BIT), - ENUM_VALUE(VK_SAMPLE_COUNT_32_BIT), - ENUM_VALUE(VK_SAMPLE_COUNT_64_BIT), - }; - - return rasterizationSamplesFlags; -} - -static const rgEnumValuesVector& GetCompareOpEnumerators() -{ - static rgEnumValuesVector compareOpEnumerators = { - ENUM_VALUE(VK_COMPARE_OP_NEVER), - ENUM_VALUE(VK_COMPARE_OP_LESS), - ENUM_VALUE(VK_COMPARE_OP_EQUAL), - ENUM_VALUE(VK_COMPARE_OP_LESS_OR_EQUAL), - ENUM_VALUE(VK_COMPARE_OP_GREATER), - ENUM_VALUE(VK_COMPARE_OP_NOT_EQUAL), - ENUM_VALUE(VK_COMPARE_OP_GREATER_OR_EQUAL), - ENUM_VALUE(VK_COMPARE_OP_ALWAYS), - }; - - return compareOpEnumerators; -} - -static const rgEnumValuesVector& GetStencilOpEnumerators() -{ - static rgEnumValuesVector stencilOpEnumerators = { - ENUM_VALUE(VK_STENCIL_OP_KEEP), - ENUM_VALUE(VK_STENCIL_OP_ZERO), - ENUM_VALUE(VK_STENCIL_OP_REPLACE), - ENUM_VALUE(VK_STENCIL_OP_INCREMENT_AND_CLAMP), - ENUM_VALUE(VK_STENCIL_OP_DECREMENT_AND_CLAMP), - ENUM_VALUE(VK_STENCIL_OP_INVERT), - ENUM_VALUE(VK_STENCIL_OP_INCREMENT_AND_WRAP), - ENUM_VALUE(VK_STENCIL_OP_DECREMENT_AND_WRAP), - }; - - return stencilOpEnumerators; -} - -static const rgEnumValuesVector& GetLogicOpEnumerators() -{ - static rgEnumValuesVector logicOpEnumerators = { - ENUM_VALUE(VK_LOGIC_OP_CLEAR), - ENUM_VALUE(VK_LOGIC_OP_AND), - ENUM_VALUE(VK_LOGIC_OP_AND_REVERSE), - ENUM_VALUE(VK_LOGIC_OP_COPY), - ENUM_VALUE(VK_LOGIC_OP_AND_INVERTED), - ENUM_VALUE(VK_LOGIC_OP_NO_OP), - ENUM_VALUE(VK_LOGIC_OP_XOR), - ENUM_VALUE(VK_LOGIC_OP_OR), - ENUM_VALUE(VK_LOGIC_OP_NOR), - ENUM_VALUE(VK_LOGIC_OP_EQUIVALENT), - ENUM_VALUE(VK_LOGIC_OP_INVERT), - ENUM_VALUE(VK_LOGIC_OP_OR_REVERSE), - ENUM_VALUE(VK_LOGIC_OP_COPY_INVERTED), - ENUM_VALUE(VK_LOGIC_OP_OR_INVERTED), - ENUM_VALUE(VK_LOGIC_OP_NAND), - ENUM_VALUE(VK_LOGIC_OP_SET), - }; - - return logicOpEnumerators; -} - -static const rgEnumValuesVector& GetBlendFactorEnumerators() -{ - static rgEnumValuesVector blendFactorEnumerators = { - ENUM_VALUE(VK_BLEND_FACTOR_ZERO), - ENUM_VALUE(VK_BLEND_FACTOR_ONE), - ENUM_VALUE(VK_BLEND_FACTOR_SRC_COLOR), - ENUM_VALUE(VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR), - ENUM_VALUE(VK_BLEND_FACTOR_DST_COLOR), - ENUM_VALUE(VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR), - ENUM_VALUE(VK_BLEND_FACTOR_SRC_ALPHA), - ENUM_VALUE(VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA), - ENUM_VALUE(VK_BLEND_FACTOR_DST_ALPHA), - ENUM_VALUE(VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA), - ENUM_VALUE(VK_BLEND_FACTOR_CONSTANT_COLOR), - ENUM_VALUE(VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR), - ENUM_VALUE(VK_BLEND_FACTOR_CONSTANT_ALPHA), - ENUM_VALUE(VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA), - ENUM_VALUE(VK_BLEND_FACTOR_SRC_ALPHA_SATURATE), - ENUM_VALUE(VK_BLEND_FACTOR_SRC1_COLOR), - ENUM_VALUE(VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR), - ENUM_VALUE(VK_BLEND_FACTOR_SRC1_ALPHA), - ENUM_VALUE(VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA), - }; - - return blendFactorEnumerators; -} - -static const rgEnumValuesVector& GetBlendOpEnumerators() -{ - static rgEnumValuesVector blendOpEnumerators = { - ENUM_VALUE(VK_BLEND_OP_ADD), - ENUM_VALUE(VK_BLEND_OP_SUBTRACT), - ENUM_VALUE(VK_BLEND_OP_REVERSE_SUBTRACT), - ENUM_VALUE(VK_BLEND_OP_MIN), - ENUM_VALUE(VK_BLEND_OP_MAX), - ENUM_VALUE(VK_BLEND_OP_ZERO_EXT), - ENUM_VALUE(VK_BLEND_OP_SRC_EXT), - ENUM_VALUE(VK_BLEND_OP_DST_EXT), - ENUM_VALUE(VK_BLEND_OP_SRC_OVER_EXT), - ENUM_VALUE(VK_BLEND_OP_DST_OVER_EXT), - ENUM_VALUE(VK_BLEND_OP_SRC_IN_EXT), - ENUM_VALUE(VK_BLEND_OP_DST_IN_EXT), - ENUM_VALUE(VK_BLEND_OP_SRC_OUT_EXT), - ENUM_VALUE(VK_BLEND_OP_DST_OUT_EXT), - ENUM_VALUE(VK_BLEND_OP_SRC_ATOP_EXT), - ENUM_VALUE(VK_BLEND_OP_DST_ATOP_EXT), - ENUM_VALUE(VK_BLEND_OP_XOR_EXT), - ENUM_VALUE(VK_BLEND_OP_MULTIPLY_EXT), - ENUM_VALUE(VK_BLEND_OP_SCREEN_EXT), - ENUM_VALUE(VK_BLEND_OP_OVERLAY_EXT), - ENUM_VALUE(VK_BLEND_OP_DARKEN_EXT), - ENUM_VALUE(VK_BLEND_OP_LIGHTEN_EXT), - ENUM_VALUE(VK_BLEND_OP_COLORDODGE_EXT), - ENUM_VALUE(VK_BLEND_OP_COLORBURN_EXT), - ENUM_VALUE(VK_BLEND_OP_HARDLIGHT_EXT), - ENUM_VALUE(VK_BLEND_OP_SOFTLIGHT_EXT), - ENUM_VALUE(VK_BLEND_OP_DIFFERENCE_EXT), - ENUM_VALUE(VK_BLEND_OP_EXCLUSION_EXT), - ENUM_VALUE(VK_BLEND_OP_INVERT_EXT), - ENUM_VALUE(VK_BLEND_OP_INVERT_RGB_EXT), - ENUM_VALUE(VK_BLEND_OP_LINEARDODGE_EXT), - ENUM_VALUE(VK_BLEND_OP_LINEARBURN_EXT), - ENUM_VALUE(VK_BLEND_OP_VIVIDLIGHT_EXT), - ENUM_VALUE(VK_BLEND_OP_LINEARLIGHT_EXT), - ENUM_VALUE(VK_BLEND_OP_PINLIGHT_EXT), - ENUM_VALUE(VK_BLEND_OP_HARDMIX_EXT), - ENUM_VALUE(VK_BLEND_OP_HSL_HUE_EXT), - ENUM_VALUE(VK_BLEND_OP_HSL_SATURATION_EXT), - ENUM_VALUE(VK_BLEND_OP_HSL_COLOR_EXT), - ENUM_VALUE(VK_BLEND_OP_HSL_LUMINOSITY_EXT), - ENUM_VALUE(VK_BLEND_OP_PLUS_EXT), - ENUM_VALUE(VK_BLEND_OP_PLUS_CLAMPED_EXT), - ENUM_VALUE(VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT), - ENUM_VALUE(VK_BLEND_OP_PLUS_DARKER_EXT), - ENUM_VALUE(VK_BLEND_OP_MINUS_EXT), - ENUM_VALUE(VK_BLEND_OP_MINUS_CLAMPED_EXT), - ENUM_VALUE(VK_BLEND_OP_CONTRAST_EXT), - ENUM_VALUE(VK_BLEND_OP_INVERT_OVG_EXT), - ENUM_VALUE(VK_BLEND_OP_RED_EXT), - ENUM_VALUE(VK_BLEND_OP_GREEN_EXT), - ENUM_VALUE(VK_BLEND_OP_BLUE_EXT), - }; - - return blendOpEnumerators; -} - -static const rgEnumValuesVector& GetColorComponentFlagEnumerators() -{ - static rgEnumValuesVector colorComponentFlagEnumerators = { - ENUM_VALUE(VK_COLOR_COMPONENT_R_BIT), - ENUM_VALUE(VK_COLOR_COMPONENT_G_BIT), - ENUM_VALUE(VK_COLOR_COMPONENT_B_BIT), - ENUM_VALUE(VK_COLOR_COMPONENT_A_BIT), - }; - - return colorComponentFlagEnumerators; -} - -static const rgEnumValuesVector& GetShaderStageFlagEnumerators() -{ - static rgEnumValuesVector stageFlagEnumerators = { - ENUM_VALUE(VK_SHADER_STAGE_VERTEX_BIT), - ENUM_VALUE(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT), - ENUM_VALUE(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT), - ENUM_VALUE(VK_SHADER_STAGE_GEOMETRY_BIT), - ENUM_VALUE(VK_SHADER_STAGE_FRAGMENT_BIT), - ENUM_VALUE(VK_SHADER_STAGE_COMPUTE_BIT), - ENUM_VALUE(VK_SHADER_STAGE_ALL_GRAPHICS), - }; - - return stageFlagEnumerators; -} - -static const rgEnumValuesVector& GetDescriptorTypeEnumerators() -{ - static rgEnumValuesVector descriptorTypeEnumerators = { - ENUM_VALUE(VK_DESCRIPTOR_TYPE_SAMPLER), - ENUM_VALUE(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER), - ENUM_VALUE(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE), - ENUM_VALUE(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE), - ENUM_VALUE(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER), - ENUM_VALUE(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER), - ENUM_VALUE(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER), - ENUM_VALUE(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER), - ENUM_VALUE(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC), - ENUM_VALUE(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC), - ENUM_VALUE(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT), - }; - - return descriptorTypeEnumerators; -} - -static const rgEnumValuesVector& GetPipelineStageFlagEnumerators() -{ - static rgEnumValuesVector pipelineStageFlagEnumerators = { - ENUM_VALUE(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT), - ENUM_VALUE(VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT), - ENUM_VALUE(VK_PIPELINE_STAGE_VERTEX_INPUT_BIT), - ENUM_VALUE(VK_PIPELINE_STAGE_VERTEX_SHADER_BIT), - ENUM_VALUE(VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT), - ENUM_VALUE(VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT), - ENUM_VALUE(VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT), - ENUM_VALUE(VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT), - ENUM_VALUE(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT), - ENUM_VALUE(VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT), - ENUM_VALUE(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT), - ENUM_VALUE(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT), - ENUM_VALUE(VK_PIPELINE_STAGE_TRANSFER_BIT), - ENUM_VALUE(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT), - ENUM_VALUE(VK_PIPELINE_STAGE_HOST_BIT), - ENUM_VALUE(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT), - ENUM_VALUE(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT), - }; - - return pipelineStageFlagEnumerators; -} - -static const rgEnumValuesVector& GetAccessFlagEnumerators() -{ - static rgEnumValuesVector accessFlagEnumerators = { - ENUM_VALUE(VK_ACCESS_INDIRECT_COMMAND_READ_BIT), - ENUM_VALUE(VK_ACCESS_INDEX_READ_BIT), - ENUM_VALUE(VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT), - ENUM_VALUE(VK_ACCESS_UNIFORM_READ_BIT), - ENUM_VALUE(VK_ACCESS_INPUT_ATTACHMENT_READ_BIT), - ENUM_VALUE(VK_ACCESS_SHADER_READ_BIT), - ENUM_VALUE(VK_ACCESS_SHADER_WRITE_BIT), - ENUM_VALUE(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT), - ENUM_VALUE(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), - ENUM_VALUE(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT), - ENUM_VALUE(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT), - ENUM_VALUE(VK_ACCESS_TRANSFER_READ_BIT), - ENUM_VALUE(VK_ACCESS_TRANSFER_WRITE_BIT), - ENUM_VALUE(VK_ACCESS_HOST_READ_BIT), - ENUM_VALUE(VK_ACCESS_HOST_WRITE_BIT), - ENUM_VALUE(VK_ACCESS_MEMORY_READ_BIT), - ENUM_VALUE(VK_ACCESS_MEMORY_WRITE_BIT), - ENUM_VALUE(VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT), - }; - - return accessFlagEnumerators; -} - -static const rgEnumValuesVector& GetDependencyFlagEnumerators() -{ - static rgEnumValuesVector dependencyFlagEnumerators = { - ENUM_VALUE(VK_DEPENDENCY_BY_REGION_BIT), - ENUM_VALUE(VK_DEPENDENCY_DEVICE_GROUP_BIT), - ENUM_VALUE(VK_DEPENDENCY_VIEW_LOCAL_BIT), - ENUM_VALUE(VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR), - ENUM_VALUE(VK_DEPENDENCY_DEVICE_GROUP_BIT_KHR), - }; - - return dependencyFlagEnumerators; -} - -static const rgEnumValuesVector& GetSubpassDescriptionFlagEnumerators() -{ - static rgEnumValuesVector subpassDescriptionFlagEnumerators = { - ENUM_VALUE(VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX), - ENUM_VALUE(VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX), - }; - - return subpassDescriptionFlagEnumerators; -} - -static const rgEnumValuesVector& GetPipelineBindPointEnumerators() -{ - static rgEnumValuesVector pipelineBindPointEnumerators = { - ENUM_VALUE(VK_PIPELINE_BIND_POINT_GRAPHICS), - ENUM_VALUE(VK_PIPELINE_BIND_POINT_COMPUTE), - }; - - return pipelineBindPointEnumerators; -} - -rgPipelineStateModelVulkan::rgPipelineStateModelVulkan(QWidget* pParent) - : rgPipelineStateModel(pParent) - , m_descriptorSetLayoutCount(0) -{ -} - -uint32_t GetSampleMaskDimension(VkSampleCountFlagBits sampleCountBits) -{ - uint32_t enumDimension = 0; - switch (sampleCountBits) - { - case VK_SAMPLE_COUNT_1_BIT: - case VK_SAMPLE_COUNT_2_BIT: - case VK_SAMPLE_COUNT_4_BIT: - case VK_SAMPLE_COUNT_8_BIT: - case VK_SAMPLE_COUNT_16_BIT: - case VK_SAMPLE_COUNT_32_BIT: - // One 32-bit uint_32 is used to hold 1 to 32 bit flags. - enumDimension = 1; - break; - case VK_SAMPLE_COUNT_64_BIT: - // Two 32-bit uint_32's are used to hold the 64 bit flags. - enumDimension = 2; - break; - default: - assert(false); - } - - return enumDimension; -} - -bool rgPipelineStateModelVulkan::CheckValidPipelineState(std::string& errorString) const -{ - bool ret = false; - - std::stringstream errorStream; - - // Choose how to validate the PSO state based on the pipeline type. - if (m_pipelineType == rgPipelineType::Graphics) - { - // Verify that if the number of resolve attachments is non-null, the dimension of - // pResolveAttachments matches that of pColorAttachments. - VkRenderPassCreateInfo* pRenderPassCreateInfo = m_pGraphicsPipelineState->GetRenderPassCreateInfo(); - assert(pRenderPassCreateInfo != nullptr); - if (pRenderPassCreateInfo != nullptr) - { - bool isResolveAttachmentsCompatible = true; - - // Step through each subpass. - for (uint32_t subpassIndex = 0; subpassIndex < pRenderPassCreateInfo->subpassCount; ++subpassIndex) - { - assert(pRenderPassCreateInfo->pSubpasses != nullptr); - if (pRenderPassCreateInfo->pSubpasses != nullptr) - { - // Step to the nth item in the subpass array. - const VkSubpassDescription* pSubpass = (pRenderPassCreateInfo->pSubpasses + subpassIndex); - assert(pSubpass != nullptr); - if (pSubpass != nullptr) - { - // Is the pResolveAttachments array used? If so, verify the dimension matches the - // number of color attachments. - if (pSubpass->pResolveAttachments != nullptr) - { - uint32_t* pSubpassResolveAttachmentCount = m_resolveAttachmentCountPerSubpass.at(subpassIndex); - if (pSubpassResolveAttachmentCount != nullptr) - { - // Does the number of resolve attachments match the number of color attachments? - assert(pSubpass->colorAttachmentCount == *pSubpassResolveAttachmentCount); - if (pSubpass->colorAttachmentCount != *pSubpassResolveAttachmentCount) - { - // Build an error string that mentions the index of the problematic subpass. - errorStream << STR_ERROR_RESOLVE_ATTACHMENTS_INVALID_A; - errorStream << subpassIndex; - errorStream << STR_ERROR_RESOLVE_ATTACHMENTS_INVALID_B; - errorStream << " "; - errorStream << STR_ERROR_RESOLVE_ATTACHMENTS_INVALID_C; - - // Return false, and exit out of the loop. Validation failed. - isResolveAttachmentsCompatible = false; - break; - } - } - } - } - } - } - - ret = isResolveAttachmentsCompatible; - } - - VkPipelineMultisampleStateCreateInfo* pMultisamplingStateCreateInfo = - m_pGraphicsPipelineState->GetPipelineMultisampleStateCreateInfo(); - assert(pMultisamplingStateCreateInfo != nullptr); - if (pMultisamplingStateCreateInfo != nullptr) - { - bool isMultisamplingSampleMaskValid = false; - - // If the multisampling state's pSampleMask is enabled, verify that the dimension - // of the array is compatible with the rasterizationSamples state. - if (pMultisamplingStateCreateInfo->pSampleMask != nullptr) - { - uint32_t enumDimension = GetSampleMaskDimension(pMultisamplingStateCreateInfo->rasterizationSamples); - - // If the pSampleMask is used, the dimension should be non-zero. - assert(enumDimension != 0); - if (enumDimension != 0) - { - // The pSampleMask array is valid if the rasterizationSamples enum - // matches the dimension that the user has set. - isMultisamplingSampleMaskValid = enumDimension == m_sampleMaskDimension; - - if (!isMultisamplingSampleMaskValid) - { - // Construct an error message indicating why the pipeline is valid. - errorStream << STR_ERROR_MULTISAMPLING_SAMPLE_MASK_INVALID_A; - errorStream << std::endl; - errorStream << STR_ERROR_MULTISAMPLING_SAMPLE_MASK_INVALID_B; - } - } - } - else - { - // Multisampling state doesn't need to be verified further if pSampleMask is null. - isMultisamplingSampleMaskValid = true; - } - - // Update the return value based on the mask validity. - ret = ret && isMultisamplingSampleMaskValid; - } - } - else if (m_pipelineType == rgPipelineType::Compute) - { - // Nothing needs to be validated for a compute pipeline. Just return true each time. - ret = true; - } - else - { - // The pipeline type couldn't be determined. This shouldn't happen. - assert(false && "Failed to validate pipeline because the pipeline type could not be determined."); - } - - errorString = errorStream.str(); - - return ret; -} - -void rgPipelineStateModelVulkan::InitializeDefaultGraphicsPipeline() -{ - std::shared_ptr pPipelineFactory = std::make_shared(); - - rgPsoGraphicsVulkan* pGraphicsPsoState = pPipelineFactory->GetDefaultGraphicsPsoCreateInfo(); - assert(pGraphicsPsoState != nullptr); - if (pGraphicsPsoState != nullptr) - { - // Configure the pipeline's default blend state to be compatible with the default shader code. - VkPipelineColorBlendAttachmentState* pColorBlendAttachment = new VkPipelineColorBlendAttachmentState{}; - pColorBlendAttachment->colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - pColorBlendAttachment->blendEnable = VK_FALSE; - pColorBlendAttachment->srcColorBlendFactor = VK_BLEND_FACTOR_ONE; - pColorBlendAttachment->dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; - pColorBlendAttachment->colorBlendOp = VK_BLEND_OP_ADD; - pColorBlendAttachment->srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - pColorBlendAttachment->dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - pColorBlendAttachment->alphaBlendOp = VK_BLEND_OP_ADD; - - // Add a default color blend create info state. - VkPipelineColorBlendStateCreateInfo* pColorBlendStateInfo = pGraphicsPsoState->GetPipelineColorBlendStateCreateInfo(); - pColorBlendStateInfo->pAttachments = pColorBlendAttachment; - pColorBlendStateInfo->attachmentCount = 1; - - // Assign the default state in the model. - m_pGraphicsPipelineState = pGraphicsPsoState; - } -} - -void rgPipelineStateModelVulkan::InitializeDefaultComputePipeline() -{ - std::shared_ptr pPipelineFactory = std::make_shared(); - - // Configure a compute pipeline state with default configuration. - rgPsoComputeVulkan* pComputePsoState = pPipelineFactory->GetDefaultComputePsoCreateInfo(); - assert(pComputePsoState != nullptr); - if (pComputePsoState != nullptr) - { - // Assign the default state in the model. - m_pComputePipelineState = pComputePsoState; - } -} - -void rgPipelineStateModelVulkan::InitializeDescriptorSetLayoutCreateInfoArray(rgEditorElement* pRootElement, rgPsoCreateInfoVulkan* pCreateInfo) -{ - // Create the root element for the Descriptor Set Layout array configuration. - rgEditorElement* pDescriptorSetLayoutsRoot = new rgEditorElement(pRootElement, STR_VULKAN_DESCRIPTOR_SET_LAYOUTS_HEADER); - - // Set the object name. - pDescriptorSetLayoutsRoot->setObjectName(STR_DESCRIPTOR_SET_LAYOUTS_ROOT); - - // Display the type name with brackets to indicate that it's an array. - std::stringstream descriptorSetLayoutsArrayStream; - descriptorSetLayoutsArrayStream << STR_VULKAN_DESCRIPTOR_SET_LAYOUT_CREATE_INFO << "[]"; - - std::vector& descriptorSetLayouts = pCreateInfo->GetDescriptorSetLayoutCreateInfo(); - - // Create the Descriptor Set Layout array root item. - rgEditorElementArrayElementAdd* pDescriptorSetLayoutsItem = new rgEditorElementArrayElementAdd(pDescriptorSetLayoutsRoot, descriptorSetLayoutsArrayStream.str().c_str(), - [=](int elementIndex) - { - std::vector& currentDescriptorSetLayouts = pCreateInfo->GetDescriptorSetLayoutCreateInfo(); - int elementCount = static_cast(currentDescriptorSetLayouts.size()); - - // If we remove the given element, is it necessary to shift other subsequent elements? - if (elementCount > 1 && elementIndex < elementCount - 1) - { - // Shift all elements after the removed element. - for (int copyIndex = elementIndex; copyIndex < (elementCount - 1); ++copyIndex) - { - memcpy(*(currentDescriptorSetLayouts.data() + copyIndex), *(currentDescriptorSetLayouts.data() + (copyIndex + 1)), sizeof(VkDescriptorSetLayoutCreateInfo)); - } - } - }); - - // Set the object name. - pDescriptorSetLayoutsItem->setObjectName(STR_DESCRIPTOR_SET_LAYOUTS_ITEM); - - // Initialize the Descriptor Set Layout count. - m_descriptorSetLayoutCount = static_cast(descriptorSetLayouts.size()); - - // Create the Descriptor Set Layout count item. - rgEditorElement* pDescriptorSetLayoutCountItem = MakeNumericElement(nullptr, STR_VULKAN_DESCRIPTOR_SET_LAYOUT_COUNT, - &m_descriptorSetLayoutCount, [=] { HandleDescriptorSetLayoutCountChanged(pDescriptorSetLayoutsItem, pCreateInfo); }); - - // Set the object name. - pDescriptorSetLayoutCountItem->setObjectName(STR_DESCRIPTOR_SET_LAYOUT_COUNT_ITEM); - - // Provide the element used to track the dimension of the Descriptor Set Layouts array. - pDescriptorSetLayoutsItem->SetArraySizeElement(static_cast*>(pDescriptorSetLayoutCountItem)); - - // Initialize the Descriptor Set Layouts array rows. - HandleDescriptorSetLayoutCountChanged(pDescriptorSetLayoutsItem, pCreateInfo, true); - - // Add the Descriptor Set Layouts create info array item. - pDescriptorSetLayoutsRoot->AppendChildItem(pDescriptorSetLayoutsItem); - - // Add the Descriptor Set Layout section. - pRootElement->AppendChildItem(pDescriptorSetLayoutsRoot); -} - -rgEditorElement* rgPipelineStateModelVulkan::InitializeGraphicsPipelineCreateInfo(QWidget* pParent) -{ - rgEditorElement* pCreateInfoRootNode = nullptr; - - assert(m_pGraphicsPipelineState != nullptr); - if (m_pGraphicsPipelineState != nullptr) - { - // Create the root node that all create info elements are attached to. - pCreateInfoRootNode = new rgEditorElement(pParent, STR_VULKAN_GRAPHICS_PIPELINE_STATE); - - // Set object name. - pCreateInfoRootNode->setObjectName(STR_CREATE_INFO_ROOT_NODE); - - // Add the Graphics Pipeline create info root node. - InitializeVkGraphicsPipelineCreateInfo(pCreateInfoRootNode, m_pGraphicsPipelineState); - - // Add the Pipeline Layout create info root node. - VkPipelineLayoutCreateInfo* pPipelineLayoutCreateInfo = m_pGraphicsPipelineState->GetPipelineLayoutCreateInfo(); - assert(pPipelineLayoutCreateInfo != nullptr); - if (pPipelineLayoutCreateInfo != nullptr) - { - InitializePipelineLayoutCreateInfo(pCreateInfoRootNode, pPipelineLayoutCreateInfo); - } - - // Initialize rows related to Descriptor Set Layout configuration. - InitializeDescriptorSetLayoutCreateInfoArray(pCreateInfoRootNode, m_pGraphicsPipelineState); - - // Add the Render Pass create info root node. - VkRenderPassCreateInfo* pRenderPassCreateInfo = m_pGraphicsPipelineState->GetRenderPassCreateInfo(); - assert(pRenderPassCreateInfo != nullptr); - if (pRenderPassCreateInfo != nullptr) - { - InitializeRenderPassCreateInfo(pCreateInfoRootNode, pRenderPassCreateInfo); - } - } - - return pCreateInfoRootNode; -} - -void rgPipelineStateModelVulkan::HandleDescriptorSetLayoutCountChanged(rgEditorElement* pRootElement, rgPsoCreateInfoVulkan* pCreateInfo, bool firstInit) -{ - int numExistingElements = pRootElement->ChildCount(); - int newElementCount = static_cast(m_descriptorSetLayoutCount); - - if (newElementCount != numExistingElements) - { - if (firstInit) - { - numExistingElements = newElementCount; - } - - std::vector& descriptorSetLayouts = pCreateInfo->GetDescriptorSetLayoutCreateInfo(); - - rgEditorElementArrayElementAdd* pArrayRoot = static_cast(pRootElement); - if (pArrayRoot != nullptr) - { - if (newElementCount == 0) - { - for (size_t elementIndex = 0; elementIndex < descriptorSetLayouts.size(); ++elementIndex) - { - RG_SAFE_DELETE(descriptorSetLayouts[elementIndex]); - } - - pRootElement->ClearChildren(); - descriptorSetLayouts.clear(); - - // Let the array root element know that the child elements were resized. - pArrayRoot->InvokeElementResizedCallback(); - } - else - { - std::vector newDescriptorSetLayouts; - for (size_t elementIndex = 0; elementIndex < newElementCount; ++elementIndex) - { - // Create an array of object with the new dimension. - VkDescriptorSetLayoutCreateInfo* pNewElement = new VkDescriptorSetLayoutCreateInfo{}; - newDescriptorSetLayouts.push_back(pNewElement); - } - - // If the element count was increased, copy all old contents. - // If it was reduced, copy as many as will fit in the new array. - uint32_t elementCount = newElementCount > numExistingElements ? numExistingElements : newElementCount; - - // Copy existing element data into the resized elements. - for (uint32_t index = 0; index < elementCount; ++index) - { - // Copy all member data into the new array elements. - memcpy(newDescriptorSetLayouts[index], descriptorSetLayouts[index], sizeof(VkDescriptorSetLayoutCreateInfo)); - } - - // Destroy the original array element data. - for (size_t elementIndex = 0; elementIndex < descriptorSetLayouts.size(); ++elementIndex) - { - RG_SAFE_DELETE(descriptorSetLayouts[elementIndex]); - } - - // Resize the number of Descriptor Set Layouts. - descriptorSetLayouts.clear(); - - // Remove all existing child element items from the array root node. - pRootElement->ClearChildren(); - - // Create a new element row for each item in the resized array. - for (int newChildIndex = 0; newChildIndex < newElementCount; ++newChildIndex) - { - pCreateInfo->AddDescriptorSetLayoutCreateInfo(newDescriptorSetLayouts[newChildIndex]); - - // Show the child index and the API's name for the structure. - std::stringstream elementNameStream; - elementNameStream << newChildIndex; - elementNameStream << " "; - elementNameStream << STR_VULKAN_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - - // Create an element node for each item in the array. - rgEditorElementArrayElementRemove* pArrayElement = new rgEditorElementArrayElementRemove(pRootElement, elementNameStream.str()); - - // Set object name. - QString name = STR_ARRAY_ELEMENT + QString::number(newChildIndex); - pArrayElement->setObjectName(name); - - // Each element in the array needs to know its index and the array root element. - pArrayElement->SetElementIndex(pArrayRoot, newChildIndex); - - // Invoke the callback used to initialize each array element. - InitializeDescriptorSetLayoutCreateInfo(pArrayElement, descriptorSetLayouts[newChildIndex]); - - // Add the element node to the array root node. - pRootElement->AppendChildItem(pArrayElement); - - // Initialize the newly added rows. - pRootElement->InitializeRows(); - } - - if (!firstInit) - { - // Let the array root element know that the child elements were resized. - pArrayRoot->InvokeElementResizedCallback(); - - // Expand the array root node that was resized. - emit ExpandNode(pArrayRoot); - } - } - } - } -} - -void rgPipelineStateModelVulkan::InitializeVkGraphicsPipelineCreateInfo(rgEditorElement* pRootElement, rgPsoGraphicsVulkan* pGraphicsPipelineCreateInfo) -{ - assert(pGraphicsPipelineCreateInfo != nullptr); - if (pGraphicsPipelineCreateInfo != nullptr) - { - // Append the new graphics pipeline create info root item to the parent. - rgEditorElement* pGraphicsPipelineCreateInfoRoot = new rgEditorElement(pRootElement, STR_VULKAN_GRAPHICS_PIPELINE_CREATE_INFO); - pRootElement->AppendChildItem(pGraphicsPipelineCreateInfoRoot); - - // Set object name. - pGraphicsPipelineCreateInfoRoot->setObjectName(STR_GRAPHICS_PIPELINE_CREATE_INFO_ROOT); - - VkGraphicsPipelineCreateInfo* pVkGraphicsPipelineCreateInfo = pGraphicsPipelineCreateInfo->GetGraphicsPipelineCreateInfo(); - - // Add the "flags" member. - const rgEnumValuesVector& pipelineFlagsEnumerators = GetPipelineCreateFlagEnumerators(); - rgEditorElement* pFlagsItem = new rgEditorElementEnum(m_pParent, STR_VULKAN_PIPELINE_MEMBER_FLAGS, pipelineFlagsEnumerators, reinterpret_cast(&pVkGraphicsPipelineCreateInfo->flags), true); - pGraphicsPipelineCreateInfoRoot->AppendChildItem(pFlagsItem); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pFlagsItem), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pFlagsItem->setObjectName(STR_FLAGS_ITEM); - - // Connect to the flags enum list widget status signal. - isConnected = connect(pFlagsItem, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pFlagsItem), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "pVertexInputState" node. - VkPipelineVertexInputStateCreateInfo* pVertexInputStateCreateInfo = pGraphicsPipelineCreateInfo->GetPipelineVertexInputStateCreateInfo(); - assert(pVertexInputStateCreateInfo != nullptr); - if (pVertexInputStateCreateInfo != nullptr) - { - InitializeVertexInputStateCreateInfo(pGraphicsPipelineCreateInfoRoot, pVertexInputStateCreateInfo); - } - - // Add the "pInputAssemblyState" node. - VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyStateCreateInfo = pGraphicsPipelineCreateInfo->GetPipelineInputAssemblyStateCreateInfo(); - assert(pInputAssemblyStateCreateInfo != nullptr); - if (pInputAssemblyStateCreateInfo != nullptr) - { - InitializeInputAssemblyStateCreateInfo(pGraphicsPipelineCreateInfoRoot, pInputAssemblyStateCreateInfo); - } - - // Add the "pTessellationState" node. - VkPipelineTessellationStateCreateInfo* pTessellationStateCreateInfo = pGraphicsPipelineCreateInfo->GetPipelineTessellationStateCreateInfo(); - assert(pTessellationStateCreateInfo != nullptr); - if (pTessellationStateCreateInfo != nullptr) - { - InitializeTessellationStateCreateInfo(pGraphicsPipelineCreateInfoRoot, pTessellationStateCreateInfo); - } - - // Add the "pViewportState" node. - VkPipelineViewportStateCreateInfo* pPipelineViewportStateCreateInfo = pGraphicsPipelineCreateInfo->GetPipelineViewportStateCreateInfo(); - assert(pPipelineViewportStateCreateInfo != nullptr); - if (pPipelineViewportStateCreateInfo != nullptr) - { - InitializeViewportStateCreateInfo(pGraphicsPipelineCreateInfoRoot, pPipelineViewportStateCreateInfo); - } - - // Add the "pRasterizationState" node. - VkPipelineRasterizationStateCreateInfo* pPipelineRasterizationStateCreateInfo = pGraphicsPipelineCreateInfo->GetPipelineRasterizationStateCreateInfo(); - assert(pPipelineRasterizationStateCreateInfo != nullptr); - if (pPipelineRasterizationStateCreateInfo != nullptr) - { - InitializeRasterizationStateCreateInfo(pGraphicsPipelineCreateInfoRoot, pPipelineRasterizationStateCreateInfo); - } - - // Add the "pMultisampleState" node. - VkPipelineMultisampleStateCreateInfo* pPipelineMultisampleStateCreateInfo = pGraphicsPipelineCreateInfo->GetPipelineMultisampleStateCreateInfo(); - assert(pPipelineMultisampleStateCreateInfo != nullptr); - if (pPipelineMultisampleStateCreateInfo != nullptr) - { - InitializeMultisampleStateCreateInfo(pGraphicsPipelineCreateInfoRoot, pPipelineMultisampleStateCreateInfo); - } - - // Add the "pDepthStencilState" node. - VkPipelineDepthStencilStateCreateInfo* pPipelineDepthStencilStateCreateInfo = pGraphicsPipelineCreateInfo->GetPipelineDepthStencilStateCreateInfo(); - assert(pPipelineDepthStencilStateCreateInfo != nullptr); - if (pPipelineDepthStencilStateCreateInfo != nullptr) - { - InitializeDepthStencilStateCreateInfo(pGraphicsPipelineCreateInfoRoot, pPipelineDepthStencilStateCreateInfo); - } - - // Add the "pColorBlendState" node. - VkPipelineColorBlendStateCreateInfo* pPipelineColorBlendStateCreateInfo = pGraphicsPipelineCreateInfo->GetPipelineColorBlendStateCreateInfo(); - assert(pPipelineColorBlendStateCreateInfo != nullptr); - if (pPipelineColorBlendStateCreateInfo != nullptr) - { - InitializeColorBlendStateCreateInfo(pGraphicsPipelineCreateInfoRoot, pPipelineColorBlendStateCreateInfo); - } - - // Add the "subpass" member. - rgEditorElement* pSubpassCreateInfo = MakeNumericElement(pGraphicsPipelineCreateInfoRoot, STR_VULKAN_PIPELINE_MEMBER_SUBPASS, &pVkGraphicsPipelineCreateInfo->subpass); - pGraphicsPipelineCreateInfoRoot->AppendChildItem(pSubpassCreateInfo); - - // Add the "basePipelineIndex" member. - rgEditorElement* pBasePipelineIndexCreateInfo = MakeNumericElement(pGraphicsPipelineCreateInfoRoot, STR_VULKAN_PIPELINE_MEMBER_BASE_INDEX, &pVkGraphicsPipelineCreateInfo->basePipelineIndex); - pGraphicsPipelineCreateInfoRoot->AppendChildItem(pBasePipelineIndexCreateInfo); - } -} - -void rgPipelineStateModelVulkan::InitializeVertexInputStateCreateInfo(rgEditorElement* pRootElement, VkPipelineVertexInputStateCreateInfo* pVertexInputStateCreateInfo) -{ - assert(pVertexInputStateCreateInfo != nullptr); - if (pVertexInputStateCreateInfo != nullptr) - { - rgEditorElement* pVertexInputStateRoot = new rgEditorElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_PVERTEX_INPUT_STATE); - pRootElement->AppendChildItem(pVertexInputStateRoot); - - // Set object name. - pVertexInputStateRoot->setObjectName(STR_VERTEX_INPUT_STATE_ROOT); - - // Add the "flags" member. - rgEditorElement* pFlagsItem = MakeNumericElement(pVertexInputStateRoot, STR_VULKAN_PIPELINE_MEMBER_FLAGS, &pVertexInputStateCreateInfo->flags); - pVertexInputStateRoot->AppendChildItem(pFlagsItem); - - // Set object name. - pFlagsItem->setObjectName(STR_FLAGS_ITEM); - - // Create the vertex binding descriptions array root item. - rgEditorElementArrayElementAdd* pVertexBindingDescriptionsItem = new rgEditorElementArrayElementAdd(pVertexInputStateRoot, STR_VULKAN_PIPELINE_MEMBER_PVERTEX_BINDING_DESCRIPTIONS, - [=](int elementIndex) { RemoveElement(pVertexInputStateCreateInfo->pVertexBindingDescriptions, pVertexInputStateCreateInfo->vertexBindingDescriptionCount, elementIndex); }); - - // Set object name. - pVertexBindingDescriptionsItem->setObjectName(STR_VERTEX_BINDING_DESCRIPTIONS_ITEM); - - // Add the "vertexBindingDescriptionCount" member. - rgEditorElement* pVertexBindingDescriptionCountItem = MakeNumericElement(nullptr, STR_VULKAN_PIPELINE_MEMBER_VERTEX_BINDING_DESCRIPTION_COUNT, - &pVertexInputStateCreateInfo->vertexBindingDescriptionCount, [=] { HandleVertexBindingDescriptionCountChanged(pVertexBindingDescriptionsItem, pVertexInputStateCreateInfo); }); - - // Set object name. - pVertexBindingDescriptionCountItem->setObjectName(STR_VERTEX_BINDING_DESCRIPTION_COUNT_ITEM); - - // Provide the element used to track the dimension of the pVertexBindingDescriptions array. - pVertexBindingDescriptionsItem->SetArraySizeElement(static_cast*>(pVertexBindingDescriptionCountItem)); - - // Initialize the pVertexBindingDescriptions array rows. - HandleVertexBindingDescriptionCountChanged(pVertexBindingDescriptionsItem, pVertexInputStateCreateInfo, true); - - // Add the "pVertexBindingDescriptions" item. - pVertexInputStateRoot->AppendChildItem(pVertexBindingDescriptionsItem); - - // Create the vertex attribute descriptions array root item. - rgEditorElementArrayElementAdd* pVertexAttributeDescriptionsItem = new rgEditorElementArrayElementAdd(pVertexInputStateRoot, STR_VULKAN_PIPELINE_MEMBER_PVERTEX_ATTRIBUTE_DESCRIPTIONS, - [=](int elementIndex) { RemoveElement(pVertexInputStateCreateInfo->pVertexAttributeDescriptions, pVertexInputStateCreateInfo->vertexAttributeDescriptionCount, elementIndex); }); - - // Set object name. - pVertexAttributeDescriptionsItem->setObjectName(STR_VERTEX_ATTRIBUTE_DESCRIPTIONS_ITEM); - - // Add the "vertexAttributeDescriptionCount" member. - rgEditorElement* pVertexAttributeDescriptionCountItem = MakeNumericElement(nullptr, STR_VULKAN_PIPELINE_MEMBER_VERTEX_ATTRIBUTE_DESCRIPTION_COUNT, - &pVertexInputStateCreateInfo->vertexAttributeDescriptionCount, [=] { HandleVertexAttributeDescriptionCountChanged(pVertexAttributeDescriptionsItem, pVertexInputStateCreateInfo); }); - - // Set object name. - pVertexAttributeDescriptionCountItem->setObjectName(STR_VERTEX_ATTRIBUTE_DESCRIPTION_COUNT_ITEM); - - // Provide the element used to track the dimension of the pVertexAttributeDescriptions array. - pVertexAttributeDescriptionsItem->SetArraySizeElement(static_cast*>(pVertexAttributeDescriptionCountItem)); - - // Initialize the pVertexAttributeDescriptions array rows. - HandleVertexAttributeDescriptionCountChanged(pVertexAttributeDescriptionsItem, pVertexInputStateCreateInfo, true); - - // Add the "pVertexAttributeDescriptions" member. - pVertexInputStateRoot->AppendChildItem(pVertexAttributeDescriptionsItem); - } -} - -void rgPipelineStateModelVulkan::HandleVertexBindingDescriptionCountChanged(rgEditorElement* pRootElement, VkPipelineVertexInputStateCreateInfo* pInputStateCreateInfo, bool firstInit) -{ - ResizeHandler(pRootElement, - pInputStateCreateInfo->vertexBindingDescriptionCount, - pInputStateCreateInfo->pVertexBindingDescriptions, - STR_VULKAN_VERTEX_INPUT_BINDING_DESCRIPTION, - std::bind(&rgPipelineStateModelVulkan::InitializeVertexInputBindingDescriptionCreateInfo, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - firstInit); -} - -void rgPipelineStateModelVulkan::HandleVertexAttributeDescriptionCountChanged(rgEditorElement* pRootElement, VkPipelineVertexInputStateCreateInfo* pInputStateCreateInfo, bool firstInit) -{ - ResizeHandler(pRootElement, - pInputStateCreateInfo->vertexAttributeDescriptionCount, - pInputStateCreateInfo->pVertexAttributeDescriptions, - STR_VULKAN_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION, - std::bind(&rgPipelineStateModelVulkan::InitializeVertexInputAttributeDescriptionCreateInfo, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - firstInit); -} - -void rgPipelineStateModelVulkan::InitializeVertexInputBindingDescriptionCreateInfo(rgEditorElement* pRootElement, VkVertexInputBindingDescription* pBaseInputBindingDescriptionItem, int itemIndex) -{ - assert(pRootElement != nullptr); - assert(pBaseInputBindingDescriptionItem != nullptr); - if (pRootElement != nullptr && pBaseInputBindingDescriptionItem != nullptr) - { - VkVertexInputBindingDescription* pOffsetInputBindingDescriptionItem = pBaseInputBindingDescriptionItem + itemIndex; - assert(pOffsetInputBindingDescriptionItem != nullptr); - if (pOffsetInputBindingDescriptionItem != nullptr) - { - // Add the "binding" member. - rgEditorElement* pBindingElement = MakeNumericElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_VERTEX_BINDING, &pOffsetInputBindingDescriptionItem->binding); - pRootElement->AppendChildItem(pBindingElement); - - // Set object name. - pBindingElement->setObjectName(STR_BINDING_ELEMENT); - - // Add the "stride" member. - rgEditorElement* pStrideElement = MakeNumericElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_VERTEX_STRIDE, &pOffsetInputBindingDescriptionItem->stride); - pRootElement->AppendChildItem(pStrideElement); - - // Set object name. - pStrideElement->setObjectName(STR_STRIDE_ELEMENT); - - // Add the "inputRate" member values. - const rgEnumValuesVector inputRateValues = { - ENUM_VALUE(VK_VERTEX_INPUT_RATE_VERTEX), - ENUM_VALUE(VK_VERTEX_INPUT_RATE_INSTANCE) - }; - rgEditorElement* pInputRateElement = new rgEditorElementEnum(m_pParent, STR_VULKAN_PIPELINE_MEMBER_VERTEX_INPUT_RATE, inputRateValues, reinterpret_cast(&pOffsetInputBindingDescriptionItem->inputRate)); - pRootElement->AppendChildItem(pInputRateElement); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pInputRateElement), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pInputRateElement->setObjectName(STR_INPUT_RATE_ELEMENT); - - // Connect to the enum list widget status signal. - isConnected = connect(pInputRateElement, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pInputRateElement), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - } - } -} - -void rgPipelineStateModelVulkan::InitializeVertexInputAttributeDescriptionCreateInfo(rgEditorElement* pRootElement, VkVertexInputAttributeDescription* pBaseInputAttributeDescription, int itemIndex) -{ - assert(pRootElement != nullptr); - assert(pBaseInputAttributeDescription != nullptr); - if (pRootElement != nullptr && pBaseInputAttributeDescription != nullptr) - { - VkVertexInputAttributeDescription* pOffsetInputAttributeDescription = pBaseInputAttributeDescription + itemIndex; - assert(pOffsetInputAttributeDescription != nullptr); - if (pOffsetInputAttributeDescription != nullptr) - { - // Add the "location" member. - rgEditorElement* pLocationElement = MakeNumericElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_VERTEX_LOCATION, &pOffsetInputAttributeDescription->location); - pRootElement->AppendChildItem(pLocationElement); - - // Set object name. - pLocationElement->setObjectName(STR_LOCATION_ELEMENT); - - // Add the "binding" member. - rgEditorElement* pBindingElement = MakeNumericElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_VERTEX_BINDING, &pOffsetInputAttributeDescription->binding); - pRootElement->AppendChildItem(pBindingElement); - - // Set object name. - pBindingElement->setObjectName(STR_BINDING_ELEMENT); - - // Add the "format" member values. - const rgEnumValuesVector& formatEnumerators = GetFormatEnumerators(); - rgEditorElement* pFormatElement = new rgEditorElementEnum(m_pParent, STR_VULKAN_PIPELINE_MEMBER_VERTEX_FORMAT, formatEnumerators, reinterpret_cast(&pOffsetInputAttributeDescription->format)); - pRootElement->AppendChildItem(pFormatElement); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pFormatElement), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pFormatElement->setObjectName(STR_FORMAT_ELEMENT); - - // Connect to the enum list widget status signal. - isConnected = connect(pFormatElement, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pFormatElement), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "offset" member. - rgEditorElement* pOffsetElement = MakeNumericElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_OFFSET, &pOffsetInputAttributeDescription->offset); - pRootElement->AppendChildItem(pOffsetElement); - - // Set object name. - pOffsetElement->setObjectName(STR_OFFSET_ELEMENT); - } - } -} - -void rgPipelineStateModelVulkan::InitializeInputAssemblyStateCreateInfo(rgEditorElement* pRootElement, VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyStateCreateInfo) -{ - assert(pInputAssemblyStateCreateInfo != nullptr); - if (pInputAssemblyStateCreateInfo != nullptr) - { - rgEditorElement* pInputAssemblyStateRoot = new rgEditorElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_PINPUT_ASSEMBLY_STATE); - pRootElement->AppendChildItem(pInputAssemblyStateRoot); - - // Set object name. - pInputAssemblyStateRoot->setObjectName(STR_INPUT_ASSEMBLY_STATE_ROOT); - - // Add the "flags" member. - rgEditorElement* pFlagsItem = MakeNumericElement(pInputAssemblyStateRoot, STR_VULKAN_PIPELINE_MEMBER_FLAGS, &pInputAssemblyStateCreateInfo->flags); - pInputAssemblyStateRoot->AppendChildItem(pFlagsItem); - - // Set object name. - pFlagsItem->setObjectName(STR_FLAGS_ITEM); - - // Add the primitive "topology" node. - const rgEnumValuesVector& primitiveTopologyEnumerators = GetPrimitiveTopologyEnumerators(); - rgEditorElement* pTopologyItem = new rgEditorElementEnum(m_pParent, STR_VULKAN_PIPELINE_MEMBER_TOPOLOGY, primitiveTopologyEnumerators, reinterpret_cast(&pInputAssemblyStateCreateInfo->topology)); - pInputAssemblyStateRoot->AppendChildItem(pTopologyItem); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pTopologyItem), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pTopologyItem->setObjectName(STR_TOPOLOGY_ITEM); - - // Connect to the enum list widget status signal. - isConnected = connect(pTopologyItem, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pTopologyItem), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "primitiveRestartEnable" member. - rgEditorElementBool* pPrimitiveRestartEnableItem = new rgEditorElementBool(pInputAssemblyStateRoot, STR_VULKAN_PIPELINE_MEMBER_PRIMITIVE_RESTART_ENABLE, &pInputAssemblyStateCreateInfo->primitiveRestartEnable); - pInputAssemblyStateRoot->AppendChildItem(pPrimitiveRestartEnableItem); - - // Set object name. - pPrimitiveRestartEnableItem->setObjectName(STR_PRIMITIVE_RESTART_ENABLE_ITEM); - } -} - -void rgPipelineStateModelVulkan::InitializeTessellationStateCreateInfo(rgEditorElement* pRootElement, VkPipelineTessellationStateCreateInfo* pTessellationStateCreateInfo) -{ - assert(pTessellationStateCreateInfo != nullptr); - if (pTessellationStateCreateInfo != nullptr) - { - rgEditorElement* pTessellationStateRoot = new rgEditorElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_PTESSELLATION_STATE); - pRootElement->AppendChildItem(pTessellationStateRoot); - - // Set object name. - pTessellationStateRoot->setObjectName(STR_TESSELLATION_STATE_ROOT); - - // Add the "flags" member. - rgEditorElement* pFlagsItem = MakeNumericElement(pTessellationStateRoot, STR_VULKAN_PIPELINE_MEMBER_FLAGS, &pTessellationStateCreateInfo->flags); - pTessellationStateRoot->AppendChildItem(pFlagsItem); - - // Set object name. - pFlagsItem->setObjectName(STR_FLAGS_ITEM); - - // Add the "patchControlPoints" member. - rgEditorElement* pPatchControlPointsItem = MakeNumericElement(pTessellationStateRoot, STR_VULKAN_PIPELINE_MEMBER_PATCH_CONTROL_POINTS, &pTessellationStateCreateInfo->patchControlPoints); - pTessellationStateRoot->AppendChildItem(pPatchControlPointsItem); - - // Set object name. - pPatchControlPointsItem->setObjectName(STR_PATCH_CONTROL_POINTS_ITEM); - } -} - -void rgPipelineStateModelVulkan::InitializeViewportStateCreateInfo(rgEditorElement* pRootElement, VkPipelineViewportStateCreateInfo* pPipelineViewportStateCreateInfo) -{ - assert(pPipelineViewportStateCreateInfo != nullptr); - if (pPipelineViewportStateCreateInfo != nullptr) - { - rgEditorElement* pViewportStateRoot = new rgEditorElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_PVIEWPORT_STATE); - pRootElement->AppendChildItem(pViewportStateRoot); - - // Set object name. - pViewportStateRoot->setObjectName(STR_VIEWPORT_STATE_ROOT_ITEM); - - // Add the "flags" member. - rgEditorElement* pFlagsItem = MakeNumericElement(pViewportStateRoot, STR_VULKAN_PIPELINE_MEMBER_FLAGS, &pPipelineViewportStateCreateInfo->flags); - pViewportStateRoot->AppendChildItem(pFlagsItem); - - // Set object name. - pFlagsItem->setObjectName(STR_FLAGS_ITEM); - - // Create the "pViewports" root node. - rgEditorElementArrayElementAdd* pViewportsRootItem = new rgEditorElementArrayElementAdd(pViewportStateRoot, STR_VULKAN_PIPELINE_MEMBER_PVIEWPORTS, - [=](int elementIndex) { RemoveElement(pPipelineViewportStateCreateInfo->pViewports, pPipelineViewportStateCreateInfo->viewportCount, elementIndex); }); - - // Set object name. - pViewportsRootItem->setObjectName(STR_VIEWPORTS_ROOT_ITEM); - - assert(pViewportsRootItem != nullptr); - if (pViewportsRootItem != nullptr) - { - // Create the "viewportCountItem" node. - rgEditorElement* pViewportCountItem = MakeNumericElement(nullptr, STR_VULKAN_PIPELINE_MEMBER_VIEWPORT_COUNT, - &pPipelineViewportStateCreateInfo->viewportCount, [=] { HandlePipelineViewportCountChanged(pViewportsRootItem, pPipelineViewportStateCreateInfo); }); - - // Set object name. - pViewportCountItem->setObjectName(STR_VIEWPORT_COUNT_ITEM); - - // Add the viewport array node. - pViewportStateRoot->AppendChildItem(pViewportsRootItem); - - // Provide the element used to track the dimension of the pViewports array. - pViewportsRootItem->SetArraySizeElement(static_cast*>(pViewportCountItem)); - - // Initialize the pViewports array rows. - HandlePipelineViewportCountChanged(pViewportsRootItem, pPipelineViewportStateCreateInfo, true); - } - - // Create the "pScissors" root node. - rgEditorElementArrayElementAdd* pScissorsRootItem = new rgEditorElementArrayElementAdd(pViewportStateRoot, STR_VULKAN_PIPELINE_MEMBER_PSCISSORS, - [=](int elementIndex) { RemoveElement(pPipelineViewportStateCreateInfo->pScissors, pPipelineViewportStateCreateInfo->scissorCount, elementIndex); }); - - // Set object name. - pScissorsRootItem->setObjectName(STR_SCISSORS_ROOT_ITEM); - - // Create the "scissorCountItem" member. - rgEditorElement* pScissorCountItem = MakeNumericElement(nullptr, STR_VULKAN_PIPELINE_MEMBER_SCISSOR_COUNT, - &pPipelineViewportStateCreateInfo->scissorCount, [=] { HandlePipelineScissorCountChanged(pScissorsRootItem, pPipelineViewportStateCreateInfo); }); - - // Set object name. - pScissorCountItem->setObjectName(STR_SCISSOR_COUNT_ITEM); - - // Add the "pScissors" member. - pViewportStateRoot->AppendChildItem(pScissorsRootItem); - - // Provide the element used to track the dimension of the pScissors array. - pScissorsRootItem->SetArraySizeElement(static_cast*>(pScissorCountItem)); - - // Initialize the pScissors array rows. - HandlePipelineScissorCountChanged(pScissorsRootItem, pPipelineViewportStateCreateInfo, true); - } -} - -void rgPipelineStateModelVulkan::HandlePipelineViewportCountChanged(rgEditorElement* pRootElement, VkPipelineViewportStateCreateInfo* pViewportStateCreateInfo, bool firstInit) -{ - ResizeHandler(pRootElement, - pViewportStateCreateInfo->viewportCount, - pViewportStateCreateInfo->pViewports, - STR_VULKAN_PIPELINE_MEMBER_VK_VIEWPORT, - std::bind(&rgPipelineStateModelVulkan::InitializePipelineViewportDescriptionCreateInfo, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - firstInit); -} - -void rgPipelineStateModelVulkan::HandlePipelineScissorCountChanged(rgEditorElement* pRootElement, VkPipelineViewportStateCreateInfo* pViewportStateCreateInfo, bool firstInit) -{ - ResizeHandler(pRootElement, - pViewportStateCreateInfo->scissorCount, - pViewportStateCreateInfo->pScissors, - STR_VULKAN_PIPELINE_MEMBER_SCISSOR_RECT, - std::bind(&rgPipelineStateModelVulkan::InitializePipelineScissorDescriptionCreateInfo, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - firstInit); -} - -void rgPipelineStateModelVulkan::InitializePipelineViewportDescriptionCreateInfo(rgEditorElement* pRootElement, VkViewport* pBaseViewportDescription, int itemIndex) -{ - assert(pRootElement != nullptr); - assert(pBaseViewportDescription != nullptr); - if (pRootElement != nullptr && pBaseViewportDescription != nullptr) - { - VkViewport* pOffsetViewportDescription = pBaseViewportDescription + itemIndex; - assert(pOffsetViewportDescription != nullptr); - if (pOffsetViewportDescription != nullptr) - { - // Add the "x" node. - rgEditorElement* pXItem = MakeNumericElement(pRootElement, STR_VULKAN_MEMBER_X, &pOffsetViewportDescription->x); - pRootElement->AppendChildItem(pXItem); - - // Set object name. - pXItem->setObjectName(STR_X_ITEM); - - // Add the "y" node. - rgEditorElement* pYItem = MakeNumericElement(pRootElement, STR_VULKAN_MEMBER_Y, &pOffsetViewportDescription->y); - pRootElement->AppendChildItem(pYItem); - - // Set object name. - pYItem->setObjectName(STR_Y_ITEM); - - // Add the "width" node. - rgEditorElement* pWidthItem = MakeNumericElement(pRootElement, STR_VULKAN_MEMBER_WIDTH, &pOffsetViewportDescription->width); - pRootElement->AppendChildItem(pWidthItem); - - // Set object name. - pWidthItem->setObjectName(STR_WIDTH_ITEM); - - // Add the "height" node. - rgEditorElement* pHeightItem = MakeNumericElement(pRootElement, STR_VULKAN_MEMBER_HEIGHT, &pOffsetViewportDescription->height); - pRootElement->AppendChildItem(pHeightItem); - - // Set object name. - pHeightItem->setObjectName(STR_HEIGHT_ITEM); - - // Add the "minDepth" node. - rgEditorElement* pMinDepthItem = MakeNumericElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_VIEWPORT_MIN_DEPTH, &pOffsetViewportDescription->minDepth); - pRootElement->AppendChildItem(pMinDepthItem); - - // Set object name. - pMinDepthItem->setObjectName(STR_MIN_DEPTH_ITEM); - - // Add the "maxDepth" node. - rgEditorElement* pMaxDepthItem = MakeNumericElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_VIEWPORT_MAX_DEPTH, &pOffsetViewportDescription->maxDepth); - pRootElement->AppendChildItem(pMaxDepthItem); - - // Set object name. - pMaxDepthItem->setObjectName(STR_MAX_DEPTH_ITEM); - } - } -} - -void rgPipelineStateModelVulkan::InitializePipelineScissorDescriptionCreateInfo(rgEditorElement* pRootElement, VkRect2D* pBaseScissorDescription, int itemIndex) -{ - assert(pRootElement != nullptr); - assert(pBaseScissorDescription != nullptr); - if (pRootElement != nullptr && pBaseScissorDescription != nullptr) - { - VkRect2D* pOffsetScissorDescription = pBaseScissorDescription + itemIndex; - assert(pOffsetScissorDescription != nullptr); - if (pOffsetScissorDescription != nullptr) - { - // Get the stencil operation enumerators. - rgEditorElement* pOffsetRoot = new rgEditorElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_OFFSET); - - // Add the "x" node. - rgEditorElement* pXItem = MakeNumericElement(pOffsetRoot, STR_VULKAN_MEMBER_X, &pOffsetScissorDescription->offset.x); - pOffsetRoot->AppendChildItem(pXItem); - - // Set object name. - pXItem->setObjectName(STR_X_ITEM); - - // Add the "y" node. - rgEditorElement* pYItem = MakeNumericElement(pOffsetRoot, STR_VULKAN_MEMBER_Y, &pOffsetScissorDescription->offset.y); - pOffsetRoot->AppendChildItem(pYItem); - - // Set object name. - pYItem->setObjectName(STR_Y_ITEM); - - // Add the offset root element. - pRootElement->AppendChildItem(pOffsetRoot); - - rgEditorElement* pExtentRoot = new rgEditorElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_EXTENT); - - // Set object name. - pExtentRoot->setObjectName(STR_EXTENT_ROOT); - - // Add the "width" node. - rgEditorElement* pWidthItem = MakeNumericElement(pExtentRoot, STR_VULKAN_MEMBER_WIDTH, &pOffsetScissorDescription->extent.width); - pExtentRoot->AppendChildItem(pWidthItem); - - // Set object name. - pWidthItem->setObjectName(STR_WIDTH_ITEM); - - // Add the "height" node. - rgEditorElement* pHeightItem = MakeNumericElement(pExtentRoot, STR_VULKAN_MEMBER_HEIGHT, &pOffsetScissorDescription->extent.height); - pExtentRoot->AppendChildItem(pHeightItem); - - // Set object name. - pHeightItem->setObjectName(STR_HEIGHT_ITEM); - - // Add the extent root element. - pRootElement->AppendChildItem(pExtentRoot); - } - } -} - -void rgPipelineStateModelVulkan::InitializeRasterizationStateCreateInfo(rgEditorElement* pRootElement, VkPipelineRasterizationStateCreateInfo* pRasterizationStateCreateInfo) -{ - assert(pRasterizationStateCreateInfo != nullptr); - if (pRasterizationStateCreateInfo != nullptr) - { - rgEditorElement* pRasterizationStateRoot = new rgEditorElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_PRASTERIZATION_STATE); - pRootElement->AppendChildItem(pRasterizationStateRoot); - - // Set object name. - pRasterizationStateRoot->setObjectName(STR_RASTERIZATION_STATE_ROOT); - - // Add the "flags" member. - rgEditorElement* pFlagsItem = MakeNumericElement(pRasterizationStateRoot, STR_VULKAN_PIPELINE_MEMBER_FLAGS, &pRasterizationStateCreateInfo->flags); - pRasterizationStateRoot->AppendChildItem(pFlagsItem); - - // Set object name. - pFlagsItem->setObjectName(STR_FLAGS_ITEM); - - // Add the "depthClampEnable" node. - rgEditorElementBool* pDepthClampEnableItem = new rgEditorElementBool(pRasterizationStateRoot, STR_VULKAN_PIPELINE_MEMBER_DEPTH_CLAMP_ENABLE, &pRasterizationStateCreateInfo->depthClampEnable); - pRasterizationStateRoot->AppendChildItem(pDepthClampEnableItem); - - // Set object name. - pDepthClampEnableItem->setObjectName(STR_DEPTH_CLAMP_ENABLE_ITEM); - - // Add the "rasterizerDiscardEnable" node. - rgEditorElementBool* pRasterizerDiscardEnable = new rgEditorElementBool(pRasterizationStateRoot, STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_DISCARD_ENABLE, &pRasterizationStateCreateInfo->rasterizerDiscardEnable); - pRasterizationStateRoot->AppendChildItem(pRasterizerDiscardEnable); - - // Set object name. - pRasterizerDiscardEnable->setObjectName(STR_RASTERIZER_DISCARD_ENABLE); - - // Add the "polygonMode" member values. - const rgEnumValuesVector& polygonModeEnumerators = GetPolygonModeEnumerators(); - rgEditorElement* pPolygonModeNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_POLYGON_MODE, polygonModeEnumerators, reinterpret_cast(&pRasterizationStateCreateInfo->polygonMode)); - pRasterizationStateRoot->AppendChildItem(pPolygonModeNode); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pPolygonModeNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pPolygonModeNode->setObjectName(STR_POLYGON_MODE_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pPolygonModeNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pPolygonModeNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "cullMode" member values. - const rgEnumValuesVector& cullModeEnumerators = GetCullModeFlagEnumerators(); - rgEditorElement* pCullModeNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_CULL_MODE, cullModeEnumerators, reinterpret_cast(&pRasterizationStateCreateInfo->cullMode), true); - pRasterizationStateRoot->AppendChildItem(pCullModeNode); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pCullModeNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pCullModeNode->setObjectName(STR_CULL_MODE_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pCullModeNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pCullModeNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "frontFace" member values. - const rgEnumValuesVector& frontFaceEnumerators = GetFrontFaceEnumerators(); - rgEditorElement* pFrontFaceNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_FRONT_FACE, frontFaceEnumerators, reinterpret_cast(&pRasterizationStateCreateInfo->frontFace)); - pRasterizationStateRoot->AppendChildItem(pFrontFaceNode); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pFrontFaceNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pFrontFaceNode->setObjectName(STR_FRONT_FACE_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pFrontFaceNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pFrontFaceNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "depthBiasEnable" node. - rgEditorElementBool* pDepthBiasEnableNode = new rgEditorElementBool(pRasterizationStateRoot, STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_DEPTH_BIAS_ENABLE, &pRasterizationStateCreateInfo->depthBiasEnable); - pRasterizationStateRoot->AppendChildItem(pDepthBiasEnableNode); - - // Set object name. - pDepthBiasEnableNode->setObjectName(STR_DEPTH_BIAS_ENABLE_NODE); - - // Add the "depthBiasConstantFactor" node. - rgEditorElement* pDepthBiasConstantFactorNode = MakeNumericElement(pRasterizationStateRoot, STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_DEPTH_BIAS_CONSTANT_FACTOR, &pRasterizationStateCreateInfo->depthBiasConstantFactor); - pRasterizationStateRoot->AppendChildItem(pDepthBiasConstantFactorNode); - - // Set object name. - pDepthBiasConstantFactorNode->setObjectName(STR_DEPTH_BIAS_CONSTANT_FACTOR_NODE); - - // Add the "depthBiasClamp" node. - rgEditorElement* pDepthBiasClampNode = MakeNumericElement(pRasterizationStateRoot, STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_DEPTH_BIAS_CLAMP, &pRasterizationStateCreateInfo->depthBiasClamp); - pRasterizationStateRoot->AppendChildItem(pDepthBiasClampNode); - - // Set object name. - pDepthBiasClampNode->setObjectName(STR_DEPTH_BIAS_CLAMP_NODE); - - // Add the "depthBiasSlopeFactor" node. - rgEditorElement* pDepthBiasSlopeFactorNode = MakeNumericElement(pRasterizationStateRoot, STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_DEPTH_BIAS_SLOPE_FACTOR, &pRasterizationStateCreateInfo->depthBiasSlopeFactor); - pRasterizationStateRoot->AppendChildItem(pDepthBiasSlopeFactorNode); - - // Set object name. - pDepthBiasSlopeFactorNode->setObjectName(STR_DEPTH_BIAS_SLOPE_FACTOR_NODE); - - // Add the "lineWidth" node. - rgEditorElement* pLineWidthNode = MakeNumericElement(pRasterizationStateRoot, STR_VULKAN_PIPELINE_MEMBER_RASTERIZER_LINE_WIDTH, &pRasterizationStateCreateInfo->lineWidth); - pRasterizationStateRoot->AppendChildItem(pLineWidthNode); - - // Set object name. - pLineWidthNode->setObjectName(STR_LINE_WIDTH_NODE); - } -} - -void rgPipelineStateModelVulkan::HandleMultisamplingSampleMaskDimensionChanged(rgEditorElement* pRootElement, VkPipelineMultisampleStateCreateInfo* pMultisampleStateCreateInfo, bool firstInit) -{ - ResizeHandler(pRootElement, - m_sampleMaskDimension, - pMultisampleStateCreateInfo->pSampleMask, - STR_VULKAN_MULTISAMPLE_RASTERIZATION_SAMPLE_FLAGS_TYPE, - std::bind(&rgPipelineStateModelVulkan::InitializeSampleMask, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - firstInit); -} - -void rgPipelineStateModelVulkan::InitializeSampleMask(rgEditorElement* pRootElement, uint32_t* pSampleMaskBase, int itemIndex) -{ - assert(pRootElement != nullptr); - assert(pSampleMaskBase != nullptr); - if (pRootElement != nullptr && pSampleMaskBase != nullptr) - { - uint32_t* pSampleMaskItem = pSampleMaskBase + itemIndex; - assert(pSampleMaskItem != nullptr); - if (pSampleMaskItem != nullptr) - { - // Add the array element. - rgEditorElement* pSampleMaskElementNode = MakeNumericElement(pRootElement, STR_VULKAN_MULTISAMPLE_RASTERIZATION_SAMPLE_FLAGS_ELEMENT_TYPE, reinterpret_cast(pSampleMaskItem)); - pRootElement->AppendChildItem(pSampleMaskElementNode); - - // Set object name. - pSampleMaskElementNode->setObjectName(STR_SAMPLE_MASK_ELEMENT_NODE); - } - } -} - -void rgPipelineStateModelVulkan::InitializeMultisampleStateCreateInfo(rgEditorElement* pRootElement, VkPipelineMultisampleStateCreateInfo* pPipelineMultisampleStateCreateInfo) -{ - // Initialize the sample mask dimension. - m_sampleMaskDimension = 0; - - assert(pPipelineMultisampleStateCreateInfo != nullptr); - if (pPipelineMultisampleStateCreateInfo != nullptr) - { - rgEditorElement* pMultisampleStateRoot = new rgEditorElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_PMULTISAMPLE_STATE); - pRootElement->AppendChildItem(pMultisampleStateRoot); - - // Set object name. - pMultisampleStateRoot->setObjectName(STR_MULTISAMPLE_STATE_ROOT); - - // Add the "flags" node. - rgEditorElement* pFlagsItem = MakeNumericElement(pMultisampleStateRoot, STR_VULKAN_PIPELINE_MEMBER_FLAGS, &pPipelineMultisampleStateCreateInfo->flags); - pMultisampleStateRoot->AppendChildItem(pFlagsItem); - - // Set object name. - pFlagsItem->setObjectName(STR_FLAGS_ITEM); - - // pSampleMask array: - if (pPipelineMultisampleStateCreateInfo->pSampleMask != nullptr) - { - // Initialize the mask dimension if the pSampleMask is used. - uint32_t enumDimension = GetSampleMaskDimension(pPipelineMultisampleStateCreateInfo->rasterizationSamples); - m_sampleMaskDimension = enumDimension; - } - - // Create the pSampleMask array root item. - rgEditorElementArrayElementAdd* pSampleMaskRootItem = new rgEditorElementArrayElementAdd(pMultisampleStateRoot, STR_VULKAN_MULTISAMPLE_P_SAMPLE_MASK, - [=](int elementIndex) { RemoveElement(pPipelineMultisampleStateCreateInfo->pSampleMask, m_sampleMaskDimension, elementIndex); }); - - // Set object name. - pSampleMaskRootItem->setObjectName(STR_SAMPLE_MASK_ROOT_ITEM); - - // The user can only have up to 2 elements within the pSampleMask array. - pSampleMaskRootItem->SetMaximumArraySize(2); - - // Create the pSampleMask dimension node. - rgEditorElement* pSampleMaskCountNode = MakeNumericElement(nullptr, STR_VULKAN_RENDER_PASS_SUBPASS_INPUT_ATTACHMENT_COUNT, - &m_sampleMaskDimension, - [=] { HandleMultisamplingSampleMaskDimensionChanged(pSampleMaskRootItem, pPipelineMultisampleStateCreateInfo); }); - - // Set object name. - pSampleMaskCountNode->setObjectName(STR_SAMPLE_MASK_COUNT_NODE); - - // Set the array size element for the pSampleMask root item. - // When the array size count value changes, the array of child elements will get resized. - pSampleMaskRootItem->SetArraySizeElement(static_cast*>(pSampleMaskCountNode)); - - // Initialize the existing array of pSampleMask data. - HandleMultisamplingSampleMaskDimensionChanged(pSampleMaskRootItem, pPipelineMultisampleStateCreateInfo, true); - - // Add the "rasterizationSamples" flags node. - const rgEnumValuesVector& rasterizationSamplesEnumerators = GetRasterizationSamplesEnumerators(); - rgEditorElement* pRasterizationSamples = new rgEditorElementEnum(m_pParent, STR_VULKAN_MULTISAMPLE_RASTERIZATION_SAMPLES, rasterizationSamplesEnumerators, reinterpret_cast(&pPipelineMultisampleStateCreateInfo->rasterizationSamples)); - pMultisampleStateRoot->AppendChildItem(pRasterizationSamples); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pRasterizationSamples), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pRasterizationSamples->setObjectName(STR_RASTERIZATION_SAMPLES); - - // Connect to the enum list widget status signal. - isConnected = connect(pRasterizationSamples, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pRasterizationSamples), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "sampleShadingEnable" node. - rgEditorElementBool* pSampleShadingEnable = new rgEditorElementBool(pMultisampleStateRoot, STR_VULKAN_MULTISAMPLE_SAMPLE_SHADING_ENABLE, &pPipelineMultisampleStateCreateInfo->sampleShadingEnable); - pMultisampleStateRoot->AppendChildItem(pSampleShadingEnable); - - // Set object name. - pSampleShadingEnable->setObjectName(STR_SAMPLE_SHADING_ENABLE); - - // Add the "minSampleShading" node. - rgEditorElement* pMinSampleShadingNode = MakeNumericElement(pMultisampleStateRoot, STR_VULKAN_MULTISAMPLE_MIN_SAMPLE_SHADING, &pPipelineMultisampleStateCreateInfo->minSampleShading); - pMultisampleStateRoot->AppendChildItem(pMinSampleShadingNode); - - // Set object name. - pMinSampleShadingNode->setObjectName(STR_MIN_SAMPLE_SHADING_NODE); - - // Add the sample mask array node. - pMultisampleStateRoot->AppendChildItem(pSampleMaskRootItem); - - // Add the "alphaToCoverageEnable" node. - rgEditorElementBool* pAlphaToCoverageNode = new rgEditorElementBool(pMultisampleStateRoot, STR_VULKAN_MULTISAMPLE_ALPHA_TO_COVERAGE_ENABLE, &pPipelineMultisampleStateCreateInfo->alphaToCoverageEnable); - pMultisampleStateRoot->AppendChildItem(pAlphaToCoverageNode); - - // Set object name. - pAlphaToCoverageNode->setObjectName(STR_ALPHA_BLEND_TO_COVERAGE_NODE); - - // Add the "alphaToOneEnable" node. - rgEditorElementBool* pAlphaToOneNode = new rgEditorElementBool(pMultisampleStateRoot, STR_VULKAN_MULTISAMPLE_ALPHA_TO_ONE_ENABLE, &pPipelineMultisampleStateCreateInfo->alphaToOneEnable); - pMultisampleStateRoot->AppendChildItem(pAlphaToOneNode); - - // Set object name. - pAlphaToOneNode->setObjectName(STR_ALPHA_TO_ONE_NODE); - } -} - -void rgPipelineStateModelVulkan::InitializeStencilOpState(rgEditorElement* pDepthStencilStateRoot, VkStencilOpState* pStencilOpState) -{ - assert(pDepthStencilStateRoot != nullptr); - assert(pStencilOpState != nullptr); - if (pDepthStencilStateRoot != nullptr && pStencilOpState != nullptr) - { - // Get the stencil operation enumerators. - const rgEnumValuesVector& stencilOpEnumerators = GetStencilOpEnumerators(); - - // Add the "failOp" node. - rgEditorElement* pFailOpNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_DEPTH_STENCIL_STATE_FAIL_OP, stencilOpEnumerators, reinterpret_cast(&pStencilOpState->failOp)); - pDepthStencilStateRoot->AppendChildItem(pFailOpNode); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pFailOpNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pFailOpNode->setObjectName(STR_FAIL_OP_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pFailOpNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pFailOpNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "passOp" node. - rgEditorElement* pPassOpNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_DEPTH_STENCIL_STATE_PASS_OP, stencilOpEnumerators, reinterpret_cast(&pStencilOpState->passOp)); - pDepthStencilStateRoot->AppendChildItem(pPassOpNode); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pPassOpNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pPassOpNode->setObjectName(STR_PASS_OP_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pPassOpNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pPassOpNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "depthFailOp" node. - rgEditorElement* pDepthFailOp = new rgEditorElementEnum(m_pParent, STR_VULKAN_DEPTH_STENCIL_STATE_DEPTH_FAIL_OP, stencilOpEnumerators, reinterpret_cast(&pStencilOpState->depthFailOp)); - pDepthStencilStateRoot->AppendChildItem(pDepthFailOp); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pDepthFailOp), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pDepthFailOp->setObjectName(STR_DEPTH_FAIL_OP); - - // Connect to the enum list widget status signal. - isConnected = connect(pDepthFailOp, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pDepthFailOp), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "compareOp" node. - const rgEnumValuesVector& compareOpEnumerators = GetCompareOpEnumerators(); - rgEditorElement* pCompareOpNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_DEPTH_STENCIL_STATE_COMPARE_OP, compareOpEnumerators, reinterpret_cast(&pStencilOpState->compareOp)); - pDepthStencilStateRoot->AppendChildItem(pCompareOpNode); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pCompareOpNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pCompareOpNode->setObjectName(STR_COMPARE_OP_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pCompareOpNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pCompareOpNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "compareMask" node. - rgEditorElement* pCompareMaskNode = MakeNumericElement(pDepthStencilStateRoot, STR_VULKAN_DEPTH_STENCIL_STATE_COMPARE_MASK, &pStencilOpState->compareMask); - pDepthStencilStateRoot->AppendChildItem(pCompareMaskNode); - - // Set object name. - pCompareMaskNode->setObjectName(STR_COMPARE_MASK_NODE); - - // Add the "writeMask" node. - rgEditorElement* pWriteMaskNode = MakeNumericElement(pDepthStencilStateRoot, STR_VULKAN_DEPTH_STENCIL_STATE_WRITE_MASK, &pStencilOpState->writeMask); - pDepthStencilStateRoot->AppendChildItem(pWriteMaskNode); - - // Set object name. - pWriteMaskNode->setObjectName(STR_WRITE_MASK_NODE); - - // Add the "reference" node. - rgEditorElement* pReferenceNode = MakeNumericElement(pDepthStencilStateRoot, STR_VULKAN_DEPTH_STENCIL_STATE_REFERENCE, &pStencilOpState->reference); - pDepthStencilStateRoot->AppendChildItem(pReferenceNode); - - // Set object name. - pReferenceNode->setObjectName(STR_REFERENCE_NODE); - } -} - -void rgPipelineStateModelVulkan::InitializeDepthStencilStateCreateInfo(rgEditorElement* pRootElement, VkPipelineDepthStencilStateCreateInfo* pPipelineDepthStencilStateCreateInfo) -{ - assert(pPipelineDepthStencilStateCreateInfo != nullptr); - if (pPipelineDepthStencilStateCreateInfo != nullptr) - { - rgEditorElement* pDepthStencilStateRoot = new rgEditorElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_PDEPTH_STENCIL_STATE); - pRootElement->AppendChildItem(pDepthStencilStateRoot); - - // Set object name. - pDepthStencilStateRoot->setObjectName(STR_DEPTH_STENCIL_STATE_ROOT); - - // Add the "flags" node. - rgEditorElement* pFlagsItem = MakeNumericElement(pDepthStencilStateRoot, STR_VULKAN_PIPELINE_MEMBER_FLAGS, &pPipelineDepthStencilStateCreateInfo->flags); - pDepthStencilStateRoot->AppendChildItem(pFlagsItem); - - // Set object name. - pFlagsItem->setObjectName(STR_FLAGS_ITEM); - - // Add the "depthTestEnable" node. - rgEditorElementBool* pDepthTestEnableNode = new rgEditorElementBool(pDepthStencilStateRoot, STR_VULKAN_DEPTH_STENCIL_DEPTH_TEST_ENABLE, &pPipelineDepthStencilStateCreateInfo->depthTestEnable); - pDepthStencilStateRoot->AppendChildItem(pDepthTestEnableNode); - - // Set object name. - pDepthTestEnableNode->setObjectName(STR_DEPTH_TEST_ENABLE_NODE); - - // Add the "depthWriteEnable" node. - rgEditorElementBool* pDepthWriteEnableNode = new rgEditorElementBool(pDepthStencilStateRoot, STR_VULKAN_DEPTH_STENCIL_DEPTH_WRITE_ENABLE, &pPipelineDepthStencilStateCreateInfo->depthWriteEnable); - pDepthStencilStateRoot->AppendChildItem(pDepthWriteEnableNode); - - // Set object name. - pDepthWriteEnableNode->setObjectName(STR_DEPTH_WRITE_ENABLE_NODE); - - // Add the "depthCompareOp" node. - const rgEnumValuesVector& compareOpEnumerators = GetCompareOpEnumerators(); - rgEditorElement* pDepthCompareOpNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_DEPTH_STENCIL_DEPTH_COMPARE_OP, compareOpEnumerators, reinterpret_cast(&pPipelineDepthStencilStateCreateInfo->depthCompareOp), m_pParent); - pDepthStencilStateRoot->AppendChildItem(pDepthCompareOpNode); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pDepthCompareOpNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pDepthCompareOpNode->setObjectName(STR_DEPTH_COMPARE_OP_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pDepthCompareOpNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pDepthCompareOpNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "depthBoundsTestEnable" node. - rgEditorElementBool* pDepthBoundsTestEnableNode = new rgEditorElementBool(pDepthStencilStateRoot, STR_VULKAN_DEPTH_STENCIL_DEPTH_BOUNDS_TEST_ENABLE, &pPipelineDepthStencilStateCreateInfo->depthBoundsTestEnable); - pDepthStencilStateRoot->AppendChildItem(pDepthBoundsTestEnableNode); - - // Set object name. - pDepthBoundsTestEnableNode->setObjectName(STR_DEPTH_BOUNDS_TEST_ENABLE_NODE); - - // Add the "stencilTestEnable" node. - rgEditorElementBool* pStencilTestEnableNode = new rgEditorElementBool(pDepthStencilStateRoot, STR_VULKAN_DEPTH_STENCIL_STENCIL_TEST_ENABLE, &pPipelineDepthStencilStateCreateInfo->stencilTestEnable); - pDepthStencilStateRoot->AppendChildItem(pStencilTestEnableNode); - - // Set object name. - pStencilTestEnableNode->setObjectName(STR_STENCIL_TEST_ENABLE_NODE); - - // Create the root node for the front stencil op state. - rgEditorElement* pFrontStencilOpStateNode = new rgEditorElement(pDepthStencilStateRoot, STR_VULKAN_DEPTH_STENCIL_FRONT); - InitializeStencilOpState(pFrontStencilOpStateNode, &pPipelineDepthStencilStateCreateInfo->front); - pDepthStencilStateRoot->AppendChildItem(pFrontStencilOpStateNode); - - // Set object name. - pFrontStencilOpStateNode->setObjectName(STR_FRONT_STENCIL_OP_STATE_NODE); - - // Create the root node for the back stencil op state. - rgEditorElement* pBackStencilOpStateNode = new rgEditorElement(pDepthStencilStateRoot, STR_VULKAN_DEPTH_STENCIL_BACK); - InitializeStencilOpState(pBackStencilOpStateNode, &pPipelineDepthStencilStateCreateInfo->back); - pDepthStencilStateRoot->AppendChildItem(pBackStencilOpStateNode); - - // Set object name. - pBackStencilOpStateNode->setObjectName(STR_BACK_STENCIL_OP_STATE_NODE); - - // Add the "minDepthBounds" node. - rgEditorElement* pMinDepthBoundsNode = MakeNumericElement(pDepthStencilStateRoot, STR_VULKAN_DEPTH_STENCIL_MIN_DEPTH_BOUNDS, &pPipelineDepthStencilStateCreateInfo->minDepthBounds); - pDepthStencilStateRoot->AppendChildItem(pMinDepthBoundsNode); - - // Set object name. - pMinDepthBoundsNode->setObjectName(STR_MIN_DEPTH_BOUNDS_NODE); - - // Add the "maxDepthBounds" node. - rgEditorElement* pMaxDepthBoundsNode = MakeNumericElement(pDepthStencilStateRoot, STR_VULKAN_DEPTH_STENCIL_MAX_DEPTH_BOUNDS, &pPipelineDepthStencilStateCreateInfo->maxDepthBounds); - pDepthStencilStateRoot->AppendChildItem(pMaxDepthBoundsNode); - - // Set object name. - pMaxDepthBoundsNode->setObjectName(STR_MAX_DEPTH_BOUNDS_NODE); - } -} - -void rgPipelineStateModelVulkan::InitializeColorBlendStateCreateInfo(rgEditorElement* pRootElement, VkPipelineColorBlendStateCreateInfo* pPipelineColorBlendStateCreateInfo) -{ - assert(pPipelineColorBlendStateCreateInfo != nullptr); - if (pPipelineColorBlendStateCreateInfo != nullptr) - { - rgEditorElement* pColorBlendStateRoot = new rgEditorElement(pRootElement, STR_VULKAN_PIPELINE_MEMBER_PCOLOR_BLEND_STATE); - pRootElement->AppendChildItem(pColorBlendStateRoot); - - // Set object name. - pColorBlendStateRoot->setObjectName(STR_COLOR_BLEND_STATE_ROOT); - - // Add the "flags" node. - rgEditorElement* pFlagsItem = MakeNumericElement(pColorBlendStateRoot, STR_VULKAN_PIPELINE_MEMBER_FLAGS, &pPipelineColorBlendStateCreateInfo->flags); - pColorBlendStateRoot->AppendChildItem(pFlagsItem); - - // Set object name. - pFlagsItem->setObjectName(STR_FLAGS_ITEM); - - // Add the "logicOpEnable" node. - rgEditorElementBool* pLogicOpEnableNode = new rgEditorElementBool(pColorBlendStateRoot, STR_VULKAN_COLOR_BLEND_STATE_LOGIC_OP_ENABLE, &pPipelineColorBlendStateCreateInfo->logicOpEnable); - pColorBlendStateRoot->AppendChildItem(pLogicOpEnableNode); - - // Set object name. - pLogicOpEnableNode->setObjectName(STR_LOGIC_OP_ENABLE_NODE); - - // Add the "logicOp" node. - const rgEnumValuesVector& logicOpEnumerators = GetLogicOpEnumerators(); - rgEditorElement* pLogicOpNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_COLOR_BLEND_STATE_LOGIC_OP, logicOpEnumerators, reinterpret_cast(&pPipelineColorBlendStateCreateInfo->logicOp)); - pColorBlendStateRoot->AppendChildItem(pLogicOpNode); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pLogicOpNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pLogicOpNode->setObjectName(STR_LOGIC_OP_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pLogicOpNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pLogicOpNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Attachment array: - // Create the attachments array root item. - rgEditorElementArrayElementAdd* pAttachmentsRootItem = new rgEditorElementArrayElementAdd(pColorBlendStateRoot, STR_VULKAN_COLOR_BLEND_STATE_P_ATTACHMENTS, - [=](int elementIndex) { RemoveElement(pPipelineColorBlendStateCreateInfo->pAttachments, pPipelineColorBlendStateCreateInfo->attachmentCount, elementIndex); }); - - // Set object name. - pAttachmentsRootItem->setObjectName(STR_ATTACHMENTS_ROOT_ITEM); - - // Create the attachmentCount member. - rgEditorElement* pColorBlendAttachmentStateCountItem = MakeNumericElement(nullptr, STR_VULKAN_COLOR_BLEND_STATE_ATTACHMENT_COUNT, - &pPipelineColorBlendStateCreateInfo->attachmentCount, [=] { HandlePipelineColorBlendAttachmentCountChanged(pAttachmentsRootItem, pPipelineColorBlendStateCreateInfo); }); - - // Set object name. - pColorBlendAttachmentStateCountItem->setObjectName(STR_COLOR_BLEND_ATTACHEMENT_STATE_COUNT_ITEM); - - // Add the attachment array node. - pColorBlendStateRoot->AppendChildItem(pAttachmentsRootItem); - - // Provide the element used to track the dimension of the pAttachments array. - pAttachmentsRootItem->SetArraySizeElement(static_cast*>(pColorBlendAttachmentStateCountItem)); - - // Initialize the pAttachments array rows. - HandlePipelineColorBlendAttachmentCountChanged(pAttachmentsRootItem, pPipelineColorBlendStateCreateInfo, true); - - // Add the blend constants array root node. - rgEditorElement* pBlendConstantsRootNode = new rgEditorElement(pColorBlendStateRoot, STR_VULKAN_COLOR_BLEND_STATE_BLEND_CONSTANTS); - - // Set object name. - pBlendConstantsRootNode->setObjectName(STR_BLEND_CONSTANTS_ROOT_NODE); - - // Add the blendConstants array item nodes. - for (uint32_t blendConstantIndex = 0; blendConstantIndex < 4; ++blendConstantIndex) - { - std::stringstream elementNameStream; - elementNameStream << STR_VULKAN_COLOR_BLEND_STATE_BLEND_CONSTANTS; - elementNameStream << "["; - elementNameStream << blendConstantIndex; - elementNameStream << "]"; - - rgEditorElement* pBlendConstantNode = MakeNumericElement(pBlendConstantsRootNode, elementNameStream.str().c_str(), &pPipelineColorBlendStateCreateInfo->blendConstants[blendConstantIndex]); - pBlendConstantsRootNode->AppendChildItem(pBlendConstantNode); - - // Set object name. - QString name = STR_BLEND_CONSTANT_NODE + QString::number(blendConstantIndex); - pBlendConstantNode->setObjectName(name); - } - - pColorBlendStateRoot->AppendChildItem(pBlendConstantsRootNode); - } -} - -void rgPipelineStateModelVulkan::HandlePipelineColorBlendAttachmentCountChanged(rgEditorElement* pRootElement, VkPipelineColorBlendStateCreateInfo* pPipelineColorBlendStateCreateInfo, bool firstInit) -{ - ResizeHandler(pRootElement, - pPipelineColorBlendStateCreateInfo->attachmentCount, - pPipelineColorBlendStateCreateInfo->pAttachments, - STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE, - std::bind(&rgPipelineStateModelVulkan::InitializePipelineBlendAttachmentStateCreateInfo, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - firstInit); -} - -void rgPipelineStateModelVulkan::InitializePipelineBlendAttachmentStateCreateInfo(rgEditorElement* pRootElement, VkPipelineColorBlendAttachmentState* pBaseColorBlendAttachmentState, int itemIndex) -{ - assert(pRootElement != nullptr); - assert(pBaseColorBlendAttachmentState != nullptr); - if (pRootElement != nullptr && pBaseColorBlendAttachmentState != nullptr) - { - VkPipelineColorBlendAttachmentState* pOffsetColorBlendAttachmentState = pBaseColorBlendAttachmentState + itemIndex; - assert(pOffsetColorBlendAttachmentState != nullptr); - if (pOffsetColorBlendAttachmentState != nullptr) - { - // Add the "blendEnable" node. - rgEditorElementBool* pBlendEnableNode = new rgEditorElementBool(pRootElement, STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE_BLEND_ENABLE, &pOffsetColorBlendAttachmentState->blendEnable); - pRootElement->AppendChildItem(pBlendEnableNode); - - // Set object name. - pBlendEnableNode->setObjectName(STR_BLEND_ENABLE_NODE); - - // Get the blend factor enumerators. - const rgEnumValuesVector& blendFactorEnumerators = GetBlendFactorEnumerators(); - - // Get the blend op enumerators. - const rgEnumValuesVector& blendOpEnumerators = GetBlendOpEnumerators(); - - // Add the "srcColorBlendFactor" node. - rgEditorElement* pSrcColorBlendFactorNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE_SRC_COLOR_BLEND_FACTOR, blendFactorEnumerators, reinterpret_cast(&pOffsetColorBlendAttachmentState->srcColorBlendFactor)); - pRootElement->AppendChildItem(pSrcColorBlendFactorNode); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pSrcColorBlendFactorNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pSrcColorBlendFactorNode->setObjectName(STR_SRC_COLOR_BLEND_FACTOR_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pSrcColorBlendFactorNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pSrcColorBlendFactorNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "dstColorBlendFactor" node. - rgEditorElement* pDstColorBlendFactorNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE_DST_COLOR_BLEND_FACTOR, blendFactorEnumerators, reinterpret_cast(&pOffsetColorBlendAttachmentState->dstColorBlendFactor)); - pRootElement->AppendChildItem(pDstColorBlendFactorNode); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pDstColorBlendFactorNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pDstColorBlendFactorNode->setObjectName(STR_DST_COLOR_BLEND_FACTOR_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pDstColorBlendFactorNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pDstColorBlendFactorNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "colorBlendOp" node. - rgEditorElement* pColorBlendOpNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE_COLOR_BLEND_OP, blendOpEnumerators, reinterpret_cast(&pOffsetColorBlendAttachmentState->colorBlendOp)); - pRootElement->AppendChildItem(pColorBlendOpNode); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pColorBlendOpNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pColorBlendOpNode->setObjectName(STR_COLOR_BLEND_OP_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pColorBlendOpNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pColorBlendOpNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "srcAlphaBlendFactor" node. - rgEditorElement* pSrcAlphaBlendFactorNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE_SRC_ALPHA_BLEND_FACTOR, blendFactorEnumerators, reinterpret_cast(&pOffsetColorBlendAttachmentState->srcAlphaBlendFactor)); - pRootElement->AppendChildItem(pSrcAlphaBlendFactorNode); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pSrcAlphaBlendFactorNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pSrcAlphaBlendFactorNode->setObjectName(STR_SRC_ALPHA_BLEND_FACTOR_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pSrcAlphaBlendFactorNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pSrcAlphaBlendFactorNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "dstAlphaBlendFactor" node. - rgEditorElement* pDstAlphaBlendFactorNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE_DST_ALPHA_BLEND_FACTOR, blendFactorEnumerators, reinterpret_cast(&pOffsetColorBlendAttachmentState->dstAlphaBlendFactor)); - pRootElement->AppendChildItem(pDstAlphaBlendFactorNode); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pDstAlphaBlendFactorNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pDstAlphaBlendFactorNode->setObjectName(STR_DST_ALPHA_BLEND_FACTOR_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pDstAlphaBlendFactorNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pDstAlphaBlendFactorNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "alphaBlendOp" node. - rgEditorElement* pAlphaBlendOpNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE_ALPHA_BLEND_OP, blendOpEnumerators, reinterpret_cast(&pOffsetColorBlendAttachmentState->alphaBlendOp)); - pRootElement->AppendChildItem(pAlphaBlendOpNode); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pAlphaBlendOpNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pAlphaBlendOpNode->setObjectName(STR_ALPHA_BLEND_OP_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pAlphaBlendOpNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pAlphaBlendOpNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "colorWriteMask" member values. - const rgEnumValuesVector& colorComponentFlagEnumerators = GetColorComponentFlagEnumerators(); - rgEditorElement* pColorComponentWriteMask = new rgEditorElementEnum(m_pParent, STR_VULKAN_COLOR_BLEND_ATTACHMENT_STATE_COLOR_WRITE_MASK, colorComponentFlagEnumerators, reinterpret_cast(&pOffsetColorBlendAttachmentState->colorWriteMask), true); - pRootElement->AppendChildItem(pColorComponentWriteMask); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pColorComponentWriteMask), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pColorComponentWriteMask->setObjectName(STR_COLOR_COMPONENT_WRITE_MASK); - - // Connect to the enum list widget status signal. - isConnected = connect(pColorComponentWriteMask, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pColorComponentWriteMask), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - } - } -} - -rgEditorElement* rgPipelineStateModelVulkan::InitializeComputePipelineCreateInfo(QWidget* pParent) -{ - rgEditorElement* pCreateInfoRootNode = nullptr; - - assert(m_pComputePipelineState != nullptr); - if (m_pComputePipelineState != nullptr) - { - // The create info root node that all other create info elements are attached to. - pCreateInfoRootNode = new rgEditorElement(pParent, STR_VULKAN_COMPUTE_PIPELINE_STATE); - - // Set object name. - pCreateInfoRootNode->setObjectName(STR_CREATE_INFO_ROOT_NODE); - - // Add the Compute Pipeline create info root node. - InitializeVkComputePipelineCreateInfo(pCreateInfoRootNode, m_pComputePipelineState); - - // Add the Pipeline Layout create info root node. - VkPipelineLayoutCreateInfo* pPipelineLayoutCreateInfo = m_pComputePipelineState->GetPipelineLayoutCreateInfo(); - assert(pPipelineLayoutCreateInfo != nullptr); - if (pPipelineLayoutCreateInfo != nullptr) - { - InitializePipelineLayoutCreateInfo(pCreateInfoRootNode, pPipelineLayoutCreateInfo); - } - - // Initialize rows related to Descriptor Set Layout configuration. - InitializeDescriptorSetLayoutCreateInfoArray(pCreateInfoRootNode, m_pComputePipelineState); - } - - return pCreateInfoRootNode; -} - -bool rgPipelineStateModelVulkan::LoadPipelineStateFile(QWidget* pParent, const std::string& psoFilePath, rgPipelineType pipelineType, std::string& errorString) -{ - bool isOk = false; - - try - { - // Assign the type of pipeline being loaded from file. - m_pipelineType = pipelineType; - - if (m_pipelineType == rgPipelineType::Graphics) - { - rgPsoGraphicsVulkan* pGraphicsPipelineState = nullptr; - - // Load the graphics pipeline state file. - isOk = RgPsoSerializerVulkan::ReadStructureFromFile(psoFilePath, &pGraphicsPipelineState, errorString); - - assert(isOk); - if (isOk) - { - // Assign the new graphics pipeline state in the model. - m_pGraphicsPipelineState = pGraphicsPipelineState; - - // Initialize the create info structure to bind it to the model. - m_pRootItem = InitializeGraphicsPipelineCreateInfo(pParent); - } - else - { - rgUtils::ShowErrorMessageBox(errorString.c_str()); - } - } - else if (m_pipelineType == rgPipelineType::Compute) - { - rgPsoComputeVulkan* pComputePipelineState = nullptr; - - // Load the compute pipeline state file. - isOk = RgPsoSerializerVulkan::ReadStructureFromFile(psoFilePath, &pComputePipelineState, errorString); - - assert(isOk); - if (isOk) - { - // Assign the new compute pipeline state in the model. - m_pComputePipelineState = pComputePipelineState; - - // Initialize the create info structure to bind it to the model. - m_pRootItem = InitializeComputePipelineCreateInfo(pParent); - } - else - { - rgUtils::ShowErrorMessageBox(errorString.c_str()); - } - } - else - { - assert(false); - errorString = STR_ERR_CANNOT_DETERMINE_PIPELINE_TYPE; - } - } - catch (...) - { - errorString = STR_ERR_CANNOT_FAILED_TO_LOAD_PIPELINE_STATE_FILE; - } - - return isOk; -} - -bool rgPipelineStateModelVulkan::SavePipelineStateFile(const std::string& psoFilePath, std::string& errorString) -{ - bool isOk = false; - - try - { - std::string validationErrorString; - bool isValid = CheckValidPipelineState(validationErrorString); - - assert(isValid); - if (isValid) - { - if (m_pipelineType == rgPipelineType::Graphics) - { - // Save the graphics pipeline state file. - isOk = RgPsoSerializerVulkan::WriteStructureToFile(m_pGraphicsPipelineState, psoFilePath, errorString); - } - else if (m_pipelineType == rgPipelineType::Compute) - { - // Save the compute pipeline state file. - isOk = RgPsoSerializerVulkan::WriteStructureToFile(m_pComputePipelineState, psoFilePath, errorString); - } - else - { - assert(false); - errorString = STR_ERR_CANNOT_DETERMINE_PIPELINE_TYPE; - } - } - else - { - std::stringstream errorStream; - errorStream << STR_ERR_FAILED_TO_VALIDATE << std::endl; - errorStream << validationErrorString; - errorString = errorStream.str(); - } - } - catch (...) - { - errorString = STR_ERR_FAILED_TO_SAVE_PIPELINE_STATE_FILE; - } - - return isOk; -} - -void rgPipelineStateModelVulkan::InitializeVkComputePipelineCreateInfo(rgEditorElement* pRootElement, rgPsoComputeVulkan* pComputePipelineCreateInfo) -{ - assert(pComputePipelineCreateInfo != nullptr); - if (pComputePipelineCreateInfo != nullptr) - { - VkComputePipelineCreateInfo* pVkComputePipelineCreateInfo = static_cast(pComputePipelineCreateInfo->GetComputePipelineCreateInfo()); - assert(pVkComputePipelineCreateInfo != nullptr); - if (pVkComputePipelineCreateInfo != nullptr) - { - rgEditorElement* pVkComputePipelineCreateInfoRoot = new rgEditorElement(pRootElement, STR_VULKAN_COMPUTE_PIPELINE_CREATE_INFO); - pRootElement->AppendChildItem(pVkComputePipelineCreateInfoRoot); - - // Set object name. - pVkComputePipelineCreateInfoRoot->setObjectName(STR_VK_COMPUTE_PIPELINE_CREATE_INFO_ROOT); - - // Add the "flags" member. - const rgEnumValuesVector& pipelineFlagsEnumerators = GetPipelineCreateFlagEnumerators(); - rgEditorElement* pFlagsItem = new rgEditorElementEnum(m_pParent, STR_VULKAN_PIPELINE_MEMBER_FLAGS, pipelineFlagsEnumerators, reinterpret_cast(&pVkComputePipelineCreateInfo->flags), true); - pVkComputePipelineCreateInfoRoot->AppendChildItem(pFlagsItem); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pFlagsItem), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pFlagsItem->setObjectName(STR_FLAGS_ITEM); - - // Connect to the flags enum list widget status signal. - isConnected = connect(pFlagsItem, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pFlagsItem), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "basePipelineIndex" member. - rgEditorElement* pBasePipelineIndexCreateInfo = MakeNumericElement(pVkComputePipelineCreateInfoRoot, STR_VULKAN_PIPELINE_MEMBER_BASE_INDEX, &pVkComputePipelineCreateInfo->basePipelineIndex); - pVkComputePipelineCreateInfoRoot->AppendChildItem(pBasePipelineIndexCreateInfo); - - // Set object name. - pBasePipelineIndexCreateInfo->setObjectName(STR_BASE_PIPELINE_INDEX_CREATE_INFO); - } - } -} - -void rgPipelineStateModelVulkan::InitializePipelineLayoutCreateInfo(rgEditorElement* pRootElement, VkPipelineLayoutCreateInfo* pPipelineLayoutCreateInfo) -{ - assert(pPipelineLayoutCreateInfo != nullptr); - if (pPipelineLayoutCreateInfo != nullptr) - { - rgEditorElement* pPipelineLayoutCreateInfoRoot = new rgEditorElement(pRootElement, STR_VULKAN_PIPELINE_LAYOUT_CREATE_INFO); - pRootElement->AppendChildItem(pPipelineLayoutCreateInfoRoot); - - // Set object name. - pPipelineLayoutCreateInfoRoot->setObjectName(STR_PIPELINE_LAYOUT_CREATE_INFO_ROOT); - - // Add the "flags" member. - rgEditorElement* pFlagsItem = MakeNumericElement(pPipelineLayoutCreateInfoRoot, STR_VULKAN_PIPELINE_MEMBER_FLAGS, &pPipelineLayoutCreateInfo->flags); - pPipelineLayoutCreateInfoRoot->AppendChildItem(pFlagsItem); - - // Set object name. - pFlagsItem->setObjectName(STR_FLAGS_ITEM); - - // Descriptor Set Layout array: - // Create the layout array root item. - rgEditorElementArrayElementAdd* pDescriptorSetLayoutsRootItem = new rgEditorElementArrayElementAdd(pPipelineLayoutCreateInfoRoot, STR_VULKAN_PIPELINE_LAYOUT_P_SET_LAYOUTS, - [=](int elementIndex) { RemoveElement(pPipelineLayoutCreateInfo->pSetLayouts, pPipelineLayoutCreateInfo->setLayoutCount, elementIndex); }); - - // Set object name. - pDescriptorSetLayoutsRootItem->setObjectName(STR_DESCRIPTOR_SET_LAYOUTS_ROOT_ITEM); - - // Create the setLayoutCount member. - rgEditorElement* pDescriptorSetLayoutCountItem = MakeNumericElement(nullptr, STR_VULKAN_PIPELINE_LAYOUT_DESCRIPTOR_SET_LAYOUT_COUNT, - &pPipelineLayoutCreateInfo->setLayoutCount, [=] { HandlePipelineLayoutDescriptorSetLayoutCountChanged(pDescriptorSetLayoutsRootItem, pPipelineLayoutCreateInfo); }); - - // Set object name. - pDescriptorSetLayoutCountItem->setObjectName(STR_DESCRIPTOR_SET_LAYOUT_COUNT_ITEM); - - // Provide the element used to track the dimension of the Descriptor Set Layouts array. - pDescriptorSetLayoutsRootItem->SetArraySizeElement(static_cast*>(pDescriptorSetLayoutCountItem)); - - // Initialize the Descriptor Set Layout array rows. - HandlePipelineLayoutDescriptorSetLayoutCountChanged(pDescriptorSetLayoutsRootItem, pPipelineLayoutCreateInfo, true); - - // Add the descriptor set layouts array node. - pPipelineLayoutCreateInfoRoot->AppendChildItem(pDescriptorSetLayoutsRootItem); - - // Push Constants array: - // Create the push constants array root item. - rgEditorElementArrayElementAdd* pPushConstantsArrayRootItem = new rgEditorElementArrayElementAdd(pPipelineLayoutCreateInfoRoot, STR_VULKAN_PIPELINE_LAYOUT_P_PUSH_CONSTANT_RANGES, - [=](int elementIndex) { RemoveElement(pPipelineLayoutCreateInfo->pPushConstantRanges, pPipelineLayoutCreateInfo->pushConstantRangeCount, elementIndex); }); - - // Set object name. - pPushConstantsArrayRootItem->setObjectName(STR_PUSH_CONSTANT_ARRAY_ROOT_ITEM); - - // Create the pushConstantRangeCount member. - rgEditorElement* pPushConstantsCountItem = MakeNumericElement(nullptr, STR_VULKAN_PIPELINE_LAYOUT_PUSH_CONSTANT_RANGE_COUNT, - &pPipelineLayoutCreateInfo->pushConstantRangeCount, [=] { HandlePushConstantsCountChanged(pPushConstantsArrayRootItem, pPipelineLayoutCreateInfo); }); - - // Set object name. - pPushConstantsCountItem->setObjectName(STR_PUSH_CONSTANTS_COUNT_ITEM); - - // Provide the element used to track the dimension of the Push Constants array. - pPushConstantsArrayRootItem->SetArraySizeElement(static_cast*>(pPushConstantsCountItem)); - - // Initialize the Push Constants array rows. - HandlePushConstantsCountChanged(pPushConstantsArrayRootItem, pPipelineLayoutCreateInfo, true); - - // Add the descriptor set layouts array node. - pPipelineLayoutCreateInfoRoot->AppendChildItem(pPushConstantsArrayRootItem); - } -} - -void rgPipelineStateModelVulkan::InitializeDescriptorSetLayoutCreateInfo(rgEditorElement* pRootElement, VkDescriptorSetLayoutCreateInfo* pDescriptorSetLayoutCreateInfo) -{ - assert(pRootElement != nullptr); - assert(pDescriptorSetLayoutCreateInfo != nullptr); - if (pRootElement != nullptr && pDescriptorSetLayoutCreateInfo != nullptr) - { - // Add the "flags" node. - const rgEnumValuesVector& descriptorSetLayoutCreateFlags = GetDescriptorSetLayoutCreateFlagEnumerators(); - rgEditorElement* pDescriptorSetLayoutFlagsNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_PIPELINE_MEMBER_FLAGS, descriptorSetLayoutCreateFlags, reinterpret_cast(&pDescriptorSetLayoutCreateInfo->flags), true); - pRootElement->AppendChildItem(pDescriptorSetLayoutFlagsNode); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pDescriptorSetLayoutFlagsNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pDescriptorSetLayoutFlagsNode->setObjectName(STR_DESCRIPTOR_SET_LAYOUT_FLAGS_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pDescriptorSetLayoutFlagsNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pDescriptorSetLayoutFlagsNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Binding array: - // Create the binding array root item. - rgEditorElementArrayElementAdd* pDescriptorSetLayoutBindingsRootItem = new rgEditorElementArrayElementAdd(pRootElement, STR_VULKAN_PIPELINE_LAYOUT_DESCRIPTOR_SET_LAYOUT_P_BINDINGS, - [=](int elementIndex) { RemoveElement(pDescriptorSetLayoutCreateInfo->pBindings, pDescriptorSetLayoutCreateInfo->bindingCount, elementIndex); }); - - // Set object name. - pDescriptorSetLayoutBindingsRootItem->setObjectName(STR_DESCRIPTOR_SET_LAYOUT_BINDINGS_ROOT_ITEM); - - // Create the bindingCount member. - rgEditorElement* pDescriptorSetBindingCountItem = MakeNumericElement(nullptr, STR_VULKAN_PIPELINE_LAYOUT_DESCRIPTOR_SET_LAYOUT_BINDING_COUNT, - &pDescriptorSetLayoutCreateInfo->bindingCount, [=] { HandleDescriptorSetLayoutBindingCountChanged(pDescriptorSetLayoutBindingsRootItem, pDescriptorSetLayoutCreateInfo); }); - - // Set object name. - pDescriptorSetBindingCountItem->setObjectName(STR_DESCRIPTOR_SET_BINDING_COUNT_ITEM); - - // Provide the element used to track the dimension of the pDescriptorSetBindings array. - pDescriptorSetLayoutBindingsRootItem->SetArraySizeElement(static_cast*>(pDescriptorSetBindingCountItem)); - - // Initialize the pDescriptorSetBindings array rows. - HandleDescriptorSetLayoutBindingCountChanged(pDescriptorSetLayoutBindingsRootItem, pDescriptorSetLayoutCreateInfo, true); - - // Add the descriptor set layout bindings array node. - pRootElement->AppendChildItem(pDescriptorSetLayoutBindingsRootItem); - } -} - -void rgPipelineStateModelVulkan::HandlePipelineLayoutDescriptorSetLayoutCountChanged(rgEditorElement* pRootElement, VkPipelineLayoutCreateInfo* pPipelineLayoutCreateInfo, bool firstInit) -{ - ResizeHandler(pRootElement, - pPipelineLayoutCreateInfo->setLayoutCount, - pPipelineLayoutCreateInfo->pSetLayouts, - STR_VULKAN_DESCRIPTOR_SET_LAYOUT_HANDLE, - std::bind(&rgPipelineStateModelVulkan::InitializeDescriptorSetLayout, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - firstInit); -} - -void rgPipelineStateModelVulkan::HandlePushConstantsCountChanged(rgEditorElement* pRootElement, VkPipelineLayoutCreateInfo* pPipelineLayoutCreateInfo, bool firstInit) -{ - ResizeHandler(pRootElement, - pPipelineLayoutCreateInfo->pushConstantRangeCount, - pPipelineLayoutCreateInfo->pPushConstantRanges, - STR_VULKAN_PUSH_CONSTANT_RANGE_TYPE, - std::bind(&rgPipelineStateModelVulkan::InitializePushConstantRange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - firstInit); -} - -void rgPipelineStateModelVulkan::HandleDescriptorSetLayoutBindingCountChanged(rgEditorElement* pRootElement, VkDescriptorSetLayoutCreateInfo* pDescriptorSetLayoutCreateInfo, bool firstInit) -{ - ResizeHandler(pRootElement, - pDescriptorSetLayoutCreateInfo->bindingCount, - pDescriptorSetLayoutCreateInfo->pBindings, - STR_VULKAN_DESCRIPTOR_SET_LAYOUT_BINDING_TYPE, - std::bind(&rgPipelineStateModelVulkan::InitializeDescriptorSetLayoutBinding, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - firstInit); -} - -void rgPipelineStateModelVulkan::InitializeDescriptorSetLayoutBinding(rgEditorElement* pRootElement, VkDescriptorSetLayoutBinding* pBaseDescriptorSetLayout, int itemIndex) -{ - assert(pRootElement != nullptr); - assert(pBaseDescriptorSetLayout != nullptr); - if (pRootElement != nullptr && pBaseDescriptorSetLayout != nullptr) - { - VkDescriptorSetLayoutBinding* pOffsetDescriptorSetLayout = pBaseDescriptorSetLayout + itemIndex; - assert(pOffsetDescriptorSetLayout != nullptr); - if (pOffsetDescriptorSetLayout != nullptr) - { - // Add the "binding" node. - rgEditorElement* pDescriptorSetLayoutBindingIndexNode = MakeNumericElement(pRootElement, STR_VULKAN_DESCRIPTOR_SET_LAYOUT_BINDING, &pOffsetDescriptorSetLayout->binding); - pRootElement->AppendChildItem(pDescriptorSetLayoutBindingIndexNode); - - // Set object name. - pDescriptorSetLayoutBindingIndexNode->setObjectName(STR_DESCRIPTOR_SET_LAYOUT_BINDING_INDEX_NODE); - - // Add the "descriptorType" node. - const rgEnumValuesVector& descriptorTypeEnumerators = GetDescriptorTypeEnumerators(); - rgEditorElement* pDescriptorTypeNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_DESCRIPTOR_SET_LAYOUT_BINDING_DESCRIPTOR_TYPE, descriptorTypeEnumerators, reinterpret_cast(&pOffsetDescriptorSetLayout->descriptorType)); - pRootElement->AppendChildItem(pDescriptorTypeNode); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pDescriptorTypeNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pDescriptorTypeNode->setObjectName(STR_DESCRIPTOR_TYPE_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pDescriptorTypeNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pDescriptorTypeNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "descriptorCount" node. - rgEditorElement* pDescriptorSetLayoutBindingCountNode = MakeNumericElement(pRootElement, STR_VULKAN_DESCRIPTOR_SET_LAYOUT_BINDING_DESCRIPTOR_COUNT, &pOffsetDescriptorSetLayout->descriptorCount); - pRootElement->AppendChildItem(pDescriptorSetLayoutBindingCountNode); - - // Set object name. - pDescriptorSetLayoutBindingCountNode->setObjectName(STR_DESCRIPTION_SET_LAYOUT_BINDING_COUNT_NODE); - - // Add the "stageFlags" member node. - const rgEnumValuesVector& stageFlagEnumerators = GetShaderStageFlagEnumerators(); - rgEditorElement* pStageFlagsNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_PIPELINE_LAYOUT_STAGE_FLAGS, stageFlagEnumerators, reinterpret_cast(&pOffsetDescriptorSetLayout->stageFlags), true); - pRootElement->AppendChildItem(pStageFlagsNode); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pStageFlagsNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pStageFlagsNode->setObjectName(STR_STAGE_FLAGS_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pStageFlagsNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pStageFlagsNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - } - } -} - -void rgPipelineStateModelVulkan::InitializeDescriptorSetLayout(rgEditorElement* pRootElement, VkDescriptorSetLayout* pBaseDescriptorSetLayout, int itemIndex) -{ - assert(pRootElement != nullptr); - assert(pBaseDescriptorSetLayout != nullptr); - if (pRootElement != nullptr && pBaseDescriptorSetLayout != nullptr) - { - VkDescriptorSetLayout* pOffsetDescriptorSetLayout = pBaseDescriptorSetLayout + itemIndex; - assert(pOffsetDescriptorSetLayout != nullptr); - if (pOffsetDescriptorSetLayout != nullptr) - { - // Add the "pDescriptorSetLayout" handle member. - rgEditorElement* pDescriptorSetLayoutHandleNode = MakeNumericElement(pRootElement, STR_VULKAN_DESCRIPTOR_SET_LAYOUT_HANDLE, reinterpret_cast(pOffsetDescriptorSetLayout)); - pRootElement->AppendChildItem(pDescriptorSetLayoutHandleNode); - - // Set object name. - pDescriptorSetLayoutHandleNode->setObjectName(STR_DESCRIPTOR_SET_LAYOUT_HANDLE_NODE); - } - } -} - -void rgPipelineStateModelVulkan::InitializePushConstantRange(rgEditorElement* pRootElement, VkPushConstantRange* pBasePushConstant, int itemIndex) -{ - assert(pRootElement != nullptr); - assert(pBasePushConstant != nullptr); - if (pRootElement != nullptr && pBasePushConstant != nullptr) - { - VkPushConstantRange* pOffsetPushConstant = pBasePushConstant + itemIndex; - assert(pOffsetPushConstant != nullptr); - if (pOffsetPushConstant != nullptr) - { - // Add the "stageFlags" member node. - const rgEnumValuesVector& stageFlagEnumerators = GetShaderStageFlagEnumerators(); - rgEditorElement* pStageFlagsNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_PIPELINE_LAYOUT_STAGE_FLAGS, stageFlagEnumerators, reinterpret_cast(&pOffsetPushConstant->stageFlags), true); - pRootElement->AppendChildItem(pStageFlagsNode); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pStageFlagsNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pStageFlagsNode->setObjectName(STR_STAGE_FLAGS_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pStageFlagsNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pStageFlagsNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "offset" member. - rgEditorElement* pOffsetNode = MakeNumericElement(pRootElement, STR_VULKAN_PIPELINE_LAYOUT_PUSH_CONSTANT_OFFSET, &pOffsetPushConstant->offset); - pRootElement->AppendChildItem(pOffsetNode); - - // Set object name. - pOffsetNode->setObjectName(STR_OFFSET_NODE); - - // Add the "size" member. - rgEditorElement* pSizeNode = MakeNumericElement(pRootElement, STR_VULKAN_PIPELINE_LAYOUT_PUSH_CONSTANT_SIZE, &pOffsetPushConstant->size); - pRootElement->AppendChildItem(pSizeNode); - - // Set object name. - pSizeNode->setObjectName(STR_SIZE_NODE); - } - } -} - -void rgPipelineStateModelVulkan::InitializeRenderPassCreateInfo(rgEditorElement* pRootElement, VkRenderPassCreateInfo* pRenderPassCreateInfo) -{ - assert(pRenderPassCreateInfo != nullptr); - if (pRenderPassCreateInfo != nullptr) - { - rgEditorElement* pRenderPassCreateInfoRoot = new rgEditorElement(pRootElement, STR_VULKAN_RENDER_PASS_CREATE_INFO); - pRootElement->AppendChildItem(pRenderPassCreateInfoRoot); - - // Set object name. - pRenderPassCreateInfoRoot->setObjectName(STR_RENDER_PASS_CREATE_INFO_ROOT); - - // Add the "flags" member. - rgEditorElement* pFlagsItem = MakeNumericElement(pRenderPassCreateInfoRoot, STR_VULKAN_PIPELINE_MEMBER_FLAGS, &pRenderPassCreateInfo->flags); - pRenderPassCreateInfoRoot->AppendChildItem(pFlagsItem); - - // Set object name. - pFlagsItem->setObjectName(STR_FLAGS_ITEM); - - // Attachment array: - // Create the attachments array root item. - rgEditorElementArrayElementAdd* pAttachmentsRootItem = new rgEditorElementArrayElementAdd(pRenderPassCreateInfoRoot, STR_VULKAN_RENDER_PASS_P_ATTACHMENTS, - [=](int elementIndex) { RemoveElement(pRenderPassCreateInfo->pAttachments, pRenderPassCreateInfo->attachmentCount, elementIndex); }); - - // Set object name. - pAttachmentsRootItem->setObjectName(STR_COLOR_ATTACHMENTS_ROOT_ITEM); - - // Create the attachmentCount member. - rgEditorElement* pAttachmentCountItem = MakeNumericElement(nullptr, STR_VULKAN_RENDER_PASS_ATTACHMENT_COUNT, - &pRenderPassCreateInfo->attachmentCount, [=] { HandleRenderPassAttachmentCountChanged(pAttachmentsRootItem, pRenderPassCreateInfo); }); - - // Set object name. - pAttachmentCountItem->setObjectName(STR_ATTACHMENT_COUNT_ITEM); - - // Add the attachment array node. - pRenderPassCreateInfoRoot->AppendChildItem(pAttachmentsRootItem); - - // Provide the element used to track the dimension of the pAttachments array. - pAttachmentsRootItem->SetArraySizeElement(static_cast*>(pAttachmentCountItem)); - - // Initialize the pAttachments rows. - HandleRenderPassAttachmentCountChanged(pAttachmentsRootItem, pRenderPassCreateInfo, true); - - // Subpass array: - // Create the subpasses array root item. - rgEditorElementArrayElementAdd* pSubpassRootItem = new rgEditorElementArrayElementAdd(pRenderPassCreateInfoRoot, STR_VULKAN_RENDER_PASS_P_SUBPASSES, - [=](int elementIndex) - { - // Remove the artificial "resolveAttachmentCount" that was configured per-subpass. - auto resolveAttachmentCountIter = m_resolveAttachmentCountPerSubpass.find(elementIndex); - if (resolveAttachmentCountIter != m_resolveAttachmentCountPerSubpass.end()) - { - // Is the resolveAttachmentCount variable valid? - uint32_t* pResolveAttachmentCount = resolveAttachmentCountIter->second; - assert(pResolveAttachmentCount != nullptr); - if (pResolveAttachmentCount != nullptr) - { - // Destroy the resolveAttachmentCount variable associated with the subpass. - RG_SAFE_DELETE(pResolveAttachmentCount); - - // Erase the variable since the subpass is being destroyed. - m_resolveAttachmentCountPerSubpass.erase(resolveAttachmentCountIter); - } - } - - // Remove the subpass at the given index. - RemoveElement(pRenderPassCreateInfo->pSubpasses, pRenderPassCreateInfo->subpassCount, elementIndex); - }); - - // Set object name. - pSubpassRootItem->setObjectName(STR_SUBPASS_ROOT_ITEM); - - // Create the subpassCount member. - rgEditorElement* pSubpassDescriptionCountItem = MakeNumericElement(nullptr, STR_VULKAN_RENDER_PASS_SUBPASS_COUNT, - &pRenderPassCreateInfo->subpassCount, [=] { HandleRenderPassSubpassCountChanged(pSubpassRootItem, pRenderPassCreateInfo); }); - - // Set object name. - pSubpassDescriptionCountItem->setObjectName(STR_SUBPASS_DESCRIPTION_COUNT_ITEM); - - // Add the pSubpasses array node. - pRenderPassCreateInfoRoot->AppendChildItem(pSubpassRootItem); - - // Provide the element used to track the dimension of the pSubpassDescription array. - pSubpassRootItem->SetArraySizeElement(static_cast*>(pSubpassDescriptionCountItem)); - - // Initialize the pSubpassDescription rows. - HandleRenderPassSubpassCountChanged(pSubpassRootItem, pRenderPassCreateInfo, true); - - // Dependency array: - // Create the dependency array root item. - rgEditorElementArrayElementAdd* pDependenciesRootItem = new rgEditorElementArrayElementAdd(pRenderPassCreateInfoRoot, STR_VULKAN_RENDER_PASS_P_DEPENDENCIES, - [=](int elementIndex) { RemoveElement(pRenderPassCreateInfo->pDependencies, pRenderPassCreateInfo->dependencyCount, elementIndex); }); - - // Set object name. - pDependenciesRootItem->setObjectName(STR_DEPENDENCIES_ROOT_ITEM); - - // Create the dependencyCount member. - rgEditorElement* pDependencyDescriptionCountItem = MakeNumericElement(nullptr, STR_VULKAN_RENDER_PASS_DEPENDENCY_COUNT, - &pRenderPassCreateInfo->dependencyCount, [=] { HandleRenderPassDependencyCountChanged(pDependenciesRootItem, pRenderPassCreateInfo); }); - - // Set object name. - pDependencyDescriptionCountItem->setObjectName(STR_DEPENDENCY_DESCRIPTION_COUNT_ITEM); - - // Add the pDependencies array node. - pRenderPassCreateInfoRoot->AppendChildItem(pDependenciesRootItem); - - // Provide the element used to track the dimension of the pDependencies array. - pDependenciesRootItem->SetArraySizeElement(static_cast*>(pDependencyDescriptionCountItem)); - - // Initialize the pDependencies rows. - HandleRenderPassDependencyCountChanged(pDependenciesRootItem, pRenderPassCreateInfo, true); - } -} - -void rgPipelineStateModelVulkan::HandleRenderPassAttachmentCountChanged(rgEditorElement* pRootElement, VkRenderPassCreateInfo* pRenderPassCreateInfo, bool firstInit) -{ - ResizeHandler(pRootElement, - pRenderPassCreateInfo->attachmentCount, - pRenderPassCreateInfo->pAttachments, - STR_VULKAN_RENDER_PASS_ATTACHMENT_DESCRIPTION, - std::bind(&rgPipelineStateModelVulkan::InitializeRenderPassAttachmentDescriptionCreateInfo, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - firstInit); -} - -void rgPipelineStateModelVulkan::HandleRenderPassSubpassCountChanged(rgEditorElement* pRootElement, VkRenderPassCreateInfo* pRenderPassCreateInfo, bool firstInit) -{ - ResizeHandler(pRootElement, - pRenderPassCreateInfo->subpassCount, - pRenderPassCreateInfo->pSubpasses, - STR_VULKAN_RENDER_PASS_SUBPASS_DESCRIPTION, - std::bind(&rgPipelineStateModelVulkan::InitializeRenderPassSubpassDescriptionCreateInfo, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - firstInit); -} - -void rgPipelineStateModelVulkan::HandleRenderPassDependencyCountChanged(rgEditorElement* pRootElement, VkRenderPassCreateInfo* pRenderPassCreateInfo, bool firstInit) -{ - ResizeHandler(pRootElement, - pRenderPassCreateInfo->dependencyCount, - pRenderPassCreateInfo->pDependencies, - STR_VULKAN_RENDER_PASS_DEPENDENCY_DESCRIPTION, - std::bind(&rgPipelineStateModelVulkan::InitializeRenderPassDependencyDescriptionCreateInfo, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - firstInit); -} - -void rgPipelineStateModelVulkan::InitializeRenderPassAttachmentDescriptionCreateInfo(rgEditorElement* pRootElement, VkAttachmentDescription* pBaseAttachmentDescription, int itemIndex) -{ - assert(pRootElement != nullptr); - assert(pBaseAttachmentDescription != nullptr); - if (pRootElement != nullptr && pBaseAttachmentDescription != nullptr) - { - VkAttachmentDescription* pOffsetAttachmentDescription = pBaseAttachmentDescription + itemIndex; - assert(pOffsetAttachmentDescription != nullptr); - if (pOffsetAttachmentDescription != nullptr) - { - // Add the "flags" member. - const rgEnumValuesVector& attachmentDescriptionFlagEnumerators = GetAttachmentDescriptionFlagEnumerators(); - rgEditorElement* pFlagsElement = new rgEditorElementEnum(m_pParent, STR_VULKAN_PIPELINE_MEMBER_FLAGS, attachmentDescriptionFlagEnumerators, reinterpret_cast(&pOffsetAttachmentDescription->flags), true); - pRootElement->AppendChildItem(pFlagsElement); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pFlagsElement), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pFlagsElement->setObjectName(STR_FLAGS_ELEMENT); - - // Connect to the enum list widget status signal. - isConnected = connect(pFlagsElement, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pFlagsElement), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "format" member values. - const rgEnumValuesVector& formatEnumerators = GetFormatEnumerators(); - rgEditorElement* pFormatElement = new rgEditorElementEnum(m_pParent, STR_VULKAN_PIPELINE_MEMBER_VERTEX_FORMAT, formatEnumerators, reinterpret_cast(&pOffsetAttachmentDescription->format)); - pRootElement->AppendChildItem(pFormatElement); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pFormatElement), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pFormatElement->setObjectName(STR_FORMAT_ELEMENT); - - // Connect to the enum list widget status signal. - isConnected = connect(pFormatElement, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pFormatElement), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "samples" member. - rgEditorElement* pSamplesItem = MakeNumericElement(pRootElement, STR_VULKAN_RENDER_PASS_ATTACHMENT_SAMPLES, reinterpret_cast(&pOffsetAttachmentDescription->samples)); - pRootElement->AppendChildItem(pSamplesItem); - - // Set object name. - pSamplesItem->setObjectName(STR_SAMPLES_ITEM); - - // Add the "loadOp" member values. - const rgEnumValuesVector& loadOpEnumerators = GetAttachmentLoadOpEnumerators(); - rgEditorElement* pLoadOpItem = new rgEditorElementEnum(m_pParent, STR_VULKAN_RENDER_PASS_LOAD_OP, loadOpEnumerators, reinterpret_cast(&pOffsetAttachmentDescription->loadOp)); - pRootElement->AppendChildItem(pLoadOpItem); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pLoadOpItem), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pLoadOpItem->setObjectName(STR_LOAD_OP_ITEM); - - // Connect to the enum list widget status signal. - isConnected = connect(pLoadOpItem, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pLoadOpItem), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "storeOp" member values. - const rgEnumValuesVector& storeOpEnumerators = GetAttachmentStoreOpEnumerators(); - rgEditorElement* pStoreOpItem = new rgEditorElementEnum(m_pParent, STR_VULKAN_RENDER_PASS_STORE_OP, storeOpEnumerators, reinterpret_cast(&pOffsetAttachmentDescription->storeOp)); - pRootElement->AppendChildItem(pStoreOpItem); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pStoreOpItem), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pStoreOpItem->setObjectName(STR_STORE_OP_ITEM); - - // Connect to the enum list widget status signal. - isConnected = connect(pStoreOpItem, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pStoreOpItem), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "stencilLoadOp" member values. - rgEditorElement* pStencilLoadOpItem = new rgEditorElementEnum(m_pParent, STR_VULKAN_RENDER_PASS_STENCIL_LOAD_OP, loadOpEnumerators, reinterpret_cast(&pOffsetAttachmentDescription->stencilLoadOp)); - pRootElement->AppendChildItem(pStencilLoadOpItem); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pStencilLoadOpItem), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pStencilLoadOpItem->setObjectName(STR_STENCIL_LOAD_OP_ITEM); - - // Connect to the enum list widget status signal. - isConnected = connect(pStencilLoadOpItem, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pStencilLoadOpItem), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "stencilStoreOp" member values. - rgEditorElement* pStencilStoreOpItem = new rgEditorElementEnum(m_pParent, STR_VULKAN_RENDER_PASS_STENCIL_STORE_OP, storeOpEnumerators, reinterpret_cast(&pOffsetAttachmentDescription->stencilStoreOp)); - pRootElement->AppendChildItem(pStencilStoreOpItem); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pStencilStoreOpItem), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pStencilStoreOpItem->setObjectName(STR_STENCIL_STORE_OP_ITEM); - - // Connect to the enum list widget status signal. - isConnected = connect(pStencilStoreOpItem, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pStencilStoreOpItem), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "initialLayout" member values. - const rgEnumValuesVector& imageLayoutEnumerators = GetImageLayoutEnumerators(); - rgEditorElement* pIinitialLayoutItem = new rgEditorElementEnum(m_pParent, STR_VULKAN_RENDER_PASS_INITIAL_LAYOUT, imageLayoutEnumerators, reinterpret_cast(&pOffsetAttachmentDescription->initialLayout)); - pRootElement->AppendChildItem(pIinitialLayoutItem); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pIinitialLayoutItem), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pIinitialLayoutItem->setObjectName(STR_INITIAL_LAYOUT_ITEM); - - // Connect to the enum list widget status signal. - isConnected = connect(pIinitialLayoutItem, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pIinitialLayoutItem), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "finalLayout" member values. - rgEditorElement* pFinalLayoutItem = new rgEditorElementEnum(m_pParent, STR_VULKAN_RENDER_PASS_FINAL_LAYOUT, imageLayoutEnumerators, reinterpret_cast(&pOffsetAttachmentDescription->finalLayout)); - pRootElement->AppendChildItem(pFinalLayoutItem); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pFinalLayoutItem), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pFinalLayoutItem->setObjectName(STR_FINAL_LAYOUT_ITEM); - - // Connect to the enum list widget status signal. - isConnected = connect(pFinalLayoutItem, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pFinalLayoutItem), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - } - } -} - -void rgPipelineStateModelVulkan::InitializeRenderPassSubpassDescriptionCreateInfo(rgEditorElement* pRootElement, VkSubpassDescription* pBaseSubpassDescription, int itemIndex) -{ - assert(pRootElement != nullptr); - assert(pBaseSubpassDescription != nullptr); - if (pRootElement != nullptr && pBaseSubpassDescription != nullptr) - { - VkSubpassDescription* pOffsetSubpassDescription = pBaseSubpassDescription + itemIndex; - assert(pOffsetSubpassDescription != nullptr); - if (pOffsetSubpassDescription != nullptr) - { - // Add the "flags" member. - const rgEnumValuesVector& subpassDescriptionFlagEnumerators = GetSubpassDescriptionFlagEnumerators(); - rgEditorElement* pFlags = new rgEditorElementEnum(m_pParent, STR_VULKAN_PIPELINE_MEMBER_FLAGS, subpassDescriptionFlagEnumerators, reinterpret_cast(&pOffsetSubpassDescription->flags), true); - pRootElement->AppendChildItem(pFlags); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pFlags), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pFlags->setObjectName(STR_FLAGS); - - // Connect to the enum list widget status signal. - isConnected = connect(pFlags, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pFlags), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "pipelineBindPoint" member. - const rgEnumValuesVector& pipelineBindPointEnumerators = GetPipelineBindPointEnumerators(); - rgEditorElement* pPipelineBindPointNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_RENDER_PASS_DEPENDENCY_PIPELINE_BIND_POINT, pipelineBindPointEnumerators, reinterpret_cast(&pOffsetSubpassDescription->pipelineBindPoint)); - pRootElement->AppendChildItem(pPipelineBindPointNode); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pPipelineBindPointNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pPipelineBindPointNode->setObjectName(STR_PIPELINE_BIND_POINT_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pPipelineBindPointNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pPipelineBindPointNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - - // Input attachment array: - // Create the input attachment array root item. - rgEditorElementArrayElementAdd* pInputAttachmentsRootItem = new rgEditorElementArrayElementAdd(pRootElement, STR_VULKAN_RENDER_PASS_SUBPASS_P_INPUT_ATTACHMENTS, - [=](int elementIndex) { RemoveElement(pOffsetSubpassDescription->pInputAttachments, pOffsetSubpassDescription->inputAttachmentCount, elementIndex); }); - - // Set object name. - pInputAttachmentsRootItem->setObjectName(STR_INPUT_ATTACHMENTS_ROOT_ITEM); - - // Create the input attachment count member. - rgEditorElement* pInputAttachmentCountNode = MakeNumericElement(nullptr, STR_VULKAN_RENDER_PASS_SUBPASS_INPUT_ATTACHMENT_COUNT, - &pOffsetSubpassDescription->inputAttachmentCount, [=] { HandleRenderPassSubpassInputAttachmentCountChanged(pInputAttachmentsRootItem, pOffsetSubpassDescription); }); - - // Set object name. - pInputAttachmentCountNode->setObjectName(STR_INPUT_ATTACHMENT_COUNT_NODE); - - // Add the pInputAttachments array node. - pRootElement->AppendChildItem(pInputAttachmentsRootItem); - - // Provide the element used to track the dimension of the pInputAttachments array. - pInputAttachmentsRootItem->SetArraySizeElement(static_cast*>(pInputAttachmentCountNode)); - - // Initialize the pInputAttachments rows. - HandleRenderPassSubpassInputAttachmentCountChanged(pInputAttachmentsRootItem, pOffsetSubpassDescription, true); - - // Color attachment and resolve attachment array: - // Create the color attachment array root item. - rgEditorElementArrayElementAdd* pColorAttachmentsRootItem = new rgEditorElementArrayElementAdd(pRootElement, STR_VULKAN_RENDER_PASS_SUBPASS_P_COLOR_ATTACHMENTS, - [=](int elementIndex) { RemoveElement(pOffsetSubpassDescription->pColorAttachments, pOffsetSubpassDescription->colorAttachmentCount, elementIndex); }); - - // Set object name. - pColorAttachmentsRootItem->setObjectName(STR_COLOR_ATTACHMENTS_ROOT_ITEM); - - // Create the color attachment count member. - rgEditorElement* pColorAttachmentCountNode = MakeNumericElement(nullptr, STR_VULKAN_RENDER_PASS_SUBPASS_COLOR_ATTACHMENT_COUNT, - &pOffsetSubpassDescription->colorAttachmentCount, [=] { HandleRenderPassSubpassColorAttachmentCountChanged(pColorAttachmentsRootItem, pOffsetSubpassDescription); }); - - // Set object name. - pColorAttachmentCountNode->setObjectName(STR_COLOR_ATTACHMENT_COUNT_NODE); - - // Add the pColorAttachments array node. - pRootElement->AppendChildItem(pColorAttachmentsRootItem); - - // Provide the element used to track the dimension of the pColorAttachments array. - pColorAttachmentsRootItem->SetArraySizeElement(static_cast*>(pColorAttachmentCountNode)); - - // Initialize the pColorAttachments rows. - HandleRenderPassSubpassColorAttachmentCountChanged(pColorAttachmentsRootItem, pOffsetSubpassDescription, true); - - int subpassIndex = itemIndex; - - // Create a new resolve attachment count. Each subpass will get its own. - uint32_t* pResolveAttachmentCount = new uint32_t{}; - m_resolveAttachmentCountPerSubpass[subpassIndex] = pResolveAttachmentCount; - - // If pResolveAttachments is non-null, we can assume that the dimension of the array matches - // that of colorAttachmentCount. Initialize the count to match the colorAttachmentCount. - if (pOffsetSubpassDescription->pResolveAttachments != nullptr) - { - *pResolveAttachmentCount = pOffsetSubpassDescription->colorAttachmentCount; - } - - // Resolve attachment array: - // Create the resolve attachment array root item. - rgEditorElementArrayElementAdd* pResolveAttachmentsRootItem = new rgEditorElementArrayElementAdd(pRootElement, STR_VULKAN_RENDER_PASS_SUBPASS_P_RESOLVE_ATTACHMENTS, - [=](int elementIndex) - { - // Ensure that the element index - assert(pResolveAttachmentCount != nullptr); - if (pResolveAttachmentCount != nullptr) - { - // An array item has been trashed. Decrease the corresponding count item. - RemoveElement(pOffsetSubpassDescription->pResolveAttachments, *pResolveAttachmentCount, elementIndex); - } - }); - - // Set object name. - pResolveAttachmentsRootItem->setObjectName(STR_RESOLVE_ATTACHMENTS_ROOT_ITEM); - - // Create an artificial resolve attachment count member. - // This member is not part of the VkSubpassDescription structure, but is required since pResolveAttachments array can be NULL, or equal to colorAttachmentCount. - rgEditorElement* pResolveAttachmentCountNode = MakeNumericElement(nullptr, STR_VULKAN_RENDER_PASS_SUBPASS_RESOLVE_ATTACHMENT_COUNT, - pResolveAttachmentCount, [=] - { - HandleRenderPassSubpassResolveAttachmentCountChanged(subpassIndex, pResolveAttachmentsRootItem, pOffsetSubpassDescription); - }); - - // Set object name. - pResolveAttachmentCountNode->setObjectName(STR_RESOLVE_ATTACHMENT_COUNT_NODE); - - // Add the pResolveAttachments array node. - pRootElement->AppendChildItem(pResolveAttachmentsRootItem); - - // Provide the element used to track the dimension of the pResolveAttachments array. - pResolveAttachmentsRootItem->SetArraySizeElement(static_cast*>(pResolveAttachmentCountNode)); - - // Initialize the pResolveAttachments rows. - HandleRenderPassSubpassResolveAttachmentCountChanged(subpassIndex, pResolveAttachmentsRootItem, pOffsetSubpassDescription, true); - - // Create the depth stencil attachment item. - rgEditorElement* pDepthStencilAttachmentsRootItem = new rgEditorElement(pRootElement, STR_VULKAN_RENDER_PASS_SUBPASS_P_DEPTH_STENCIL_ATTACHMENT); - if (pOffsetSubpassDescription->pDepthStencilAttachment != nullptr) - { - // Create a copy of the depth stencil attachment that can be modified. - m_pDepthStencilAttachment = new VkAttachmentReference{}; - memcpy(m_pDepthStencilAttachment, pOffsetSubpassDescription->pDepthStencilAttachment, sizeof(VkAttachmentReference)); - pOffsetSubpassDescription->pDepthStencilAttachment = m_pDepthStencilAttachment; - - // Initialize the tree items with the modifiable attachment pointer. - InitializeAttachmentReference(pDepthStencilAttachmentsRootItem, m_pDepthStencilAttachment, 0); - } - pRootElement->AppendChildItem(pDepthStencilAttachmentsRootItem); - - // Set object name. - pDepthStencilAttachmentsRootItem->setObjectName(STR_DEPTH_STENCIL_ATTACHMENTS_ROOT_ITEM); - - // Input attachment array: - // Create the preserveAttachments array root item. - rgEditorElementArrayElementAdd* pPreserveInputAttachmentsRootItem = new rgEditorElementArrayElementAdd(pRootElement, STR_VULKAN_RENDER_PASS_SUBPASS_P_PRESERVE_ATTACHMENTS, - [=](int elementIndex) { RemoveElement(pOffsetSubpassDescription->pPreserveAttachments, pOffsetSubpassDescription->preserveAttachmentCount, elementIndex); }); - - // Set object name. - pPreserveInputAttachmentsRootItem->setObjectName(STR_PRESERVE_INPUT_ATTACHMENT_ROOT_ITEM); - - // Create the preserveAttachment count member. - rgEditorElement* pPreserveAttachmentCountNode = MakeNumericElement(nullptr, STR_VULKAN_RENDER_PASS_SUBPASS_PRESERVE_ATTACHMENT_COUNT, - &pOffsetSubpassDescription->preserveAttachmentCount, [=] { HandleRenderPassSubpassPreserveAttachmentCountChanged(pPreserveInputAttachmentsRootItem, pOffsetSubpassDescription); }); - - // Set object name. - pPreserveAttachmentCountNode->setObjectName(STR_PRESERVE_ATTACHMENT_COUNT_NODE); - - // Add the pPreserveAttachments array node. - pRootElement->AppendChildItem(pPreserveInputAttachmentsRootItem); - - // Provide the element used to track the dimension of the pPreserveInputAttachments array. - pPreserveInputAttachmentsRootItem->SetArraySizeElement(static_cast*>(pPreserveAttachmentCountNode)); - - // Initialize the pPreserveInputAttachments rows. - HandleRenderPassSubpassPreserveAttachmentCountChanged(pPreserveInputAttachmentsRootItem, pOffsetSubpassDescription, true); - } - } -} - -void rgPipelineStateModelVulkan::HandleRenderPassSubpassInputAttachmentCountChanged(rgEditorElement* pRootElement, VkSubpassDescription* pSubpassCreateInfo, bool firstInit) -{ - ResizeHandler(pRootElement, - pSubpassCreateInfo->inputAttachmentCount, - pSubpassCreateInfo->pInputAttachments, - STR_VULKAN_RENDER_SUBPASS_ATTACHMENT_REFERENCE, - std::bind(&rgPipelineStateModelVulkan::InitializeAttachmentReference, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - firstInit); -} - -void rgPipelineStateModelVulkan::HandleRenderPassSubpassColorAttachmentCountChanged(rgEditorElement* pRootElement, VkSubpassDescription* pSubpassCreateInfo, bool firstInit) -{ - // Resize the color attachments array. - ResizeHandler(pRootElement, - pSubpassCreateInfo->colorAttachmentCount, - pSubpassCreateInfo->pColorAttachments, - STR_VULKAN_RENDER_SUBPASS_ATTACHMENT_REFERENCE, - std::bind(&rgPipelineStateModelVulkan::InitializeAttachmentReference, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - firstInit); -} - -void rgPipelineStateModelVulkan::HandleRenderPassSubpassResolveAttachmentCountChanged(int subpassIndex, rgEditorElement* pRootElement, VkSubpassDescription* pSubpassCreateInfo, bool firstInit) -{ - uint32_t* pSubpassResolveAttachmentCount = m_resolveAttachmentCountPerSubpass.at(subpassIndex); - - assert(pSubpassResolveAttachmentCount != nullptr); - if (pSubpassResolveAttachmentCount != nullptr) - { - // Resize the resolve attachments array. - ResizeHandler(pRootElement, - *pSubpassResolveAttachmentCount, - pSubpassCreateInfo->pResolveAttachments, - STR_VULKAN_RENDER_SUBPASS_ATTACHMENT_REFERENCE, - std::bind(&rgPipelineStateModelVulkan::InitializeAttachmentReference, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - firstInit); - } -} - -void rgPipelineStateModelVulkan::HandleRenderPassSubpassPreserveAttachmentCountChanged(rgEditorElement* pRootElement, VkSubpassDescription* pSubpassCreateInfo, bool firstInit) -{ - // Resize the preserve attachments array. - ResizeHandler(pRootElement, - pSubpassCreateInfo->preserveAttachmentCount, - pSubpassCreateInfo->pPreserveAttachments, - STR_VULKAN_RENDER_SUBPASS_PRESERVE_ATTACHMENT_ELEMENT_TYPE, - std::bind(&rgPipelineStateModelVulkan::InitializePreserveAttachment, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - firstInit); -} - -void rgPipelineStateModelVulkan::InitializeAttachmentReference(rgEditorElement* pRootElement, VkAttachmentReference* pBaseAttachmentReference, int itemIndex) -{ - assert(pRootElement != nullptr); - assert(pBaseAttachmentReference != nullptr); - if (pRootElement != nullptr && pBaseAttachmentReference != nullptr) - { - VkAttachmentReference* pOffsetAttachmentReference = pBaseAttachmentReference + itemIndex; - assert(pOffsetAttachmentReference != nullptr); - if (pOffsetAttachmentReference != nullptr) - { - // Add the "attachment" member. - rgEditorElement* pAttachmentNode = MakeNumericElement(pRootElement, STR_VULKAN_RENDER_PASS_SUBPASS_ATTACHMENT_INDEX, &pOffsetAttachmentReference->attachment); - pRootElement->AppendChildItem(pAttachmentNode); - - // Set object name. - pAttachmentNode->setObjectName(STR_ATTACHMENT_NODE); - - // Add the "layout" member node. - const rgEnumValuesVector& imageLayoutEnumerators = GetImageLayoutEnumerators(); - rgEditorElement* pImageLayoutNode = new rgEditorElementEnum(m_pParent, STR_VULKAN_RENDER_PASS_SUBPASS_ATTACHMENT_LAYOUT, imageLayoutEnumerators, reinterpret_cast(&pOffsetAttachmentReference->layout)); - pRootElement->AppendChildItem(pImageLayoutNode); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pImageLayoutNode), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pImageLayoutNode->setObjectName(STR_IMAGE_LAYOUT_NODE); - - // Connect to the enum list widget status signal. - isConnected = connect(pImageLayoutNode, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pImageLayoutNode), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - } - } -} - -void rgPipelineStateModelVulkan::InitializePreserveAttachment(rgEditorElement* pRootElement, uint32_t* pBaseReserveAttachment, int itemIndex) -{ - assert(pRootElement != nullptr); - assert(pBaseReserveAttachment != nullptr); - if (pRootElement != nullptr && pBaseReserveAttachment != nullptr) - { - uint32_t* pOffsetReserveAttachment = pBaseReserveAttachment + itemIndex; - assert(pOffsetReserveAttachment != nullptr); - if (pOffsetReserveAttachment != nullptr) - { - // Add the "pReserveAttachment" member. - rgEditorElement* pPreserveAttachmentNode = MakeNumericElement(pRootElement, STR_VULKAN_RENDER_PASS_PRESERVE_ATTACHMENT, reinterpret_cast(pOffsetReserveAttachment)); - pRootElement->AppendChildItem(pPreserveAttachmentNode); - - // Set object name. - pPreserveAttachmentNode->setObjectName(STR_PRESERVE_ATTACHMENT_NODE); - } - } -} - -void rgPipelineStateModelVulkan::InitializeRenderPassDependencyDescriptionCreateInfo(rgEditorElement* pRootElement, VkSubpassDependency* pBaseDependencyDescription, int itemIndex) -{ - assert(pRootElement != nullptr); - assert(pBaseDependencyDescription != nullptr); - if (pRootElement != nullptr && pBaseDependencyDescription != nullptr) - { - VkSubpassDependency* pOffsetDependencyDescription = pBaseDependencyDescription + itemIndex; - assert(pOffsetDependencyDescription != nullptr); - if (pOffsetDependencyDescription != nullptr) - { - // Add the "srcSubpass" member. - rgEditorElement* pSrcSubpass = MakeNumericElement(pRootElement, STR_VULKAN_RENDER_PASS_DEPENDENCY_SRC_SUBPASS, reinterpret_cast(&pOffsetDependencyDescription->srcSubpass)); - pRootElement->AppendChildItem(pSrcSubpass); - - // Set object name. - pSrcSubpass->setObjectName(STR_SRC_SUBPASS); - - // Add the "dstSubpass" member. - rgEditorElement* pDstSubpass = MakeNumericElement(pRootElement, STR_VULKAN_RENDER_PASS_DEPENDENCY_DST_SUBPASS, reinterpret_cast(&pOffsetDependencyDescription->dstSubpass)); - pRootElement->AppendChildItem(pDstSubpass); - - // Set object name. - pDstSubpass->setObjectName(STR_DST_SUBPASS); - - // Get the stage flag enumerators. - const rgEnumValuesVector& stageFlagEnumerators = GetPipelineStageFlagEnumerators(); - - // Add the "srcStageMask" member. - rgEditorElement* pSrcStageMask = new rgEditorElementEnum(m_pParent, STR_VULKAN_RENDER_PASS_DEPENDENCY_SRC_STAGE_MASK, stageFlagEnumerators, reinterpret_cast(&pOffsetDependencyDescription->srcStageMask), true); - pRootElement->AppendChildItem(pSrcStageMask); - - // Connect to the splitter moved signal to close the drop down. - rgBuildViewVulkan* pBuildViewVulkan = static_cast(m_pParent); - bool isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pSrcStageMask), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pSrcStageMask->setObjectName(STR_SRC_STAGE_MASK); - - // Connect to the enum list widget status signal. - isConnected = connect(pSrcStageMask, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pSrcStageMask), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "dstStageMask" member. - rgEditorElement* pDstStageMask = new rgEditorElementEnum(m_pParent, STR_VULKAN_RENDER_PASS_DEPENDENCY_DST_STAGE_MASK, stageFlagEnumerators, reinterpret_cast(&pOffsetDependencyDescription->dstStageMask), true); - pRootElement->AppendChildItem(pDstStageMask); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pDstStageMask), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pDstStageMask->setObjectName(STR_DST_STAGE_MASK); - - // Connect to the enum list widget status signal. - isConnected = connect(pDstStageMask, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pDstStageMask), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Get the access flag enumerators. - const rgEnumValuesVector& accessFlagEnumerators = GetAccessFlagEnumerators(); - - // Add the "srcAccessMask" member. - rgEditorElement* pSrcAccessMask = new rgEditorElementEnum(m_pParent, STR_VULKAN_RENDER_PASS_DEPENDENCY_SRC_ACCESS_MASK, accessFlagEnumerators, reinterpret_cast(&pOffsetDependencyDescription->srcAccessMask), true); - pRootElement->AppendChildItem(pSrcAccessMask); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pSrcAccessMask), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pSrcAccessMask->setObjectName(STR_SRC_ACCESS_MASK); - - // Connect to the enum list widget status signal. - isConnected = connect(pSrcAccessMask, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pSrcAccessMask), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "dstAccessMask" member. - rgEditorElement* pDstAccessMask = new rgEditorElementEnum(m_pParent, STR_VULKAN_RENDER_PASS_DEPENDENCY_DST_ACCESS_MASK, accessFlagEnumerators, reinterpret_cast(&pOffsetDependencyDescription->dstAccessMask), true); - pRootElement->AppendChildItem(pDstAccessMask); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pDstAccessMask), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pDstAccessMask->setObjectName(STR_DST_ACCESS_MASK); - - // Connect to the enum list widget status signal. - isConnected = connect(pDstAccessMask, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pDstAccessMask), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - - // Add the "dependencyFlags" member. - const rgEnumValuesVector& dependencyFlagEnumerators = GetDependencyFlagEnumerators(); - rgEditorElement* pDependencyFlags = new rgEditorElementEnum(m_pParent, STR_VULKAN_RENDER_PASS_DEPENDENCY_DEPENDENCY_FLAGS, dependencyFlagEnumerators, reinterpret_cast(&pOffsetDependencyDescription->dependencyFlags), true); - pRootElement->AppendChildItem(pDependencyFlags); - - // Connect to the splitter moved signal to close the drop down. - pBuildViewVulkan = static_cast(m_pParent); - isConnected = connect(pBuildViewVulkan, &rgBuildViewVulkan::SplitterMoved, static_cast(pDependencyFlags), &rgEditorElementEnum::HotKeyPressedSignal); - - // Set object name. - pDependencyFlags->setObjectName(STR_DEPENDENCY_FLAGS); - - // Connect to the enum list widget status signal. - isConnected = connect(pDependencyFlags, &rgEditorElement::EnumListWidgetStatusSignal, this, &rgPipelineStateModelVulkan::EnumListWidgetStatusSignal); - assert(isConnected); - - // Connect the shortcut hot key signal. - isConnected = connect(this, &rgPipelineStateModelVulkan::HotKeyPressedSignal, static_cast(pDependencyFlags), &rgEditorElementEnum::HotKeyPressedSignal); - assert(isConnected); - } - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateSearcher.cpp b/RadeonGPUAnalyzerGUI/Src/rgPipelineStateSearcher.cpp deleted file mode 100644 index 319a8e4..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateSearcher.cpp +++ /dev/null @@ -1,168 +0,0 @@ -// C++. -#include - -// Qt. -#include - -// Local. -#include -#include -#include - -// The value used to represent the state where a search doesn't return any results. -static const int s_INVALID_SEARCH_LOCATION = -1; - -rgPipelineStateSearcher::rgPipelineStateSearcher() - : m_lastFoundPosition(s_INVALID_SEARCH_LOCATION) -{ -} - -uint32_t rgPipelineStateSearcher::GetSupportedOptions() -{ - return - SupportedOptions::FindPrevious | - SupportedOptions::FindNext | - SupportedOptions::FilterTree | - SupportedOptions::MatchCase; -} - -bool rgPipelineStateSearcher::Find(const QString& searchString, SearchDirection direction) -{ - bool ret = SearchPsoTree(searchString, direction); - - // Select the search results in the view. - SelectResults(); - - return ret; -} - -void rgPipelineStateSearcher::ResetSearch() -{ - // Reset the currently-selected result index. - m_lastFoundPosition = s_INVALID_SEARCH_LOCATION; - - // Clear the existing search string and results. - m_searchString.clear(); - m_searchResults.m_resultOccurrences.clear(); - m_searchResults.m_selectedIndex = s_INVALID_SEARCH_LOCATION; - - // Select the search results in the view. - SelectResults(); -} - -void rgPipelineStateSearcher::SelectResults() -{ - // The PSO tree can potentially be resized or filtered as part of displaying search results. - // Processing all pending events will allow the tree to re-layout, and update the vertical - // scrollbar's minimum and maximum values. This is necessary to scroll to the proper result rows. - qApp->processEvents(); - - assert(m_pTargetView != nullptr); - if (m_pTargetView != nullptr) - { - // If the last search is invalid, remove the highlighted search row from the view. - if (m_lastFoundPosition == s_INVALID_SEARCH_LOCATION) - { - // Reset the highlighted search row since there are no results. - m_pTargetView->SetHighlightedSearchResults(m_searchResults); - - if (!m_searchResults.m_resultOccurrences.empty()) - { - m_lastFoundPosition = 0; - } - } - - // If the search found valid results, highlight the result. - if (m_lastFoundPosition != s_INVALID_SEARCH_LOCATION) - { - // Update the selected result index. - m_searchResults.m_selectedIndex = m_lastFoundPosition; - - // Verify that the search result index is valid. - bool isValidIndex = m_lastFoundPosition >= 0 && m_lastFoundPosition < m_searchResults.m_resultOccurrences.size(); - assert(isValidIndex); - if (isValidIndex) - { - // Highlight the row containing the search result, and scroll to it if necessary. - m_pTargetView->SetHighlightedSearchResults(m_searchResults); - - // Scroll to the current search result. - const OccurrenceLocation& currentOccurrence = m_searchResults.m_resultOccurrences[m_lastFoundPosition]; - assert(currentOccurrence.m_pResultRow != nullptr); - if (currentOccurrence.m_pResultRow != nullptr) - { - m_pTargetView->ScrollToRow(currentOccurrence.m_pResultRow); - } - } - } - } -} - -void rgPipelineStateSearcher::SetSearchOptions(const SearchOptions& options) -{ - m_searchResults.m_searchOptions = options; -} - -void rgPipelineStateSearcher::SetTargetModel(rgPipelineStateModel* pTargetModel) -{ - // Set the target model that will be searched. - m_pTargetModel = pTargetModel; -} - -void rgPipelineStateSearcher::SetTargetView(rgPipelineStateTree* pView) -{ - m_pTargetView = pView; -} - -bool rgPipelineStateSearcher::SearchPsoTree(const QString& searchString, SearchDirection direction) -{ - bool hasSearchResults = false; - - // If the search text changed, re-search. - if (m_searchString.compare(searchString) != 0) - { - // Reset the search before starting the next one. - ResetSearch(); - - // Only search if the target string is valid. - if (!searchString.isEmpty()) - { - // Update the search string. - m_searchString = searchString; - - // Search the target pipeline state model. - assert(m_pTargetModel != nullptr); - if (m_pTargetModel != nullptr) - { - m_pTargetModel->Search(m_searchString, m_searchResults); - } - } - } - - hasSearchResults = !m_searchResults.m_resultOccurrences.empty(); - if (hasSearchResults) - { - if (direction == ISearchable::SearchDirection::Previous) - { - // Step to the next result, looping back to the start if necessary. - m_lastFoundPosition--; - - if (m_lastFoundPosition < 0) - { - m_lastFoundPosition = static_cast(m_searchResults.m_resultOccurrences.size()) - 1; - } - } - else if (direction == ISearchable::SearchDirection::Next) - { - // Step to the next result, looping back to the start if necessary. - m_lastFoundPosition++; - - if (m_lastFoundPosition == m_searchResults.m_resultOccurrences.size()) - { - m_lastFoundPosition = 0; - } - } - } - - return hasSearchResults; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateTree.cpp b/RadeonGPUAnalyzerGUI/Src/rgPipelineStateTree.cpp deleted file mode 100644 index 186c42c..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateTree.cpp +++ /dev/null @@ -1,753 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include -#include - -// Local. -//#include -#include -#include -#include -#include - -// A stylesheet applied to the entire pipeline state tree. -static const QString s_PSO_TREE_STYLESHEET = "background-color: rgb(255, 255, 255, 255);"; - -rgPipelineStateTree::rgPipelineStateTree(QWidget* pParent) - : QScrollArea(pParent) -{ - ui.setupUi(this); - - // Apply the stylesheet to the custom tree widget. - this->setStyleSheet(s_PSO_TREE_STYLESHEET); - - // Enable mouse hover events for each row. - ui.scrollingPanel->setMouseTracking(true); -} - -void rgPipelineStateTree::keyPressEvent(QKeyEvent* pEvent) -{ - bool isKeyPressHandled = false; - - // Get a pointer to the currently selected row. - rgEditorElement* pSelectedRow = m_currentSelection.m_pSelectedRow; - - // Only handle key press events if there's a row already selected in the state tree. - assert(pEvent != nullptr); - if (pEvent != nullptr && pSelectedRow != nullptr) - { - if (pEvent->key() == Qt::Key_Left) - { - CollapseSelectedRow(); - - isKeyPressHandled = true; - } - else if (pEvent->key() == Qt::Key_Right) - { - ExpandSelectedRow(); - - isKeyPressHandled = true; - } - else if (pEvent->key() == Qt::Key_Up) - { - SelectPreviousRow(); - - isKeyPressHandled = true; - } - else if (pEvent->key() == Qt::Key_Down) - { - SelectNextRow(); - - isKeyPressHandled = true; - } - } - - if (!isKeyPressHandled) - { - // Invoke the base implementation. - QScrollArea::keyPressEvent(pEvent); - } -} - -void rgPipelineStateTree::CollapseSelectedRow() -{ - rgEditorElement* pSelectedRow = m_currentSelection.m_pSelectedRow; - assert(pSelectedRow != nullptr); - if (pSelectedRow != nullptr) - { - int numChildren = pSelectedRow->ChildCount(); - - // If the row is currently expanded, collapse it. - if (numChildren > 0 && pSelectedRow->GetExpansionState() == rgRowExpansionState::Expanded) - { - pSelectedRow->SetExpansionState(rgRowExpansionState::Collapsed); - } - else - { - // If the row is currently collapsed, select the parent row. - rgEditorElement* pParentElement = pSelectedRow->GetParentItem(); - if (pParentElement != nullptr) - { - // Select the parent row. - SetCurrentSelection(pParentElement, m_currentSelection.m_focusedColumn); - - // The parent element got selected, but it may not be visible. - // Scroll to the newly selected parent row if necessary. - ScrollToRow(pParentElement); - } - } - } -} - -void rgPipelineStateTree::ExpandSelectedRow() -{ - rgEditorElement* pSelectedRow = m_currentSelection.m_pSelectedRow; - assert(pSelectedRow != nullptr); - if (pSelectedRow != nullptr) - { - pSelectedRow->SetExpansionState(rgRowExpansionState::Expanded); - } -} - -rgEditorElement* rgPipelineStateTree::GetPreviousRow(rgEditorElement* pFrom) const -{ - rgEditorElement* pPreviousRow = nullptr; - - assert(pFrom != nullptr); - if (pFrom != nullptr && pFrom != m_pRootElement) - { - // Does the currently selected row have an index of 1 or more? - int rowIndex = pFrom->GetRowIndex(); - if (rowIndex >= 1) - { - rgEditorElement* pParentRow = pFrom->GetParentItem(); - if (pParentRow != nullptr) - { - // Find the oldest visible sibling. - for (int childIndex = rowIndex - 1; childIndex >= 0; childIndex--) - { - // Get the sibling element directly above the selected row. - rgEditorElement* pPreviousSibling = pParentRow->GetChild(childIndex); - assert(pPreviousSibling != nullptr); - if (pPreviousSibling != nullptr && pPreviousSibling->isVisible()) - { - // If the sibling is collapsed, stop searching and select the sibling. - int numChildren = pPreviousSibling->ChildCount(); - if (numChildren == 0 || pPreviousSibling->GetExpansionState() == rgRowExpansionState::Collapsed) - { - pPreviousRow = pPreviousSibling; - } - else - { - // Find the last descendant child of the previous sibling. - pPreviousRow = pPreviousSibling->GetLastVisibleDescendant(); - } - break; - } - } - - // If none of the older siblings are visible, revert to - // selecting the parent, which must be visible. - if (pPreviousRow == nullptr) - { - pPreviousRow = pParentRow; - } - } - } - else - { - // The row is the first child. Step up to the parent row. - rgEditorElement* pParentElement = pFrom->GetParentItem(); - assert(pParentElement != nullptr); - if (pParentElement != nullptr) - { - pPreviousRow = pParentElement; - } - } - } - - return pPreviousRow; -} - -rgEditorElement* rgPipelineStateTree::GetNextRow(rgEditorElement* pFrom) const -{ - rgEditorElement* pNextRow = nullptr; - - assert(pFrom != nullptr); - if (pFrom != nullptr) - { - // Does the currently selected row have any children? Is the current row expanded? - int numChildren = pFrom->ChildCount(); - rgRowExpansionState expandState = pFrom->GetExpansionState(); - if (numChildren > 0 && expandState == rgRowExpansionState::Expanded) - { - // Find the first visible child. - for (int childIndex = 0; childIndex < numChildren; ++childIndex) - { - rgEditorElement* pChild = pFrom->GetChild(childIndex); - assert(pChild != nullptr); - if (pChild != nullptr && pChild->isVisible()) - { - // Select the first non-filtered child. - pNextRow = pChild; - break; - } - } - } - else - { - // Need to find the first parent ancestor with a single child. - pNextRow = pFrom->FindNextAnscestor(); - } - } - - return pNextRow; -} - -void rgPipelineStateTree::SelectPreviousRow() -{ - if (m_currentSelection.m_pSelectedRow != nullptr) - { - // Get the row directly above the currently selected row. - rgEditorElement* pPreviousRow = GetPreviousRow(m_currentSelection.m_pSelectedRow); - - // Only select and scroll to the new row if necessary. - if (pPreviousRow != nullptr) - { - // Update the currently selected row. - SetCurrentSelection(pPreviousRow); - - // Scroll to the new row if necessary. - ScrollToRow(pPreviousRow); - } - } -} - -void rgPipelineStateTree::SelectNextRow() -{ - if (m_currentSelection.m_pSelectedRow != nullptr) - { - // Get the next row directly underneath the currently selected row. - rgEditorElement* pNextRow = GetNextRow(m_currentSelection.m_pSelectedRow); - - // Only select and scroll to the new row if necessary. - if (pNextRow != nullptr) - { - // Update the currently selected row. - SetCurrentSelection(pNextRow); - - // Scroll to the new row if necessary. - ScrollToRow(pNextRow); - } - } -} - -void rgPipelineStateTree::focusInEvent(QFocusEvent* pEvent) -{ - emit PipelineStateTreeFocusIn(); - - QScrollArea::focusInEvent(pEvent); -} - -void rgPipelineStateTree::focusOutEvent(QFocusEvent* pEvent) -{ - emit PipelineStateTreeFocusOut(); - - QScrollArea::focusOutEvent(pEvent); -} - -bool rgPipelineStateTree::focusNextPrevChild(bool next) -{ - bool res = false; - - rgEditorElement* pNextFocusRow = nullptr; - - // Only attempt to transfer focus if there's a selected row. - if (m_currentSelection.m_pSelectedRow != nullptr) - { - if (next) - { - // If advancing to the next item, find the row directly below the selected row. - pNextFocusRow = GetNextRow(m_currentSelection.m_pSelectedRow); - } - else - { - // If stepping backwards to the previous item, find the row above the selected row. - pNextFocusRow = GetPreviousRow(m_currentSelection.m_pSelectedRow); - } - - // Was the next row to focus on found? - if (pNextFocusRow != nullptr) - { - // Update the currently selected row to the next focused row. - SetCurrentSelection(pNextFocusRow); - - // Scroll to the new row if necessary. - ScrollToRow(pNextFocusRow); - - // Focus on the editor widget within the row (if one exists). - rgPipelineStateEditorWidget* pEditorWidget = pNextFocusRow->GetEditorWidget(); - if (pEditorWidget != nullptr) - { - // Successfully focused on the next focus target. - pEditorWidget->setFocus(); - res = true; - } - else - { - // Focus on the row itself if there is no editor widget. - pNextFocusRow->setFocus(); - } - } - } - else - { - // Invoke default handling to find the next focused widget. - res = QScrollArea::focusNextPrevChild(next); - } - - return res; -} - -const rgPipelineStateTree::CurrentSelection& rgPipelineStateTree::GetCurrentSelection() const -{ - return m_currentSelection; -} - -rgEditorElement* rgPipelineStateTree::GetRootItem() const -{ - return m_pRootElement; -} - -bool rgPipelineStateTree::ComputeVerticalOffset(rgEditorElement* pRootElement, rgEditorElement* pTargetRow, int& offset) -{ - bool ret = false; - - assert(pRootElement != nullptr); - assert(pTargetRow != nullptr); - if (pRootElement != nullptr && pTargetRow != nullptr) - { - // We found the target row to count up to- we're done iterating. - if (pRootElement == pTargetRow) - { - ret = true; - } - else - { - // Add the height of the current row to the vertical offset. - offset += pRootElement->GetRowHeight(); - - // Only take child rows into account if the parent row is expanded and not filtered out. - if (pRootElement->GetExpansionState() == rgRowExpansionState::Expanded && - !pRootElement->m_isFilteredOut) - { - int numChildren = pRootElement->ChildCount(); - for (int childIndex = 0; childIndex < numChildren; ++childIndex) - { - // Recursively add child height to the vertical offset. - rgEditorElement* pChild = pRootElement->GetChild(childIndex); - ret = ComputeVerticalOffset(pChild, pTargetRow, offset); - if (ret) - { - break; - } - } - } - } - } - - return ret; -} - -void rgPipelineStateTree::ScrollToRow(rgEditorElement* pRow) -{ - assert(pRow != nullptr); - if (pRow != nullptr) - { - // Update the vertical scrollbar's position to bring the target widget into view. - QScrollBar* pVerticalScrollbar = this->verticalScrollBar(); - assert(pVerticalScrollbar != nullptr); - if (pVerticalScrollbar != nullptr) - { - // What's the current scroll position? What's the vertical extent of the rows that are - // currently being displayed? - int visibleTreeHeight = this->height(); - int currentSliderPosition = pVerticalScrollbar->sliderPosition(); - int currentVerticalExtentShown = currentSliderPosition + visibleTreeHeight; - - // Compute the vertical offset for the given row item. - int verticalOffset = 0; - ComputeVerticalOffset(m_pRootElement, pRow, verticalOffset); - - int elementHeight = pRow->GetRowHeight(); - - // Scroll the tree only when the target element is not currently visible, and scrolling - // is necessary to bring the target element into view. - bool isScrollingUp = verticalOffset < currentSliderPosition; - bool isScrollingDown = verticalOffset + elementHeight > currentVerticalExtentShown; - if (isScrollingUp) - { - // When scrolling up, set the slider to the vertical offset of the target row. - pVerticalScrollbar->setSliderPosition(verticalOffset); - } - else if (isScrollingDown) - { - int currentPosition = pVerticalScrollbar->sliderPosition(); - - // Is there a big difference between the current scroll position and the new one? - if (verticalOffset - currentPosition > visibleTreeHeight) - { - // If the gap is large enough, snap the scrollbar to the row. - pVerticalScrollbar->setSliderPosition(verticalOffset); - } - else - { - // When scrolling down, offset the slider position by the height of the row. - // This results in sliding the lower row into view at the bottom of the tree. - pVerticalScrollbar->setSliderPosition(currentPosition + elementHeight); - } - } - } - } -} - -void rgPipelineStateTree::SetHighlightedSearchResults(const rgPipelineStateSearcher::SearchResultData& searchResults) -{ - // Save the search results. - m_previousSearcherResults = m_searcherResults; - - // Update the search results structure. - m_searcherResults = searchResults; - - // Update the highlight state of all rows in the tree. - UpdateRowsWithSearchResults(m_pRootElement); -} - -void rgPipelineStateTree::SetRootItem(rgEditorElement* pItem) -{ - assert(pItem != nullptr); - if (pItem != nullptr) - { - // Erase knowledge of the current element, since it will be deleted shortly. - SetCurrentSelection(nullptr); - - // Replace the current root element with the provided element. - m_pRootElement = pItem; - - // Set the root element's parent state tree, so that all elements in the tree - // are aware of the widget they are ultimately parented to in the hierarchy. - m_pRootElement->SetParentStateTree(this); - - QVBoxLayout* pVerticalLayout = static_cast(ui.scrollingPanel->layout()); - assert(pVerticalLayout != nullptr); - if (pVerticalLayout != nullptr) - { - // When a root element has already been inserted, there are two children attached to - // the scrolling panel. One is the root element of the tree to be removed, and the - // other is a spacer used to push all elements up. Remove and destroy the original root - // element before inserting the new root element above the spacer. - if (ui.scrollingPanel->children().size() == 2) - { - QLayoutItem* pRootLayout = pVerticalLayout->takeAt(0); - if (pRootLayout != nullptr) - { - // Destroy the existing root element. - QWidget* pRootItem = pRootLayout->widget(); - if (pRootItem != nullptr) - { - pVerticalLayout->removeWidget(pRootItem); - RG_SAFE_DELETE(pRootItem); - } - } - } - - // Add the given root tree item to the scrolling panel above the spacer. - pVerticalLayout->insertWidget(0, m_pRootElement); - - // Initialize all rows in the tree. - m_pRootElement->InitializeRows(); - } - } -} - -// A predicate used to find the given rgEditorElement within a list. -struct rgRowSearcher -{ - rgRowSearcher(rgEditorElement* m_pElement) : m_pElement(m_pElement) { } - - // Check if the occurrence matches the target row. - bool operator()(const rgPipelineStateSearcher::OccurrenceLocation& occurrence) const - { - return occurrence.m_pResultRow == m_pElement; - } - - // The element to search for. - rgEditorElement* m_pElement = nullptr; -}; - -void rgPipelineStateTree::ClearPreviousSearchResults(rgEditorElement* pRootElement) -{ - auto firstOccurrence = m_previousSearcherResults.m_resultOccurrences.begin(); - auto lastOccurrence = m_previousSearcherResults.m_resultOccurrences.end(); - - // Update the "is filtered" flag for each row. Don't filter anything if there aren't any search results. - bool isFilteringEnabled = m_previousSearcherResults.m_searchOptions.m_filterTree && - !m_previousSearcherResults.m_resultOccurrences.empty(); - assert(pRootElement != nullptr); - if (pRootElement != nullptr) - { - pRootElement->m_isFilteredOut = isFilteringEnabled; - - // Try to find the given element within the list of search results. - rgRowSearcher searcher(pRootElement); - auto occurrenceIter = std::find_if(firstOccurrence, lastOccurrence, searcher); - - // Iterate over m_searcherResults.m_resultOccurrences and highlight every - // occurrence found on the current line. - int count = 0; - while (occurrenceIter != lastOccurrence) - { - if (occurrenceIter != lastOccurrence) - { - pRootElement->m_isFilteredOut = false; - - // Highlight the sub string in various columns. - if ((*occurrenceIter).m_rowDataIndex == static_cast(rgRowData::RowDataMemberName)) - { - // Column zero is occupied by a QLabel. - // Find and reset the substring in a QLabel. - pRootElement->ResetLabelSubString(); - } - else if ((*occurrenceIter).m_rowDataIndex == static_cast(rgRowData::RowDataMemberValue)) - { - // Check to see if this is a button or a numeric editor. - rgPipelineStateEditorWidgetEnum* pElement = qobject_cast(pRootElement); - if (pElement != nullptr) - { - pRootElement->ResetButtonSubString(); - } - else - { - pRootElement->ResetLineEditSubString(); - } - } - } - - // Find the next occurrence. - occurrenceIter = std::find_if(occurrenceIter + 1, lastOccurrence, searcher); - count++; - } - } -} - -void rgPipelineStateTree::UpdateRowsWithSearchResults(rgEditorElement* pRootElement) -{ - // First clear any previously highlighted search results. - ClearPreviousSearchResults(pRootElement); - - auto firstOccurrence = m_searcherResults.m_resultOccurrences.begin(); - auto lastOccurrence = m_searcherResults.m_resultOccurrences.end(); - - // Update the "is filtered" flag for each row. Don't filter anything if there aren't any search results. - bool isFilteringEnabled = m_searcherResults.m_searchOptions.m_filterTree && - !m_searcherResults.m_resultOccurrences.empty(); - pRootElement->m_isFilteredOut = isFilteringEnabled; - - // Try to find the given element within the list of search results. - rgRowSearcher searcher(pRootElement); - auto occurrenceIter = std::find_if(firstOccurrence, lastOccurrence, searcher); - - // Clear the previous search string data. - pRootElement->ClearSearchStringData(); - - // Iterate over m_searcherResults.m_resultOccurrences and highlight every - // occurrence found on the current line. - int prevDataIndex = 0; - if (occurrenceIter != lastOccurrence) - { - prevDataIndex = occurrenceIter->m_rowDataIndex; - } - - while (occurrenceIter != lastOccurrence) - { - bool isCurrentMatch = false; - if (occurrenceIter != lastOccurrence) - { - pRootElement->m_isFilteredOut = false; - - // Highlight the current match vs other matches. - int occurrenceIndex = (occurrenceIter - firstOccurrence); - if (occurrenceIndex == m_searcherResults.m_selectedIndex) - { - // The current result is being focused on. - isCurrentMatch = true; - } - else - { - // This search result is only a single occurrence that needs to - // be highlighted- it's not the current result. - isCurrentMatch = false; - } - - // Highlight the row with the current match. - if (isCurrentMatch) - { - int columnIndex = m_searcherResults.m_resultOccurrences[occurrenceIndex].m_rowDataIndex; - SetCurrentSelection(pRootElement, columnIndex, false); - } - - // Highlight the sub string in various columns. - if ((*occurrenceIter).m_rowDataIndex == static_cast(rgRowData::RowDataMemberName)) - { - // Column zero is occupied by a QLabel. - // Find and highlight the substring in a QLabel. - pRootElement->HighlightLabelSubString((*occurrenceIter).m_characterIndex, m_searcherResults.m_searchString, isCurrentMatch); - } - else if ((*occurrenceIter).m_rowDataIndex == static_cast(rgRowData::RowDataMemberValue)) - { - // Check to see if this is a button or a numeric editor. - rgEditorElementEnum* pElement = qobject_cast(pRootElement); - if (pElement != nullptr) - { - pRootElement->HighlightButtonSubString((*occurrenceIter).m_characterIndex, m_searcherResults.m_searchString, isCurrentMatch); - } - else - { - pRootElement->HighlightLineEditSubString((*occurrenceIter).m_characterIndex, m_searcherResults.m_searchString, isCurrentMatch); - } - } - } - - prevDataIndex = occurrenceIter->m_rowDataIndex; - occurrenceIter = std::find_if(occurrenceIter + 1, lastOccurrence, searcher); - - // Clear the previous search string data, process the next match. - if (occurrenceIter != lastOccurrence) - { - if (prevDataIndex != occurrenceIter->m_rowDataIndex) - { - pRootElement->ClearSearchStringDataVector(); - } - } - } - - // If filtering is enabled, determine if the row should be visible or hidden. - if (isFilteringEnabled) - { - if (!pRootElement->m_isFilteredOut) - { - // If the current row is included in the filtered search results, - // expand and make visible all parent ancestors. - pRootElement->SetExpansionState(rgRowExpansionState::Expanded); - SetAncestorsVisible(pRootElement); - } - else - { - // Hide the row if it's not relevant in the filtered search results. - pRootElement->hide(); - } - } - else - { - // If filtering is not enabled, all rows should be visible. - pRootElement->show(); - pRootElement->SetExpansionState(rgRowExpansionState::Expanded); - } - - // Traverse to each child element. - int numChildren = pRootElement->ChildCount(); - for (int childIndex = 0; childIndex < numChildren; ++childIndex) - { - // Update each child element. - rgEditorElement* pChild = pRootElement->GetChild(childIndex); - UpdateRowsWithSearchResults(pChild); - } -} - -void rgPipelineStateTree::SetAncestorsVisible(rgEditorElement* pElement) -{ - if (pElement != nullptr) - { - rgEditorElement* pParent = pElement->GetParentItem(); - if (pParent != nullptr) - { - // Make the parent visible and expanded. - pParent->show(); - pParent->SetExpansionState(rgRowExpansionState::Expanded); - - // Update parent visibility recursively up to the root element. - SetAncestorsVisible(pParent); - } - } -} - -bool rgPipelineStateTree::eventFilter(QObject* pObject, QEvent* pEvent) -{ - Q_UNUSED(pObject); - - bool isFiltered = false; - - if (pEvent != nullptr) - { - if (pEvent->type() == QEvent::Type::Wheel) - { - // If any of the drop downs are open, ignore the wheel event. - if (m_isListWidgetOpen) - { - isFiltered = true; - } - } - } - - return isFiltered; -} - -void rgPipelineStateTree::SetEnumListWidgetStatus(bool isOpen) -{ - m_isListWidgetOpen = isOpen; - - // Enable/disable the scrollbars. - if (isOpen) - { - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - } - else - { - setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - } -} - -void rgPipelineStateTree::SetCurrentSelection(rgEditorElement* pElement, int column, bool setFocus) -{ - // If there's already a current element, deselect it. - if (m_currentSelection.m_pSelectedRow != nullptr) - { - m_currentSelection.m_pSelectedRow->RemoveStyleFlag(rgStyleFlags::CurrentRow); - } - - // If the new element is valid, select it. - if (pElement != nullptr) - { - pElement->AddStyleFlag(rgStyleFlags::CurrentRow); - } - - m_currentSelection.m_pSelectedRow = pElement; - m_currentSelection.m_focusedColumn = column; - - if (setFocus && pElement != nullptr) - { - if (column != -1) - { - // Focus on the given column. - pElement->SetFocusedColumn(static_cast(column)); - } - else - { - // Focus on the overall row to allow arrow key navigation. - pElement->setFocus(); - } - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateView.cpp b/RadeonGPUAnalyzerGUI/Src/rgPipelineStateView.cpp deleted file mode 100644 index 2ae46c9..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgPipelineStateView.cpp +++ /dev/null @@ -1,331 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include - -// Infra. -#include -#include - -// Local. -#include -#include -#include -#include -#include - -rgPipelineStateView::rgPipelineStateView(QWidget* pParent) : - rgSettingsView(pParent) -{ - // Initialize the generated view object. - ui.setupUi(this); - - // Block recursively repolishing all child widgets within the PSO tree. - ui.settingsTree->setProperty(gs_IS_REPOLISHING_BLOCKED, true); - - // Connect interface signals. - ConnectSignals(); - - // Set button cursor to pointing hand cursor. - ui.saveButton->setCursor(Qt::PointingHandCursor); - ui.loadButton->setCursor(Qt::PointingHandCursor); - - // Enable drag and drop. - setAcceptDrops(true); - - // Set focus policy. - setFocusPolicy(Qt::FocusPolicy::StrongFocus); -} - -void rgPipelineStateView::ScaleSettingsTree() -{ - // Unregister/Register this object with the scaling manager. - ScalingManager::Get().UnregisterObject(this); - ScalingManager::Get().RegisterObject(this); -} - -void rgPipelineStateView::resizeEvent(QResizeEvent* pEvent) -{ - QWidget::resizeEvent(pEvent); - - emit EditorResized(); -} - -void rgPipelineStateView::hideEvent(QHideEvent* pEvent) -{ - QWidget::hideEvent(pEvent); - - emit EditorHidden(); -} - -rgPipelineStateSearcher* rgPipelineStateView::GetSearcher() const -{ - return m_pPipelineStateSearcher; -} - -bool rgPipelineStateView::GetSelectedText(std::string& selectedTextString) const -{ - bool ret = false; - - // Is there a current selection in the table? - const rgPipelineStateTree::CurrentSelection& selectedRow = ui.settingsTree->GetCurrentSelection(); - if (selectedRow.m_pSelectedRow != nullptr) - { - int columnIndex = selectedRow.m_focusedColumn; - - if (columnIndex != -1) - { - // Return the data stored in the first selected model index. - QVariant selectedData = selectedRow.m_pSelectedRow->Data(columnIndex); - selectedTextString = selectedData.toString().toStdString(); - - // If the user selected the left column containing member names, treat it differently. - // In this case, we'll trim off the leading array index from the output string. - if (selectedRow.m_pSelectedRow->GetType() == rgEditorDataType::ArrayElement && columnIndex == static_cast(rgRowData::RowDataMemberName)) - { - - // Find the first space in the string- the array index number directly precedes it. - size_t spaceOffset = selectedTextString.find_first_of(' '); - if (spaceOffset != std::string::npos) - { - selectedTextString = selectedTextString.substr(spaceOffset + 1); - } - } - - // Return true since data was extracted from the selected index. - ret = true; - } - } - - return ret; -} - -void rgPipelineStateView::InitializeModel(rgPipelineStateModel* pPipelineStateModel) -{ - m_pipelineType = pPipelineStateModel->GetPipelineType(); - - // Bind the provided pipeline state model to the settings tree view. - assert(pPipelineStateModel != nullptr); - if (pPipelineStateModel != nullptr) - { - // Set the model root element into the tree. - rgEditorElement* pModelRootItem = pPipelineStateModel->GetRootElement(); - ui.settingsTree->SetRootItem(pModelRootItem); - - // Create the pipeline state tree searcher instance. - m_pPipelineStateSearcher = new rgPipelineStateSearcher(); - - // Attach a pipeline searcher instance to be used by the find widget. - assert(m_pPipelineStateSearcher != nullptr); - if (m_pPipelineStateSearcher != nullptr) - { - m_pPipelineStateSearcher->SetTargetModel(pPipelineStateModel); - m_pPipelineStateSearcher->SetTargetView(ui.settingsTree); - } - - // Connect the expand node handler. - bool isConnected = connect(pPipelineStateModel, &rgPipelineStateModel::ExpandNode, this, &rgPipelineStateView::HandleNodeExpanded); - assert(isConnected); - - // Update the label depending on pipeline type. - if (m_pipelineType == rgPipelineType::Graphics) - { - ui.labelPipelineType->setText(QString(STR_PIPELINE_STATE_EDITOR_LABEL_GRAPHICS) + QString(STR_PIPELINE_STATE_EDITOR_LABEL_HELP)); - } - else if (m_pipelineType == rgPipelineType::Compute) - { - ui.labelPipelineType->setText(QString(STR_PIPELINE_STATE_EDITOR_LABEL_COMPUTE) + QString(STR_PIPELINE_STATE_EDITOR_LABEL_HELP)); - } - else - { - // Should not get here. - assert(false); - } - } -} - -void rgPipelineStateView::ResetSearch() -{ - assert(m_pPipelineStateSearcher != nullptr); - if (m_pPipelineStateSearcher != nullptr) - { - m_pPipelineStateSearcher->ResetSearch(); - } -} - -void rgPipelineStateView::HandleNodeExpanded(rgEditorElementArrayElementAdd* pArrayRoot) -{ - assert(pArrayRoot != nullptr); - if (pArrayRoot != nullptr) - { - // Expand the given row. - pArrayRoot->SetExpansionState(rgRowExpansionState::Expanded); - } -} - -void rgPipelineStateView::HandlePsoFileLoaded() -{ - rgEditorElement* pRootElement = ui.settingsTree->GetRootItem(); - - assert(pRootElement != nullptr); - if (pRootElement != nullptr) - { - // Recursively expand all nodes after loading the new file. - pRootElement->SetExpansionState(rgRowExpansionState::Expanded, true); - } -} - -void rgPipelineStateView::ConnectSignals() -{ - // Connect the save button handler. - bool isConnected = connect(ui.saveButton, &QPushButton::clicked, this, &rgPipelineStateView::SaveButtonClicked); - assert(isConnected); - - // Connect the load button handler. - isConnected = connect(ui.loadButton, &QPushButton::clicked, this, &rgPipelineStateView::LoadButtonClicked); - assert(isConnected); - - // Connect the settings tree in focus signals. - isConnected = connect(ui.settingsTree, &rgPipelineStateTree::PipelineStateTreeFocusIn, this, &rgPipelineStateView::PipelineStateTreeFocusIn); - assert(isConnected); - - // Connect the settings tree out of focus signals. - isConnected = connect(ui.settingsTree, &rgPipelineStateTree::PipelineStateTreeFocusOut, this, &rgPipelineStateView::PipelineStateTreeFocusOut); - assert(isConnected); -} - -void rgPipelineStateView::focusInEvent(QFocusEvent* pEvent) -{ - emit PipelineStateTreeFocusIn(); -} - -void rgPipelineStateView::focusOutEvent(QFocusEvent* pEvent) -{ - emit PipelineStateTreeFocusOut(); -} - -void rgPipelineStateView::SetInitialWidgetFocus() -{ - assert(ui.settingsTree != nullptr); - if (ui.settingsTree != nullptr) - { - // Focus on the PSO tree widget within the PSO editor view. - ui.settingsTree->setFocus(); - - // Is there already a row selected in the tree? If not, select the first row. - const rgPipelineStateTree::CurrentSelection& selection = ui.settingsTree->GetCurrentSelection(); - if (selection.m_pSelectedRow == nullptr) - { - // Get the root element of the tree in order to select the first row. - rgEditorElement* pRootElement = ui.settingsTree->GetRootItem(); - assert(pRootElement != nullptr); - if (pRootElement != nullptr) - { - // Set the selection in the PSO tree. - ui.settingsTree->SetCurrentSelection(pRootElement); - } - } - } -} - -void rgPipelineStateView::dragEnterEvent(QDragEnterEvent* pEvent) -{ - assert(pEvent != nullptr); - if (pEvent != nullptr) - { - const QMimeData* pMimeData = pEvent->mimeData(); - assert(pMimeData != nullptr); - if (pMimeData != nullptr) - { - const int numFiles = pMimeData->urls().size(); - - // Make sure the drop data has only one file url, and is a valid file. - if (pMimeData->hasUrls() && (numFiles == 1)) - { - // Check to make sure the file is valid. - QUrl url = pMimeData->urls().at(0); - - // Verify we have the correct file for the current pipeline type. - bool validFile = false; - QString extension; - const QString filePath = url.toLocalFile(); - QStringList nameExtension = filePath.split(STR_FILE_EXTENSION_DELIMITER); - assert(nameExtension.size() == 2); - if (nameExtension.size() == 2) - { - extension = filePath.split(".").at(1); - if (m_pipelineType == rgPipelineType::Graphics && extension.compare(STR_DEFAULT_PIPELINE_FILE_EXTENSION_NAME_GRAPHICS) == 0) - { - validFile = true; - } - else if (m_pipelineType == rgPipelineType::Compute && extension.compare(STR_DEFAULT_PIPELINE_FILE_EXTENSION_NAME_COMPUTE) == 0) - { - validFile = true; - } - - if (url.isLocalFile() && validFile) - { - // Accept the action, making it so we receive a dropEvent when the items are released. - pEvent->setDropAction(Qt::DropAction::CopyAction); - pEvent->accept(); - } - else - { - pEvent->ignore(); - } - } - else - { - pEvent->ignore(); - } - } - else - { - pEvent->ignore(); - } - } - } -} - -void rgPipelineStateView::dropEvent(QDropEvent* pEvent) -{ - assert(pEvent != nullptr); - if (pEvent != nullptr) - { - const QMimeData* pMimeData = pEvent->mimeData(); - assert(pMimeData != nullptr); - if (pMimeData != nullptr) - { - // Make sure the drop data has a file. - if (pMimeData->hasUrls()) - { - // Check to make sure the file is valid. - QUrl url = pMimeData->urls().at(0); - if (url.isLocalFile()) - { - // Get the file path. - std::string filePath = url.toLocalFile().toStdString(); - - // Emit a signal to open an existing PSO file. - emit DragAndDropExistingFile(filePath); - } - } - else - { - pEvent->ignore(); - } - } - } -} - -void rgPipelineStateView::InsertFindWidget(QWidget* pWidget) -{ - ui.gridLayout->addWidget(pWidget, 0, 1, Qt::AlignTop); -} - -void rgPipelineStateView::SetEnumListWidgetStatus(bool isOpen) -{ - ui.settingsTree->SetEnumListWidgetStatus(isOpen); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgPreprocessorDirectivesDialog.cpp b/RadeonGPUAnalyzerGUI/Src/rgPreprocessorDirectivesDialog.cpp deleted file mode 100644 index 709aa4b..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgPreprocessorDirectivesDialog.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// C++. -#include - -// Local. -#include -#include -#include - -rgPreprocessorDirectivesDialog::rgPreprocessorDirectivesDialog(const char* pDelimiter, QWidget* pParent) : - rgOrderedListDialog(pDelimiter, pParent) -{ - // Set the window title. - setWindowTitle(STR_PREPROCESSOR_DIRECTIVES_DIALOG_TITLE); - - // Update various buttons. - UpdateButtons(); -} - -void rgPreprocessorDirectivesDialog::OnListItemChanged(QListWidgetItem* pItem) -{ - // Block signals from the list widget. - ui.itemsList->blockSignals(true); - - m_editingInvalidEntry = false; - - // Process the newly-entered data. - if (pItem != nullptr) - { - QString newMacro = pItem->text(); - - bool isDuplicateItem = m_itemsList.contains(newMacro); - bool isContainsWhitespace = rgUtils::IsContainsWhitespace(newMacro.toStdString()); - - // If the new macro exists, and it is not a duplicate entry, update local data. - if (newMacro.isEmpty()) - { - // The user has emptied out the entry, so delete it. - // Simulate a click on the delete button to remove the entry from the UI. - ui.deletePushButton->click(); - } - else - { - if (isDuplicateItem || isContainsWhitespace) - { - // Display an error message box. - std::stringstream errorString; - if (isDuplicateItem) - { - errorString << STR_PREPROCESSOR_DIRECTIVES_DIALOG_DIRECTIVE_IS_DUPLICATE; - errorString << newMacro.toStdString().c_str(); - } - else if (isContainsWhitespace) - { - errorString << STR_PREPROCESSOR_DIRECTIVES_DIALOG_DIRECTIVE_CONTAINS_WHITESPACE; - errorString << newMacro.toStdString().c_str(); - } - - rgUtils::ShowErrorMessageBox(errorString.str().c_str(), this); - m_editingInvalidEntry = true; - } - - // Update local data. - int itemRow = ui.itemsList->row(pItem); - if (itemRow < m_itemsList.count()) - { - m_itemsList[itemRow] = newMacro; - } - else - { - m_itemsList.append(newMacro); - } - } - - // Update tool tips. - UpdateToolTips(); - - // Unblock signals from the list widget. - ui.itemsList->blockSignals(false); - - // Update buttons. - UpdateButtons(); - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgRecentProjectWidget.cpp b/RadeonGPUAnalyzerGUI/Src/rgRecentProjectWidget.cpp deleted file mode 100644 index bfda5e4..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgRecentProjectWidget.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// C++. -#include - -// Qt. -#include - -// Local. -#include "rgRecentProjectWidget.h" - -const static QString s_PROJECT_BUTTON_STYLESHEET( - "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 s_API_ICON_WIDTH = 50; -static const int s_API_ICON_HEIGHT = 25; - -rgRecentProjectWidget::rgRecentProjectWidget(QWidget* pParent) : - QWidget(pParent), - m_pProjectButton(new QPushButton(this)) -{ - m_pHorizontalLayout = new QHBoxLayout(this); - m_pHorizontalLayout->setContentsMargins(0, 0, 0, 0); - m_pHorizontalLayout->setSpacing(5); - - // Additional settings for the project button. - QSizePolicy policy(QSizePolicy::Fixed, QSizePolicy::Fixed); - m_pProjectButton->setSizePolicy(policy); - m_pProjectButton->setCursor(Qt::PointingHandCursor); - - // Create a button to hold the icon. - m_pIconButton = new QPushButton(this); - - m_pHorizontalLayout->addWidget(m_pProjectButton); - m_pHorizontalLayout->addWidget(m_pIconButton); - - m_pProjectButton->setStyleSheet(s_PROJECT_BUTTON_STYLESHEET); - m_pIconButton->setStyleSheet(s_PROJECT_BUTTON_STYLESHEET); - m_pIconButton->setFocusPolicy(Qt::NoFocus); - - // Set the icon size. - QSize size(s_API_ICON_WIDTH, s_API_ICON_HEIGHT); - m_pIconButton->setIconSize(size); -} - -void rgRecentProjectWidget::SetProjectName(const QString& fileName) -{ - // Set project button text. - assert(m_pProjectButton != nullptr); - if (m_pProjectButton != nullptr) - { - m_pProjectButton->setText(fileName); - } -} - -void rgRecentProjectWidget::SetIcon(QIcon icon) -{ - // Set the icon. - assert(m_pIconButton != nullptr); - if (m_pIconButton != nullptr) - { - m_pIconButton->setIcon(QIcon(icon)); - } -} - -void rgRecentProjectWidget::SetIconProjectType(const char* projectType) -{ - QString projectTypeString = projectType; - - // Set the icon project type. - assert(m_pIconButton != nullptr); - if (m_pIconButton != nullptr) - { - m_pIconButton->setObjectName(projectTypeString); - } -} - -QString rgRecentProjectWidget::GetProjectName() const -{ - QString projectName = ""; - - assert(m_pProjectButton != nullptr); - if (m_pProjectButton != nullptr) - { - projectName = m_pProjectButton->text(); - } - - return projectName; -} - -QString rgRecentProjectWidget::GetIconProjectType() const -{ - QString projectType = ""; - - assert(m_pIconButton != nullptr); - if (m_pIconButton != nullptr) - { - projectType = m_pIconButton->objectName(); - } - - return projectType; -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgRenameProjectDialog.cpp b/RadeonGPUAnalyzerGUI/Src/rgRenameProjectDialog.cpp deleted file mode 100644 index b6b1243..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgRenameProjectDialog.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// C++. -#include -#include -#include - -// Qt. -#include - -// Local. -#include -#include -#include - -rgRenameProjectDialog::rgRenameProjectDialog(std::string& projectName, QWidget* pParent) : - m_projectName(projectName), QDialog(pParent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint) -{ - // 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. - m_projectName = rgUtils::GenerateDefaultProjectName(); - ui.lineEditProjectName->setText(m_projectName.c_str()); - ui.lineEditProjectName->setFocus(); - - // Read the use default project name value and update the check box. - std::shared_ptr pGlobalConfig = rgConfigManager::Instance().GetGlobalConfig(); - if (pGlobalConfig != nullptr) - { - ui.projectNameCheckBox->setChecked(pGlobalConfig->m_useDefaultProjectName); - } - - // Set the tool tip for default project name check box. - SetCheckboxToolTip(STR_GLOBAL_SETTINGS_CHECKBOX_TOOLTIP); - - // Disable resizing of this dialog. - setFixedSize(size()); - - // Connect signals. - ConnectSignals(); - - // Set the cursor type. - SetCursor(Qt::PointingHandCursor); -} - -void rgRenameProjectDialog::ConnectSignals() -{ - // Connect the OK button. - bool isConnected = connect(this->ui.okPushButton, &QPushButton::clicked, this, &rgRenameProjectDialog::HandleOKButtonClicked); - assert(isConnected); - - // Connect the Cancel button. - isConnected = connect(this->ui.cancelPushButton, &QPushButton::clicked, this, &rgRenameProjectDialog::HandleCancelButtonClicked); - assert(isConnected); -} - -void rgRenameProjectDialog::accept() -{ - // Trim the leading and trailing whitespace characters from the project name. - std::string projectName = ui.lineEditProjectName->text().toStdString(); - rgUtils::TrimLeadingAndTrailingWhitespace(projectName, projectName); - - // Input validation. - if (rgUtils::IsValidProjectName(projectName)) - { - // Save the project name. - m_projectName = projectName; - - // Save the default project name check box value. - bool checked = ui.projectNameCheckBox->checkState() == Qt::Checked; - std::shared_ptr pGlobalConfig = rgConfigManager::Instance().GetGlobalConfig(); - if (pGlobalConfig != nullptr) - { - pGlobalConfig->m_useDefaultProjectName = checked; - rgConfigManager::Instance().SaveGlobalConfigFile(); - } - - QDialog::accept(); - } - else - { - // Notify the user that the project name is illegal. - std::stringstream msg; - msg << STR_ERR_ILLEGAL_PROJECT_NAME <<" \""; - msg << projectName << "\"."; - rgUtils::ShowErrorMessageBox(msg.str().c_str(), this); - } -} - -void rgRenameProjectDialog::SetCheckboxToolTip(const std::string& text) -{ - ui.projectNameCheckBox->setToolTip(text.c_str()); -} - -void rgRenameProjectDialog::HandleOKButtonClicked(bool /* checked */) -{ - this->accept(); -} - -void rgRenameProjectDialog::HandleCancelButtonClicked(bool /* checked */) -{ - this->reject(); -} - -void rgRenameProjectDialog::SetCursor(const QCursor& cursor) -{ - this->ui.okPushButton->setCursor(cursor); - this->ui.cancelPushButton->setCursor(cursor); -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgResourceUsageCsvFileParser.cpp b/RadeonGPUAnalyzerGUI/Src/rgResourceUsageCsvFileParser.cpp deleted file mode 100644 index ec9675b..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgResourceUsageCsvFileParser.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// C++. -#include - -// Local. -#include - -bool rgResourceUsageCsvFileParser::ProcessLineTokens(const std::vector& tokens) -{ - bool ret = false; - - // Verify that the number of tokens matches the number of columns in the file being parsed. - int numTokens = static_cast(tokens.size()); - assert(numTokens == rgResourceUsageCsvFileColumns::Count); - if (numTokens == rgResourceUsageCsvFileColumns::Count) - { - // Extract all info from the file's line tokens. - m_resourceUsageData.m_device = tokens[rgResourceUsageCsvFileColumns::Device]; - m_resourceUsageData.m_scratchMemory = std::atoi(tokens[rgResourceUsageCsvFileColumns::ScratchMemory].c_str()); - m_resourceUsageData.m_threadsPerWorkgroup = std::atoi(tokens[rgResourceUsageCsvFileColumns::ThreadsPerWorkgroup].c_str()); - m_resourceUsageData.m_wavefrontSize = std::atoi(tokens[rgResourceUsageCsvFileColumns::WavefrontSize].c_str()); - m_resourceUsageData.m_availableLdsBytes = std::atoi(tokens[rgResourceUsageCsvFileColumns::AvailableLdsBytes].c_str()); - m_resourceUsageData.m_usedLdsBytes = std::atoi(tokens[rgResourceUsageCsvFileColumns::UsedLdsBytes].c_str()); - m_resourceUsageData.m_availableSgprs = std::atoi(tokens[rgResourceUsageCsvFileColumns::AvailableSgprs].c_str()); - m_resourceUsageData.m_usedSgprs = std::atoi(tokens[rgResourceUsageCsvFileColumns::UsedSgprs].c_str()); - m_resourceUsageData.m_sgprSpills = std::atoi(tokens[rgResourceUsageCsvFileColumns::SgprSpills].c_str()); - m_resourceUsageData.m_availableVgprs = std::atoi(tokens[rgResourceUsageCsvFileColumns::AvailableVgprs].c_str()); - m_resourceUsageData.m_usedVgprs = std::atoi(tokens[rgResourceUsageCsvFileColumns::UsedVgprs].c_str()); - m_resourceUsageData.m_vgprSpills = std::atoi(tokens[rgResourceUsageCsvFileColumns::VgprSpills].c_str()); - m_resourceUsageData.m_clWorkgroupXDimension = std::atoi(tokens[rgResourceUsageCsvFileColumns::ClWorkgroupXDimension].c_str()); - m_resourceUsageData.m_clWorkgroupYDimension = std::atoi(tokens[rgResourceUsageCsvFileColumns::ClWorkgroupYDimension].c_str()); - m_resourceUsageData.m_clWorkgroupZDimension = std::atoi(tokens[rgResourceUsageCsvFileColumns::ClWorkgroupZDimension].c_str()); - m_resourceUsageData.m_isaSize = std::atoi(tokens[rgResourceUsageCsvFileColumns::IsaSize].c_str()); - ret = true; - } - - return ret; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgResourceUsageView.cpp b/RadeonGPUAnalyzerGUI/Src/rgResourceUsageView.cpp deleted file mode 100644 index fa9cf92..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgResourceUsageView.cpp +++ /dev/null @@ -1,173 +0,0 @@ -// C++. -#include - -// Infra. -#include - -// Local. -#include -#include -#include - -// *** INTERNALLY-LINKED AUXILIARY FUNCTIONS - BEGIN *** - -// Use this to apply a different font color for highlighting hazards. -const char* BEGIN_HAZARD_FONT = " "; -const char* END_HAZARD_FONT = " "; - -static const char* StartResourceSection(bool isHazard) -{ - return isHazard ? BEGIN_HAZARD_FONT : ""; -} - -static const char* EndResourceSection(bool isHazard) -{ - return isHazard ? END_HAZARD_FONT : ""; -} - -// *** INTERNALLY-LINKED AUXILIARY FUNCTIONS - END *** - -rgResourceUsageView::rgResourceUsageView(QWidget* pParent) - : QWidget(pParent) -{ - ui.setupUi(this); -} - -void rgResourceUsageView::PopulateView(const rgResourceUsageData& resourceUsage) -{ - // The size of the instruction cache in bytes. - const int ICACHE_SIZE_IN_BYTES = 32768; - - // True if we should warn the user about resource usage info - // that may imply a performance issue. - bool isResourceUsageHazard = false; - - // Register spills. - QString sgprSpills; - QString vgprSpills; - - bool isVgprHazard = false; - bool isVgprSpilled = false; - bool isSgprHazard = false; - bool isSgprSpilled = false; - bool isLdsHazard = false; - bool isScratchMemoryHazard = false; - bool isIcacheHazard = false; - - - // SGPR spills. - if (resourceUsage.m_sgprSpills > 0) - { - sgprSpills = QString::number(resourceUsage.m_sgprSpills); - isSgprSpilled = true; - } - - // It's a SGPR hazard either if we spilled, or reached at our maximum usage. - isSgprHazard = isSgprSpilled || (resourceUsage.m_usedSgprs >= resourceUsage.m_availableSgprs); - - // VGPR spills. - if (resourceUsage.m_vgprSpills > 0) - { - vgprSpills = QString::number(resourceUsage.m_vgprSpills); - isVgprSpilled = true; - } - - // It's a VGPR hazard either if we spilled, or reached at our maximum usage. - isVgprHazard = isVgprSpilled || (resourceUsage.m_usedVgprs >= resourceUsage.m_availableVgprs); - - // Build the string to be presented. - std::stringstream resourceUsageHeaderStream; - - // Add the header title text to the beginning of the stream. - resourceUsageHeaderStream << "" << STR_GPU_RESOURCE_USAGE << " "; - - // Append a string to display the number of VGPRs used over the number available. - resourceUsageHeaderStream << " | " << StartResourceSection(isVgprHazard) << "" << STR_RESOURCE_USAGE_VGPRS << ": " << - resourceUsage.m_usedVgprs << " / " << resourceUsage.m_availableVgprs; - - // Only add VGPR spills if relevant (> 0). - if (!vgprSpills.isEmpty()) - { - resourceUsageHeaderStream << " -> " << vgprSpills.toStdString() << " " << STR_RESOURCE_USAGE_SPILLS; - } - - resourceUsageHeaderStream << EndResourceSection(isVgprHazard); - resourceUsageHeaderStream << " | "; - - - // Create a string to display the number of SGPRs used over the number available. - resourceUsageHeaderStream << StartResourceSection(isSgprHazard) << "" << STR_RESOURCE_USAGE_SGPRS << ": " << resourceUsage.m_usedSgprs << " / " << resourceUsage.m_availableSgprs; - - // Only add SGPR spills if relevant (> 0). - if (!sgprSpills.isEmpty()) - { - resourceUsageHeaderStream << " -> " << sgprSpills.toStdString() << " " << STR_RESOURCE_USAGE_SPILLS; - } - resourceUsageHeaderStream << EndResourceSection(isSgprHazard); - resourceUsageHeaderStream << " | "; - - // LDS. - // Convert the LDS used and available byte counts to an abbreviated file size with an acronym. - QString ldsBytesUsed; - QString ldsBytesAvailable; - QtCommon::QtUtil::GetFilesizeAcronymFromByteCount(resourceUsage.m_availableLdsBytes, ldsBytesAvailable); - isLdsHazard = (resourceUsage.m_usedLdsBytes >= resourceUsage.m_availableLdsBytes); - - // Set the LDS usage string in the view. - resourceUsageHeaderStream << StartResourceSection(isLdsHazard) << "" << STR_RESOURCE_USAGE_LDS << ": " << resourceUsage.m_usedLdsBytes << (resourceUsage.m_usedLdsBytes > 0 ? " B" : "") << " / " << ldsBytesAvailable.toStdString() << EndResourceSection(isLdsHazard) << " | "; - - // Scratch memory. - QString scratchMem; - QtCommon::QtUtil::GetFilesizeAcronymFromByteCount(resourceUsage.m_scratchMemory, scratchMem); - isScratchMemoryHazard = (resourceUsage.m_scratchMemory > 0); - resourceUsageHeaderStream << StartResourceSection(isScratchMemoryHazard) << "" << STR_RESOURCE_USAGE_SCRATCH << ": " << scratchMem.toStdString() << EndResourceSection(isScratchMemoryHazard) << " | "; - - // Instruction cache. - if (resourceUsage.m_isaSize > 0) - { - // Check if the size of the code is larger the size of the instruction cache. - isIcacheHazard = (resourceUsage.m_isaSize > ICACHE_SIZE_IN_BYTES); - - // Only display the iCache usage if there is a hazard. - if (isIcacheHazard) - { - resourceUsageHeaderStream << StartResourceSection(isIcacheHazard) << "" << STR_RESOURCE_USAGE_ICACHE << ": " << resourceUsage.m_isaSize << " B / " << "32KB " << EndResourceSection(isIcacheHazard) << "|"; - } - } - - // We have a hazard if any of the resources produces a hazard. - isResourceUsageHazard = isVgprHazard || isSgprHazard || isLdsHazard || isScratchMemoryHazard || isIcacheHazard; - - // Show the warning icon if a hazard was detected. - ui.warningLabel->setVisible(isResourceUsageHazard); - - // Set the resource usage text in the view's title bar. - std::string resourceUsageString = resourceUsageHeaderStream.str(); - ui.resourceUsageHeaderLabel->setText(resourceUsageString.c_str()); -} - -std::string rgResourceUsageView::GetResourceUsageText() -{ - return ui.resourceUsageHeaderLabel->text().toStdString(); -} - -QFont rgResourceUsageView::GetResourceUsageFont() -{ - return ui.resourceUsageHeaderLabel->font(); -} - -void rgResourceUsageView::mousePressEvent(QMouseEvent* pEvent) -{ - emit ResourceUsageViewClickedSignal(); - - // Pass the event onto the base class. - QWidget::mousePressEvent(pEvent); -} - -void rgResourceUsageView::focusOutEvent(QFocusEvent* pEvent) -{ - emit ResourceUsageViewFocusOutEventSignal(); - - // Pass the event onto the base class. - QWidget::focusOutEvent(pEvent); -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgScrollArea.cpp b/RadeonGPUAnalyzerGUI/Src/rgScrollArea.cpp deleted file mode 100644 index e3f94bb..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgScrollArea.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// C++. -#include -#include - -// Local. -#include - -rgScrollArea::rgScrollArea(QWidget* pParent) : QScrollArea(pParent) -{ -} - -void rgScrollArea::mousePressEvent(QMouseEvent* pEvent) -{ - emit ScrollAreaClickedEvent(); - - // Pass the event onto the base class. - QScrollArea::mousePressEvent(pEvent); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgSettingsButtonsView.cpp b/RadeonGPUAnalyzerGUI/Src/rgSettingsButtonsView.cpp deleted file mode 100644 index b8487fb..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgSettingsButtonsView.cpp +++ /dev/null @@ -1,116 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include -#include -#include -#include -#include -#include - -// Infra. -#include -#include -#include -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include - - -rgSettingsButtonsView::rgSettingsButtonsView(QWidget* pParent) : - QWidget(pParent) -{ - // Setup the UI. - ui.setupUi(this); - - // Set the background to white. - QPalette pal = palette(); - pal.setColor(QPalette::Background, Qt::white); - this->setAutoFillBackground(true); - this->setPalette(pal); - - // Connect the signals. - ConnectSignals(); - - // Set the mouse cursor to the pointing hand cursor for various widgets. - SetCursor(); - - // Disable the "Save" button located on build settings view initially. - ui.saveSettingsButton->setEnabled(false); -} - -rgSettingsButtonsView::~rgSettingsButtonsView() -{ -} - -void rgSettingsButtonsView::ConnectSignals() -{ - // Restore default settings button. - bool isConnected = connect(this->ui.defaultSettingsPushButton, &QPushButton::clicked, this, &rgSettingsButtonsView::HandleRestoreDefaultSettingsButtonClick); - assert(isConnected); - - // Save settings button. - isConnected = connect(this->ui.saveSettingsButton, &QPushButton::clicked, this, &rgSettingsButtonsView::HandleSaveSettingsButtonClick); - assert(isConnected); - - m_pRestoreSettingsAction = new QAction(tr(STR_RESTORE_DEFAULT_SETTINGS), this); - assert(m_pRestoreSettingsAction != nullptr); - if (m_pRestoreSettingsAction != nullptr) - { - // Configure the hot key for the Restore default settings action. - m_pRestoreSettingsAction->setShortcut(QKeySequence(gs_RESTORE_DEFAULT_SETTINGS)); - - // Connect the handler for the "Restore default settings" button hot key action. - isConnected = connect(m_pRestoreSettingsAction, &QAction::triggered, this, &rgSettingsButtonsView::HandleRestoreDefaultSettingsButtonClick); - assert(isConnected); - - // Add a hot key action to the button. - ui.defaultSettingsPushButton->addAction(m_pRestoreSettingsAction); - } -} - - -void rgSettingsButtonsView::SetCursor() -{ - // Set the cursor to pointing hand cursor. - ui.defaultSettingsPushButton->setCursor(Qt::PointingHandCursor); - ui.saveSettingsButton->setCursor(Qt::PointingHandCursor); -} - -void rgSettingsButtonsView::HandleRestoreDefaultSettingsButtonClick() -{ - // Emit the signal to indicate clicking of "Restore default settings" button. - emit RestoreDefaultSettingsButtonClickedSignal(); -} - -void rgSettingsButtonsView::HandleSaveSettingsButtonClick() -{ - // Emit the signal to indicate clicking of "Save" button. - emit SaveSettingsButtonClickedSignal(); -} - -void rgSettingsButtonsView::EnableSaveButton(bool isEnabled) -{ - ui.saveSettingsButton->setEnabled(isEnabled); -} - -void rgSettingsButtonsView::HideRestoreDefaultSettingsButton(bool isHidden) -{ - ui.defaultSettingsPushButton->setHidden(isHidden); -} - - -void rgSettingsButtonsView::mousePressEvent(QMouseEvent *pEvent) -{ - emit SettingsButtonsViewClickedSignal(); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgSettingsModelBase.cpp b/RadeonGPUAnalyzerGUI/Src/rgSettingsModelBase.cpp deleted file mode 100644 index 6d9fa97..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgSettingsModelBase.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// C++. -#include -#include - -// Local. -#include -#include -#include -#include - -rgSettingsModelBase::rgSettingsModelBase(unsigned int modelCount) : - ModelViewMapper(modelCount) {} - -void rgSettingsModelBase::RevertPendingChanges() -{ - // Clear the map of pending changes to the settings. - m_pendingValues.clear(); - - // After submitting the user's pending changes, the interface has no changes pending. - SetHasPendingChanges(false); - - // Reset the build settings to the current settings, which will update the UI. - InitializeModelValues(); -} - -bool rgSettingsModelBase::HasPendingChanges() const -{ - return m_hasPendingChanges; -} - -void rgSettingsModelBase::InitializeModelValues() -{ - // Initialize the model values. - InitializeModelValuesImpl(); - - // Since the model data has just been initialized for the first time, it is in a "dirty" state. - // Reset the model's pending changes so that the Build Settings aren't displayed - SetHasPendingChanges(false); -} - -void rgSettingsModelBase::SetHasPendingChanges(bool hasPendingChanges) -{ - // Only confirm the state change if it's different from the current state. - if (m_hasPendingChanges != hasPendingChanges) - { - m_hasPendingChanges = hasPendingChanges; - - // Emit a signal that the dirtiness of the model has changed. - emit PendingChangesStateChanged(hasPendingChanges); - } -} - -void rgSettingsModelBase::SubmitPendingChanges() -{ - // Step through each control and update the displayed value if necessary. - uint32_t modelCount = GetModelCount(); - for (uint32_t controlIndex = 0; controlIndex < modelCount; ++controlIndex) - { - auto controlValue = m_pendingValues.find(controlIndex); - if (controlValue != m_pendingValues.end()) - { - UpdateModelValue(controlIndex, controlValue->second, true); - } - } - - // After submitting the changes, clear all of the user's pending changes. - RevertPendingChanges(); -} - -bool rgSettingsModelBase::GetHasPendingChanges() const -{ - bool hasPendingChanges = false; - - // Step through the initial values, and compare to pending values. - auto initialValuesStartIter = m_initialValues.begin(); - auto initialValuesEndIter = m_initialValues.end(); - for (auto initialValuesIter = initialValuesStartIter; initialValuesIter != initialValuesEndIter; ++initialValuesIter) - { - // Extract the initial value for the control. - int modelIndex = initialValuesIter->first; - const QVariant& initialValue = initialValuesIter->second; - - // Attempt to find a pending value for the control. - auto pendingValueIter = m_pendingValues.find(modelIndex); - if (pendingValueIter != m_pendingValues.end()) - { - const QVariant& pendingValue = pendingValueIter->second; - - // If the original and pending values match, there is no pending change. - if (initialValue != pendingValue) - { - hasPendingChanges = true; - break; - } - } - } - - return hasPendingChanges; -} - -bool rgSettingsModelBase::GetPendingValue(int control, QVariant& value) const -{ - bool ret = false; - - auto pendingValueIter = m_pendingValues.find(control); - if (pendingValueIter != m_pendingValues.end()) - { - ret = true; - value = pendingValueIter->second; - } - - return ret; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgSettingsTab.cpp b/RadeonGPUAnalyzerGUI/Src/rgSettingsTab.cpp deleted file mode 100644 index c8bcd5f..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgSettingsTab.cpp +++ /dev/null @@ -1,632 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include - -rgSettingsTab::rgSettingsTab(QWidget* pParent) - : QWidget(pParent) -{ - // Setup the UI. - ui.setupUi(this); -} - -void rgSettingsTab::Initialize() -{ - // Create the global settings view and add it to the Settings Tab. - rgConfigManager& configManager = rgConfigManager::Instance(); - rgProjectAPI currentApi = configManager.GetCurrentAPI(); - std::shared_ptr pGlobalSettings = configManager.GetGlobalConfig(); - - // Set various properties for the scroll area. - QPalette palette; - palette.setColor(QPalette::Background, Qt::GlobalColor::transparent); - ui.scrollArea->setPalette(palette); - ui.scrollArea->setFrameShape(QFrame::NoFrame); - ui.scrollArea->setAlignment(Qt::AlignTop); - ui.scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); - ui.scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - - ScalingManager::Get().RegisterObject(ui.settingsButtonsView); - - // Create the application settings view and add it to the settings tab. - m_pGlobalSettingsView = new rgGlobalSettingsView(this, *pGlobalSettings); - assert(m_pGlobalSettingsView != nullptr); - if (m_pGlobalSettingsView != nullptr) - { - AddSettingsView(m_pGlobalSettingsView); - ScalingManager::Get().RegisterObject(m_pGlobalSettingsView); - } - - // Create the API-specific build settings view and add it to the Settings Tab. - m_pBuildSettingsView = CreateApiBuildSettingsView(); - assert(m_pBuildSettingsView != nullptr); - if (m_pBuildSettingsView != nullptr) - { - AddSettingsView(m_pBuildSettingsView); - ScalingManager::Get().RegisterObject(m_pBuildSettingsView); - } - - // Add vertical spacer to the scroll area contents to ensure settings are top aligned. - ui.scrollAreaWidgetContents->layout()->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding)); - - // Connect signals within the start tab. - ConnectSignals(); - - // Apply style from stylesheet. - std::vector stylesheetFileNames; - stylesheetFileNames.push_back(STR_MAIN_WINDOW_STYLESHEET_FILE); - stylesheetFileNames.push_back(STR_APPLICATION_STYLESHEET_FILE); - rgUtils::LoadAndApplyStyle(stylesheetFileNames, this); - - // Apply the stylesheets for the global settings. - std::shared_ptr pFactory = rgFactory::CreateFactory(GetApiType()); - assert(pFactory != nullptr); - std::shared_ptr pAppState = pFactory->CreateAppState(); - assert(pAppState != nullptr); - if (pAppState != nullptr) - { - SetGlobalSettingsStylesheet(pAppState->GetGlobalSettingsViewStylesheet()); - SetBuildSettingsStylesheet(pAppState->GetBuildSettingsViewStylesheet()); - } - - // Set the cursor type for specific widgets in the view. - SetCursor(); - - // Set the title for the API-specific build settings. - UpdateBuildSettingsTitle(false); - - // Resize the list widget to fit its contents. - const int extraWidthToAvoidScrollbar = 20 * ScalingManager::Get().GetScaleFactor(); - ui.settingsListWidget->setMinimumWidth(ui.settingsListWidget->sizeHintForColumn(0) + extraWidthToAvoidScrollbar); - ScalingManager::Get().DisableScalingForObject(ui.settingsListWidget); - - // Set the settings list widget's current row to "Global". - ui.settingsListWidget->setCurrentRow(static_cast(SettingsListWidgetEntries::Global)); - - // Set the focus to the settings list widget. - ui.settingsListWidget->setFocus(); - - // Install an event filter to prompt user to save settings when switching pages on the settings tab. - ui.settingsListWidget->viewport()->installEventFilter(this); - - // Make sure all child objects (except those which were excluded) get registered for scaling. - ScalingManager::Get().RegisterObject(this); -} - -rgBuildSettingsView* rgSettingsTab::CreateApiBuildSettingsView() -{ - // Create an API-specific factory to create an API-specific rgBuildSettingsView. - std::shared_ptr pFactory = rgFactory::CreateFactory(GetApiType()); - assert(pFactory != nullptr); - - // Get the API-specific build settings from the rgConfigManager. - std::shared_ptr pBuildSettings = rgConfigManager::Instance().GetUserGlobalBuildSettings(GetApiType()); - assert(pBuildSettings != nullptr); - - // If the factory and build settings are valid, then create an API-specific rgBuildSettingsView - // with the API-specific settings. - rgBuildSettingsView* pBuildSettingsView = nullptr; - if (pFactory != nullptr && pBuildSettings != nullptr) - { - pBuildSettingsView = pFactory->CreateBuildSettingsView(parentWidget(), pBuildSettings, true); - } - - return pBuildSettingsView; -} - -void rgSettingsTab::AddSettingsView(rgBuildSettingsView* pSettingsView) -{ - assert(pSettingsView != nullptr); - if (pSettingsView != nullptr) - { - // Add the view's title to the list widget. - QString title(pSettingsView->GetTitleString().c_str()); - ui.settingsListWidget->addItem(title); - ui.settingsListWidget->item(ui.settingsListWidget->count() - 1)->setToolTip(title); - - // Add the view to the scroll area. - ui.scrollAreaWidgetContents->layout()->addWidget(pSettingsView); - } -} - -void rgSettingsTab::ConnectSignals() -{ - // Global settings view has pending changes. - bool isConnected = connect(m_pGlobalSettingsView, &rgGlobalSettingsView::PendingChangesStateChanged, this, &rgSettingsTab::HandleGlobalPendingChangesStateChanged); - assert(isConnected); - - // Global settings view has empty input file names. - isConnected = connect(m_pGlobalSettingsView, &rgGlobalSettingsView::InputFileNameBlankSignal, this, &rgSettingsTab::HandleInputFileNameBlank); - assert(isConnected); - - // "Save" button. - isConnected = connect(ui.settingsButtonsView, &rgSettingsButtonsView::SaveSettingsButtonClickedSignal, this, &rgSettingsTab::HandleSaveSettingsButtonClicked); - assert(isConnected); - - // "Restore default settings" button. - isConnected = connect(ui.settingsButtonsView, &rgSettingsButtonsView::RestoreDefaultSettingsButtonClickedSignal, this, &rgSettingsTab::HandleRestoreDefaultsSettingsClicked); - assert(isConnected); - - // Connect the default API's settings view's handler for pending changes. - isConnected = connect(static_cast(m_pBuildSettingsView), &rgBuildSettingsView::PendingChangesStateChanged, this, &rgSettingsTab::HandleBuildSettingsPendingChangesStateChanged); - assert(isConnected); - - // Connect the settings list widget to detect clicks. - isConnected = connect(ui.settingsListWidget, &QListWidget::currentRowChanged, this, &rgSettingsTab::HandleSettingsListWidgetClick); - assert(isConnected); - - // Connect the settings command line update. - isConnected = connect(this, &rgSettingsTab::UpdateCommandLineTextSignal, m_pBuildSettingsView, &rgBuildSettingsView::UpdateCommandLineText); - assert(isConnected); -} - -void rgSettingsTab::HandleInputFileNameBlank(bool isBlank) -{ - // Disable clicking on the list widget. - if (isBlank) - { - ui.settingsListWidget->setSelectionMode(QAbstractItemView::NoSelection); - } - else - { - ui.settingsListWidget->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection); - } -} - -bool rgSettingsTab::eventFilter(QObject* pObject, QEvent* pEvent) -{ - assert(pObject != nullptr); - assert(pEvent != nullptr); - - bool isFiltered = false; - - if (pEvent != nullptr) - { - const QEvent::Type eventType = pEvent->type(); - - if (eventType == QEvent::MouseButtonPress) - { - const QMouseEvent* pMouseEvent = static_cast(pEvent); - assert(pMouseEvent != nullptr); - - if (pMouseEvent != nullptr) - { - const QPoint localPoint = pMouseEvent->localPos().toPoint(); - QListWidgetItem* pItem = ui.settingsListWidget->itemAt(localPoint); - QListWidgetItem* pCurrentItem = ui.settingsListWidget->currentItem(); - if (pItem != nullptr && pCurrentItem != nullptr) - { - if (pItem != pCurrentItem) - { - if (m_pGlobalSettingsView->IsInputFileBlank() == false && PromptToSavePendingChanges() == false) - { - // User canceled the dialog, so the event should be filtered out. - isFiltered = true; - } - } - } - } - } - } - - // Allow base class to filter the event if needed. - if (!isFiltered) - { - isFiltered = QWidget::eventFilter(pObject, pEvent); - } - - return isFiltered; -} - -void rgSettingsTab::SelectNextListWidgetItem(const int keyPressed) -{ - const int currentRow = ui.settingsListWidget->currentRow(); - if (keyPressed == Qt::Key_Up) - { - // Process the key up event only if the existing selection is not the top one. - if (currentRow == static_cast(SettingsListWidgetEntries::Api)) - { - const int nextRow = static_cast(SettingsListWidgetEntries::Global); - ui.settingsListWidget->setCurrentRow(nextRow); - } - } - else if (keyPressed == Qt::Key_Down) - { - // Process the key down event only if the existing selection is not the bottom one. - if (currentRow == static_cast(SettingsListWidgetEntries::Global)) - { - const int nextRow = static_cast(SettingsListWidgetEntries::Api); - ui.settingsListWidget->setCurrentRow(nextRow); - } - } -} - -void rgSettingsTab::SaveSettings() -{ - // First verify all inputs before saving them by calling all their handlers. - assert(m_pGlobalSettingsView != nullptr); - if (m_pGlobalSettingsView != nullptr) - { - m_pGlobalSettingsView->HandleIncludeFilesViewerEditingFinished(); - m_pGlobalSettingsView->HandleLogFileEditingFinished(); - } - - // Disable the "Save" button. - ui.settingsButtonsView->EnableSaveButton(false); - - assert(m_pGlobalSettingsView != nullptr); - if (m_pGlobalSettingsView != nullptr && m_pGlobalSettingsView->GetHasPendingChanges()) - { - // Save global application settings. - m_pGlobalSettingsView->SaveSettings(); - } - - assert(m_pBuildSettingsView != nullptr); - if (m_pBuildSettingsView != nullptr && m_pBuildSettingsView->GetHasPendingChanges()) - { - // Save default build settings. - m_pBuildSettingsView->SaveSettings(); - } -} - -void rgSettingsTab::HandleSaveSettingsButtonClicked() -{ - PromptToSavePendingChanges(); -} - -void rgSettingsTab::HandleRestoreDefaultsSettingsClicked() -{ - // Ask the user for confirmation. - bool isConfirmation = rgUtils::ShowConfirmationMessageBox(STR_BUILD_SETTINGS_DEFAULT_SETTINGS_CONFIRMATION_TITLE, STR_BUILD_SETTINGS_DEFAULT_SETTINGS_CONFIRMATION, this); - - if (isConfirmation) - { - // Disable the "Save" button. - ui.settingsButtonsView->EnableSaveButton(false); - - // Only restore the settings for the current view. - const SettingsListWidgetEntries currentRow = static_cast(ui.settingsListWidget->currentRow()); - switch (currentRow) - { - case (SettingsListWidgetEntries::Global): - { - // Restore default values for global settings. - if (m_pGlobalSettingsView != nullptr) - { - m_pGlobalSettingsView->RestoreDefaultSettings(); - } - } - break; - case (SettingsListWidgetEntries::Api): - { - // Restore default values for the default API settings. - if (m_pBuildSettingsView != nullptr) - { - m_pBuildSettingsView->RestoreDefaultSettings(); - - // Also update the settings command line. - emit UpdateCommandLineTextSignal(); - } - } - break; - default: - // We shouldn't get here. - assert(false); - break; - } - } -} - -void rgSettingsTab::UpdateBuildSettingsTitle(bool hasPendingChanges) -{ - QListWidgetItem* pItem = ui.settingsListWidget->item(static_cast(SettingsListWidgetEntries::Api)); - assert(pItem != nullptr); - if (pItem != nullptr) - { - std::string settingsTitle; - - assert(m_pBuildSettingsView != nullptr); - if (m_pBuildSettingsView != nullptr) - { - settingsTitle = m_pBuildSettingsView->GetTitleString(); - } - else - { - settingsTitle = std::string(STR_BUILD_SETTINGS_DEFAULT_TITLE).append(STR_BUILD_SETTINGS_DEFAULT_TITLE_B); - } - - if (hasPendingChanges) - { - pItem->setText(QString(settingsTitle.c_str()) + STR_UNSAVED_FILE_SUFFIX); - } - else - { - pItem->setText(QString(settingsTitle.c_str())); - } - } -} - -SettingsListWidgetEntries rgSettingsTab::GetSelectedSettingCategory() const -{ - // Cast the currently-selected row to a settings enum type. - int currentRow = ui.settingsListWidget->currentRow(); - return static_cast(currentRow); -} - -bool rgSettingsTab::PromptToSavePendingChanges() -{ - bool result = true; - if (m_hasPendingChanges) - { - rgUnsavedItemsDialog::UnsavedFileDialogResult saveSettingsResult = ShowSaveSettingsConfirmationDialog(); - - if (saveSettingsResult == rgUnsavedItemsDialog::UnsavedFileDialogResult::Yes) - { - SaveSettings(); - } - else if (saveSettingsResult == rgUnsavedItemsDialog::UnsavedFileDialogResult::No) - { - RevertPendingChanges(); - } - else - { - // User canceled the prompt. - result = false; - } - } - return result; -} - -void rgSettingsTab::SavePendingChanges() -{ - PromptToSavePendingChanges(); -} - -rgUnsavedItemsDialog::UnsavedFileDialogResult rgSettingsTab::ShowSaveSettingsConfirmationDialog() -{ - rgUnsavedItemsDialog::UnsavedFileDialogResult result = rgUnsavedItemsDialog::No; - - if (m_hasBuildPendingChanges || m_hasApplicationPendingChanges) - { - // Create a modal unsaved file dialog. - rgUnsavedItemsDialog* pUnsavedChangesDialog = new rgUnsavedItemsDialog(this); - assert(pUnsavedChangesDialog != nullptr); - if (pUnsavedChangesDialog != nullptr) - { - pUnsavedChangesDialog->setModal(true); - pUnsavedChangesDialog->setWindowTitle(STR_UNSAVED_ITEMS_DIALOG_TITLE); - - // Add a message string to the dialog list. - if (m_hasApplicationPendingChanges) - { - pUnsavedChangesDialog->AddFile(STR_SETTINGS_CONFIRMATION_APPLICATION_SETTINGS); - } - if (m_hasBuildPendingChanges) - { - pUnsavedChangesDialog->AddFile(m_pBuildSettingsView->GetTitleString().c_str()); - } - - // Register the dialog with the scaling manager. - ScalingManager::Get().RegisterObject(pUnsavedChangesDialog); - - // Center the dialog on the view (registering with the scaling manager - // shifts it out of the center so we need to manually center it). - rgUtils::CenterOnWidget(pUnsavedChangesDialog, parentWidget()); - - // Execute the dialog and get the result. - result = static_cast(pUnsavedChangesDialog->exec()); - - // Set the focus to settings tab so keyboard shortcuts work. - setFocus(); - } - } - - return result; -} - -void rgSettingsTab::RevertPendingChanges() -{ - // Revert pending changes for the Global Application Settings. - if (m_pGlobalSettingsView != nullptr) - { - m_pGlobalSettingsView->RevertPendingChanges(); - } - - // Revert pending changes for the API-specific Build Settings. - if (m_pBuildSettingsView != nullptr) - { - m_pBuildSettingsView->RevertPendingChanges(); - } -} - -void rgSettingsTab::SetGlobalSettingsStylesheet(const std::string& stylesheet) -{ - assert(m_pGlobalSettingsView != nullptr); - if (m_pGlobalSettingsView != nullptr) - { - m_pGlobalSettingsView->setStyleSheet(stylesheet.c_str()); - } -} - -void rgSettingsTab::SetBuildSettingsStylesheet(const std::string& stylesheet) -{ - assert(m_pBuildSettingsView != nullptr); - if (m_pBuildSettingsView != nullptr) - { - m_pBuildSettingsView->setStyleSheet(stylesheet.c_str()); - } -} - -void rgSettingsTab::HandleSettingsListWidgetClick(int index) -{ - assert(m_pBuildSettingsView != nullptr); - assert(m_pGlobalSettingsView != nullptr); - - bool isSaveEnabled = false; - - if (m_pGlobalSettingsView->IsInputFileBlank() == false) - { - switch (index) - { - case (static_cast(SettingsListWidgetEntries::Global)): - { - if (m_pBuildSettingsView != nullptr) - { - m_pBuildSettingsView->hide(); - } - - if (m_pGlobalSettingsView != nullptr) - { - m_pGlobalSettingsView->show(); - - isSaveEnabled = m_pGlobalSettingsView->GetHasPendingChanges(); - - m_pGlobalSettingsView->SetInitialWidgetFocus(); - } - } - break; - case (static_cast(SettingsListWidgetEntries::Api)): - { - if (m_pGlobalSettingsView != nullptr) - { - m_pGlobalSettingsView->hide(); - } - - if (m_pBuildSettingsView != nullptr) - { - m_pBuildSettingsView->show(); - - isSaveEnabled = m_pBuildSettingsView->GetHasPendingChanges(); - - m_pBuildSettingsView->SetInitialWidgetFocus(); - } - } - break; - default: - // We shouldn't get here. - assert(false); - break; - } - - // Enable or disable the save button. - ui.settingsButtonsView->EnableSaveButton(isSaveEnabled); - - // Set the list widget cursor to arrow cursor. - ui.settingsListWidget->setCursor(Qt::ArrowCursor); - - // Set the focus to settings buttons view. - ui.settingsButtonsView->setFocus(); - } - else - { - if (m_pGlobalSettingsView != nullptr) - { - // Reset the current item for the list widget to the previous one. - switch (index) - { - case (static_cast(SettingsListWidgetEntries::Global)): - { - QSignalBlocker signalBlocker(ui.settingsListWidget); - ui.settingsListWidget->selectionModel()->setCurrentIndex(ui.settingsListWidget->model()->index(static_cast(SettingsListWidgetEntries::Api), 0), QItemSelectionModel::SelectionFlag::Select); - } - break; - case (static_cast(SettingsListWidgetEntries::Api)): - { - QSignalBlocker signalBlocker(ui.settingsListWidget); - ui.settingsListWidget->selectionModel()->setCurrentIndex(ui.settingsListWidget->model()->index(static_cast(SettingsListWidgetEntries::Global), 0), QItemSelectionModel::SelectionFlag::Select); - } - break; - default: - // We shouldn't get here. - assert(false); - break; - } - - // Display the empty input file name message box. - m_pGlobalSettingsView->ProcessInputFileBlank(); - } - } -} - -void rgSettingsTab::HandleBuildSettingsPendingChangesStateChanged(bool hasPendingChanges) -{ - m_hasBuildPendingChanges = hasPendingChanges; - - // Enable the "Save" button located on settings buttons view. - ui.settingsButtonsView->EnableSaveButton(hasPendingChanges); - - // Update the settings list widget "API" entry. - UpdateBuildSettingsTitle(hasPendingChanges); - - NotifyOfPendingChanges(); -} - -void rgSettingsTab::HandleGlobalPendingChangesStateChanged(bool hasPendingChanges) -{ - // Update the "Save" button located on settings buttons view. - ui.settingsButtonsView->EnableSaveButton(hasPendingChanges); - - // Update the settings list widget "Application" entry. - QListWidgetItem* pItem = ui.settingsListWidget->item(static_cast(SettingsListWidgetEntries::Global)); - assert(pItem); - - if (pItem != nullptr) - { - if (hasPendingChanges) - { - pItem->setText(QString(m_pGlobalSettingsView->GetTitleString().c_str()) + STR_UNSAVED_FILE_SUFFIX); - } - else - { - pItem->setText(QString(m_pGlobalSettingsView->GetTitleString().c_str())); - } - - m_hasApplicationPendingChanges = hasPendingChanges; - - NotifyOfPendingChanges(); - } -} - -void rgSettingsTab::NotifyOfPendingChanges() -{ - bool anyPendingChanges = m_hasApplicationPendingChanges || m_hasBuildPendingChanges; - - // Only emit the signal if the state of the pending changes is different - // than it was before. - if (m_hasPendingChanges != anyPendingChanges) - { - m_hasPendingChanges = anyPendingChanges; - - emit PendingChangesStateChanged(m_hasPendingChanges); - } -} - -void rgSettingsTab::SetCursor() -{ - // Set the cursor to pointing hand cursor. - ui.settingsListWidget->setCursor(Qt::PointingHandCursor); -} - -rgListWidget* rgSettingsTab::GetSettingsListWidget() -{ - return ui.settingsListWidget; -} - -rgGlobalSettingsView* rgSettingsTab::GetGlobalSettingsView() -{ - return m_pGlobalSettingsView; -} - diff --git a/RadeonGPUAnalyzerGUI/Src/rgSettingsTabOpenCL.cpp b/RadeonGPUAnalyzerGUI/Src/rgSettingsTabOpenCL.cpp deleted file mode 100644 index 3d1ae8d..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgSettingsTabOpenCL.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// C++. -#include - -// Local. -#include - -rgSettingsTabOpenCL::rgSettingsTabOpenCL(QWidget* pParent) - : rgSettingsTab(pParent) -{ -} - -rgProjectAPI rgSettingsTabOpenCL::GetApiType() -{ - return rgProjectAPI::OpenCL; -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgSettingsTabVulkan.cpp b/RadeonGPUAnalyzerGUI/Src/rgSettingsTabVulkan.cpp deleted file mode 100644 index 5d85eae..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgSettingsTabVulkan.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// C++. -#include - -// Local. -#include -#include - -rgSettingsTabVulkan::rgSettingsTabVulkan(QWidget* pParent) - : rgSettingsTab(pParent) -{ -} - -rgProjectAPI rgSettingsTabVulkan::GetApiType() -{ - return rgProjectAPI::Vulkan; -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgSettingsView.cpp b/RadeonGPUAnalyzerGUI/Src/rgSettingsView.cpp deleted file mode 100644 index b702205..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgSettingsView.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// Local. -#include - -rgSettingsView::rgSettingsView(QWidget* pParent) - : QWidget(pParent) -{ - -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgSourceCodeEditor.cpp b/RadeonGPUAnalyzerGUI/Src/rgSourceCodeEditor.cpp deleted file mode 100644 index e843162..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgSourceCodeEditor.cpp +++ /dev/null @@ -1,583 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include - -// Local. -#include -#include -#include - -// Use a light yellow to highlight the line that the cursor is on. -static const QColor COLOR_HIGHLIGTED_ROW = QColor(Qt::yellow).lighter(170); - -rgSourceCodeEditor::rgSourceCodeEditor(QWidget* pParent, rgSrcLanguage lang) : QPlainTextEdit(pParent) -{ - m_pLineNumberArea = new LineNumberArea(this); - - // The duration of time between the text cursor blinking on and off. - static const int gs_CURSOR_BLINK_TOGGLE_DURATION_MS = 500; - - // Create the blinking cursor update timer. - m_pCursorBlinkTimer = new QTimer(this); - m_pCursorBlinkTimer->setInterval(gs_CURSOR_BLINK_TOGGLE_DURATION_MS); - m_pCursorBlinkTimer->start(); - - // Connect signals. - ConnectSignals(); - - // Set the border color. - setObjectName("sourceCodeEditor"); - setStyleSheet("#sourceCodeEditor {border: 1px solid black;}"); - - // Create the syntax highlighter. - if (lang != rgSrcLanguage::Unknown) - { - m_pSyntaxHighlighter = new rgSyntaxHighlighter(document(), lang); - } - - UpdateLineNumberAreaWidth(0); - - // Initialize rendering of highlighted lines within the editor. - UpdateCursorPosition(); - - // Set the default font. - QTextDocument* pDoc = this->document(); - if (pDoc != nullptr) - { - QFont font = pDoc->defaultFont(); - font.setFamily(STR_BUILD_VIEW_FONT_FAMILY); - font.setPointSize(gs_BUILD_VIEW_FONT_SIZE); - pDoc->setDefaultFont(font); - - // A tab is the same width as 4 spaces. - QFontMetrics metrics(font); - int tabWidth = metrics.width(' ') * 4; - setTabStopWidth(tabWidth); - } - - // Configure the word wrap mode. - setWordWrapMode(QTextOption::NoWrap); - - // Disable accepting dropped files. - setAcceptDrops(false); - - // Set up the open header file action. - m_pOpenHeaderFileAction = new QAction(tr(STR_SOURCE_EDITOR_CONTEXT_MENU_OPEN_HEADER), this); - - // Cut action. - m_pCutTextAction = new QAction(tr(STR_SOURCE_EDITOR_CONTEXT_MENU_CUT), this); - m_pCutTextAction->setShortcut(QKeySequence(gs_SOURCE_EDITOR_HOTKEY_CONTEXT_MENU_CUT)); - - // Copy action. - m_pCopyTextAction = new QAction(tr(STR_SOURCE_EDITOR_CONTEXT_MENU_COPY), this); - m_pCopyTextAction->setShortcut(QKeySequence(gs_SOURCE_EDITOR_HOTKEY_CONTEXT_MENU_COPY)); - - // Paste action. - m_pPasteTextAction = new QAction(tr(STR_SOURCE_EDITOR_CONTEXT_MENU_PASTE), this); - m_pPasteTextAction->setShortcut(QKeySequence(gs_SOURCE_EDITOR_HOTKEY_CONTEXT_MENU_PASTE)); - - // Select All action. - m_pSelectAllTextAction = new QAction(tr(STR_SOURCE_EDITOR_CONTEXT_MENU_SELECT_ALL), this); - m_pCutTextAction->setShortcut(QKeySequence(gs_SOURCE_EDITOR_HOTKEY_CONTEXT_MENU_SELECT_ALL)); - - // Open header file. - bool isConnected = connect(m_pOpenHeaderFileAction, &QAction::triggered, this, &rgSourceCodeEditor::HandleOpenHeaderFile); - assert(isConnected); - - // Cut action. - isConnected = connect(m_pCutTextAction, &QAction::triggered, this, &QPlainTextEdit::cut); - assert(isConnected); - - // Copy action. - isConnected = connect(m_pCopyTextAction, &QAction::triggered, this, &QPlainTextEdit::copy); - assert(isConnected); - - // Paste action. - isConnected = connect(m_pPasteTextAction, &QAction::triggered, this, &QPlainTextEdit::paste); - assert(isConnected); - - // Select All action. - isConnected = connect(m_pSelectAllTextAction, &QAction::triggered, this, &QPlainTextEdit::selectAll); - assert(isConnected); - - m_pContextMenu = this->createStandardContextMenu(); - assert(m_pContextMenu != nullptr); - if (m_pContextMenu != nullptr) - { - // Reconstruct the context menu. - m_pContextMenu->clear(); - m_pContextMenu->addAction(m_pOpenHeaderFileAction); - m_pContextMenu->addSeparator(); - m_pContextMenu->addAction(m_pCutTextAction); - m_pContextMenu->addAction(m_pCopyTextAction); - m_pContextMenu->addAction(m_pPasteTextAction); - m_pContextMenu->addSeparator(); - m_pContextMenu->addAction(m_pSelectAllTextAction); - this->setContextMenuPolicy(Qt::CustomContextMenu); - - // Set hand pointer for the context menu. - m_pContextMenu->setCursor(Qt::PointingHandCursor); - - // Connect the signal for showing the context menu. - isConnected = connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(ShowContextMenu(const QPoint&))); - assert(isConnected); - } - -} - -int rgSourceCodeEditor::LineNumberAreaWidth() const -{ - int digits = 1; - int max = qMax(1, blockCount()); - while (max >= 10) - { - max /= 10; - ++digits; - } - - int space = 15 + fontMetrics().width(QLatin1Char('9')) * digits; - - return space; -} - -void rgSourceCodeEditor::ScrollToLine(int lineNumber) -{ - // Compute the last visible text block. - QTextBlock firstVisible = firstVisibleBlock(); - auto lastVisibleLinePosition = QPoint(0, viewport()->height() - 1); - QTextBlock lastVisibleBlock = cursorForPosition(lastVisibleLinePosition).block(); - - // Get the first and last visible line numbers in the editor. - int firstVisibleLineNumber = firstVisibleBlock().blockNumber(); - int lastVisibleLineNumber = lastVisibleBlock.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. - bool isOnscreen = (firstVisibleLineNumber < lineNumber) && (lineNumber < lastVisibleLineNumber); - if (!isOnscreen) - { - // Compensate for the scrollbar being zero-based, while the incoming line number is one-based. - int scrollLine = lineNumber - 1; - - // Scroll to 5 lines above the given line index. - verticalScrollBar()->setValue(scrollLine - 5); - } - else if (lineNumber - firstVisibleLineNumber < 5) - { - verticalScrollBar()->setValue(verticalScrollBar()->value() - 5); - } -} - -void rgSourceCodeEditor::setText(const QString& txt) -{ - QTextDocument* pDoc = this->document(); - if (pDoc != nullptr) - { - // Set the text. - pDoc->setPlainText(txt); - - // Set the cursor to the first line and column. - this->moveCursor(QTextCursor::Start); - this->ensureCursorVisible(); - } -} - -void rgSourceCodeEditor::clearText(const QString& txt) -{ - QTextDocument* pDoc = this->document(); - if (pDoc != nullptr && !pDoc->isEmpty()) - { - pDoc->clear(); - } -} - -const std::string& rgSourceCodeEditor::GetTitleBarText() -{ - return m_titleBarNotificationText; -} - -void rgSourceCodeEditor::SetTitleBarText(const std::string& text) -{ - m_titleBarNotificationText = text; -} - -void rgSourceCodeEditor::HandleToggleCursorVisibility() -{ - // Toggle the visibility of the cursor and trigger a repaint. - m_isCursorVisible = !m_isCursorVisible; - viewport()->update(); -} - -void rgSourceCodeEditor::UpdateLineNumberAreaWidth(int /* newBlockCount */) -{ - setViewportMargins(LineNumberAreaWidth(), 0, 0, 0); -} - -void rgSourceCodeEditor::UpdateLineNumberArea(const QRect &rect, int dy) -{ - if (dy) - m_pLineNumberArea->scroll(0, dy); - else - m_pLineNumberArea->update(0, rect.y(), m_pLineNumberArea->width(), rect.height()); - - if (rect.contains(viewport()->rect())) - UpdateLineNumberAreaWidth(0); -} - -void rgSourceCodeEditor::HandleOpenHeaderFile() -{ - QString lineText; - bool isValid = GetCurrentLineText(lineText); - if (isValid) - { - // Parse the line. - if (IsIncludeDirectiveLine(lineText)) - { - // Check the type of the include directive: double-quotes or triangular. - bool isDoubleQuoted = (lineText.count("\"") == 2); - bool isTriangular = !isDoubleQuoted && (lineText.count("<") == 1) && (lineText.count(">") == 1) && - (std::find(lineText.begin(), lineText.end(), "<") < std::find(lineText.begin(), lineText.end(), ">")); - - if (isDoubleQuoted) - { - // Extract the file name. - QStringList lineBroken = lineText.split("\""); - if (lineBroken.size() >= 2) - { - QString fileName = lineBroken[1]; - - // Fire the signal: user requested to open header file. - emit OpenHeaderFileRequested(fileName); - } - } - else if (isTriangular) - { - // Extract the part that is after the first < character. - QStringList lineBrokenA = lineText.split("<"); - if (lineBrokenA.size() >= 2) - { - // Extract the part that is before the > character. - QStringList lineBrokenB = lineBrokenA.at(1).split(">"); - if (lineBrokenB.size() >= 1) - { - // Fire the signal: user requested to open header file. - QString fileName = lineBrokenB[0]; - emit OpenHeaderFileRequested(fileName); - } - } - } - } - } -} - -bool rgSourceCodeEditor::GetCurrentLineText(QString& lineText) -{ - // Get the current line. - QTextCursor cursor = this->textCursor(); - cursor.movePosition(QTextCursor::StartOfLine); - int lines = 1; - while (cursor.positionInBlock() > 0) - { - cursor.movePosition(QTextCursor::Up); - lines++; - } - - QTextBlock block = cursor.block().previous(); - while (block.isValid()) - { - lines += block.lineCount(); - block = block.previous(); - } - - // Extract the current line's text. - bool isValid = GetTextAtLine(lines, lineText) && !lineText.isEmpty(); - return isValid; -} - -bool rgSourceCodeEditor::IsIncludeDirectiveLine(const QString& lineTxt) -{ - // We use this token to identify if a line is an include directive. - static const char* INCLUDE_DIR_TOKEN = "#include "; - bool isIncludeDirective = lineTxt.startsWith(INCLUDE_DIR_TOKEN); - return isIncludeDirective; -} - -void rgSourceCodeEditor::ShowContextMenu(const QPoint& pt) -{ - // Is the open header file action relevant. - QString lineText; - bool isValid = GetCurrentLineText(lineText); - - // Set the open header action to enabled - // only when the line is an include directive. - m_pOpenHeaderFileAction->setEnabled(IsIncludeDirectiveLine(lineText)); - - // Only enable cut, copy if there is text selected. - QTextCursor cursor = this->textCursor(); - bool hasSelection = cursor.hasSelection(); - m_pCutTextAction->setEnabled(hasSelection); - m_pCopyTextAction->setEnabled(hasSelection); - - // Paste is enabled if there is anything in the clipboard. - QString clipboard = QApplication::clipboard()->text(); - m_pPasteTextAction->setEnabled(!clipboard.isEmpty()); - - // Show the context menu to the user where the mouse is. - assert(m_pContextMenu != nullptr); - if (m_pContextMenu != nullptr) - { - m_pContextMenu->exec(QCursor::pos()); - } -} - -void rgSourceCodeEditor::ConnectSignals() -{ - bool isConnected = connect(this, &rgSourceCodeEditor::blockCountChanged, this, &rgSourceCodeEditor::UpdateLineNumberAreaWidth); - assert(isConnected); - - isConnected = connect(this, &rgSourceCodeEditor::updateRequest, this, &rgSourceCodeEditor::UpdateLineNumberArea); - assert(isConnected); - - isConnected = connect(this, &rgSourceCodeEditor::cursorPositionChanged, this, &rgSourceCodeEditor::UpdateCursorPosition); - assert(isConnected); - - isConnected = connect(m_pCursorBlinkTimer, &QTimer::timeout, this, &rgSourceCodeEditor::HandleToggleCursorVisibility); - assert(isConnected); -} - -void rgSourceCodeEditor::HighlightCursorLine(QList& selections) -{ - if (!isReadOnly()) - { - QTextEdit::ExtraSelection currentLineSelection; - currentLineSelection.format.setBackground(COLOR_HIGHLIGTED_ROW); - currentLineSelection.format.setProperty(QTextFormat::FullWidthSelection, true); - currentLineSelection.cursor = textCursor(); - currentLineSelection.cursor.clearSelection(); - - // Add the current line's selection to the output list. - selections.append(currentLineSelection); - } -} - -void rgSourceCodeEditor::HighlightCorrelatedSourceLines(QList& selections) -{ - if (!isReadOnly()) - { - QTextDocument* pFileDocument = document(); - for (int rowIndex : m_highlightedRowIndices) - { - QTextEdit::ExtraSelection selection; - selection.format.setBackground(COLOR_HIGHLIGTED_ROW); - selection.format.setProperty(QTextFormat::FullWidthSelection, true); - - QTextBlock lineTextBlock = pFileDocument->findBlockByLineNumber(rowIndex - 1); - QTextCursor cursor(lineTextBlock); - selection.cursor = cursor; - selection.cursor.clearSelection(); - - // Add the line highlight to the output list. - selections.append(selection); - } - } -} - -void rgSourceCodeEditor::SetHighlightedLines(const QList& lineIndices) -{ - // Set the list of highlighted lines. - m_highlightedRowIndices = lineIndices; - - // Perform the cursor position change related logic. - UpdateCursorPositionHelper(true); - - if (!lineIndices.isEmpty()) - { - // Emit a signal indicating that the highlighted line has changed. - emit SelectedLineChanged(this, lineIndices[0]); - } -} - -void rgSourceCodeEditor::UpdateCursorPositionHelper(bool isCorrelated) -{ - // A list of highlights to apply to the source editor lines. - QList extraSelections; - - if (isCorrelated) - { - // Automatic correlation: add highlights for the disassembly-correlated source lines. - HighlightCorrelatedSourceLines(extraSelections); - } - - // If there aren't any correlated lines to highlight, just highlight the user's currently-selected line. - if (extraSelections.empty()) - { - // Standard user selection: add a highlight for the current line. - HighlightCursorLine(extraSelections); - } - - // Set the line selections in the source editor. - setExtraSelections(extraSelections); - - // Track the current and previously-selected line numbers. - int currentLine = GetSelectedLineNumber(); - static int lastCursorPosition = currentLine; - if (currentLine != lastCursorPosition) - { - // If the selected line number has changed, emit a signal. - emit SelectedLineChanged(this, currentLine); - lastCursorPosition = currentLine; - } -} - -void rgSourceCodeEditor::paintEvent(QPaintEvent* pEvent) -{ - // Invoke the default QPlainTextEdit paint function. - QPlainTextEdit::paintEvent(pEvent); - - // Paint the cursor manually. - if (m_isCursorVisible) - { - QPainter cursorPainter(viewport()); - - // Draw the cursor on top of the text editor. - QRect cursorLine = cursorRect(); - cursorLine.setWidth(1); - cursorPainter.fillRect(cursorLine, Qt::SolidPattern); - } -} - -void rgSourceCodeEditor::resizeEvent(QResizeEvent* pEvent) -{ - QPlainTextEdit::resizeEvent(pEvent); - - QRect cr = contentsRect(); - m_pLineNumberArea->setGeometry(QRect(cr.left(), cr.top(), LineNumberAreaWidth(), cr.height())); - - emit EditorResized(); -} - -void rgSourceCodeEditor::hideEvent(QHideEvent* pEvent) -{ - emit EditorHidden(); -} - -void rgSourceCodeEditor::UpdateCursorPosition() -{ - UpdateCursorPositionHelper(false); -} - -bool rgSourceCodeEditor::SetSyntaxHighlighting(rgSrcLanguage lang) -{ - bool result = (lang != rgSrcLanguage::Unknown); - if (result) - { - if (m_pSyntaxHighlighter != nullptr) - { - delete m_pSyntaxHighlighter; - } - m_pSyntaxHighlighter = new rgSyntaxHighlighter(document(), lang); - } - - return result; -} - -int rgSourceCodeEditor::GetSelectedLineNumber() const -{ - return textCursor().blockNumber() + 1; -} - -bool rgSourceCodeEditor::GetTextAtLine(int lineNumber, QString& text) const -{ - bool ret = false; - - bool isLineValid = lineNumber >= 1 && lineNumber < document()->blockCount(); - if (isLineValid) - { - QTextBlock lineBlock = document()->findBlockByLineNumber(lineNumber - 1); - text = lineBlock.text(); - ret = true; - } - - return ret; -} - -void rgSourceCodeEditor::LineNumberAreaPaintEvent(QPaintEvent* pEvent) -{ - QPainter painter(m_pLineNumberArea); - painter.fillRect(pEvent->rect(), QColor(Qt::lightGray).lighter(120)); - - QTextBlock block = firstVisibleBlock(); - int blockNumber = block.blockNumber(); - int top = (int)blockBoundingGeometry(block).translated(contentOffset()).top(); - int bottom = top + (int)blockBoundingRect(block).height(); - - while (block.isValid() && top <= pEvent->rect().bottom()) - { - if (block.isVisible() && bottom >= pEvent->rect().top()) - { - QString number = QString::number(blockNumber + 1); - painter.setPen(QColor(Qt::darkGray).darker(100)); - QFont defaultFont = this->document()->defaultFont(); - painter.setFont(defaultFont); - painter.drawText(0, top, m_pLineNumberArea->width(), fontMetrics().height(), - Qt::AlignCenter, number); - } - - block = block.next(); - top = bottom; - bottom = top + (int)blockBoundingRect(block).height(); - ++blockNumber; - } -} - -void rgSourceCodeEditor::mousePressEvent(QMouseEvent* pEvent) -{ - // Close the context menu if it is open. - if (m_pContextMenu != nullptr) - { - m_pContextMenu->close(); - } - - // Only open the context menu on right-click. - // In that case do not process the event further. - if (pEvent != nullptr && pEvent->button() == Qt::RightButton) - { - // Simulate a left click event to bring us to the current line. - Qt::MouseButtons buttons; - QMouseEvent* pDummyEvent = new QMouseEvent(pEvent->type(), pEvent->localPos(), pEvent->screenPos(), - Qt::MouseButton::LeftButton, buttons, pEvent->modifiers()); - emit mousePressEvent(pDummyEvent); - } - else - { - // Disable disassembly view's scroll bar signals. - // This is needed because when the user clicks on source code editor, - // the disassembly view's scroll bars emit a signal, causing the - // disassembly view's border to be colored red, and now the user - // will see both the source code editor and the disassembly view - // with a red border around it. - emit DisableScrollbarSignals(); - - emit SourceCodeEditorFocusInEvent(); - - // Pass the event onto the base class. - QPlainTextEdit::mousePressEvent(pEvent); - - // Enable disassembly view's scroll bar signals. - emit EnableScrollbarSignals(); - } -} - -void rgSourceCodeEditor::mouseDoubleClickEvent(QMouseEvent * pEvent) -{ - // Override the double-click event to avoid QPlainTextEdit - // from interpreting the sequence that happens when we simulate - // a left click as an event of a triple click and select the entire - // row's text. - QTextCursor cursor = this->textCursor(); - cursor.select(QTextCursor::SelectionType::WordUnderCursor); - this->setTextCursor(cursor); -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgSourceEditorSearcher.cpp b/RadeonGPUAnalyzerGUI/Src/rgSourceEditorSearcher.cpp deleted file mode 100644 index fe52ecd..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgSourceEditorSearcher.cpp +++ /dev/null @@ -1,194 +0,0 @@ -// C++. -#include - -// Local. -#include -#include -#include - -// The value used to represent the state where a search doesn't return any results. -static const int s_INVALID_SEARCH_LOCATION = -1; - -rgSourceEditorSearcher::rgSourceEditorSearcher() - : m_lastFoundPosition(s_INVALID_SEARCH_LOCATION) -{ -} - -uint32_t rgSourceEditorSearcher::GetSupportedOptions() -{ - return SupportedOptions::FindNext | - SupportedOptions::FindPrevious | - SupportedOptions::MatchCase; -} - -bool rgSourceEditorSearcher::Find(const QString& searchString, SearchDirection direction) -{ - bool ret = false; - - if (searchString.isEmpty()) - { - ResetSearch(); - } - else - { - // The search string has changed since the last search. Search with the new string. - if (searchString.compare(m_lastSearchString.c_str()) != 0) - { - // Reset the search results. - ResetSearch(); - - // Attempt to find new results. - ret = FindResults(searchString); - } - else - { - ret = !m_resultIndices.empty(); - } - } - - // Are there results to step through? - if (ret && !m_resultIndices.empty()) - { - if (direction == ISearchable::SearchDirection::Next) - { - // Step to the next result. Loop back around to the first result if necessary. - m_lastFoundPosition++; - if (m_lastFoundPosition >= m_resultIndices.size()) - { - m_lastFoundPosition = 0; - } - } - else if (direction == ISearchable::SearchDirection::Previous) - { - // Step to the previous result. Loop back around to the last result if necessary. - m_lastFoundPosition--; - if (m_lastFoundPosition < 0) - { - m_lastFoundPosition = static_cast(m_resultIndices.size()) - 1; - } - } - else - { - assert(false); - } - - // Verify that the result index is valid. - bool isValidResultIndex = m_lastFoundPosition >= 0 && m_lastFoundPosition < m_resultIndices.size(); - assert(isValidResultIndex); - if (isValidResultIndex) - { - // Find the location of the current result. - size_t occurrencePosition = m_resultIndices[m_lastFoundPosition]; - - // Select the result in the editor. - QTextCursor currentCursor = m_pTargetEditor->textCursor(); - currentCursor.setPosition(static_cast(occurrencePosition)); - currentCursor.setPosition(static_cast(occurrencePosition) + searchString.size(), QTextCursor::KeepAnchor); - SetCodeEditorCursor(currentCursor); - } - } - - return ret; -} - -void rgSourceEditorSearcher::ResetSearch() -{ - // Reset the last found position. - m_lastFoundPosition = s_INVALID_SEARCH_LOCATION; - - // Reset the last search string. - m_lastSearchString.clear(); - - // Clear the result indices. - m_resultIndices.clear(); - - // Clear the current selection, since the search is over. - QTextCursor clearedSelection = m_pTargetEditor->textCursor(); - clearedSelection.clearSelection(); - SetCodeEditorCursor(clearedSelection); -} - -void rgSourceEditorSearcher::SetSearchOptions(const SearchOptions& options) -{ - m_searchOptions = options; -} - -void rgSourceEditorSearcher::SetTargetEditor(rgSourceCodeEditor* pTargetEditor) -{ - // Set the target editor that will be searched. - m_pTargetEditor = pTargetEditor; -} - -void FindSearchResultIndices(const QString& text, const QString& textToFind, std::vector& searchResultIndices) -{ - // Step the cursor through the entire field of text to search. - size_t cursorIndex = text.indexOf(textToFind, 0); - - // Step through the text to search until we hit the end. - size_t searchStringLength = textToFind.size(); - while (cursorIndex != std::string::npos) - { - // Found an result occurrence. Push it into the results list. - searchResultIndices.push_back(cursorIndex); - - // Search for the next result location. - cursorIndex = text.indexOf(textToFind, static_cast(cursorIndex + searchStringLength)); - } -} - -bool rgSourceEditorSearcher::FindResults(const QString& searchString) -{ - bool ret = false; - - assert(m_pTargetEditor != nullptr); - if (m_pTargetEditor != nullptr) - { - // Search the target source editor for the search text. - if (!searchString.isEmpty()) - { - const QString& text = m_pTargetEditor->toPlainText(); - - // Create a search predicate that search using the case sensitivity option. - if (!m_searchOptions.m_matchCase) - { - // When case insensitive, convert the search string and document text to lowercase. - QString lowercaseText = text; - lowercaseText = lowercaseText.toLower(); - - QString lowercaseTextToFind = searchString; - lowercaseTextToFind = lowercaseTextToFind.toLower(); - - // Perform the search on the converted text. - FindSearchResultIndices(lowercaseText, lowercaseTextToFind, m_resultIndices); - } - else - { - // Search the text for the given search string. - FindSearchResultIndices(text, searchString, m_resultIndices); - } - - // If any results were found, store the search string. - if (!m_resultIndices.empty()) - { - m_lastSearchString = searchString.toStdString(); - ret = true; - } - } - } - - return ret; -} - -void rgSourceEditorSearcher::SetCodeEditorCursor(const QTextCursor& cursor) -{ - assert(m_pTargetEditor != nullptr); - if (m_pTargetEditor != nullptr) - { - // Disable signals emitted by the Code Editor to prevent switching kernel/correlation context. - // The signal block will be released right after getting out of scope of this function. - QSignalBlocker blocker(m_pTargetEditor); - - // Set cursor for the current Code Editor. - m_pTargetEditor->setTextCursor(cursor); - } -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgSourceEditorTitlebar.cpp b/RadeonGPUAnalyzerGUI/Src/rgSourceEditorTitlebar.cpp deleted file mode 100644 index 80bcde2..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgSourceEditorTitlebar.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// C++. -#include -#include - -// Local -#include -#include -#include - -rgSourceEditorTitlebar::rgSourceEditorTitlebar(QWidget* pParent) : - QFrame(pParent) -{ - ui.setupUi(this); - - // Initialize the title bar text and tooltip. - std::stringstream titlebarText; - titlebarText << STR_SOURCE_EDITOR_TITLEBAR_CORRELATION_DISABLED_A; - titlebarText << STR_SOURCE_EDITOR_TITLEBAR_CORRELATION_DISABLED_B; - ui.sourceCorrelationLabel->setText(titlebarText.str().c_str()); - - // Initialize the title bar contents to be hidden. - SetTitlebarContentsVisibility(false); - - // Set the mouse cursor to pointing hand cursor. - SetCursor(); - - // Connect the signals. - ConnectSignals(); - - // Prep the dismiss message push button. - ui.dismissMessagePushButton->setIcon(QIcon(":/icons/deleteIcon.svg")); - ui.dismissMessagePushButton->setStyleSheet("border: none"); -} - -void rgSourceEditorTitlebar::ConnectSignals() -{ - bool isConnected = connect(ui.dismissMessagePushButton, &QPushButton::clicked, this, &rgSourceEditorTitlebar::HandleDismissMessagePushButtonClicked); - assert(isConnected); - - isConnected = connect(ui.dismissMessagePushButton, &QPushButton::clicked, this, &rgSourceEditorTitlebar::DismissMsgButtonClicked); - assert(isConnected); -} - -void rgSourceEditorTitlebar::HandleDismissMessagePushButtonClicked(/* bool checked */) -{ - SetTitlebarContentsVisibility(false); -} - -void rgSourceEditorTitlebar::SetIsCorrelationEnabled(bool isEnabled) -{ - // Only show the title bar content if source line correlation is disabled. - SetTitlebarContentsVisibility(!isEnabled); -} - -void rgSourceEditorTitlebar::ShowMessage(const std::string& msg) -{ - ui.sourceCorrelationLabel->setText(msg.c_str()); - SetTitlebarContentsVisibility(true); -} - -void rgSourceEditorTitlebar::SetCursor() -{ - // Set the mouse cursor to pointing hand cursor. - ui.viewMaximizeButton->setCursor(Qt::PointingHandCursor); - ui.dismissMessagePushButton->setCursor(Qt::PointingHandCursor); -} - -void rgSourceEditorTitlebar::SetTitlebarContentsVisibility(bool isVisible) -{ - ui.sourceCorrelationIcon->setVisible(isVisible); - ui.sourceCorrelationLabel->setVisible(isVisible); - ui.dismissMessagePushButton->setVisible(isVisible); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgStartTab.cpp b/RadeonGPUAnalyzerGUI/Src/rgStartTab.cpp deleted file mode 100644 index 7652471..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgStartTab.cpp +++ /dev/null @@ -1,539 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include -#include - -// Infra. -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include - -rgStartTab::rgStartTab(QWidget* pParent) - : QWidget(pParent), - m_pParent(pParent) -{ - // Setup the UI. - ui.setupUi(this); - - // Set the cursor for the context menu. - m_menu.setCursor(Qt::PointingHandCursor); -} - -void rgStartTab::Initialize() -{ - // Connect signals within the start tab. - ConnectSignals(); - - // Create the context menu for recent files - CreateContextMenu(); - - // Apply string constants to the view's widgets. - ApplyStringConstants(); - - // Initialize the start buttons. - InitializeStartButtons(); - - // Populate the list of recent projects. - PopulateRecentProjectsList(); - - // Set the cursor type for specific widgets in the view. - SetCursor(); - - // Install an event filter to handle up/down arrow keys on the recent files list widget. - qApp->installEventFilter(this); -} - -void rgStartTab::ApplyStringConstants() -{ - // Apply string constants that apply to a specific API. - ApplyApiStringConstants(); - - // Set tooltips and status tips. - rgUtils::SetToolAndStatusTip(STR_MENU_BAR_OPEN_PROJECT_TOOLTIP, ui.recentProjectsOtherPushButton); - rgUtils::SetToolAndStatusTip(STR_MENU_BAR_HELP_ABOUT_TOOLTIP, ui.aboutRGAPushButton); - rgUtils::SetToolAndStatusTip(STR_MENU_BAR_HELP_MANUAL_TOOLTIP, ui.helpManualPushButton); - rgUtils::SetToolAndStatusTip(STR_MENU_BAR_HELP_GETTING_STARTED_GUIDE_TOOLTIP, ui.gettingStartedPushButton); -} - -void rgStartTab::ConnectSignals() -{ - // Open recent project with the "Other..." button. - bool isConnected = connect(this->ui.recentProjectsOtherPushButton, &QPushButton::pressed, this, &rgStartTab::OpenProjectFileEvent); - assert(isConnected); - - // About RGA. - isConnected = connect(this->ui.aboutRGAPushButton, &QPushButton::pressed, this, &rgStartTab::AboutEvent); - assert(isConnected); - - // Getting started guide. - isConnected = connect(this->ui.gettingStartedPushButton, &QPushButton::pressed, this, &rgStartTab::GettingStartedGuideEvent); - assert(isConnected); - - // Help manual. - isConnected = connect(this->ui.helpManualPushButton, &QPushButton::pressed, this, &rgStartTab::HelpManual); - assert(isConnected); -} - -void rgStartTab::ClearRecentProjectsList() -{ - // Only clear the list if it already exists. - if (m_pRecentProjectButtonGroup != nullptr) - { - // Remove all Recent Project buttons added to the list. - QLayout* pRecentProjectsList = ui.recentProgramsWrapper->layout(); - assert(pRecentProjectsList != nullptr); - - // Delete the custom recent projects widgets. - QList widgetList = ui.recentProgramsWrapper->findChildren(); - for (rgRecentProjectWidget* pRecentProjectWidget : widgetList) - { - assert(pRecentProjectWidget != nullptr); - if (pRecentProjectWidget != nullptr) - { - // Remove each button widget from the list of recent projects, and destroy it. - pRecentProjectsList->removeWidget(pRecentProjectWidget); - RG_SAFE_DELETE(pRecentProjectWidget); - } - } - - // Destroy the recent projects list button group. - RG_SAFE_DELETE(m_pRecentProjectButtonGroup); - - // Reorder the tab order to allow for the recent projects list removals. - ReorderTabOrder(); - } -} - -void rgStartTab::CreateContextMenu() -{ - m_pOpenRecentAction = new QAction(STR_MAIN_WINDOW_LOAD_PROJECT, nullptr); - m_menu.addAction(m_pOpenRecentAction); - - // Add a separator between the current menu items. - m_menu.addSeparator(); - - m_pOpenContainingFolderAction = new QAction(STR_FILE_CONTEXT_MENU_OPEN_CONTAINING_FOLDER, nullptr); - m_menu.addAction(m_pOpenContainingFolderAction); -} - -void rgStartTab::InitializeStartButtons() -{ - QVBoxLayout* pVerticalButtonsLayout = ui.startLinkLayout; - assert(pVerticalButtonsLayout != nullptr); - if (pVerticalButtonsLayout != nullptr) - { - // Retrieve the list of start buttons to add to the tab. - std::vector startButtons; - GetStartButtons(startButtons); - - // Add the Start buttons to the view. - for (auto pStartButton : startButtons) - { - // Set the cursor for each of the start buttons being added to the start tab. - pStartButton->setCursor(Qt::PointingHandCursor); - - // Add the widget to the start tab and the ScalingManager. - pVerticalButtonsLayout->addWidget(pStartButton); - ScalingManager::Get().RegisterObject(pStartButton); - } - } -} - -void rgStartTab::ReorderTabOrder() -{ - std::vector startButtons; - GetStartButtons(startButtons); - - QPushButton* pLastStartButton = nullptr; - if (!startButtons.empty()) - { - // Initialize to the first start button. - pLastStartButton = startButtons[0]; - - // Start at the second button if one exists. - for (size_t startButtonIndex = 1; startButtonIndex < startButtons.size(); ++startButtonIndex) - { - setTabOrder(pLastStartButton, startButtons[startButtonIndex]); - pLastStartButton = startButtons[startButtonIndex]; - } - } - - // Get the recent projects buttons list. - QList recentProjectsList; - if (m_pRecentProjectButtonGroup != nullptr) - { - recentProjectsList = m_pRecentProjectButtonGroup->buttons(); - } - - // If the recent projects list is not empty, add tab order for these projects. - if (!recentProjectsList.isEmpty()) - { - setTabOrder(pLastStartButton, recentProjectsList.at(0)); - - for (int i = 1; i < recentProjectsList.count() - 1; i++) - { - setTabOrder(recentProjectsList.at(i), recentProjectsList.at(i + 1)); - } - setTabOrder(recentProjectsList.at(recentProjectsList.count() - 1), ui.recentProjectsOtherPushButton); - } - else - { - setTabOrder(pLastStartButton, ui.recentProjectsOtherPushButton); - } - - setTabOrder(ui.recentProjectsOtherPushButton, ui.aboutRGAPushButton); - setTabOrder(ui.aboutRGAPushButton, ui.helpManualPushButton); - setTabOrder(ui.helpManualPushButton, ui.gettingStartedPushButton); -} - -void rgStartTab::SetCursor() -{ - // Set the cursor to pointing hand cursor. - ui.recentProjectsOtherPushButton->setCursor(Qt::PointingHandCursor); - ui.aboutRGAPushButton->setCursor(Qt::PointingHandCursor); - ui.gettingStartedPushButton->setCursor(Qt::PointingHandCursor); - ui.helpManualPushButton->setCursor(Qt::PointingHandCursor); -} - -void rgStartTab::SetProjectAPIIcon(rgProjectAPI api, rgRecentProjectWidget* pRecentProjectWidget) -{ - // Get and set the appropriate API icon. - switch (api) - { - case rgProjectAPI::OpenCL: - { - pRecentProjectWidget->SetIcon(QIcon(":/icons/ApiLogos/openCLIconWide.png")); - pRecentProjectWidget->SetIconProjectType(STR_API_NAME_OPENCL); - } - break; - case rgProjectAPI::Vulkan: - { - pRecentProjectWidget->SetIcon(QIcon(":/icons/ApiLogos/vulkanIcon.png")); - pRecentProjectWidget->SetIconProjectType(STR_API_NAME_VULKAN); - } - break; - case rgProjectAPI::Unknown: - default: - { - // Should not get here. - assert(false); - } - break; - } -} - -void rgStartTab::PopulateRecentProjectsList() -{ - // Clear the existing list of recent project buttons added to the view. - ClearRecentProjectsList(); - - const std::vector>& recentProjects = rgConfigManager::Instance().GetRecentProjects(); - - bool hasRecentProjects = recentProjects.size() > 0; - - // Change the visibility of the "No recent sessions" label depending on what's in the settings file. - ui.noRecentSessionsDummyPushButton->setVisible(!hasRecentProjects); - - if (hasRecentProjects) - { - // Create a new button group to handle clicks on recent project buttons. - m_pRecentProjectButtonGroup = new QButtonGroup(this); - bool isConnected = connect(m_pRecentProjectButtonGroup, static_cast(&QButtonGroup::buttonClicked), - this, &rgStartTab::HandleRecentProjectClickedEvent); - assert(isConnected); - - // If the button group handler is connected correctly, add a button for each recent project entry. - if (isConnected) - { - QLayout* pRecentProjectsList = ui.recentProgramsWrapper->layout(); - assert(pRecentProjectsList != nullptr); - - int numRecentProjects = static_cast(recentProjects.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 buttonIndex = numRecentProjects; - for (std::vector>::const_reverse_iterator projectIter = recentProjects.rbegin(); - projectIter != recentProjects.rend(); ++projectIter) - { - if (*projectIter != nullptr) - { - // Display the most recent projects at the end of the list. - const std::string& projectPath = (*projectIter)->projectPath; - rgProjectAPI projectApiType = (*projectIter)->apiType; - - // Extract just the filename to display in the list of recent projects. - std::string projectName; - bool isOk = rgUtils::ExtractFileName(projectPath, projectName, true); - assert(isOk); - - if (isOk) - { - // Build and set the status tip message. - std::stringstream statusTipMsg; - statusTipMsg << STR_MAIN_WINDOW_LOAD_PROJECT << " " << projectName.c_str(); - - // Add the layout to the list of recent project buttons. - rgRecentProjectWidget* pRecentProjectWidget = new rgRecentProjectWidget(); - pRecentProjectsList->addWidget(pRecentProjectWidget); - - // Set the text as the project name, and the tooltip as the full path. - pRecentProjectWidget->SetProjectName(QString::fromStdString(projectName)); - pRecentProjectWidget->setToolTip(projectPath.c_str()); - pRecentProjectWidget->setStatusTip(statusTipMsg.str().c_str()); - - // Set the appropriate project API icon. - SetProjectAPIIcon(projectApiType, pRecentProjectWidget); - - // Set the context menu. - pRecentProjectWidget->setContextMenuPolicy(Qt::CustomContextMenu); - - // Connect signal/slot for the context menu. - bool isConnected = connect(pRecentProjectWidget, &rgRecentProjectWidget::customContextMenuRequested, this, &rgStartTab::HandleContextMenuRequest); - assert(isConnected); - - // Add the recent project button to the group. - m_pRecentProjectButtonGroup->addButton(pRecentProjectWidget->GetPushButton(), --buttonIndex); - } - } - } - } - } - - // Reorder the tab order to allow for the recent projects list additions. - ReorderTabOrder(); -} - -QWidget* rgStartTab::GetRecentProgramsListWidget() const -{ - return ui.recentProgramsWrapper; -} - -// Get the button used to create a new project. -QPushButton* rgStartTab::GetCreateNewFileButton() -{ - QPushButton* pButton = nullptr; - - std::vector startButtons; - GetStartButtons(startButtons); - - if (!startButtons.empty()) - { - // Return the first button in the list, which will create a new project. - pButton = startButtons[0]; - } - - return pButton; -} - -void rgStartTab::HandleContextMenuRequest(const QPoint& pos) -{ - // Set context menu mouse cursor - m_menu.setCursor(Qt::PointingHandCursor); - - // The list of actions in the context menu. - QList menuActions = m_menu.actions(); - - // Extract the file name clicked on - QObject* pSender = QObject::sender(); - rgRecentProjectWidget* pRecentProjectWidget = qobject_cast(pSender); - assert(pRecentProjectWidget != nullptr); - if (pRecentProjectWidget != nullptr) - { - QString fileName = pRecentProjectWidget->GetProjectName(); - - foreach(auto pAction, menuActions) - { - if (pAction == m_pOpenRecentAction) - { - // Build the Load string. - QString loadString; - loadString.append(STR_MAIN_WINDOW_LOAD_PROJECT); - loadString.append(" "); - loadString.append(fileName); - pAction->setText(loadString); - break; - } - } - - QAction* pAction = m_menu.exec(QCursor::pos()); - - // Process the context menu selection - if (pAction != nullptr) - { - QString menuSelection = pAction->text(); - - // Find out the index into the button group for this file - QList buttonList = m_pRecentProjectButtonGroup->buttons(); - int recentFileIndex = 0; - - // Find the index for the button clicked on - foreach(auto pButton, buttonList) - { - recentFileIndex++; - if (fileName.compare(pButton->text()) == 0) - { - break; - } - } - - // Determine the index of the recent item that was clicked. - int selectedFileIndex = buttonList.count() - recentFileIndex; - bool isIndexValid = (selectedFileIndex >= 0 && selectedFileIndex < buttonList.count()); - assert(isIndexValid); - if (isIndexValid) - { - // Pull the recent project info out of the global settings structure. - std::shared_ptr pGlobalSettings = rgConfigManager::Instance().GetGlobalConfig(); - const std::string& projectPath = pGlobalSettings->m_recentProjects[selectedFileIndex]->projectPath; - - if (pAction == m_pOpenRecentAction) - { - // Attempt to load the recent project. - assert(false); - emit OpenProjectFileAtPath(projectPath); - } - else if (pAction == m_pOpenContainingFolderAction) - { - // Get the directory where the project's settings file lives. - std::string fileDirectory; - bool gotDirectory = rgUtils::ExtractFileDirectory(projectPath, fileDirectory); - assert(gotDirectory); - - if (gotDirectory) - { - // Open a system file browser window pointing to the given directory. - rgUtils::OpenFolderInFileBrowser(fileDirectory); - } - } - } - } - } -} - -void rgStartTab::HandleRecentProjectClickedEvent(int recentFileIndex) -{ - std::shared_ptr pGlobalSettings = rgConfigManager::Instance().GetGlobalConfig(); - - if (pGlobalSettings != nullptr) - { - bool isValidRange = (recentFileIndex >= 0 && recentFileIndex < pGlobalSettings->m_recentProjects.size()); - assert(isValidRange); - - // If the file index is valid, attempt to open the file. - if (isValidRange) - { - assert(pGlobalSettings->m_recentProjects[recentFileIndex] != nullptr); - if (pGlobalSettings->m_recentProjects[recentFileIndex] != nullptr) - { - // Pull the recent project info out of the global settings structure. - std::string projectPath = pGlobalSettings->m_recentProjects[recentFileIndex]->projectPath; - - // Attempt to load the project. - emit OpenProjectFileAtPath(projectPath); - } - } - } -} - -bool rgStartTab::eventFilter(QObject* pObject, QEvent* pEvent) -{ - assert(pObject != nullptr); - assert(pEvent != nullptr); - - bool filtered = false; - - if (pEvent != nullptr && pEvent->type() == QEvent::KeyPress) - { - QKeyEvent* pKeyEvent = static_cast(pEvent); - assert(pKeyEvent != nullptr); - - // Find out if we need to process this key press. - QString objectName; - if (pObject != nullptr) - { - objectName = pObject->objectName(); - } - bool processKeyPress = ProcessKeyPress(pKeyEvent, objectName); - - if (processKeyPress) - { - if (pObject == ui.recentProgramsWrapper) - { - if (pKeyEvent != nullptr) - { - switch (pKeyEvent->key()) - { - case Qt::Key_Up: - { - // Give focus to the last item under the "Start" section. - std::vector startButtons; - GetStartButtons(startButtons); - if (!startButtons.empty()) - { - QPushButton* pLastStartButton = *(startButtons.rbegin()); - pLastStartButton->setFocus(); - } - filtered = true; - } - break; - case Qt::Key_Down: - // Give focus to the next widget. - ui.recentProjectsOtherPushButton->setFocus(); - filtered = true; - - break; - } - } - } - } - else - { - // Ignore up/down key presses for top and bottom buttons. - filtered = true; - } - } - - // Allow base class to filter the event if needed. - if (!filtered) - { - filtered = QWidget::eventFilter(pObject, pEvent); - } - - return filtered; -} - -bool rgStartTab::ProcessKeyPress(QKeyEvent* pKeyEvent, const QString& objectName) -{ - assert(pKeyEvent != nullptr); - - static const char* STR_NEW_FILE_PUSH_BUTTON = "newFilePushButton"; - static const char* STR_GETTING_STARTED_PUSH_BUTTON = "gettingStartedPushButton"; - - bool result = true; - - if (pKeyEvent != nullptr) - { - if (objectName.compare(STR_NEW_FILE_PUSH_BUTTON) == 0 && pKeyEvent->key() == Qt::Key_Up) - { - result = false; - } - else if (objectName.compare(STR_GETTING_STARTED_PUSH_BUTTON) == 0 && pKeyEvent->key() == Qt::Key_Down) - { - result = false; - } - } - - return result; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgStartTabOpenCL.cpp b/RadeonGPUAnalyzerGUI/Src/rgStartTabOpenCL.cpp deleted file mode 100644 index 250c768..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgStartTabOpenCL.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// C++. -#include - -// Qt. -#include - -// Local. -#include -#include -#include -#include - -rgStartTabOpenCL::rgStartTabOpenCL(QWidget* pParent) - : rgStartTab(pParent) -{ - // Initialize the OpenCL start buttons. - InitializeStartButtons(); - - // Connect OpenCL start page signals. - ConnectSignals(); -} - -void rgStartTabOpenCL::ApplyApiStringConstants() -{ - // Set label/button text. - m_pCreateNewCLSourceFile->setText(STR_MENU_BAR_CREATE_NEW_FILE_OPENCL); - m_pAddExistingCLSourceFile->setText(STR_MENU_BAR_OPEN_EXISTING_FILE_OPENCL); - - // Set tooltips and status tips. - rgUtils::SetToolAndStatusTip(STR_MENU_BAR_CREATE_NEW_FILE_TOOLTIP_OPENCL, m_pCreateNewCLSourceFile); - rgUtils::SetToolAndStatusTip(STR_MENU_BAR_OPEN_EXISTING_FILE_TOOLTIP_OPENCL, m_pAddExistingCLSourceFile); -} - -void rgStartTabOpenCL::GetStartButtons(std::vector& startButtons) -{ - startButtons.push_back(m_pCreateNewCLSourceFile); - startButtons.push_back(m_pAddExistingCLSourceFile); -} - -void rgStartTabOpenCL::InitializeStartButtons() -{ - // Create the "Create .cl file" button. - m_pCreateNewCLSourceFile = new QPushButton(this); - m_pCreateNewCLSourceFile->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - m_pCreateNewCLSourceFile->setText(STR_MENU_BAR_CREATE_NEW_FILE_OPENCL); - m_pCreateNewCLSourceFile->setToolTip(STR_MENU_BAR_CREATE_NEW_FILE_TOOLTIP_OPENCL); - - // Create the "Add existing .cl file" button. - m_pAddExistingCLSourceFile = new QPushButton(this); - m_pAddExistingCLSourceFile->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - m_pAddExistingCLSourceFile->setText(STR_MENU_BAR_OPEN_EXISTING_FILE_OPENCL); - m_pAddExistingCLSourceFile->setToolTip(STR_MENU_BAR_OPEN_EXISTING_FILE_TOOLTIP_OPENCL); -} - -void rgStartTabOpenCL::ConnectSignals() -{ - // Create New File action. - bool isConnected = connect(m_pCreateNewCLSourceFile, &QPushButton::clicked, this, &rgStartTabOpenCL::CreateNewCLFileEvent); - assert(isConnected); - - // Open a file. - isConnected = connect(m_pAddExistingCLSourceFile, &QPushButton::clicked, this, &rgStartTabOpenCL::OpenExistingFileEvent); - assert(isConnected); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgStartTabVulkan.cpp b/RadeonGPUAnalyzerGUI/Src/rgStartTabVulkan.cpp deleted file mode 100644 index 2760aa2..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgStartTabVulkan.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// C++. -#include - -// Infra. -#include - -// Local. -#include -#include -#include - -rgStartTabVulkan::rgStartTabVulkan(QWidget* pParent) - : rgStartTab(pParent) -{ - // Initialize the start buttons. - InitializeStartButtons(); - - // Connect the start page signals. - ConnectSignals(); -} - -void rgStartTabVulkan::ApplyApiStringConstants() -{ - // Set label/button text. - m_pCreateGraphicsPipelinePushButton->setText(STR_MENU_BAR_CREATE_NEW_GRAPHICS_PSO_VULKAN); - m_pCreateComputePipelinePushButton->setText(STR_MENU_BAR_CREATE_NEW_COMPUTE_PSO_VULKAN); - - // Set tooltips and status tips. - rgUtils::SetToolAndStatusTip(STR_MENU_BAR_CREATE_NEW_GRAPHICS_PSO_TOOLTIP_VULKAN, m_pCreateGraphicsPipelinePushButton); - rgUtils::SetToolAndStatusTip(STR_MENU_BAR_CREATE_NEW_COMPUTE_PSO_TOOLTIP_VULKAN, m_pCreateComputePipelinePushButton); -} - -void rgStartTabVulkan::GetStartButtons(std::vector& startButtons) -{ - startButtons.push_back(m_pCreateGraphicsPipelinePushButton); - startButtons.push_back(m_pCreateComputePipelinePushButton); -} - -void rgStartTabVulkan::InitializeStartButtons() -{ - // Create the "Create graphics pipeline" button. - m_pCreateGraphicsPipelinePushButton = new QPushButton(this); - m_pCreateGraphicsPipelinePushButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - m_pCreateGraphicsPipelinePushButton->setText(STR_MENU_BAR_CREATE_NEW_GRAPHICS_PSO_VULKAN); - - // Create the "Create compute pipeline" button. - m_pCreateComputePipelinePushButton = new QPushButton(this); - m_pCreateComputePipelinePushButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - m_pCreateComputePipelinePushButton->setText(STR_MENU_BAR_CREATE_NEW_COMPUTE_PSO_VULKAN); -} - -void rgStartTabVulkan::ConnectSignals() -{ - // Create new Graphics PSO action. - bool isConnected = connect(m_pCreateGraphicsPipelinePushButton, &QPushButton::clicked, this, &rgStartTabVulkan::CreateGraphicsPipelineEvent); - assert(isConnected); - - // Connect the new Compute PSO action. - isConnected = connect(m_pCreateComputePipelinePushButton, &QPushButton::clicked, this, &rgStartTabVulkan::CreateComputePipelineEvent); - assert(isConnected); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgStartupDialog.cpp b/RadeonGPUAnalyzerGUI/Src/rgStartupDialog.cpp deleted file mode 100644 index b473f2f..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgStartupDialog.cpp +++ /dev/null @@ -1,268 +0,0 @@ -// C++. -#include -#include - -// Infra. -#include - -// Local. -#include -#include -#include -#include -#include -#include "ui_rgStartupDialog.h" - -static const int s_HORIZONTAL_LAYOUT_SPACING = 15; -static const int s_LEFT_AND_RIGHT_MARGIN = 23; -static const int s_SPACING_AFTER_LABEL = 10; -static const std::vector s_DESCRIPTION_STRINGS = { STR_STARTUP_DIALOG_OPENCL_DESCRIPTION, - STR_STARTUP_DIALOG_VULKAN_DESCRIPTION }; - -rgStartupDialog::rgStartupDialog(QWidget* pParent) : - QDialog(pParent), - m_selectedApi(rgProjectAPI::Vulkan), - m_shouldNotAskAgain(false) -{ - ui.setupUi(this); - - // Set the background color to white. - QPalette pal = palette(); - pal.setColor(QPalette::Background, Qt::white); - setAutoFillBackground(true); - setPalette(pal); - - // Disable the help button in the title bar, and disable resizing of this dialog. - setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint); - - // Shift the initial focus to the Do Not Ask Me Again check box. - ui.DoNotAskMeAgainCheckBox->setFocus(); - - // Connect signals. - ConnectSignals(); - - // Populate the API list widget. (Starting with Vulkan, and going backwards). - for (int apiIndex = static_cast(rgProjectAPI::Vulkan); apiIndex > 0; --apiIndex) - { - rgProjectAPI currentApi = static_cast(apiIndex); - std::string apiString; - rgUtils::ProjectAPIToString(currentApi, apiString); - ui.apiListWidget->addItem(QString::fromStdString(apiString)); - } - - // Select Vulkan selection in the list widget by default. - ui.apiListWidget->setCurrentRow(0); - ui.apiListWidget->setFocus(); - - // Set the description for Vulkan selection. - ui.descriptionLabel->setText(STR_STARTUP_DIALOG_VULKAN_DESCRIPTION); - - clearFocus(); - - // Set the cursor to pointing hand cursor. - SetCursor(); - - // Set description field length. - SetDescriptionLength(); - - // Set button shortcuts. - ui.exitPushButton->setShortcut(Qt::AltModifier + Qt::Key_X); - ui.startRGAPushButton->setShortcut(Qt::AltModifier + Qt::Key_R); - - //Scale the dialog and the widget inside it. - ScaleDialog(); -} - -void rgStartupDialog::ConnectSignals() const -{ - // Connect the handler invoked when the user clicks the Exit push button. - bool isConnected = connect(ui.exitPushButton, &QPushButton::clicked, this, &rgStartupDialog::HandleExitButtonClicked); - assert(isConnected); - - // Connect the handler invoked when the user clicks the Start RGA push button. - isConnected = connect(ui.startRGAPushButton, &QPushButton::clicked, this, &rgStartupDialog::HandleStartRGAButtonClicked); - assert(isConnected); - - // Connect the handler invoked when the user clicks an item in the API list widget. - isConnected = connect(ui.apiListWidget, &QListWidget::itemClicked, this, &rgStartupDialog::HandleListWidgetItemClicked); - assert(isConnected); - - // Connect the handler invoked when the user double clicks an item in the API list widget. - isConnected = connect(ui.apiListWidget, &QListWidget::itemDoubleClicked, this, &rgStartupDialog::HandleListWidgetItemDoubleClicked); - assert(isConnected); - - // Connect the handler invoked when the user selects the API by using up/down arrow keys. - isConnected = connect(ui.apiListWidget, &QListWidget::currentRowChanged, this, &rgStartupDialog::HandleListWidgetItemSelected); - assert(isConnected); -} - -void rgStartupDialog::SetCursor() const -{ - // Set the cursor to pointing hand cursor for various widgets. - ui.DoNotAskMeAgainCheckBox->setCursor(Qt::PointingHandCursor); - ui.exitPushButton->setCursor(Qt::PointingHandCursor); - ui.startRGAPushButton->setCursor(Qt::PointingHandCursor); - ui.apiListWidget->setCursor(Qt::PointingHandCursor); -} - -rgProjectAPI rgStartupDialog::SelectedApi() const -{ - return m_selectedApi; -} - -bool rgStartupDialog::ShouldNotAskAgain() const -{ - return m_shouldNotAskAgain; -} - -void rgStartupDialog::keyPressEvent(QKeyEvent* pEvent) -{ - // Disable the escape key from closing the dialog - if (pEvent->key() != Qt::Key_Escape) - { - QDialog::keyPressEvent(pEvent); - } -} - -void rgStartupDialog::HandleExitButtonClicked(bool /* checked */) -{ - reject(); -} - -void rgStartupDialog::HandleStartRGAButtonClicked(bool /* checked */) -{ - m_shouldNotAskAgain = ui.DoNotAskMeAgainCheckBox->isChecked(); - - accept(); -} - -void rgStartupDialog::HandleListWidgetItemClicked(QListWidgetItem* pItem) -{ - if (pItem->text().compare(STR_API_NAME_OPENCL) == 0) - { - m_selectedApi = rgProjectAPI::OpenCL; - - // Also update the description. - ui.descriptionLabel->setText(STR_STARTUP_DIALOG_OPENCL_DESCRIPTION); - } - else if (pItem->text().compare(STR_API_NAME_VULKAN) == 0) - { - m_selectedApi = rgProjectAPI::Vulkan; - - // Also update the description. - ui.descriptionLabel->setText(STR_STARTUP_DIALOG_VULKAN_DESCRIPTION); - } - else - { - // Should not get here. - assert(false); - m_selectedApi = rgProjectAPI::Unknown; - } -} - -void rgStartupDialog::HandleListWidgetItemDoubleClicked(QListWidgetItem* pItem) -{ - if (pItem->text().compare(STR_API_NAME_OPENCL) == 0) - { - m_selectedApi = rgProjectAPI::OpenCL; - - // Also update the description. - ui.descriptionLabel->setText(STR_STARTUP_DIALOG_OPENCL_DESCRIPTION); - - // Start RGA. - HandleStartRGAButtonClicked(false); - } - else if (pItem->text().compare(STR_API_NAME_VULKAN) == 0) - { - m_selectedApi = rgProjectAPI::Vulkan; - - // Also update the description. - ui.descriptionLabel->setText(STR_STARTUP_DIALOG_VULKAN_DESCRIPTION); - - // Start RGA. - HandleStartRGAButtonClicked(false); - } - else - { - // Should not get here. - assert(false); - m_selectedApi = rgProjectAPI::Unknown; - } -} - -void rgStartupDialog::HandleListWidgetItemSelected(int currentRow) -{ - // Extract the QListWidgetItem that the user just selected and process it. - HandleListWidgetItemClicked(ui.apiListWidget->item(currentRow)); -} - -void rgStartupDialog::SetDescriptionLength() -{ - int maxWidth = 0; - - for (const char* text : s_DESCRIPTION_STRINGS) - { - const QFont font = ui.descriptionLabel->font(); - QFontMetrics fm(font); - const int textWidth = fm.width(text); - - if (textWidth > maxWidth) - { - maxWidth = textWidth; - } - } - ui.descriptionLabel->setMinimumWidth(maxWidth); -} - -void rgStartupDialog::ScaleDialog() -{ - ScalingManager& scalingManager = ScalingManager::Get(); - const double scaleFactor = scalingManager.GetScaleFactor(); - - // Scale the dialog. - QSize size; - size.setWidth(width() * scaleFactor); - size.setHeight(height() * scaleFactor); - setFixedSize(size); - - int leftMargin; - int topMargin; - int rightMargin; - int bottomMargin; - this->layout()->getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin); - leftMargin = leftMargin * scaleFactor; - topMargin = topMargin * scaleFactor; - rightMargin = rightMargin * scaleFactor; - bottomMargin = bottomMargin * scaleFactor; - this->layout()->setContentsMargins(leftMargin, topMargin, rightMargin, bottomMargin); - - // Scale the description header label. - size.setWidth(ui.descriptionLabel_1->width() * scaleFactor); - size.setHeight(ui.descriptionLabel_1->height() * scaleFactor); - ui.descriptionLabel_1->setFixedSize(size); - - // Scale the list widget. - size.setWidth(ui.apiListWidget->width() * scaleFactor); - size.setHeight(ui.apiListWidget->height() * scaleFactor); - ui.apiListWidget->setFixedSize(size); - - // Scale the description text label. - size.setWidth(ui.descriptionLabel->width() * scaleFactor); - size.setHeight(ui.descriptionLabel->height() * scaleFactor); - ui.descriptionLabel->setFixedSize(size); - - // Scale the buttons. - ui.exitPushButton->setFixedWidth(ui.exitPushButton->width() * scaleFactor); - ui.startRGAPushButton->setFixedWidth(ui.startRGAPushButton->width() * scaleFactor); - - // Recalculate and set the width. - QFontMetrics fontMetrics(ui.descriptionLabel->font()); - QRect boundingRect = fontMetrics.boundingRect(ui.descriptionLabel->text()); - const int width = boundingRect.width(); - setFixedWidth(width + ui.apiListWidget->width() - + s_HORIZONTAL_LAYOUT_SPACING * ScalingManager::Get().GetScaleFactor() - + s_LEFT_AND_RIGHT_MARGIN * ScalingManager::Get().GetScaleFactor() - + s_SPACING_AFTER_LABEL * ScalingManager::Get().GetScaleFactor() - ); - -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgStatusBar.cpp b/RadeonGPUAnalyzerGUI/Src/rgStatusBar.cpp deleted file mode 100644 index 07ee8f7..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgStatusBar.cpp +++ /dev/null @@ -1,586 +0,0 @@ -// C++. -#include -#include - -// Qt. -#include -#include -#include -#include -#include -#include -#include - -// Infra. -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include - -static const int s_WIDGET_MINIMUM_HEIGHT = 25; -static const int s_MODE_BUTTON_MINIMUM_WIDTH = 110; -static const int s_PUSH_BUTTON_FONT_SIZE = 11; -static const int s_TREE_WIDGET_ITEM_HEIGHT = 20; -static const int s_MODE_BUTTON_ICON_HEIGHT = 15; -static const int s_TREE_WIDGET_ICON_COLUMN_ID = 0; -static const int s_TREE_WIDGET_API_COLUMN_ID = 1; -static const int s_TREE_WIDGET_ICON_COLUMN_WIDTH = 40; -static const int s_MODE_API_TREE_WIDGET_COLUMN_COUNT = 2; -static const int s_OFFSET_ABOVE_STATUS_BAR = 3; -static const int s_CURRENT_API_INDEX = 0; -static const char* s_STR_MODE = "Mode: "; -static const char* s_CUSTOM_STATUS_BAR_STYLESHEET = "border: none"; -static const char* s_API_BUTTON_TOOLTIP_A = "Switch to "; -static const char* s_API_BUTTON_TOOLTIP_B = " mode."; -static const char* s_CONFIRMATION_MESSAGE = "RGA will switch to %1 mode. Are you sure?"; -static const char* s_CONFIRMATION_MESSAGE_BOX_TITLE = "Switch application mode"; -static const char* s_API_MODE_TREE_WIDGET_STYLESHEET = "border: 1px solid black"; -static const char* s_API_MODE_TREE_WIDGET_OBJECT_NAME = "modeAPIList"; -static const char* s_CHECK_BOX_DISABLED_ICON_FILE = ":/icons/checkedDisabledIcon.svg"; -static const char* s_CHECK_BOX_ICON_LABEL_STYLESHEET = "border: none"; -static const QColor s_API_MODE_TREE_WIDGET_FIRST_COLUMN_BACKGROUND_COLOR = QColor(240, 240, 240); - -class rgApiTreeWidgetItemStyleDelegate : public QStyledItemDelegate -{ -public: - rgApiTreeWidgetItemStyleDelegate(QObject* pParent = nullptr) - : QStyledItemDelegate(pParent) {} - - - void paint(QPainter* pPainter, const QStyleOptionViewItem& option, - const QModelIndex& modelIndex) const - { - // Draw the text for column one manually since we don't want to call the base class' paint method. - if (modelIndex.column() == 1) - { - // Save the painter object. - pPainter->save(); - - // Get the current API. - rgConfigManager& configManager = rgConfigManager::Instance(); - rgProjectAPI currentAPI = configManager.GetCurrentAPI(); - - // Create the API string. - std::string apiString = ""; - rgUtils::ProjectAPIToString(currentAPI, apiString); - - // Set painter options. - QFont font = pPainter->font(); - font.setBold(false); - font.setPointSize(9); - QPen pen = pPainter->pen(); - pen.setColor(Qt::GlobalColor::gray); - pPainter->setPen(pen); - pPainter->setFont(font); - - // Get the text height. - QRect textBoundingRect = pPainter->boundingRect(QRect(0, 0, 0, 0), Qt::AlignLeft, QString::fromStdString(apiString)); - const int textHeight = textBoundingRect.height(); - const int textWidth = textBoundingRect.width(); - - // Calculate the text rect. - QRect rect = option.rect; - int textOffset = (rect.height() - textHeight) / 2; - QRect textRect; - textRect.setLeft(rect.left()); - textRect.setWidth(textWidth); - textRect.setTop(rect.y() + textOffset); - textRect.setHeight(textHeight); - - // Draw the current API text. - pPainter->drawText(textRect, QString::fromStdString(apiString)); - - // Restore the painter object. - pPainter->restore(); - } - } -}; - -rgStatusBar::rgStatusBar(QStatusBar* pStatusBar, QWidget* pParent) : - m_pStatusBar(pStatusBar), - m_pParent(pParent), - QWidget(pParent) -{ - // Create the mode button. - CreateModeButton(); - - // Get the supported API names and create a tree widget. - CreateApiTreeWidget(); - - // Set contents margins. - setContentsMargins(5, 0, 5000, 0); - - // Remove the borders. - setStyleSheet(s_CUSTOM_STATUS_BAR_STYLESHEET); - - // Create a horizontal layout. - m_pHLayout = new QHBoxLayout(); - m_pHLayout->setContentsMargins(0, 0, 0, 0); - m_pHLayout->setSpacing(0); - - // Set layout to horizontal layout. - setLayout(m_pHLayout); - - // Add the mode button to the layout. - m_pHLayout->addWidget(m_pModePushButton); - m_pHLayout->setSizeConstraint(QLayout::SetDefaultConstraint); - - // Set the cursor to pointing hand cursor. - SetCursor(); - - // Connect signals. - ConnectSignals(); - - // Set dimensions. - SetDimensions(); - - // Install an event filter on tree widget to handle up/down arrow keys. - m_pApiModeTreeWidget->installEventFilter(this); - - // Set the delegate for the first row of tree widget. - rgApiTreeWidgetItemStyleDelegate* pItemDelegate = new rgApiTreeWidgetItemStyleDelegate(); - m_pApiModeTreeWidget->setItemDelegateForRow(0, pItemDelegate); -} - -void rgStatusBar::CreateModeButton() -{ - // Get the startup API. - rgConfigManager& configManager = rgConfigManager::Instance(); - rgProjectAPI currentAPI = configManager.GetCurrentAPI(); - - // Create the string for the mode button. - std::string apiString = ""; - rgUtils::ProjectAPIToString(currentAPI, apiString); - QString modePushButtonString = QString(s_STR_MODE) + QString::fromStdString(apiString); - - // Create the mode button. - m_pModePushButton = new rgModePushButton(this); - - // Set text. - m_pModePushButton->SetText(modePushButtonString.toStdString()); - - // Set the font color. - m_pModePushButton->SetColor(Qt::GlobalColor::white); - - // Set the focus policy. - m_pModePushButton->setFocusPolicy(Qt::StrongFocus); -} - -void rgStatusBar::CreateApiTreeWidget() -{ - // Get the list of supported APIs. - std::vector supportedAPIs; - rgConfigManager& configManager = rgConfigManager::Instance(); - configManager.GetSupportedApis(supportedAPIs); - - // Create a tree widget to show API modes. - InitializeTreeWidget(); - - assert(m_pApiModeTreeWidget != nullptr); - if (m_pApiModeTreeWidget != nullptr) - { - for (const std::string& api : supportedAPIs) - { - QTreeWidgetItem* pItem = new QTreeWidgetItem(); - - // If this item is current, disable it so the user cannot select it. - rgProjectAPI currentAPI = configManager.GetCurrentAPI(); - std::string currentAPIString = ""; - rgUtils::ProjectAPIToString(currentAPI, currentAPIString); - if (api.compare(currentAPIString) == 0) - { - // Set the item text. - pItem->setText(s_TREE_WIDGET_API_COLUMN_ID, QString::fromStdString(api)); - - // Add the check box icon in the first column of this item. - AddCheckBoxIcon(pItem); - - // Do not show a tooltip for the current mode. - pItem->setToolTip(s_TREE_WIDGET_ICON_COLUMN_ID, QString()); - pItem->setToolTip(s_TREE_WIDGET_API_COLUMN_ID, QString()); - } - else - { - pItem->setText(s_TREE_WIDGET_API_COLUMN_ID, QString::fromStdString(api)); - m_pApiModeTreeWidget->addTopLevelItem(pItem); - - // Set the tooltip. - QString toolTip = s_API_BUTTON_TOOLTIP_A + QString::fromStdString(api) + s_API_BUTTON_TOOLTIP_B; - pItem->setToolTip(s_TREE_WIDGET_ICON_COLUMN_ID, toolTip); - pItem->setToolTip(s_TREE_WIDGET_API_COLUMN_ID, toolTip); - pItem->setBackgroundColor(s_TREE_WIDGET_ICON_COLUMN_ID, s_API_MODE_TREE_WIDGET_FIRST_COLUMN_BACKGROUND_COLOR); - } - } - m_pApiModeTreeWidget->resizeColumnToContents(s_TREE_WIDGET_API_COLUMN_ID); - m_pApiModeTreeWidget->setColumnWidth(s_TREE_WIDGET_ICON_COLUMN_ID, s_TREE_WIDGET_ICON_COLUMN_WIDTH); - m_pApiModeTreeWidget->setSelectionMode(QAbstractItemView::NoSelection); - m_pApiModeTreeWidget->setFocusPolicy(Qt::NoFocus); - - m_pApiModeTreeWidget->hide(); - } -} - -void rgStatusBar::InitializeTreeWidget() -{ - m_pApiModeTreeWidget = new rgTreeWidget(m_pParent); - m_pApiModeTreeWidget->setColumnCount(s_MODE_API_TREE_WIDGET_COLUMN_COUNT); - m_pApiModeTreeWidget->setColumnWidth(s_TREE_WIDGET_ICON_COLUMN_ID, s_TREE_WIDGET_ICON_COLUMN_WIDTH); - m_pApiModeTreeWidget->setStyleSheet(s_API_MODE_TREE_WIDGET_STYLESHEET); - m_pApiModeTreeWidget->setWindowFlags(Qt::FramelessWindowHint); - m_pApiModeTreeWidget->setObjectName(s_API_MODE_TREE_WIDGET_OBJECT_NAME); - m_pApiModeTreeWidget->setHeaderHidden(true); - m_pApiModeTreeWidget->setContentsMargins(0, 0, 0, 0); - m_pApiModeTreeWidget->setIndentation(0); - m_pApiModeTreeWidget->setAllColumnsShowFocus(true); - - // Disable scrollbars on this tree widget. - m_pApiModeTreeWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_pApiModeTreeWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); -} - -void rgStatusBar::SetDimensions() -{ - assert(m_pModePushButton != nullptr); - if (m_pModePushButton != nullptr) - { - // Mode push button dimensions. - m_pModePushButton->setMinimumHeight(s_WIDGET_MINIMUM_HEIGHT); - m_pModePushButton->setMaximumHeight(s_WIDGET_MINIMUM_HEIGHT); - m_pModePushButton->setMinimumWidth(s_MODE_BUTTON_MINIMUM_WIDTH); - - // Gear icon widget dimensions. - QSize iconSize = m_pModePushButton->iconSize(); - iconSize.setHeight(s_MODE_BUTTON_ICON_HEIGHT); - m_pModePushButton->setIconSize(iconSize); - } - - // Status bar dimensions. - setMinimumHeight(s_WIDGET_MINIMUM_HEIGHT); - setMaximumHeight(s_WIDGET_MINIMUM_HEIGHT); -} - -void rgStatusBar::ConnectSignals() const -{ - // Connect the mode push button's clicked signal. - bool isConnected = connect(m_pModePushButton, &QPushButton::clicked, this, &rgStatusBar::HandleModePushButtonClicked); - assert(isConnected); - - // Connect the API tree widget's clicked signal. - isConnected = connect(m_pApiModeTreeWidget, &QTreeWidget::itemClicked, this, &rgStatusBar::HandleTreeWidgetItemClicked); - assert(isConnected); - - // Connect the API tree widget's itemEntered signal. - isConnected = connect(m_pApiModeTreeWidget, &QTreeWidget::itemEntered, this, &rgStatusBar::HandleTreeWidgetItemEntered); - assert(isConnected); -} - -void rgStatusBar::SetCursor() const -{ - // Set the cursor to pointing hand cursor. - m_pModePushButton->setCursor(Qt::PointingHandCursor); -} - -void rgStatusBar::SetStatusBarVisibility(bool isVisible) -{ - if (isVisible) - { - show(); - } - else - { - hide(); - } -} - -void rgStatusBar::HandleModePushButtonClicked(bool /* checked */) -{ - const int s_TREE_WIDGET_HEIGHT = s_TREE_WIDGET_ITEM_HEIGHT * (static_cast(rgProjectAPI::ApiCount)-1); - - // Process the mode button click. - assert(m_pApiModeTreeWidget != nullptr); - if (m_pApiModeTreeWidget != nullptr) - { - if (m_pApiModeTreeWidget->isVisible()) - { - // Hide the API tree widget. - SetApiListVisibility(false); - } - else - { - // Sort the mode string so the current mode is at the top. - ReorderCurrentMode(); - - // Show the API tree widget. - SetApiListVisibility(true); - QPoint pos(0, 0); - pos = m_pModePushButton->mapTo(m_pParent, pos); - const int yPosition = pos.y() - (s_TREE_WIDGET_HEIGHT * ScalingManager::Get().GetScaleFactor()) - s_OFFSET_ABOVE_STATUS_BAR;; - const int height = s_TREE_WIDGET_HEIGHT * ScalingManager::Get().GetScaleFactor(); - m_pApiModeTreeWidget->setGeometry(pos.x(), yPosition, m_pModePushButton->width(), height); - m_pApiModeTreeWidget->setFocus(); - - // Remove highlight from all rows. - QTreeWidgetItemIterator it(m_pApiModeTreeWidget); - while (*it) - { - (*it)->setBackgroundColor(s_TREE_WIDGET_ICON_COLUMN_ID, Qt::GlobalColor::transparent); - (*it)->setBackgroundColor(s_TREE_WIDGET_API_COLUMN_ID, Qt::GlobalColor::transparent); - ++it; - } - } - } -} - -void rgStatusBar::ReorderCurrentMode() const -{ - assert(m_pApiModeTreeWidget != nullptr); - if (m_pApiModeTreeWidget != nullptr) - { - for (int row = 0; row < m_pApiModeTreeWidget->topLevelItemCount(); row++) - { - QTreeWidgetItem* pItem = m_pApiModeTreeWidget->topLevelItem(row); - bool isItemEnabled = pItem->flags() & Qt::ItemIsSelectable; - if (!isItemEnabled) - { - // Move this item to the top and break out of the loop. - pItem = m_pApiModeTreeWidget->takeTopLevelItem(row); - m_pApiModeTreeWidget->insertTopLevelItem(0, pItem); - - // Add the check box icon in the first column of this item. - AddCheckBoxIcon(pItem); - - break; - } - } - } -} - -void rgStatusBar::AddCheckBoxIcon(QTreeWidgetItem* pItem) const -{ - QIcon icon(s_CHECK_BOX_DISABLED_ICON_FILE); - QLabel* pIconLabel = new QLabel(); - pIconLabel->setAutoFillBackground(true); - QPixmap pixmap = icon.pixmap(QSize(s_TREE_WIDGET_ITEM_HEIGHT * ScalingManager::Get().GetScaleFactor(), s_TREE_WIDGET_ITEM_HEIGHT * ScalingManager::Get().GetScaleFactor())); - pIconLabel->setPixmap(pixmap); - pIconLabel->setContentsMargins(10, 0, 0, 0); - pIconLabel->setStyleSheet(s_CHECK_BOX_ICON_LABEL_STYLESHEET); - pItem->setFlags(pItem->flags() & ~Qt::ItemIsSelectable); - m_pApiModeTreeWidget->addTopLevelItem(pItem); - m_pApiModeTreeWidget->setItemWidget(pItem, s_TREE_WIDGET_ICON_COLUMN_ID, pIconLabel); -} - -bool rgStatusBar::ShowConfirmationDialogBox(const char* pMessage) const -{ - // Create a custom confirmation dialog box. - QMessageBox confirmationDialog; - confirmationDialog.setWindowIcon(QIcon(gs_ICON_RESOURCE_RGA_LOGO)); - confirmationDialog.setWindowTitle(s_CONFIRMATION_MESSAGE_BOX_TITLE); - confirmationDialog.setText(pMessage); - confirmationDialog.setIcon(QMessageBox::Question); - confirmationDialog.setModal(true); - confirmationDialog.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - confirmationDialog.setFocus(); - - // Set button cursor to pointing hand cursor. - QAbstractButton* pButton = confirmationDialog.button(QMessageBox::Button::Yes); - assert(pButton != nullptr); - if (pButton != nullptr) - { - pButton->setCursor(Qt::PointingHandCursor); - } - - pButton = confirmationDialog.button(QMessageBox::Button::No); - assert(pButton != nullptr); - if (pButton != nullptr) - { - pButton->setCursor(Qt::PointingHandCursor); - } - - // Display the dialog box just above the status bar. - QPoint globalCursorPos = QCursor::pos(); - const int dialogHeight = confirmationDialog.height(); - globalCursorPos.setY(globalCursorPos.y() - dialogHeight/2); - confirmationDialog.move(globalCursorPos); - - // Return true if the user clicked yes, otherwise return false. - return (confirmationDialog.exec() == QMessageBox::Yes); -} - -void rgStatusBar::HandleTreeWidgetItemClicked(QTreeWidgetItem* pItem, const int column) -{ - Q_UNUSED(column); - - assert(pItem != nullptr); - if (pItem != nullptr && (pItem->flags() & Qt::ItemIsSelectable)) - { - // If the user clicked on the first item, do nothing. - const int row = m_pApiModeTreeWidget->indexOfTopLevelItem(pItem); - - if (row != s_CURRENT_API_INDEX) - { - QString text = pItem->text(s_TREE_WIDGET_API_COLUMN_ID); - - // Put up a confirmation dialog box. - QString messageString = QString(s_CONFIRMATION_MESSAGE).arg(text); - - // Hide the API list widget. - SetApiListVisibility(false); - - // Show a confirmation dialog box. - bool status = ShowConfirmationDialogBox(messageString.toStdString().c_str()); - - // Set the focus to the mode push button. - m_pModePushButton->setFocus(); - - if (status) - { - // Save any pending changes. - bool isNotCancelled = false; - rgMainWindow* pMainWindow = static_cast(m_pParent); - if (pMainWindow != nullptr) - { - isNotCancelled = pMainWindow->HandleSavePendingChanges(); - } - - // Emit a signal to indicate API change. - if (isNotCancelled) - { - emit ChangeAPIModeSignal(rgUtils::ProjectAPIToEnum((text.toStdString()))); - - // Disable the selected item so the user cannot select it next time around. - pItem->setFlags(pItem->flags() & ~Qt::ItemIsSelectable); - } - } - } - } - else - { - QTreeWidgetItem* pSecondItem = m_pApiModeTreeWidget->topLevelItem(1); - m_pApiModeTreeWidget->setCurrentItem(pSecondItem); - } -} - -void rgStatusBar::SetApiListVisibility(bool isVisible) const -{ - if (isVisible) - { - m_pApiModeTreeWidget->show(); - } - else - { - m_pApiModeTreeWidget->hide(); - } -} - -bool rgStatusBar::eventFilter(QObject* pObject, QEvent* pEvent) -{ - bool status = false; - - if ((pObject == m_pApiModeTreeWidget) && (pEvent->type() == QEvent::KeyPress)) - { - QTreeWidgetItem* pItem = m_pApiModeTreeWidget->currentItem(); - if (pItem != nullptr) - { - QString apiString = pItem->text(s_TREE_WIDGET_API_COLUMN_ID); - const int currentIndex = m_pApiModeTreeWidget->indexOfTopLevelItem(pItem); - if (pEvent->type() == QEvent::KeyPress) - { - QKeyEvent* pKeyEvent = static_cast(pEvent); - if (pKeyEvent->key() == Qt::Key_Up) - { - if (currentIndex == 1 || currentIndex == 0) - { - const int numRows = m_pApiModeTreeWidget->topLevelItemCount(); - QTreeWidgetItem* pItem = m_pApiModeTreeWidget->topLevelItem(numRows - 1); - m_pApiModeTreeWidget->setCurrentItem(pItem); - HandleTreeWidgetItemEntered(pItem, 0); - } - else - { - QTreeWidgetItem* pItem = m_pApiModeTreeWidget->topLevelItem(currentIndex-1); - m_pApiModeTreeWidget->setCurrentItem(pItem); - HandleTreeWidgetItemEntered(pItem, 0); - } - - status = true; - } - else if (pKeyEvent->key() == Qt::Key_Down) - { - if (currentIndex == (m_pApiModeTreeWidget->topLevelItemCount() - 1)) - { - QTreeWidgetItem* pItem = m_pApiModeTreeWidget->topLevelItem(1); - m_pApiModeTreeWidget->setCurrentItem(pItem); - HandleTreeWidgetItemEntered(pItem, 0); - } - else - { - QTreeWidgetItem* pItem = m_pApiModeTreeWidget->topLevelItem(currentIndex+1); - m_pApiModeTreeWidget->setCurrentItem(pItem); - HandleTreeWidgetItemEntered(pItem, 0); - } - - status = true; - } - else if ((pKeyEvent->key() == Qt::Key_Enter) || (pKeyEvent->key() == Qt::Key_Return)) - { - QTreeWidgetItem* pItem = m_pApiModeTreeWidget->currentItem(); - HandleTreeWidgetItemClicked(pItem, s_TREE_WIDGET_API_COLUMN_ID); - HandleTreeWidgetItemEntered(pItem, 0); - - status = true; - } - else if (pKeyEvent->key() == Qt::Key_Escape) - { - SetApiListVisibility(false); - - // Set the focus to the mode push button. - m_pModePushButton->setFocus(); - - status = true; - } - } - } - } - - return status; -} - -void rgStatusBar::HandleTreeWidgetItemEntered(QTreeWidgetItem* pItem, const int column) -{ - // Set background color for all items to transparent. - QTreeWidgetItemIterator it(m_pApiModeTreeWidget); - while (*it) - { - (*it)->setBackgroundColor(s_TREE_WIDGET_ICON_COLUMN_ID, Qt::GlobalColor::transparent); - (*it)->setBackgroundColor(s_TREE_WIDGET_API_COLUMN_ID, Qt::GlobalColor::transparent); - ++it; - } - - // Set the background color for the current item to light blue. - QColor lightBlue(229, 243, 255); - assert(pItem != nullptr); - if (pItem != nullptr) - { - const int columnCount = pItem->columnCount(); - for (int columnNumber = 0; columnNumber < columnCount; columnNumber++) - { - pItem->setBackgroundColor(columnNumber, lightBlue); - } - } -} - -rgModePushButton* rgStatusBar::GetModePushButton() -{ - return m_pModePushButton; -} - -QTreeWidget* rgStatusBar::GetApiListTreeWidget() -{ - return m_pApiModeTreeWidget; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgStatusBarOpenCL.cpp b/RadeonGPUAnalyzerGUI/Src/rgStatusBarOpenCL.cpp deleted file mode 100644 index 3dd47f4..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgStatusBarOpenCL.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// C++. -#include -// Qt. -#include -#include - -// Infra. -#include - -// Local. -#include -#include -#include - -static const QString s_MODE_PUSH_BUTTON_STYLESHEET( - "QPushButton" - "{" - "padding: 5px;" - "border: none;" - "color: white;" - "}" - "QPushButton:hover" - "{" - "background-color: rgb(20, 175, 0, 255);" - "}" -); -static const QString s_STATUS_BAR_BACKRGOUND_COLOR_OPENCL = "background-color: rgb(18, 152, 0)"; -static const QColor s_MODE_PUSH_BUTTON_HOVER_COLOR = QColor(20, 175, 0, 255); -static const QColor s_MODE_PUSH_BUTTON_NON_HOVER_COLOR = QColor(18, 152, 0); - -rgStatusBarOpenCL::rgStatusBarOpenCL(QStatusBar* pStatusBar, QWidget* pParent) : - rgStatusBar(pStatusBar, pParent), - m_pParent(pParent) -{ - // Set style sheets. - SetStylesheets(pStatusBar); -} - -void rgStatusBarOpenCL::SetStylesheets(QStatusBar* pStatusBar) -{ - assert(m_pModePushButton); - if (m_pModePushButton) - { - m_pModePushButton->setStyleSheet(s_MODE_PUSH_BUTTON_STYLESHEET); - m_pModePushButton->SetHoverColor(s_MODE_PUSH_BUTTON_HOVER_COLOR); - m_pModePushButton->SetNonHoverColor(s_MODE_PUSH_BUTTON_NON_HOVER_COLOR); - } - - // Set status bar stylesheet. - assert(pStatusBar != nullptr); - if (pStatusBar != nullptr) - { - pStatusBar->setStyleSheet(s_STATUS_BAR_BACKRGOUND_COLOR_OPENCL); - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgStatusBarVulkan.cpp b/RadeonGPUAnalyzerGUI/Src/rgStatusBarVulkan.cpp deleted file mode 100644 index ab8f1ab..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgStatusBarVulkan.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// C++. -#include - -// Qt. -#include - -// Infra. -#include - -// Local. -#include -#include -#include - -static const QString s_MODE_PUSH_BUTTON_STYLESHEET( - "QPushButton" - "{" - "padding: 5px;" - "border: none;" - "color: white;" - "}" - "QPushButton:hover" - "{" - "background-color: rgb(255, 36, 65, 255);" - "}" -); -static const QString s_STATUS_BAR_BACKRGOUND_COLOR_VULKAN = "background-color: rgb(224,30,55)"; -static const QColor s_MODE_PUSH_BUTTON_HOVER_COLOR = QColor(255, 36, 65, 255); -static const QColor s_MODE_PUSH_BUTTON_NON_HOVER_COLOR = QColor(224, 30, 55, 255); - -rgStatusBarVulkan::rgStatusBarVulkan(QStatusBar* pStatusBar, QWidget* pParent) : - rgStatusBar(pStatusBar, pParent), - m_pParent(pParent) -{ - // Set style sheets. - SetStylesheets(pStatusBar); -} - -void rgStatusBarVulkan::SetStylesheets(QStatusBar* pStatusBar) -{ - assert(m_pModePushButton); - if (m_pModePushButton) - { - m_pModePushButton->setStyleSheet(s_MODE_PUSH_BUTTON_STYLESHEET); - m_pModePushButton->SetHoverColor(s_MODE_PUSH_BUTTON_HOVER_COLOR); - m_pModePushButton->SetNonHoverColor(s_MODE_PUSH_BUTTON_NON_HOVER_COLOR); - } - - // Set status bar stylesheet. - assert(pStatusBar != nullptr); - if (pStatusBar != nullptr) - { - pStatusBar->setStyleSheet(s_STATUS_BAR_BACKRGOUND_COLOR_VULKAN); - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgTargetGpusDialog.cpp b/RadeonGPUAnalyzerGUI/Src/rgTargetGpusDialog.cpp deleted file mode 100644 index 8ad6264..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgTargetGpusDialog.cpp +++ /dev/null @@ -1,766 +0,0 @@ -// C++. -#include -#include -#include -#include - -// Qt. -#include -#include -#include -#include -#include -#include - -// Infra. -#include - -// Local. -#include -#include -#include -#include -#include - -// A class used to filter the GPU table widget. -class rgTableFilterProxyModel : public QSortFilterProxyModel -{ -public: - rgTableFilterProxyModel(rgTargetGpusDialog* pParentDialog = nullptr) : QSortFilterProxyModel(pParentDialog), m_pParentDialog(pParentDialog) {} - virtual ~rgTableFilterProxyModel() = default; - -protected: - // A row-filtering predicate responsible for matching rows against the user's search text. - virtual bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override - { - bool isFiltered = false; - - // Filter each row using rgFilterProxyModel's regex. - if (filterRegExp().isEmpty() == false) - { - isFiltered = m_pParentDialog->IsRowVisible(sourceRow, sourceParent, filterRegExp()); - } - else - { - // Invoke the default filtering on the row. - isFiltered = QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); - } - - return isFiltered; - } - -private: - // The parent dialog whose table is being filtered. - rgTargetGpusDialog* m_pParentDialog = nullptr; -}; - -bool rgTreeEventFilter::eventFilter(QObject* pObject, QEvent* pEvent) -{ - bool isHandled = false; - - assert(pEvent != nullptr); - if (pEvent != nullptr && pEvent->type() == QEvent::Type::KeyPress) - { - // Watch for KeyPress events on only the Spacebar. - QKeyEvent* pKeyEvent = dynamic_cast(pEvent); - assert(pKeyEvent != nullptr); - if (pKeyEvent != nullptr && pKeyEvent->key() == Qt::Key_Space) - { - // Emit the signal used to activate the selected row. - emit RowActivated(); - isHandled = true; - } - } - - if (!isHandled) - { - // Invoke the base implementation. - isHandled = QObject::eventFilter(pObject, pEvent); - } - - return isHandled; -} - -rgTargetGpusDialog::rgTargetGpusDialog(const QString& selectedGPUs, QWidget* pParent) : - QDialog(pParent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint), - m_pParent(pParent) -{ - ui.setupUi(this); - - // Double-clicking an item within the QTreeView will toggle its check state- not expand/collapse the children. - ui.gpuTreeView->setExpandsOnDoubleClick(false); - - // Disable editing cells within the table. - ui.gpuTreeView->setEditTriggers(QAbstractItemView::EditTrigger::NoEditTriggers); - - // Create an eventFilter used to handle keyPress events in the GPU treeview. - rgTreeEventFilter* pKeypressEventFilter = new rgTreeEventFilter(this); - assert(pKeypressEventFilter != nullptr); - if (pKeypressEventFilter != nullptr) - { - // Connect the handler that gets invoked when the user toggles a row with the spacebar. - bool isConnected = connect(pKeypressEventFilter, &rgTreeEventFilter::RowActivated, this, &rgTargetGpusDialog::HandleRowToggled); - assert(isConnected); - if (isConnected) - { - // Install the eventFilter in the treeview. - ui.gpuTreeView->installEventFilter(pKeypressEventFilter); - } - } - - // Use the cached CLI version info structure to populate the GPU tree. - std::shared_ptr pVersionInfo = rgConfigManager::Instance().GetVersionInfo(); - assert(pVersionInfo != nullptr); - if (pVersionInfo != nullptr) - { - const std::string& currentMode = rgConfigManager::Instance().GetCurrentModeString(); - PopulateTableData(pVersionInfo, currentMode); - } - - // Connect the target GPUs dialog signals. - ConnectSignals(); - - // Set window flags. - setWindowFlags(windowFlags() | Qt::MSWindowsFixedSizeDialogHint); - - // Split the incoming string of comma-separated families into a vector. - std::vector selectedGPUsVector; - rgUtils::splitString(selectedGPUs.toStdString(), rgConfigManager::RGA_LIST_DELIMITER, selectedGPUsVector); - - // 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(selectedGPUsVector.begin(), selectedGPUsVector.end(), - selectedGPUsVector.begin(), [&](std::string& familyName) - { - std::stringstream fixedName; - std::string gfxNotation; - bool hasGfxNotation = rgUtils::GetGfxNotation(familyName, gfxNotation); - if (hasGfxNotation && familyName.find("/") == std::string::npos) - { - fixedName << gfxNotation << "/" << familyName; - } - else - { - fixedName << familyName; - } - return fixedName.str(); - }); - - // Update the state of the OK button based on the number of selected GPUs. - ToggleOKButtonEnabled(!selectedGPUsVector.empty()); - - // Initialize the model item's initial checkState for each row. - InitializeCheckedRows(selectedGPUsVector); - - // Set the cursor for the treeview to be pointing hand cursor. - ui.gpuTreeView->setCursor(Qt::PointingHandCursor); -} - -std::vector rgTargetGpusDialog::GetSelectedCapabilityGroups() const -{ - std::vector selectedFamilies; - - // Step through all rows in the table to find rows that are checked. - for (int rowIndex = 0; rowIndex < m_pGpuTreeModel->rowCount(); ++rowIndex) - { - QStandardItem* pRowCheckItem = m_pGpuTreeModel->item(rowIndex, ColumnType::SelectedCheckbox); - if (pRowCheckItem != nullptr) - { - bool isRowChecked = pRowCheckItem->checkState(); - if (isRowChecked) - { - // If the row is checked, find the compute capability group associated with the row. - auto rowToGroupIndexIter = m_tableRowIndexToGroupIndex.find(rowIndex); - if (rowToGroupIndexIter != m_tableRowIndexToGroupIndex.end()) - { - int groupIndex = rowToGroupIndexIter->second; - bool isValidIndex = (groupIndex >= 0 && groupIndex < m_capabilityGroups.size()); - assert(isValidIndex); - if (isValidIndex) - { - const CapabilityGroup& groupInfo = m_capabilityGroups[groupIndex]; - - // Retrieve the compute capability string from the first row of the group. - std::string groupName = groupInfo.m_groupRows[0].m_computeCapability; - auto isAlreadyAddedIter = std::find(selectedFamilies.begin(), selectedFamilies.end(), groupName); - if (isAlreadyAddedIter == selectedFamilies.end()) - { - selectedFamilies.push_back(groupName); - } - } - } - } - } - } - - - return selectedFamilies; -} - -void rgTargetGpusDialog::HandleItemChanged(QStandardItem* pItem) -{ - // Disable the item check changed handler to avoid a recursive overflow. - ToggleItemCheckChangedHandler(false); - - // Update the check state for the selected group's rows. - QModelIndex selectedItemIndex = pItem->index(); - if (selectedItemIndex.isValid()) - { - int selectedRow = selectedItemIndex.row(); - auto groupIndexIter = m_tableRowIndexToGroupIndex.find(selectedRow); - if (groupIndexIter != m_tableRowIndexToGroupIndex.end()) - { - int groupIndex = groupIndexIter->second; - bool isChecked = (pItem->checkState() == Qt::Checked); - SetIsGroupChecked(groupIndex, isChecked); - } - } - - // Only allow the user to confirm their changes if there's at least one family selected. - std::vector selectedFamilies = GetSelectedCapabilityGroups(); - bool isOkEnabled = !selectedFamilies.empty(); - - // Update the enabledness of the dialog's OK button. - ToggleOKButtonEnabled(isOkEnabled); - - // Re-enable the item check changed handler. - ToggleItemCheckChangedHandler(true); -} - -void rgTargetGpusDialog::HandleRowToggled() -{ - // Use the treeView's selectionModel to find the currently selected row index. - QItemSelectionModel* pSelectionModel = ui.gpuTreeView->selectionModel(); - assert(pSelectionModel != nullptr); - if (pSelectionModel != nullptr) - { - // Is the selected row index valid? - QModelIndex selectedRow = pSelectionModel->currentIndex(); - if (selectedRow.isValid()) - { - assert(m_pTableFilterModel != nullptr); - if (m_pTableFilterModel != nullptr) - { - // The selection model index doesn't know anything about the filtering model. Convert - // the (potentially filtered) selection model index to a source model index. - QModelIndex sourceModelIndex = m_pTableFilterModel->mapToSource(selectedRow); - if (sourceModelIndex.isValid()) - { - // Provide the source model index for the row being toggled. - ToggleRowChecked(sourceModelIndex); - } - } - } - } -} - -void rgTargetGpusDialog::HandleRowDoubleClicked(const QModelIndex& index) -{ - assert(m_pTableFilterModel != nullptr); - if (m_pTableFilterModel != nullptr) - { - QModelIndex sourceModelIndex = m_pTableFilterModel->mapToSource(index); - if (sourceModelIndex.isValid()) - { - // Provide the source model index for the row being toggled. - ToggleRowChecked(sourceModelIndex); - } - } -} - -void rgTargetGpusDialog::HandleSearchTextChanged(const QString& searchText) -{ - // A regex used to check the user's search term against the incoming test string. - QRegExp regex("", Qt::CaseInsensitive); - if (!searchText.isEmpty()) - { - regex.setPattern(".*" + searchText + ".*"); - } - - // Set the filter model regex. - m_pTableFilterModel->setFilterRegExp(regex); - -#ifdef _HIGHLIGHT_MATCHING_ROWS - // Disable this for now as the value we get from the feature - // is negligible compared to the performance impact - it makes - // the view sluggish. To be optimized. - - // Highlight the matching rows. - HighlightMatchingRows(regex); -#endif -} - -void rgTargetGpusDialog::ComputeGroupColor(int groupIndex, QColor& color) const -{ - // Use 25% saturation for a more muted color palette, but 100% value to maintain brightness. - static const int s_BACKGROUND_COLOR_NUM_HUE_STEPS = 10; - static const float s_BACKGROUND_COLOR_HUE_STEP_INCREMENT = 1.0f / s_BACKGROUND_COLOR_NUM_HUE_STEPS; - static const float s_BACKGROUND_COLOR_SATURATION = 0.25f; - static const float s_BACKGROUND_COLOR_VALUE = 1.0f; - - // If the number of groups exceeds the number of hue steps, reset the hue to the start of the color wheel. - int colorGroupIndex = groupIndex % s_BACKGROUND_COLOR_NUM_HUE_STEPS; - - // Compute the group's color based on the group index vs. the total group count. - float hue = colorGroupIndex * s_BACKGROUND_COLOR_HUE_STEP_INCREMENT; - color.setHsvF(hue, s_BACKGROUND_COLOR_SATURATION, s_BACKGROUND_COLOR_VALUE); -} - -void rgTargetGpusDialog::ConnectSignals() -{ - // Connect the tree's model to the check changed handler. - bool isConnected = connect(this->ui.searchTextbox, &QLineEdit::textChanged, this, &rgTargetGpusDialog::HandleSearchTextChanged); - assert(isConnected); - - // Connect the table's double click handler to toggle the row's check state. - isConnected = connect(this->ui.gpuTreeView, &QTreeView::doubleClicked, this, &rgTargetGpusDialog::HandleRowDoubleClicked); - assert(isConnected); - - // Connect the OK button. - isConnected = connect(this->ui.OkPushButton, &QPushButton::clicked, this, &rgTargetGpusDialog::HandleOKButtonClicked); - assert(isConnected); - - // Connect the Cancel button. - isConnected = connect(this->ui.cancelPushButton, &QPushButton::clicked, this, &rgTargetGpusDialog::HandleCancelButtonClicked); - assert(isConnected); - - // Connect the tree's model to the check changed handler. - ToggleItemCheckChangedHandler(true); -} - -void rgTargetGpusDialog::InitializeCheckedRows(std::vector computeCapabilityGroupNames) -{ - // Step through each group and find the first row that belongs to the group. - for (const std::string& groupName : computeCapabilityGroupNames) - { - for (size_t groupIndex = 0; groupIndex < m_capabilityGroups.size(); ++groupIndex) - { - const CapabilityGroup& groupData = m_capabilityGroups[groupIndex]; - if (groupData.m_groupRows[0].m_computeCapability.compare(groupName) == 0) - { - // Found a table row that belongs to a group that's enabled. Check the row off. - int rowIndex = groupData.m_groupRows[0].m_rowIndex; - - QStandardItem* pRowCheckItem = m_pGpuTreeModel->item(rowIndex, ColumnType::SelectedCheckbox); - pRowCheckItem->setCheckState(Qt::Checked); - break; - } - } - } -} - -bool rgTargetGpusDialog::IsRowVisible(int rowIndex, const QModelIndex& sourceParent, const QRegExp& searchFilter) -{ - bool isFiltered = false; - - // Determine the group index for the given row. - auto tableRowToGroupIter = m_tableRowIndexToGroupIndex.find(rowIndex); - if (tableRowToGroupIter != m_tableRowIndexToGroupIndex.end()) - { - int groupIndex = tableRowToGroupIter->second; - const CapabilityGroup& groupInfo = m_capabilityGroups[groupIndex]; - - // Check if any of the cells associated with the group match the user's search string. - for (const TableRow& currentRow : groupInfo.m_groupRows) - { - // Does the architecture name match the filter string? - isFiltered = IsRowMatchingSearchString(currentRow, searchFilter); - - // If the row is included, early out and don't check the other rows in the group. - if (isFiltered) - { - break; - } - } - - } - - return isFiltered; -} - -void rgTargetGpusDialog::HighlightMatchingRows(const QRegExp& searchFilter) -{ - // Reset the table colors to default background colors. - SetDefaultTableBackgroundColors(); - - // Filter the matching rows and highlight them with a different color. - if (!searchFilter.isEmpty()) - { - // Container for indices of rows containing matching GPU names. - std::vector matchingRows; - - for (int rowIndex = 0; rowIndex < m_tableRowIndexToGroupIndex.size(); rowIndex++) - { - auto tableRowToGroupIter = m_tableRowIndexToGroupIndex.find(rowIndex); - if (tableRowToGroupIter != m_tableRowIndexToGroupIndex.end()) - { - int groupIndex = tableRowToGroupIter->second; - const CapabilityGroup& groupInfo = m_capabilityGroups[groupIndex]; - - // Check if any of the cells associated with the group match the user's search string. - for (const TableRow& currentRow : groupInfo.m_groupRows) - { - bool isMatching = IsRowMatchingSearchString(currentRow, searchFilter); - - // If this is a matching row, set it as selected. - if (isMatching) - { - // Store the model index for this row. - QModelIndex modelIndex = m_pGpuTreeModel->index(currentRow.m_rowIndex, 0); - matchingRows.push_back(modelIndex); - } - } - } - } - - // Highlight matching rows. - for (const QModelIndex& index : matchingRows) - { - ui.gpuTreeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); - } - - // Update the table. - ui.gpuTreeView->update(); - } -} - -void rgTargetGpusDialog::ToggleItemCheckChangedHandler(bool isEnabled) -{ - if (isEnabled) - { - bool isConnected = connect(m_pGpuTreeModel, &QStandardItemModel::itemChanged, this, &rgTargetGpusDialog::HandleItemChanged); - assert(isConnected); - } - else - { - bool isDisconnected = disconnect(m_pGpuTreeModel, &QStandardItemModel::itemChanged, this, &rgTargetGpusDialog::HandleItemChanged); - assert(isDisconnected); - } -} - -std::string rgTargetGpusDialog::GetItemText(const QStandardItem* pItem) const -{ - // Extract and return the item text. - QVariant itemDisplay = pItem->data(Qt::DisplayRole); - return itemDisplay.toString().toStdString(); -} - -void rgTargetGpusDialog::PopulateTableData(std::shared_ptr pVersionInfo, const std::string& mode) -{ - // Create the GPU tree model, and fill it. - m_pGpuTreeModel = new QStandardItemModel(0, ColumnType::Count, this); - QStandardItem* pSelectedCheckbox = new QStandardItem(); - pSelectedCheckbox->setCheckable(true); - - // Configure the column headers for the GPU table. - m_pGpuTreeModel->setHorizontalHeaderItem(ColumnType::SelectedCheckbox, pSelectedCheckbox); - m_pGpuTreeModel->setHorizontalHeaderItem(ColumnType::ProductName, new QStandardItem(STR_TARGET_GPU_PRODUCT_NAME)); - m_pGpuTreeModel->setHorizontalHeaderItem(ColumnType::Architecture, new QStandardItem(STR_TARGET_GPU_ARCHITECTURE)); - m_pGpuTreeModel->setHorizontalHeaderItem(ColumnType::ComputeCapability, new QStandardItem(STR_TARGET_GPU_COMPUTE_CAPABILITY)); - - // Set tooltips on the table headers. - m_pGpuTreeModel->setHeaderData(ColumnType::ProductName, Qt::Orientation::Horizontal, STR_TABLE_TOOLTIP_COLUMN_PRODUCT_NAME, Qt::ToolTipRole); - m_pGpuTreeModel->setHeaderData(ColumnType::Architecture, Qt::Orientation::Horizontal, STR_TABLE_TOOLTIP_COLUMN_ARCHITECTURE, Qt::ToolTipRole); - m_pGpuTreeModel->setHeaderData(ColumnType::ComputeCapability, Qt::Orientation::Horizontal, STR_TABLE_TOOLTIP_COLUMN_COMPUTE_CAPABILITY, Qt::ToolTipRole); - - assert(pVersionInfo != nullptr); - if (pVersionInfo != nullptr) - { - int currentRowIndex = 0; - int groupIndex = 0; - - // Search the supported hardware data for the given mode's supported hardware list. - auto currentModeArchitecturesIter = pVersionInfo->m_gpuArchitectures.find(mode); - bool isModeFound = (currentModeArchitecturesIter != pVersionInfo->m_gpuArchitectures.end()); - assert(isModeFound); - if (isModeFound) - { - // Most recent hardware appears at the end of the architectures list. Reverse it so that it appears at the top of the table. - std::vector architectures = currentModeArchitecturesIter->second; - std::sort(architectures.begin(), architectures.end(), [&](const rgGpuArchitecture& arch1, - const rgGpuArchitecture& arch2) - { - bool is1LessThan2 = true; - const char* GRAPHICS_TOKEN = "Graphics"; - size_t posGraphics1 = arch1.m_architectureName.find(GRAPHICS_TOKEN); - size_t posGraphics2 = arch2.m_architectureName.find(GRAPHICS_TOKEN); - if (posGraphics1 != std::string::npos && - posGraphics2 != std::string::npos) - { - is1LessThan2 = (arch1.m_architectureName.compare(arch2.m_architectureName) < 0); - } - else if (posGraphics1 == std::string::npos && posGraphics2 != std::string::npos) - { - is1LessThan2 = false; - } - else if (posGraphics1 == std::string::npos && posGraphics2 == std::string::npos) - { - const char* RDNA2_TOKEN = "RDNA2"; - const char* RDNA_TOKEN = "RDNA"; - size_t rdna2Pos1 = arch1.m_architectureName.find(RDNA2_TOKEN); - size_t rdna2Pos2 = arch2.m_architectureName.find(RDNA2_TOKEN); - size_t rdnaPos1 = arch1.m_architectureName.find(RDNA_TOKEN); - size_t rdnaPos2 = arch2.m_architectureName.find(RDNA_TOKEN); - - if (rdna2Pos1 != std::string::npos && rdna2Pos2 == std::string::npos) - { - is1LessThan2 = false; - } - else if (rdnaPos1 != std::string::npos && rdnaPos2 == std::string::npos) - { - is1LessThan2 = false; - } - } - - return is1LessThan2; - }); - - std::reverse(architectures.begin(), architectures.end()); - - // Step through each GPU hardware architecture. - for (const rgGpuArchitecture& hardwareArchitecture : architectures) - { - const std::string& currentArchitecture = hardwareArchitecture.m_architectureName; - - // Determine how many families are found within the architecture. - std::vector gpuFamilies = hardwareArchitecture.m_gpuFamilies; - int numFamiliesInArchitecture = static_cast(gpuFamilies.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 < numFamiliesInArchitecture; i++) - { - std::string gfxNotation; - std::stringstream familyNameRevised; - bool hasGfxNotation = rgUtils::GetGfxNotation(gpuFamilies[i].m_familyName, gfxNotation); - if (hasGfxNotation && !gfxNotation.empty()) - { - familyNameRevised << gfxNotation << "/"; - } - familyNameRevised << gpuFamilies[i].m_familyName; - gpuFamilies[i].m_familyName = familyNameRevised.str().c_str(); - } - - // 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(gpuFamilies.rbegin(), gpuFamilies.rend(), [&](rgGpuFamily familyA, - rgGpuFamily familyB) { return familyA.m_familyName < familyB.m_familyName; }); - - // Step through each family within the architecture. - for (int familyIndex = 0; familyIndex < numFamiliesInArchitecture; familyIndex++) - { - // Create a copy of the family info and sort by product name. - rgGpuFamily familySortedByProductName = gpuFamilies[familyIndex]; - const std::string& familyName = familySortedByProductName.m_familyName; - - // Sort the product name column alphabetically. - std::sort(familySortedByProductName.m_productNames.begin(), familySortedByProductName.m_productNames.end()); - - m_capabilityGroups.resize(groupIndex + 1); - CapabilityGroup& capabilityGroup = m_capabilityGroups[groupIndex]; - - // Create a node for each GPU's product name. - int numGPUNames = static_cast(familySortedByProductName.m_productNames.size()); - for (int productIndex = 0; productIndex < numGPUNames; productIndex++) - { - const std::string& productName = familySortedByProductName.m_productNames[productIndex]; - - // Add a new row to the model by increasing the count by 1. - m_pGpuTreeModel->setRowCount(currentRowIndex + 1); - - // Create a checkbox item in the first column. - QModelIndex checkboxColumnIndex = m_pGpuTreeModel->index(currentRowIndex, ColumnType::SelectedCheckbox); - if (checkboxColumnIndex.isValid()) - { - QStandardItem* pCheckboxItem = m_pGpuTreeModel->itemFromIndex(checkboxColumnIndex); - pCheckboxItem->setCheckState(Qt::Unchecked); - pCheckboxItem->setCheckable(true); - } - - TableRow newRow = { currentRowIndex, currentArchitecture, productName, familyName }; - capabilityGroup.m_groupRows.push_back(newRow); - - // Set the data for each column in the new row. - SetTableIndexData(currentRowIndex, ColumnType::ProductName, newRow.m_productName); - SetTableIndexData(currentRowIndex, ColumnType::Architecture, newRow.m_architecture); - SetTableIndexData(currentRowIndex, ColumnType::ComputeCapability, newRow.m_computeCapability); - - m_tableRowIndexToGroupIndex[currentRowIndex] = groupIndex; - - // Update the row index for other GPUs. - currentRowIndex++; - } - - groupIndex++; - } - } - } - else - { - // Show an error string telling the user that the given mode seems to be invalid. - std::stringstream errorString; - errorString << STR_ERR_CANNOT_LOAD_SUPPORTED_GPUS_LIST_FOR_MODE_A; - errorString << mode; - errorString << STR_ERR_CANNOT_LOAD_SUPPORTED_GPUS_LIST_FOR_MODE_B; - rgUtils::ShowErrorMessageBox(errorString.str().c_str(), m_pParent); - } - } - - // Generate the colors for each group. - SetDefaultTableBackgroundColors(); - - // Filter the tree model with the proxy model. - m_pTableFilterModel = new rgTableFilterProxyModel(this); - m_pTableFilterModel->setSourceModel(m_pGpuTreeModel); - - // Display the filtered model in the QTreeView. - ui.gpuTreeView->setModel(m_pTableFilterModel); - QtCommon::QtUtil::AutoAdjustTableColumns(ui.gpuTreeView, 32, 10); -} - -void rgTargetGpusDialog::SetIsGroupChecked(int groupIndex, bool isChecked) -{ - bool isValidIndex = (groupIndex >= 0 && groupIndex < m_capabilityGroups.size()); - assert(isValidIndex); - if (isValidIndex) - { - CapabilityGroup& targetGroup = m_capabilityGroups[groupIndex]; - for (auto currentRow : targetGroup.m_groupRows) - { - QStandardItem* pCheckItem = m_pGpuTreeModel->item(currentRow.m_rowIndex, ColumnType::SelectedCheckbox); - pCheckItem->setCheckState(isChecked ? Qt::Checked : Qt::Unchecked); - } - } -} - -void rgTargetGpusDialog::SetTableIndexData(int row, int column, const std::string& stringData) -{ - // Generate an index and verify that it's valid. - QModelIndex modelIndex = m_pGpuTreeModel->index(row, column); - bool isValid = modelIndex.isValid(); - assert(isValid); - if (isValid) - { - // Set the data at the correct index in the GPU tree. - m_pGpuTreeModel->setData(modelIndex, stringData.c_str()); - } -} - -void rgTargetGpusDialog::SetTableBackgroundColor(int row, const QColor& backgroundColor) -{ - // Generate an index and verify that it's valid. - for (int columnIndex = ColumnType::SelectedCheckbox; columnIndex < ColumnType::Count; ++columnIndex) - { - QModelIndex modelIndex = m_pGpuTreeModel->index(row, columnIndex); - bool isValid = modelIndex.isValid(); - assert(isValid); - if (isValid) - { - // Set the data at the correct index in the GPU tree. - m_pGpuTreeModel->setData(modelIndex, backgroundColor, Qt::BackgroundColorRole); - } - } -} - -void rgTargetGpusDialog::ToggleOKButtonEnabled(bool isOkEnabled) -{ - ui.OkPushButton->setEnabled(isOkEnabled); -} - -void rgTargetGpusDialog::ToggleRowChecked(const QModelIndex& sourceModelIndex) -{ - // Find the group index associated with the product row. - auto groupIndexIter = m_tableRowIndexToGroupIndex.find(sourceModelIndex.row()); - if (groupIndexIter != m_tableRowIndexToGroupIndex.end()) - { - assert(m_pTableFilterModel != nullptr); - if (m_pTableFilterModel != nullptr) - { - // Find the filtered index for the checkbox item in the row. - QAbstractItemModel* pSourceItemModel = m_pTableFilterModel->sourceModel(); - assert(pSourceItemModel != nullptr); - if (pSourceItemModel != nullptr) - { - QModelIndex checkboxColumnFilteredIndex = pSourceItemModel->index(sourceModelIndex.row(), ColumnType::SelectedCheckbox); - bool isFilteredIndexValid = checkboxColumnFilteredIndex.isValid(); - assert(isFilteredIndexValid); - if (isFilteredIndexValid) - { - assert(m_pGpuTreeModel != nullptr); - if (m_pGpuTreeModel != nullptr) - { - // Retrieve a pointer to the checkbox item in the table. - QStandardItem* pClickedItem = m_pGpuTreeModel->itemFromIndex(checkboxColumnFilteredIndex); - assert(pClickedItem != nullptr); - if (pClickedItem != nullptr) - { - // Determine the current check state for the row's checkbox item. - int groupIndex = groupIndexIter->second; - CapabilityGroup& group = m_capabilityGroups[groupIndex]; - bool checkState = (pClickedItem->checkState() == Qt::Checked) ? true : false; - - // Toggle the checkbox for the entire group of products. - SetIsGroupChecked(groupIndex, !checkState); - } - } - } - } - } - } -} - -void rgTargetGpusDialog::SetDefaultTableBackgroundColors() -{ - for (int groupIndex = 0; groupIndex < static_cast(m_capabilityGroups.size()); ++groupIndex) - { - CapabilityGroup& groupInfo = m_capabilityGroups[groupIndex]; - - // Compute the group's color based on the group index. - ComputeGroupColor(groupIndex, groupInfo.m_color); - - // Set the table background color for each row in the group. - for (size_t rowIndex = 0; rowIndex < groupInfo.m_groupRows.size(); ++rowIndex) - { - auto groupRow = groupInfo.m_groupRows[rowIndex]; - SetTableBackgroundColor(groupRow.m_rowIndex, groupInfo.m_color); - - // Set each row to deselected. - if (ui.gpuTreeView->selectionModel() != nullptr) - { - QModelIndex modelIndex = m_pGpuTreeModel->index(static_cast(rowIndex), 0); - ui.gpuTreeView->selectionModel()->select(modelIndex, QItemSelectionModel::Deselect | QItemSelectionModel::Rows); - } - } - } -} - -bool rgTargetGpusDialog::IsRowMatchingSearchString(const TableRow& currentRow, const QRegExp searchFilter) -{ - bool isMatching = false; - - // Does the architecture name match the filter string? - isMatching = searchFilter.exactMatch(currentRow.m_architecture.c_str()); - if (!isMatching) - { - // Does the compute capability match the filter string? - isMatching = searchFilter.exactMatch(currentRow.m_computeCapability.c_str()); - if (!isMatching) - { - // Does the product name match the filter string? - isMatching = searchFilter.exactMatch(currentRow.m_productName.c_str()); - } - } - - return isMatching; -} - -void rgTargetGpusDialog::HandleOKButtonClicked(bool /* checked */) -{ - this->accept(); -} - -void rgTargetGpusDialog::HandleCancelButtonClicked(bool /* checked */) -{ - this->reject(); -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgTreeWidget.cpp b/RadeonGPUAnalyzerGUI/Src/rgTreeWidget.cpp deleted file mode 100644 index a7c7064..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgTreeWidget.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include - -// Local. -#include - -static const int s_TREE_WIDGET_ICON_COLUMN_ID = 0; -static const int s_TREE_WIDGET_API_COLUMN_ID = 1; - -rgTreeWidget::rgTreeWidget(QWidget* pParent) : - QTreeWidget(pParent) -{ - setMouseTracking(true); -} - -void rgTreeWidget::focusOutEvent(QFocusEvent *event) -{ - hide(); -} - -void rgTreeWidget::mouseMoveEvent(QMouseEvent* pEvent) -{ - setCursor(Qt::ArrowCursor); - if (pEvent != nullptr) - { - const QPoint pos = pEvent->pos(); - - QTreeWidgetItem* pItem = itemAt(pos); - if (pItem != nullptr) - { - const int row = indexOfTopLevelItem(pItem); - if (row != 0) - { - setCursor(Qt::PointingHandCursor); - - QColor lightBlue(229, 243, 255); - const int columnCount = pItem->columnCount(); - for (int columnNumber = 0; columnNumber < columnCount; columnNumber++) - { - pItem->setBackgroundColor(columnNumber, lightBlue); - } - - // Pass the event onto the base class. - QTreeWidget::mouseMoveEvent(pEvent); - } - } - } - else - { - // Pass the event onto the base class. - QTreeWidget::mouseMoveEvent(pEvent); - } -} - -void rgTreeWidget::leaveEvent(QEvent* pEvent) -{ - // Remove highlight from all of the items. - // Set background color for all items to transparent. - QTreeWidgetItemIterator it(this); - while (*it) - { - (*it)->setBackgroundColor(s_TREE_WIDGET_ICON_COLUMN_ID, Qt::GlobalColor::transparent); - (*it)->setBackgroundColor(s_TREE_WIDGET_API_COLUMN_ID, Qt::GlobalColor::transparent); - ++it; - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgUnsavedItemsDialog.cpp b/RadeonGPUAnalyzerGUI/Src/rgUnsavedItemsDialog.cpp deleted file mode 100644 index 2d590c2..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgUnsavedItemsDialog.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include -#include - -// Local. -#include -#include -#include - -rgUnsavedItemsDialog::rgUnsavedItemsDialog(QWidget *pParent) - : QDialog(pParent) -{ - // Setup the UI. - ui.setupUi(this); - - // Disable the help button in the titlebar. - setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); - - // Connect the signals. - ConnectSignals(); - - // Create item delegate for the list widget. - m_pItemDelegate = new rgUnsavedFileItemDelegate(); - bool isDelegateValid = (m_pItemDelegate != nullptr); - assert(isDelegateValid); - - if (isDelegateValid) - { - // Set custom delegate for the list widget. - ui.fileListWidget->setItemDelegate(m_pItemDelegate); - } - - // Disable selection of items. - ui.fileListWidget->setSelectionMode(QAbstractItemView::NoSelection); - - // Do not allow the file list widget to have focus. - ui.fileListWidget->setFocusPolicy(Qt::FocusPolicy::NoFocus); - - // Set default focus to "Yes" button. - ui.yesPushButton->setFocus(); - - // Set the tab order. - setTabOrder(ui.yesPushButton, ui.noPushButton); - setTabOrder(ui.noPushButton, ui.cancelPushButton); - setTabOrder(ui.cancelPushButton, ui.yesPushButton); -} - -rgUnsavedItemsDialog::~rgUnsavedItemsDialog() -{ - if (m_pItemDelegate != nullptr) - { - delete m_pItemDelegate; - } -} - -void rgUnsavedItemsDialog::ConnectSignals() -{ - // Yes button. - bool isConnected = connect(ui.yesPushButton, &QPushButton::clicked, [=] { done(UnsavedFileDialogResult::Yes); }); - assert(isConnected); - - // No button. - isConnected = connect(ui.noPushButton, &QPushButton::clicked, [=] { done(UnsavedFileDialogResult::No); }); - assert(isConnected); - - // Cancel button. - isConnected = connect(ui.cancelPushButton, &QPushButton::clicked, [=] { done(UnsavedFileDialogResult::Cancel); }); - assert(isConnected); -} - -void rgUnsavedItemsDialog::AddFile(QString filename) -{ - ui.fileListWidget->addItem(filename); -} - -void rgUnsavedItemsDialog::AddFiles(QStringList filenames) -{ - foreach(const QString& filename, filenames) - { - AddFile(filename); - } -} - -void rgUnsavedFileItemDelegate::drawDisplay(QPainter* pPainter, const QStyleOptionViewItem& option, const QRect &rect, const QString& text) const -{ - bool isPainterValid = (pPainter != nullptr); - assert(isPainterValid); - - if (isPainterValid) - { - // Truncate string so it fits within rect. - QString truncatedString = rgUtils::TruncateString(text.toStdString(), gs_TEXT_TRUNCATE_LENGTH_FRONT, - gs_TEXT_TRUNCATE_LENGTH_BACK, rect.width(), pPainter->font(), rgUtils::EXPAND_BACK).c_str(); - - // Draw text within rect. - pPainter->drawText(rect, Qt::AlignVCenter, truncatedString); - } -} - -QSize rgUnsavedFileItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const -{ - // Use standard size hint implementation, but with a fixed width of 0 (width will be determined by view width). - QSize adjustedHint = QItemDelegate::sizeHint(option, index); - adjustedHint.setWidth(0); - - return adjustedHint; -} - - diff --git a/RadeonGPUAnalyzerGUI/Src/rgUnsignedIntValidator.cpp b/RadeonGPUAnalyzerGUI/Src/rgUnsignedIntValidator.cpp deleted file mode 100644 index b70e75d..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgUnsignedIntValidator.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// C++. -#include - -// Local. -#include - -rgUnsignedIntValidator::rgUnsignedIntValidator(QObject* pParent) - : QValidator(pParent) - , m_minimumValue(0) - , m_maximumValue(std::numeric_limits::max()) -{ -} - -rgUnsignedIntValidator::rgUnsignedIntValidator(uint32_t bottom, uint32_t top, QObject* pParent) - : QValidator(pParent) - , m_minimumValue(bottom) - , m_maximumValue(top) -{ -} - -QValidator::State rgUnsignedIntValidator::validate(QString& valueString, int&) const -{ - QValidator::State isValidState = QValidator::State::Invalid; - - if (valueString.isEmpty()) - { - // If the string is empty, it's probably still being edited. - isValidState = QValidator::State::Intermediate; - } - else - { - // Attempt to parse the given string as an unsigned integer. - bool isOk = false; - uint currentValue = valueString.toUInt(&isOk); - - if (isOk) - { - // Does the given string fall between the allowable value range? - if (currentValue >= m_minimumValue && currentValue <= m_maximumValue) - { - isValidState = QValidator::State::Acceptable; - } - } - } - - return isValidState; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgUtils.cpp b/RadeonGPUAnalyzerGUI/Src/rgUtils.cpp deleted file mode 100644 index b5df60f..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgUtils.cpp +++ /dev/null @@ -1,1525 +0,0 @@ -// C++. -#include -#include -#include -#include -#include -#include - -// Qt. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Infra. -#ifdef _WIN32 -#pragma warning(push) -#pragma warning(disable:4309) -#endif -#include -#include -#include -#ifdef _WIN32 -#pragma warning(pop) -#endif - -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include -#include - -// Static constants - -static const uint32_t SPV_BINARY_MAGIC_NUMBER = 0x07230203; - - -// *** INTERNALLY-LINKED AUXILIARY FUNCTIONS - START *** - -static bool OpenFileDialogHelper(QWidget* pParent, const QString& caption, const std::string& initialFolder, - const QString& filter, std::string& selectedFilePath) -{ - bool ret = false; - selectedFilePath.clear(); - - QString filename = QFileDialog::getOpenFileName(pParent, caption, initialFolder.c_str(), filter); - - if (!filename.isNull()) - { - selectedFilePath = filename.toStdString(); - ret = !selectedFilePath.empty(); - } - - return ret; -} - -static bool OpenMultipleFileDialogHelper(QWidget* pParent, const QString& caption, - const QString& filter, QStringList& selectedFilePaths) -{ - bool ret = false; - selectedFilePaths.clear(); - - QStringList filenames = QFileDialog::getOpenFileNames(pParent, caption, rgConfigManager::Instance().GetLastSelectedFolder().c_str(), filter); - - if (!filenames.isEmpty()) - { - selectedFilePaths = filenames; - ret = !selectedFilePaths.empty(); - } - - return ret; -} - -// Build the file filter for Open File dialog in Vulkan mode. -static QString ConstructVulkanOpenFileFilter() -{ - QString filter; - auto settings = rgConfigManager::Instance().GetGlobalConfig(); - assert(settings != nullptr); - if (settings != nullptr) - { - // Convert the extensions stored in the Global Settings to the Qt file filter format. - QStringList glslExts = QString(settings->m_inputFileExtGlsl.c_str()).split(';'); - QStringList spvTxtExts = QString(settings->m_inputFileExtSpvTxt.c_str()).split(';'); - QStringList spvBinExts = QString(settings->m_inputFileExtSpvBin.c_str()).split(';'); - - QString glslExtList, spvTxtExtList, spvBinExtList; - - for (QString& ext : glslExts) { glslExtList += ("*." + ext + " "); } - for (QString& ext : spvTxtExts) { spvTxtExtList += ("*." + ext + " "); } - for (QString& ext : spvBinExts) { spvBinExtList += ("*." + ext + " "); } - - glslExtList.chop(1); - spvTxtExtList.chop(1); - spvBinExtList.chop(1); - - filter += (QString(STR_FILE_DIALOG_FILTER_GLSL_SPIRV) + " (" + glslExtList + " " + spvTxtExtList + " " + - STR_FILE_DIALOG_FILTER_SPIRV_BINARY_EXT + " " + ");;"); - filter += (QString(STR_FILE_DIALOG_FILTER_SPIRV) + ";;"); - filter += (QString(STR_FILE_DIALOG_FILTER_GLSL) + " (" + glslExtList + ");;"); - filter += (QString(STR_FILE_DIALOG_FILTER_SPV_TXT) + " (" + spvTxtExtList + ");;"); - filter += (QString(STR_FILE_DIALOG_FILTER_SPIRV_BINARY_EXT) + " (" + spvBinExtList + ");;"); - - filter += STR_FILE_DIALOG_FILTER_ALL; - } - - return filter; -} - -// *** INTERNALLY-LINKED AUXILIARY FUNCTIONS - END *** - -void rgUtils::splitString(const std::string& str, char delim, std::vector& dst) -{ - std::stringstream ss; - ss.str(str); - std::string substr; - while (std::getline(ss, substr, delim)) - { - dst.push_back(substr); - } -} - -std::string rgUtils::BuildSemicolonSeparatedBoolList(const std::vector& boolList) -{ - std::stringstream stream; - for (size_t i = 0; i < boolList.size(); i++) - { - stream << boolList[i] ? 1 : 0; - - // If this is not the last item, add the delimiter. - if (i < (boolList.size() - 1)) - { - stream << rgConfigManager::RGA_LIST_DELIMITER; - } - } - return stream.str(); -} - -std::string rgUtils::BuildSemicolonSeparatedStringList(const std::vector& strList) -{ - std::stringstream stream; - for (size_t i = 0; i < strList.size(); i++) - { - stream << strList[i]; - - // If this is not the last item, add the delimiter. - if (i < (strList.size() - 1)) - { - stream << rgConfigManager::RGA_LIST_DELIMITER; - } - } - return stream.str(); -} - -std::string rgUtils::BuildSemicolonSeparatedIntList(const std::vector& intList) -{ - std::stringstream stream; - for (size_t i = 0; i < intList.size(); i++) - { - stream << intList[i]; - - // If this is not the last item, add the delimiter. - if (i < (intList.size() - 1)) - { - stream << rgConfigManager::RGA_LIST_DELIMITER; - } - } - return stream.str(); -} - -bool rgUtils::IsContainsWhitespace(const std::string& text) -{ - bool isContainsWhitespace = false; - - // Step through each character in the string. - for (size_t characterIndex = 0; characterIndex < text.length(); ++characterIndex) - { - // Check if the current character is whitespace. - if (isspace(text[characterIndex])) - { - isContainsWhitespace = true; - break; - } - } - - return isContainsWhitespace; -} - -void rgUtils::LeftTrim(const std::string& text, std::string& trimmedText) -{ - trimmedText = text; - auto spaceIter = std::find_if(trimmedText.begin(), trimmedText.end(), [](char ch) { return !std::isspace(ch, std::locale::classic()); }); - trimmedText.erase(trimmedText.begin(), spaceIter); -} - -void rgUtils::RightTrim(const std::string& text, std::string& trimmedText) -{ - trimmedText = text; - auto spaceIter = std::find_if(trimmedText.rbegin(), trimmedText.rend(), [](char ch) { return !std::isspace(ch, std::locale::classic()); }); - trimmedText.erase(spaceIter.base(), trimmedText.end()); -} - -void rgUtils::TrimLeadingAndTrailingWhitespace(const std::string& text, std::string& trimmedText) -{ - // Trim the whitespace off the left and right sides of the incoming text. - std::string leftTrimmed; - LeftTrim(text, leftTrimmed); - RightTrim(leftTrimmed, trimmedText); -} - -void rgUtils::Replace(std::string& text, const std::string& target, const std::string& replacement) -{ - if (!target.empty()) - { - // Search for instances of the given target text in the source string. - size_t startPosition = 0; - while ((startPosition = text.find(target, startPosition)) != std::string::npos) - { - // Replace the target text in the string with the replacement text. - text.replace(startPosition, target.length(), replacement); - - // Update the start position for the next search. - startPosition += replacement.length(); - } - } -} - -std::string rgUtils::GenerateTemplateCode(rgProjectAPI apiName, const std::string& entryPointPrefix) -{ - std::stringstream strBuilder; - switch (apiName) - { - case rgProjectAPI::OpenCL: - { - strBuilder << STR_NEW_FILE_TEMPLATE_CODE_OPENCL_A; - if (!entryPointPrefix.empty()) - { - strBuilder << entryPointPrefix << "_"; - } - strBuilder << STR_NEW_FILE_TEMPLATE_CODE_OPENCL_B; - break; - } - case rgProjectAPI::Unknown: - default: - // We shouldn't get here. - assert(false); - break; - } - return strBuilder.str(); -} - -std::string rgUtils::GenerateDefaultProjectName() -{ - rgProjectAPI currentAPI = rgConfigManager::Instance().GetCurrentAPI(); - - // Generate a timestamp to append to the base filename. - QDateTime rightNow = QDateTime::currentDateTime(); - QString localTime = rightNow.toString("yyMMdd-HHmmss"); - std::stringstream projectName(localTime.toStdString()); - return projectName.str(); -} - -const char* rgUtils::GenerateProjectName(rgProjectAPI apiName) -{ - static const char* STR_FILE_MENU_PROJECT_NAME = "Project"; - const char* pRet = nullptr; - switch (apiName) - { - case rgProjectAPI::OpenCL: - case rgProjectAPI::Vulkan: - pRet = STR_FILE_MENU_PROJECT_NAME; - break; - default: - // We shouldn't get here. - assert(false); - break; - } - return pRet; -} - -std::string rgUtils::GetProjectTitlePrefix(rgProjectAPI currentApi) -{ - std::stringstream str; - str << "" << rgUtils::GenerateProjectName(currentApi) << " name: "; - return str.str(); -} - -bool rgUtils::GetStageShaderPath(const rgPipelineShaders& pipeline, rgPipelineStage stage, std::string& shaderPath) -{ - bool res = false; - - size_t stageIndex = static_cast(stage); - const auto& stageInputFilePath = pipeline.m_shaderStages[stageIndex]; - if (!stageInputFilePath.empty()) - { - // Extract the shader's file path. - shaderPath = stageInputFilePath; - res = true; - } - - return res; -} - -bool rgUtils::SetStageShaderPath(rgPipelineStage stage, const std::string& shaderPath, rgPipelineShaders& pipeline) -{ - bool res = false; - - assert(!shaderPath.empty()); - if (!shaderPath.empty()) - { - // Set the shader's file path within the pipeline. - size_t stageIndex = static_cast(stage); - pipeline.m_shaderStages[stageIndex] = shaderPath; - res = true; - } - - return res; -} - -bool rgUtils::GetComputeCapabilityToArchMapping(std::map& deviceNameMapping) -{ - deviceNameMapping.clear(); - bool ret = false; - - // Get the current app mode. - const std::string& currentMode = rgConfigManager::Instance().GetCurrentModeString(); - - // Get the version info. - std::shared_ptr pVersionInfo = rgConfigManager::Instance().GetVersionInfo(); - - // Find the architecture node for our current mode. - auto currentModeArchitecturesIter = pVersionInfo->m_gpuArchitectures.find(currentMode); - bool isModeFound = (currentModeArchitecturesIter != pVersionInfo->m_gpuArchitectures.end()); - assert(isModeFound); - if (isModeFound) - { - // Step through each GPU hardware architecture. - std::vector architectures = currentModeArchitecturesIter->second; - for (const rgGpuArchitecture& hardwareArchitecture : architectures) - { - const std::string& currentArchitecture = hardwareArchitecture.m_architectureName; - - // Determine how many families are found within the architecture. - std::vector gpuFamilies = hardwareArchitecture.m_gpuFamilies; - int numFamiliesInArchitecture = static_cast(gpuFamilies.size()); - - // Step through each family within the architecture. - for (int familyIndex = 0; familyIndex < numFamiliesInArchitecture; familyIndex++) - { - // Create a copy of the family info and sort by product name. - rgGpuFamily currentFamily = gpuFamilies[familyIndex]; - deviceNameMapping[currentFamily.m_familyName] = currentArchitecture; - } - } - } - - ret = !deviceNameMapping.empty(); - return ret; -} - -bool rgUtils::GetGfxNotation(const std::string& codeName, std::string& gfxNotation) -{ - bool ret = false; - - // Mapping between codename and gfx compute capability notation. - static const std::map gfxNotationMapping - { - std::make_pair("Tahiti", "gfx600"), - std::make_pair("Hainan", "gfx601"), - std::make_pair("Oland", "gfx601"), - std::make_pair("Capeverde", "gfx601"), - std::make_pair("Pitcairn", "gfx601"), - std::make_pair("Kaveri", "gfx700"), - std::make_pair("Spectre", "gfx700"), - std::make_pair("Spooky", "gfx700"), - std::make_pair("Hawaii", "gfx701"), - std::make_pair("Kabini", "gfx703"), - std::make_pair("Kalindi", "gfx703"), - std::make_pair("Godavari", "gfx703"), - std::make_pair("Mullins", "gfx703"), - std::make_pair("Bonaire", "gfx704"), - std::make_pair("Carrizo", "gfx801"), - std::make_pair("Bristol Ridge", "gfx801"), - std::make_pair("Iceland", "gfx802"), - std::make_pair("Tonga", "gfx802"), - std::make_pair("Fiji", "gfx803"), - std::make_pair("Ellesmere", "gfx803"), - std::make_pair("Baffin", "gfx803"), - std::make_pair("Lexa", "gfx803"), - std::make_pair("Stoney", "gfx810"), - }; - - auto iter = gfxNotationMapping.find(codeName); - if (iter != gfxNotationMapping.end()) - { - gfxNotation = iter->second; - ret = true; - } - - return ret; -} - -std::string rgUtils::RemoveGfxNotation(const std::string& familyName) -{ - std::string fixedGroupName; - size_t bracketPos = familyName.find("/"); - if (bracketPos != std::string::npos) - { - fixedGroupName = familyName.substr(bracketPos + 1); - } - else - { - fixedGroupName = familyName; - } - return fixedGroupName; -} - -bool rgUtils::GetFirstValidOutputGpu(const rgBuildOutputsMap& buildOutputs, std::string& firstValidGpu, std::shared_ptr& pOutput) -{ - bool ret = false; - - // Find the first target ASIC that appears to have valid compilation results. - auto asicOutputsIter = buildOutputs.begin(); - for (; asicOutputsIter != buildOutputs.end(); ++asicOutputsIter) - { - if (asicOutputsIter->second != nullptr) - { - // The current ASIC appears to have valid output, so return the output's info. - firstValidGpu = asicOutputsIter->first; - pOutput = asicOutputsIter->second; - ret = true; - break; - } - } - - return ret; -} - -void rgUtils::SetupComboList(QWidget* pParent, ListWidget* &pListWidget, ArrowIconWidget* &pButton, QObject* &pEventFilter, bool hide) -{ - assert(pButton != nullptr); - if (pButton != nullptr) - { - // Create list widget for the combo box. - pListWidget = new ListWidget(pParent, pButton, hide); - - assert(pListWidget != nullptr); - if (pListWidget != nullptr) - { - pListWidget->hide(); - - // Also disable scrollbars on this list widget. - pListWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - pListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - - // Install a custom event filter on this list widget - // so it can be hidden when something else is clicked on. - pEventFilter = new rgHideListWidgetEventFilter(pListWidget, pButton); - pListWidget->installEventFilter(pEventFilter); - qApp->installEventFilter(pEventFilter); - - // Start out the combo box with the first entry. - pListWidget->setCurrentRow(0); - } - } -} - -std::string rgUtils::GenerateCloneName(int cloneIndex) -{ - // Generate a name based on the default clone name and the incoming index. - std::stringstream cloneName; - cloneName << STR_CLONE_FOLDER_NAME; - cloneName << cloneIndex; - return cloneName.str(); -} - -std::string rgUtils::GetEntrypointsNameString(rgProjectAPI api) -{ - std::string resultString; - - switch (api) - { - case rgProjectAPI::OpenCL: - { - resultString = STR_MENU_BAR_FILE_ITEM_ENTRYPOINT_HEADER_OPENCL; - } - break; - case rgProjectAPI::Unknown: - default: - { - // All other cases use API-agnostic label text. - resultString = STR_MENU_BAR_FILE_ITEM_ENTRYPOINT_HEADER_DEFAULT; - } - break; - } - - return resultString; -} - -bool rgUtils::ProjectAPIToString(rgProjectAPI api, std::string& str) -{ - bool ret = true; - switch (api) - { - case rgProjectAPI::OpenCL: - str = STR_API_NAME_OPENCL; - break; - case rgProjectAPI::Vulkan: - str = STR_API_NAME_VULKAN; - break; - case rgProjectAPI::Unknown: - default: - // We shouldn't get here. - ret = false; - assert(ret); - break; - } - return ret; -} - -rgProjectAPI rgUtils::ProjectAPIToEnum(const std::string& str) -{ - rgProjectAPI projectAPI = rgProjectAPI::Unknown; - - if (str.compare(STR_API_NAME_OPENCL) == 0) - { - projectAPI = rgProjectAPI::OpenCL; - } - else if (str.compare(STR_API_NAME_VULKAN) == 0) - { - projectAPI = rgProjectAPI::Vulkan; - } - - return projectAPI; -} - -bool rgUtils::ProjectAPIToSourceFileExtension(rgProjectAPI api, std::string& extension) -{ - bool ret = true; - switch (api) - { - case rgProjectAPI::OpenCL: - extension = STR_SOURCE_FILE_EXTENSION_CL; - break; - case rgProjectAPI::Vulkan: - extension = STR_SOURCE_FILE_EXTENSION_VULKAN_GLSL; - break; - case rgProjectAPI::Unknown: - default: - // We shouldn't get here. - ret = false; - assert(ret); - break; - } - - return ret; -} - -bool rgUtils::IsProjectSourcePathsValid(std::shared_ptr pProject, int cloneIndex, QWidget* pParent) -{ - bool ret = false; - - rgConfigManager& configManager = rgConfigManager::Instance(); - - // Extract the source file paths from the clone. - std::vector sourceFilepaths; - configManager.GetProjectSourceFilePaths(pProject, cloneIndex, sourceFilepaths); - - // Create a list for files that the project wants to load, but couldn't. - std::vector missingFilesList; - - // Add all the project's source files into the rgBuildView. - for (const std::string& filePath : sourceFilepaths) - { - // Check that the file exists before attempting to load it. - bool isFileExists = rgUtils::IsFileExists(filePath); - if (!isFileExists) - { - missingFilesList.push_back(filePath); - } - } - - // If the list of missing files is non-empty, ask the user where the files were moved to. - if (!missingFilesList.empty()) - { - // Present the user with a dialog that allows them to update the paths for any missing source files. - std::map updatedFilePaths; - rgUtils::ShowBrowseMissingFilesDialog(pProject, missingFilesList, updatedFilePaths, pParent); - } - else - { - // The list of missing files is empty. All paths are valid. - ret = true; - } - - return ret; -} - -bool rgUtils::IsSourceFileTypeValid(const std::string& str) -{ - bool ret = false; - - // Convert to QString for convenience (QString has "endsWith" functionality). - QString qtString = str.c_str(); - - // Check file headers. - if (qtString.endsWith(STR_SOURCE_FILE_EXTENSION_CL) || qtString.endsWith(STR_PROJECT_FILE_EXTENSION)) - { - ret = true; - } - - return ret; -} - -bool rgUtils::ShowBrowseMissingFilesDialog(std::shared_ptr pProject, const std::vector& missingFilesList, std::map& updatedFilePaths, QWidget* pParent) -{ - bool ret = false; - - assert(pProject != nullptr); - if (pProject != nullptr) - { - // Ensure that the incoming list of filenames isn't empty. - int numMissingFiles = static_cast(missingFilesList.size()); - assert(numMissingFiles > 0); - - // Create a new dialog to let the user browse to the missing source files. - rgBrowseMissingFileDialog* pMissingFileDialog = new rgBrowseMissingFileDialog(pProject->m_api, pParent); - pMissingFileDialog->setModal(true); - pMissingFileDialog->setWindowTitle(STR_BROWSE_MISSING_FILE_DIALOG_TITLE); - - // Add each missing file to the dialog. - for (const std::string currentFile : missingFilesList) - { - pMissingFileDialog->AddFile(currentFile); - } - - // Execute the dialog and get the result. - rgBrowseMissingFileDialog::MissingFileDialogResult result; - result = static_cast(pMissingFileDialog->exec()); - - switch (result) - { - case rgBrowseMissingFileDialog::OK: - { - // The user is finished browsing to the missing source files. Extract and return the map of updated file paths. - auto updatedFilePathMap = pMissingFileDialog->GetUpdateFilePathsMap(); - updatedFilePaths = updatedFilePathMap; - ret = true; - } - break; - - case rgBrowseMissingFileDialog::Cancel: - // The user doesn't want to complete finding the missing source files. They intend to abandon opening the project file. - ret = false; - break; - - default: - // Shouldn't get here. - assert(false); - } - - // Free the memory. - delete pMissingFileDialog; - } - - return ret; -} - -void rgUtils::ShowErrorMessageBox(const char* pErrorMessage, QWidget* pWidget) -{ - if (pWidget == nullptr) - { - // The parent widget is null, so need to specify the Window icon - // in addition to all the other settings to recreate the 'critical' look. - QMessageBox messageBox; - messageBox.setWindowIcon(QIcon(gs_ICON_RESOURCE_RGA_LOGO)); - messageBox.setFixedSize(500, 200); - messageBox.setIcon(QMessageBox::Icon::Critical); - messageBox.setText(pErrorMessage); - messageBox.setWindowTitle("Error"); - messageBox.exec(); - } - else - { - QMessageBox::critical(pWidget, "Error", pErrorMessage); - } -} - -bool rgUtils::ShowConfirmationMessageBox(const char* pDialogTitle, const char* pDialogText, QWidget* pParent) -{ - QMessageBox confirmationDialog(pParent); - confirmationDialog.setWindowIcon(QIcon(gs_ICON_RESOURCE_RGA_LOGO)); - confirmationDialog.setWindowTitle(pDialogTitle); - confirmationDialog.setText(pDialogText); - confirmationDialog.setIcon(QMessageBox::Question); - confirmationDialog.setModal(true); - confirmationDialog.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - - // Set button cursor to pointing hand cursor. - QAbstractButton* pButton = confirmationDialog.button(QMessageBox::Button::Yes); - assert(pButton != nullptr); - if (pButton != nullptr) - { - pButton->setCursor(Qt::PointingHandCursor); - } - - pButton = confirmationDialog.button(QMessageBox::Button::No); - assert(pButton != nullptr); - if (pButton != nullptr) - { - pButton->setCursor(Qt::PointingHandCursor); - } - - // Return true if the user clicked yes, otherwise return false. - return (confirmationDialog.exec() == QMessageBox::Yes); -} - -bool rgUtils::OpenFileDialog(QWidget* pParent, rgProjectAPI api, std::string& selectedFilePath) -{ - bool ret = false; - switch (api) - { - case rgProjectAPI::OpenCL: - { - QString filter = QString(STR_FILE_DIALOG_FILTER_OPENCL) + ";;" + STR_FILE_DIALOG_FILTER_ALL; - ret = OpenFileDialogHelper(pParent, STR_FILE_DIALOG_CAPTION, - rgConfigManager::Instance().GetLastSelectedFolder(), filter, selectedFilePath); - break; - } - case rgProjectAPI::Vulkan: - { - QString filter = ConstructVulkanOpenFileFilter(); - ret = OpenFileDialogHelper(pParent, STR_FILE_DIALOG_CAPTION, - rgConfigManager::Instance().GetLastSelectedFolder(), filter, selectedFilePath); - break; - } - case rgProjectAPI::Unknown: - default: - // We shouldn't get here. - assert(false); - break; - } - - // Update last selected directory when selected directory is valid. - if (ret == true) - { - // Extract directory from full path. - std::string fileDirectory; - bool isOk = rgUtils::ExtractFileDirectory(selectedFilePath, fileDirectory); - assert(isOk); - - if (isOk) - { - // Update last selected directory in global config. - rgConfigManager::Instance().SetLastSelectedDirectory(fileDirectory); - } - } - - return ret; -} - -bool rgUtils::OpenFileDialog(QWidget* pParent, std::string& selectedFilePath, const std::string& caption, const std::string& filter) -{ - bool ret = OpenFileDialogHelper(pParent, caption.c_str(), - rgConfigManager::Instance().GetLastSelectedFolder(), filter.c_str(), selectedFilePath); - - return ret; -} - -bool rgUtils::OpenFileDialogForMultipleFiles(QWidget* pParent, rgProjectAPI api, QStringList& selectedFilePaths) -{ - bool ret = false; - switch (api) - { - case rgProjectAPI::OpenCL: - ret = OpenMultipleFileDialogHelper(pParent, STR_FILE_DIALOG_CAPTION, STR_FILE_DIALOG_FILTER_OPENCL, selectedFilePaths); - break; - case rgProjectAPI::Unknown: - default: - // We shouldn't get here. - assert(false); - break; - } - - // Update last selected directory when selected directory is valid. - if (ret == true) - { - // Extract directory from full path. - std::string fileDirectory; - - // Directory will be the same for all selected files so just use the first one. - std::string firstSelectedFile = selectedFilePaths[0].toStdString(); - - bool isOk = rgUtils::ExtractFileDirectory(firstSelectedFile, fileDirectory); - assert(isOk); - - if (isOk) - { - // Update last selected directory in global config. - rgConfigManager::Instance().SetLastSelectedDirectory(fileDirectory); - } - } - - return ret; -} - -bool rgUtils::OpenFolderInFileBrowser(const std::string& folderPath) -{ - bool isBrowserOpened = false; - - bool isDirExists = rgUtils::IsDirExists(folderPath); - assert(isDirExists); - if (isDirExists) - { - // Opening a directory url launches the OS specific window manager. - isBrowserOpened = QDesktopServices::openUrl(QUrl::fromLocalFile(folderPath.c_str())); - if (!isBrowserOpened) - { - // Tell the user that we've failed to open the file browser to the given folder. - rgUtils::ShowErrorMessageBox(STR_ERR_FAILED_TO_OPEN_FILE_BROWSER); - } - } - - return isBrowserOpened; -} - -bool rgUtils::OpenProjectDialog(QWidget* pParent, std::string& selectedFilePath) -{ - bool ret = false; - - // Get RGA's default projects folder. - std::string initialFolder; - rgConfigManager::GetDefaultProjectsFolder(initialFolder); - - // Open the file dialog. - ret = OpenFileDialogHelper(pParent, STR_FILE_DIALOG_RGA_CAPTION, initialFolder, STR_FILE_DIALOG_RGA_FILTER, selectedFilePath); - - // Update last selected directory when selected directory is valid. - if (ret == true) - { - // Extract directory from full path. - std::string fileDirectory; - bool isOk = rgUtils::ExtractFileDirectory(selectedFilePath, fileDirectory); - assert(isOk); - - if (isOk) - { - // Update last selected directory in global config. - rgConfigManager::Instance().SetLastSelectedDirectory(fileDirectory); - } - } - - return ret; -} - -bool rgUtils::ExtractFileName(const std::string& fileFullPath, std::string& fileName, bool includeFileExtension/* = true*/) -{ - bool ret = false; - fileName.clear(); - - // Create a cross-platform file path object. - gtString gtstrFullPath; - gtstrFullPath << fileFullPath.c_str(); - osFilePath filePath; - filePath.setFullPathFromString(gtstrFullPath); - - // Extract and convert the file name. - gtString gtstrFileName; - if (includeFileExtension) - { - filePath.getFileNameAndExtension(gtstrFileName); - } - else - { - filePath.getFileName(gtstrFileName); - } - fileName = gtstrFileName.asASCIICharArray(); - ret = !fileName.empty(); - - return ret; -} - -bool rgUtils::ExtractFileDirectory(const std::string& fileFullPath, std::string& pathToFileDirectory) -{ - bool ret = false; - - // Create a cross-platform file path object. - gtString gtstrFullPath; - gtstrFullPath << fileFullPath.c_str(); - osFilePath filePath; - filePath.setFullPathFromString(gtstrFullPath); - - osDirectory fileDirectory; - ret = filePath.getFileDirectory(fileDirectory); - if (ret) - { - const osFilePath& asFilepath = fileDirectory.asFilePath(); - pathToFileDirectory = asFilepath.asString().asASCIICharArray(); - } - - return ret; -} - -bool rgUtils::ExtractFileExtension(const std::string& filePathString, std::string& fileExtension) -{ - bool ret = false; - fileExtension.clear(); - - // Create a cross-platform file path object. - gtString gtstrFullPath; - gtstrFullPath << filePathString.c_str(); - osFilePath filePath; - filePath.setFullPathFromString(gtstrFullPath); - - // Extract and convert the file name. - gtString gtstrFileExtension; - filePath.getFileExtension(gtstrFileExtension); - - fileExtension = gtstrFileExtension.asASCIICharArray(); - ret = !fileExtension.empty(); - - return ret; -} - -void rgUtils::GetDisplayText(const std::string& fileName, std::string& displayText, const int availableSpace, QWidget* pWidget, const int numBackChars) -{ - std::string extension; - rgUtils::ExtractFileExtension(fileName, extension); - - // Always include the file extension (the +1 is to include the '.' from the file extension too). - const int NUM_BACK_CHARS = numBackChars + static_cast(extension.length() + 1); - const int NUM_FRONT_CHARS = gs_TEXT_TRUNCATE_LENGTH_FRONT; - - // Truncate filename within available space to get display text. - displayText = rgUtils::TruncateString(fileName, NUM_FRONT_CHARS, NUM_BACK_CHARS, availableSpace, pWidget->font(), rgUtils::EXPAND_NONE); -} - -bool rgUtils::ReadTextFile(const std::string& fileFullPath, QString& txt) -{ - bool ret = false; - QFile f(fileFullPath.c_str()); - if (f.open(QFile::ReadOnly | QFile::Text)) - { - QTextStream in(&f); - - // Support Unicode characters. - in.setCodec("UTF-8"); - - txt = in.readAll(); - ret = true; - f.close(); - } - return ret; -} - -bool rgUtils::RenameFile(const std::string& oldFilepath, const std::string& newFilepath) -{ - bool wasRenamed = false; - - // Verify that the target file already exists. - QFile f(oldFilepath.c_str()); - bool fileExists = f.exists(); - assert(fileExists); - if (fileExists) - { - wasRenamed = f.rename(newFilepath.c_str()); - assert(wasRenamed); - } - - return wasRenamed; -} - -bool rgUtils::WriteTextFile(const std::string& targetFilePath, const std::string& txt) -{ - std::ofstream outStream(targetFilePath); - outStream << txt; - bool ret = !outStream.bad(); - outStream.close(); - if (!ret) - { - std::stringstream msg; - msg << STR_ERR_CANNOT_WRITE_TO_FILE << targetFilePath << "."; - rgUtils::ShowErrorMessageBox(msg.str().c_str()); - } - return ret; -} - -bool rgUtils::AppendFolderToPath(const std::string& basePath, const std::string& folderName, std::string& updatedPath) -{ - // Convert the base path to gtString. - gtString gtStrBasePath; - gtStrBasePath << basePath.c_str(); - - // Convert the folder name to gtString. - gtString gtStrSubDir; - gtStrSubDir << folderName.c_str(); - - // Append the path in a cross-platform manner. - osDirectory dir; - dir.setDirectoryFullPathFromString(gtStrBasePath); - osFilePath baseFilePath(dir.asFilePath()); - baseFilePath.appendSubDirectory(gtStrSubDir); - updatedPath = baseFilePath.asString().asASCIICharArray(); - - return !updatedPath.empty(); -} - -bool rgUtils::AppendFileNameToPath(const std::string& basePath, const std::string& fileName, std::string& updatedPath) -{ - // Convert the base path to gtString. - gtString gtStrBasePath; - gtStrBasePath << basePath.c_str(); - - // Convert the folder name to gtString. - gtString gtStrFileName; - gtStrFileName << fileName.c_str(); - - // Append to the path in a cross-platform manner. - osDirectory dir; - dir.setDirectoryFullPathFromString(gtStrBasePath); - osFilePath baseFilePath(dir.asFilePath()); - baseFilePath.setFileName(gtStrFileName); - updatedPath = baseFilePath.asString().asASCIICharArray(); - - return !updatedPath.empty(); -} - -bool rgUtils::AppendPathSeparator(const std::string& basePath, std::string& updatedPath) -{ - // Start with the base path. - updatedPath.assign(basePath); - - // Append a separator to the end, and return. - QString separatorString = QDir::separator(); - updatedPath.append(separatorString.toStdString()); - - return !updatedPath.empty(); -} - -void rgUtils::StandardizePathSeparator(std::string& path) -{ - rgUtils::Replace(path, "\\\\", "/"); - rgUtils::Replace(path, "\\", "/"); -} - -bool rgUtils::IsFileExists(const std::string& fileFullPath) -{ - // Convert the full path to gtString. - gtString gtStrFullPath; - gtStrFullPath << fileFullPath.c_str(); - osFilePath filePath(gtStrFullPath); - - // Check if the file exists. - bool ret = filePath.exists(); - return ret; -} - -bool rgUtils::IsDirExists(const std::string& dirFullPath) -{ - // Convert the path to gtString. - gtString gtStrFullPath; - gtStrFullPath << dirFullPath.c_str(); - - // Check if the directory exists. - osDirectory dir; - dir.setDirectoryFullPathFromString(gtStrFullPath); - bool ret = dir.exists(); - return ret; -} - -bool rgUtils::CreateFolder(const std::string& dirPath) -{ - bool ret = false; - - // Convert the path to gtString. - gtString gtStrFullPath; - gtStrFullPath << dirPath.c_str(); - - // Create the directory if it doesn't already exist. - osDirectory dir; - dir.setDirectoryFullPathFromString(gtStrFullPath); - if (!dir.exists()) - { - ret = dir.create(); - } - - return ret; -} - -bool rgUtils::IsValidFileName(const std::string& fileName) -{ - // Verify that no illegal characters are included in the file name. - bool isValid = - !fileName.empty() && - fileName.find('/') == std::string::npos && - fileName.find('\\') == std::string::npos && - fileName.find(':') == std::string::npos && - fileName.find('|') == std::string::npos && - fileName.find('<') == std::string::npos && - fileName.find('>') == std::string::npos && -#ifdef _WIN32 - // Windows only. - fileName.find('*') == std::string::npos && - fileName.find('\"') == std::string::npos; -#else - // Linux only. - fileName.find('&') == std::string::npos; -#endif - return isValid; -} - -bool rgUtils::IsValidProjectName(const std::string& fileName) -{ - const int MAX_PROJECT_NAME_LENGTH = 50; - return IsValidFileName(fileName) && - !fileName.empty() && - fileName.size() <= MAX_PROJECT_NAME_LENGTH; -} - -bool rgUtils::IsSpvBinFile(const std::string& filePath) -{ - bool isSpv = false; - - if (rgUtils::IsFileExists(filePath)) - { - QFile file(filePath.c_str()); - if (file.open(QFile::ReadOnly)) - { - // Read the first 32-bit word of the file and check if it matches the SPIR-V binary magic number. - uint32_t word; - if (file.read(reinterpret_cast(&word), sizeof(word))) - { - isSpv = (word == SPV_BINARY_MAGIC_NUMBER); - } - } - } - - return isSpv; -} - -bool rgUtils::ConstructSpvDisasmFileName(const std::string& projFolder, const std::string& spvFileName, std::string& spvDisasmFileName) -{ - bool result = (!projFolder.empty() && !spvFileName.empty()); - if (result) - { - std::stringstream outFileName; - std::string inFileName; - rgUtils::ExtractFileName(spvFileName, inFileName); - const std::string dirSep = QString(QDir::separator()).toStdString(); - - outFileName << projFolder << dirSep << STR_PROJECT_SUBFOLDER_GENERATED << dirSep << inFileName << "." << STR_VK_FILE_EXT_SPIRV_TXT; - spvDisasmFileName = outFileName.str(); - } - - return result; -} - -std::pair rgUtils::DetectInputFileType(const std::string& filePath) -{ - std::pair ret = { rgVulkanInputType::Unknown, rgSrcLanguage::Unknown }; - - if (rgUtils::IsSpvBinFile(filePath)) - { - ret = { rgVulkanInputType::Spirv, rgSrcLanguage::SPIRV_Text }; - } - else - { - QFileInfo fileInfo(filePath.c_str()); - const QString& ext = fileInfo.suffix().toLower(); - - rgConfigManager& configManager = rgConfigManager::Instance(); - std::shared_ptr pGlobalSettings = configManager.GetGlobalConfig(); - - if (QString(QString(pGlobalSettings->m_inputFileExtSpvTxt.c_str())).split(STR_VK_FILE_EXT_DELIMITER).contains(ext)) - { - ret = { rgVulkanInputType::SpirvTxt, rgSrcLanguage::SPIRV_Text }; - } - else if (QString(pGlobalSettings->m_inputFileExtGlsl.c_str()).split(STR_VK_FILE_EXT_DELIMITER).contains(ext)) - { - ret = { rgVulkanInputType::Glsl, rgSrcLanguage::GLSL }; - } - else if (QString(pGlobalSettings->m_inputFileExtHlsl.c_str()).split(STR_VK_FILE_EXT_DELIMITER).contains(ext)) - { - ret = { rgVulkanInputType::Hlsl, rgSrcLanguage::HLSL }; - } - } - - return ret; -} - -bool rgUtils::LoadAndApplyStyle(const std::vector& stylesheetFileNames, QWidget* pWidget) -{ - bool ret = false; - QString styleSheet = ""; - - for (const auto& fileName : stylesheetFileNames) - { - std::string stylePath = STR_STYLESHEET_RESOURCE_PATH + fileName; - - // Open file. - QFile stylesheetFile(stylePath.c_str()); - ret = stylesheetFile.open(QFile::ReadOnly); - assert(ret); - - if (ret) - { - // Apply stylesheet. - QString style(stylesheetFile.readAll()); - styleSheet += style; - } - else - { - break; - } - } - pWidget->setStyleSheet(styleSheet); - - return ret; -} - -bool rgUtils::LoadAndApplyStyle(const std::vector& stylesheetFileNames, QApplication* pApplication) -{ - bool ret = false; - QString styleSheet = ""; - - for (const auto& fileName : stylesheetFileNames) - { - std::string stylePath = STR_STYLESHEET_RESOURCE_PATH + fileName; - - // Open file. - QFile stylesheetFile(stylePath.c_str()); - ret = stylesheetFile.open(QFile::ReadOnly); - assert(ret); - - if (ret) - { - // Apply stylesheet. - QString style(stylesheetFile.readAll()); - styleSheet += style; - } - else - { - break; - } - } - pApplication->style()->unpolish(pApplication); - pApplication->setStyleSheet(styleSheet); - - return ret; -} - -void rgUtils::SetToolAndStatusTip(const std::string& tip, QWidget* pWidget) -{ - if (pWidget != nullptr) - { - pWidget->setToolTip(tip.c_str()); - - // Remove any formatting from the incoming string. - const std::string plainText = GetPlainText(tip); - pWidget->setStatusTip(plainText.c_str()); - } -} - -void rgUtils::SetStatusTip(const std::string& tip, QWidget* pWidget) -{ - if (pWidget != nullptr) - { - // Remove any formatting from the incoming string. - const std::string plainText = GetPlainText(tip); - pWidget->setStatusTip(plainText.c_str()); - } -} - -void rgUtils::CenterOnWidget(QWidget* pWidget, QWidget* pCenterOn) -{ - if (pWidget != nullptr && pCenterOn != nullptr) - { - // Get global coordinate of widget to be centered on. - QPoint globalCoord = pCenterOn->mapToGlobal(QPoint(0, 0)); - - // Calculate coordinates to center pWidget relative to pCenterOn. - int xPos = globalCoord.x() + (pCenterOn->width() - pWidget->width()) / 2; - int yPos = globalCoord.y() + (pCenterOn->height() - pWidget->height()) / 2; - - // Set coordinates. - pWidget->move(xPos, yPos); - } -} - -void rgUtils::FocusOnFirstValidAncestor(QWidget* pWidget) -{ - if (pWidget != nullptr) - { - // Step through ancestors until one is found which accepts focus, or there is none found. - QWidget* pAncestor = pWidget->parentWidget(); - while (pAncestor != nullptr && pAncestor->focusPolicy() == Qt::NoFocus) - { - pAncestor = pAncestor->parentWidget(); - } - - // Set focus on the ancestor if it exists. - if (pAncestor != nullptr) - { - pAncestor->setFocus(); - } - } -} - -void rgUtils::StyleRepolish(QWidget* pWidget, bool repolishChildren) -{ - if (pWidget != nullptr) - { - bool isBlocked = false; - - // Check to see if recursive repolishing has been explicitly blocked by this widget. - QVariant isBlockProperty = pWidget->property(gs_IS_REPOLISHING_BLOCKED); - if (isBlockProperty.isValid()) - { - // If the property is found on the widget, and set to true, recursive repolishing is cut short. - isBlocked = isBlockProperty.toBool(); - } - - if (!isBlocked) - { - // Re-polish the widget if it has a style. - if (pWidget->style() != nullptr) - { - pWidget->style()->unpolish(pWidget); - pWidget->style()->polish(pWidget); - } - - // Re-polish all the child widgets. - if (repolishChildren) - { - for (QObject* pChildObject : pWidget->children()) - { - QWidget* pChildWidget = qobject_cast(pChildObject); - StyleRepolish(pChildWidget, repolishChildren); - } - } - } - } -} - -void rgUtils::SetBackgroundColor(QWidget* pWidget, const QColor& color) -{ - assert(pWidget != nullptr); - if (pWidget != nullptr) - { - // Set the background color. - QPalette palette = pWidget->palette(); - palette.setColor(QPalette::Background, color); - pWidget->setAutoFillBackground(true); - pWidget->setPalette(palette); - } -} - -std::string rgUtils::TruncateString(const std::string& text, unsigned int numFrontChars, unsigned int numBackChars, unsigned int availableWidth, const QFont& textFont, TruncateType truncateType) -{ - // Get font metrics for the given font. - QFontMetrics fm(textFont); - - std::string truncatedString(text); - std::string front; - std::string back; - - // Start indices for the front and back segments of the truncated string. - const size_t FRONT_START_INDEX = 0; - const size_t BACK_START_INDEX = text.length() - numBackChars; - - // If the sum of the character minimums at the front and back of the string is - // greater than the string length then no truncation is needed. - if (numFrontChars + numBackChars < text.length()) - { - switch (truncateType) - { - // Non-expanding truncation. - case EXPAND_NONE: - { - front = text.substr(FRONT_START_INDEX, numFrontChars); - back = text.substr(BACK_START_INDEX, numBackChars); - - // Combine strings into result string with delimeter. - truncatedString = front + STR_TRUNCATED_STRING_DELIMETER + back; - } - break; - - // Expanding truncation. - case EXPAND_FRONT: - case EXPAND_BACK: - { - // Some of these variables/calculations are a little unnecessary, but they have - // been written as such for convenience in understanding what the code is doing. - const size_t FRONT_END_INDEX = numFrontChars; - const size_t BACK_END_INDEX = text.length(); - const size_t FRONT_EXPAND_START_INDEX = FRONT_START_INDEX; - const size_t BACK_EXPAND_START_INDEX = FRONT_END_INDEX; - const size_t FRONT_EXPAND_LENGTH = BACK_START_INDEX - FRONT_START_INDEX; - const size_t BACK_EXPAND_LENGTH = BACK_END_INDEX - FRONT_END_INDEX; - - // Determine front and back sub strings. - if (truncateType == EXPAND_FRONT) - { - front = text.substr(FRONT_EXPAND_START_INDEX, FRONT_EXPAND_LENGTH); - back = text.substr(BACK_START_INDEX, numBackChars); - } - else if (truncateType == EXPAND_BACK) - { - front = text.substr(FRONT_START_INDEX, numFrontChars); - back = text.substr(BACK_EXPAND_START_INDEX, BACK_EXPAND_LENGTH); - } - - // Combine strings into result string (check first without delimeter). - truncatedString = front + back; - - // Check text width/length to see if truncation is needed. - unsigned textWidth = fm.width(truncatedString.c_str()); - bool isWithinBounds = textWidth <= availableWidth; - bool isAtMinLength = front.length() <= numFrontChars && back.length() <= numBackChars; - - const unsigned MAX_ATTEMPTS = 1024; - unsigned attempts = 0; - while (!isWithinBounds && !isAtMinLength && ++attempts < MAX_ATTEMPTS) - { - // Reduce string (either front or back depending on truncate type) by one character. - if (truncateType == EXPAND_FRONT) - { - front.pop_back(); - } - else if (truncateType == EXPAND_BACK) - { - back.erase(0, 1); - } - - // Combine strings into result string. - truncatedString = front + STR_TRUNCATED_STRING_DELIMETER + back; - - // Check text width/length to see if truncation is still needed. - textWidth = fm.width(truncatedString.c_str()); - isWithinBounds = textWidth <= availableWidth; - isAtMinLength = front.length() <= numFrontChars && back.length() <= numBackChars; - } - - // This should never happen, but is a safeguard against hanging. - assert(attempts < MAX_ATTEMPTS); - } - break; - - // Invalid truncation type. - default: - assert(false); - } - } - - return truncatedString; -} - -std::string rgUtils::GetPlainText(const std::string& text) -{ - const char* STR_BOLD_MARKUP_START = ""; - const char* STR_BOLD_MARKUP_END = ""; - - // Create a QString - QString plainText(QString::fromStdString(text)); - - // Remove "" and "". - plainText.replace(STR_BOLD_MARKUP_START, ""); - plainText.replace(STR_BOLD_MARKUP_END, ""); - - return plainText.toStdString(); -} - -bool rgUtils::IsInList(const std::string & list, const std::string & token, char delim) -{ - size_t start = 0, end = 0; - bool stop = false, ret = false; - while (!stop) - { - end = list.find(STR_VK_FILE_EXT_DELIMITER, start); - ret = (token == list.substr(start, (end == std::string::npos ? std::string::npos : end - start))); - stop = (ret || end == std::string::npos); - start = end + 1; - } - - return ret; -} - -bool rgUtils::IsSpvasTextFile(const std::string& stageInputFile, std::string& stageAbbreviation) -{ - static const std::string DEFAULT_TEXT_FILE_EXTENSION = "txt"; - bool result = false; - - // Extract file extension. - std::string fileExtension; - rgUtils::ExtractFileExtension(stageInputFile, fileExtension); - - // Get global settings. - rgConfigManager& configManager = rgConfigManager::Instance(); - std::shared_ptr pGlobalSettings = configManager.GetGlobalConfig(); - - // Extract allowed extensions. - QStringList extentions = QString::fromStdString(pGlobalSettings->m_inputFileExtSpvTxt).split((s_OPTIONS_LIST_DELIMITER)); - - // Check if the extension is txt and is in the list. - if ((fileExtension.compare(DEFAULT_TEXT_FILE_EXTENSION) == 0) && (extentions.contains(QString::fromStdString(fileExtension)))) - { - result = true; - } - - return result; -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgUtilsGraphics.cpp b/RadeonGPUAnalyzerGUI/Src/rgUtilsGraphics.cpp deleted file mode 100644 index 7407a99..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgUtilsGraphics.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// Local. -#include -#include - -std::shared_ptr rgUtilsGraphics::CreateUtility(rgProjectAPI api) -{ - std::shared_ptr pUtilityInstance = nullptr; - - switch (api) - { - case rgProjectAPI::Vulkan: - { - pUtilityInstance = std::make_shared(); - } - break; - default: - // If this assert fires, a new graphics API utility instance must be implemented. - assert(false && "Unknown API used to create graphics utility class."); - break; - } - - // If this assert fires, the factory failed to be created properly. - assert(pUtilityInstance != nullptr); - - return pUtilityInstance; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgUtilsVulkan.cpp b/RadeonGPUAnalyzerGUI/Src/rgUtilsVulkan.cpp deleted file mode 100644 index faa8329..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgUtilsVulkan.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// C++. -#include - -// Local. -#include -#include - -std::string rgUtilsVulkan::PipelineStageToAbbreviation(rgPipelineStage pipelineStage) -{ - std::string stageName; - switch (pipelineStage) - { - case rgPipelineStage::Vertex: - stageName = STR_VULKAN_STAGE_NAME_VERTEX_ABBREVIATION; - break; - case rgPipelineStage::TessellationControl: - stageName = STR_VULKAN_STAGE_NAME_TESSELLATION_CONTROL_ABBREVIATION; - break; - case rgPipelineStage::TessellationEvaluation: - stageName = STR_VULKAN_STAGE_NAME_TESSELLATION_EVALUATION_ABBREVIATION; - break; - case rgPipelineStage::Geometry: - stageName = STR_VULKAN_STAGE_NAME_GEOMETRY_ABBREVIATION; - break; - case rgPipelineStage::Fragment: - stageName = STR_VULKAN_STAGE_NAME_FRAGMENT_ABBREVIATION; - break; - case rgPipelineStage::Compute: - stageName = STR_VULKAN_STAGE_NAME_COMPUTE_ABBREVIATION; - break; - default: - // If this assert fires, the given stage isn't recognized. - assert(false); - break; - } - - return stageName; -} - -std::string rgUtilsVulkan::PipelineStageToString(rgPipelineStage pipelineStage) -{ - std::string stageName; - switch (pipelineStage) - { - case rgPipelineStage::Vertex: - stageName = STR_VULKAN_STAGE_NAME_VERTEX; - break; - case rgPipelineStage::TessellationControl: - stageName = STR_VULKAN_STAGE_NAME_TESSELLATION_CONTROL; - break; - case rgPipelineStage::TessellationEvaluation: - stageName = STR_VULKAN_STAGE_NAME_TESSELLATION_EVALUATION; - break; - case rgPipelineStage::Geometry: - stageName = STR_VULKAN_STAGE_NAME_GEOMETRY; - break; - case rgPipelineStage::Fragment: - stageName = STR_VULKAN_STAGE_NAME_FRAGMENT; - break; - case rgPipelineStage::Compute: - stageName = STR_VULKAN_STAGE_NAME_COMPUTE; - break; - default: - // If this assert fires, the given stage isn't recognized. - assert(false); - break; - } - - return stageName; -} - -std::string rgUtilsVulkan::GetDefaultShaderCode(rgPipelineStage pipelineStage) -{ - std::string sourcecode; - switch (pipelineStage) - { - case rgPipelineStage::Vertex: - sourcecode = STR_NEW_FILE_TEMPLATE_CODE_VULKAN_GLSL_VERTEX_SHADER; - break; - case rgPipelineStage::TessellationControl: - sourcecode = STR_NEW_FILE_TEMPLATE_CODE_VULKAN_GLSL_TESSELLATION_CONTROL_SHADER; - break; - case rgPipelineStage::TessellationEvaluation: - sourcecode = STR_NEW_FILE_TEMPLATE_CODE_VULKAN_GLSL_TESSELLATION_EVALUATION_SHADER; - break; - case rgPipelineStage::Geometry: - sourcecode = STR_NEW_FILE_TEMPLATE_CODE_VULKAN_GLSL_GEOMETRY_SHADER; - break; - case rgPipelineStage::Fragment: - sourcecode = STR_NEW_FILE_TEMPLATE_CODE_VULKAN_GLSL_FRAGMENT_SHADER; - break; - case rgPipelineStage::Compute: - sourcecode = STR_NEW_FILE_TEMPLATE_CODE_VULKAN_GLSL_COMPUTE_SHADER; - break; - default: - // If this assert fires, the given stage isn't recognized. - assert(false); - break; - } - - return sourcecode; -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgViewContainer.cpp b/RadeonGPUAnalyzerGUI/Src/rgViewContainer.cpp deleted file mode 100644 index d023e69..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgViewContainer.cpp +++ /dev/null @@ -1,301 +0,0 @@ -// C++. -#include - -// Qt. -#include -#include -#include -#include -#include -#include -#include - -// Local. -#include -#include -#include - -// Identifying widget names. -static const char* s_MAXIMIZE_BUTTON_NAME = "viewMaximizeButton"; -static const char* s_TITLEBAR_WIDGET_NAME = "viewTitlebar"; - -// Identifying property names. -static const char* s_MAXIMIZED_STATE_PROPERTY_NAME = "isMaximized"; -static const char* s_HOVERED_STATE_PROPERTY_NAME = "viewHovered"; -static const char* s_FOCUSED_STATE_PROPERTY_NAME = "viewFocused"; - -rgViewContainer::rgViewContainer(QWidget* pParent) : - QWidget(pParent) -{ - // Default initialize state properties. - setProperty(s_MAXIMIZED_STATE_PROPERTY_NAME, false); - setProperty(s_HOVERED_STATE_PROPERTY_NAME, false); - setProperty(s_FOCUSED_STATE_PROPERTY_NAME, false); - - setFocusPolicy(Qt::StrongFocus); -} - -void rgViewContainer::SwitchContainerSize() -{ - SetMaximizedState(!m_isInMaximizedState); - emit MaximizeButtonClicked(); -} - -void rgViewContainer::SetIsMaximizable(bool isEnabled) -{ - m_isMaximizable = isEnabled; - - if (m_pMaximizeButton != nullptr) - { - // Toggle the visibility of the maximize/restore button in the container's titlebar. - m_pMaximizeButton->setVisible(isEnabled); - } -} - -void rgViewContainer::SetMainWidget(QWidget* pWidget) -{ - if (pWidget != nullptr) - { - // Reparent the widget. - pWidget->setParent(this); - - // Force the same max size as the main widget. - setMaximumSize(pWidget->maximumSize()); - - // Store pointer to main widget. - m_pMainWidget = pWidget; - - // Use the main widget as the focus proxy for this container. - setFocusProxy(pWidget); - - // Extract the title bar if it isn't set. - if (m_pTitleBarWidget == nullptr) - { - ExtractTitlebar(); - } - - // Extract the maximize button. - ExtractMaximizeButton(); - - // Refresh widget sizes. - RefreshGeometry(); - } -} - -void rgViewContainer::SetTitlebarWidget(QWidget* pWidget) -{ - if (pWidget != nullptr) - { - // Reparent the widget. - pWidget->setParent(this); - } - - // Store pointer to title bar widget. - m_pTitleBarWidget = pWidget; - - // Indicate the title bar is not embedded. - m_isEmbeddedTitlebar = false; - - // Extract the maximize button. - ExtractMaximizeButton(); - - // Refresh widget sizes. - RefreshGeometry(); -} - -QWidget* rgViewContainer::GetTitleBar() -{ - return m_pTitleBarWidget; -} - -void rgViewContainer::SetMaximizedState(bool isMaximized) -{ - setProperty(s_MAXIMIZED_STATE_PROPERTY_NAME, isMaximized); - m_isInMaximizedState = isMaximized; - rgUtils::StyleRepolish(this, true); -} - -void rgViewContainer::SetFocusedState(bool isFocused) -{ - setProperty(s_FOCUSED_STATE_PROPERTY_NAME, isFocused); - rgUtils::StyleRepolish(this, true); -} - -bool rgViewContainer::IsInMaximizedState() const -{ - return m_isInMaximizedState; -} - -void rgViewContainer::SetHiddenState(bool isHidden) -{ - m_isInHiddenState = isHidden; -} - -bool rgViewContainer::IsMaximizable() const -{ - return m_isMaximizable; -} - -bool rgViewContainer::IsInHiddenState() const -{ - return m_isInHiddenState; -} - -QWidget* rgViewContainer::GetMainWidget() const -{ - return m_pMainWidget; -} - -void rgViewContainer::resizeEvent(QResizeEvent* pEvent) -{ - // Refresh widget sizes. - RefreshGeometry(); - - // Normal event processing. - QWidget::resizeEvent(pEvent); -} - -QSize rgViewContainer::sizeHint() const -{ - QSize ret(0, 0); - - // Use the main widget size hint, if it exists. - if (m_pMainWidget != nullptr) - { - ret = m_pMainWidget->sizeHint(); - } - else - { - ret = QWidget::sizeHint(); - } - - return ret; -} - -QSize rgViewContainer::minimumSizeHint() const -{ - QSize ret(0, 0); - - // Use the main widget minimum size hint, if it exists. - if (m_pMainWidget != nullptr) - { - ret = m_pMainWidget->minimumSizeHint(); - } - else - { - ret = QWidget::minimumSizeHint(); - } - - return ret; -} - -void rgViewContainer::enterEvent(QEvent* pEvent) -{ - setProperty(s_HOVERED_STATE_PROPERTY_NAME, true); - - if (m_pTitleBarWidget != nullptr) - { - rgUtils::StyleRepolish(m_pTitleBarWidget, true); - } -} - -void rgViewContainer::leaveEvent(QEvent* pEvent) -{ - setProperty(s_HOVERED_STATE_PROPERTY_NAME, false); - - if (m_pTitleBarWidget != nullptr) - { - rgUtils::StyleRepolish(m_pTitleBarWidget, true); - } -} - -void rgViewContainer::mouseDoubleClickEvent(QMouseEvent* pEvent) -{ - if (pEvent != nullptr && pEvent->button() == Qt::LeftButton) - { - // A double-click on the top bar should behave like a click on the Resize button. - MaximizeButtonClicked(); - } -} - -void rgViewContainer::mousePressEvent(QMouseEvent* pEvent) -{ - // A click in this view should unfocus the build settings view. - emit ViewContainerMouseClickEventSignal(); - - // Pass the event onto the base class. - QWidget::mousePressEvent(pEvent); -} - -void rgViewContainer::RefreshGeometry() -{ - bool doOverlayTitlebar = false; - int titlebarHeight = 0; - - // If there is a titlebar, position it at the top and always on top of the main widget. - if (m_pTitleBarWidget != nullptr && !m_isEmbeddedTitlebar) - { - // Get height of titlebar area. - titlebarHeight = m_pTitleBarWidget->minimumSize().height(); - - m_pTitleBarWidget->raise(); - m_pTitleBarWidget->setGeometry(0, 0, size().width(), titlebarHeight); - } - - if (m_pMainWidget != nullptr) - { - // If there is no titlebar or if the titlebar is being overlayed, fill the entire - // container with the main widget. Otherwise leave room for a titlebar. - if (m_pTitleBarWidget == nullptr || doOverlayTitlebar || m_isEmbeddedTitlebar) - { - m_pMainWidget->setGeometry(0, 0, size().width(), size().height()); - } - else - { - m_pMainWidget->setGeometry(0, titlebarHeight, size().width(), size().height() - titlebarHeight); - } - } -} - -void rgViewContainer::ExtractTitlebar() -{ - m_pTitleBarWidget = nullptr; - - if (m_pMainWidget != nullptr) - { - // Get the titlebar by name. - m_pTitleBarWidget = m_pMainWidget->findChild(s_TITLEBAR_WIDGET_NAME); - - if (m_pTitleBarWidget != nullptr) - { - // Indicate the titlebar is embedded. - m_isEmbeddedTitlebar = true; - } - } -} - -void rgViewContainer::ExtractMaximizeButton() -{ - m_pMaximizeButton = nullptr; - - // Try to get the button from the titlebar. - if (m_pTitleBarWidget != nullptr) - { - // Get the maximize button by name. - m_pMaximizeButton = m_pTitleBarWidget->findChild(s_MAXIMIZE_BUTTON_NAME); - } - - // Try to get the button from the main widget. - if (m_pMaximizeButton == nullptr && m_pMainWidget != nullptr) - { - // Get the maximize button by name. - m_pMaximizeButton = m_pMainWidget->findChild(s_MAXIMIZE_BUTTON_NAME); - } - - // Connect the button's signals/slots if a valid one is found. - if (m_pMaximizeButton != nullptr) - { - bool isConnected = connect(m_pMaximizeButton, &QAbstractButton::clicked, this, &rgViewContainer::MaximizeButtonClicked); - assert(isConnected); - } -} \ No newline at end of file diff --git a/RadeonGPUAnalyzerGUI/Src/rgViewManager.cpp b/RadeonGPUAnalyzerGUI/Src/rgViewManager.cpp deleted file mode 100644 index 4883a18..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgViewManager.cpp +++ /dev/null @@ -1,542 +0,0 @@ - -// C++. -#include - -// Qt. -#include -#include - -// Local. -#include -#include -#include -#include -#include -#include - -rgViewManager::rgViewManager(QWidget* pParent) : - m_pParent(pParent), - m_focusViewIndex(-1) -{ - CreateActions(); - - // Handler for when the focus object changes. - bool isConnected = connect(qApp, &QGuiApplication::focusObjectChanged, this, &rgViewManager::HandleFocusObjectChanged); - assert(isConnected); - - // Handler for when the application is about to quit. - isConnected = connect(qApp, &QCoreApplication::aboutToQuit, this, &rgViewManager::HandleApplicationAboutToQuit); - assert(isConnected); -} - -rgViewManager::~rgViewManager() -{ - -} - -void rgViewManager::CreateActions() -{ - // Focus next view action. - m_pFocusNextViewAction = new QAction(this); - m_pFocusNextViewAction->setShortcutContext(Qt::ApplicationShortcut); - m_pFocusNextViewAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_NEXT_VIEW)); - assert(m_pParent != nullptr); - if (m_pParent != nullptr) - { - m_pParent->addAction(m_pFocusNextViewAction); - } - - bool isConnected = connect(m_pFocusNextViewAction, &QAction::triggered, this, &rgViewManager::HandleFocusNextViewAction); - assert(isConnected); - - // Focus previous view action. - m_pFocusPrevViewAction = new QAction(this); - m_pFocusPrevViewAction->setShortcutContext(Qt::ApplicationShortcut); - m_pFocusPrevViewAction->setShortcut(QKeySequence(gs_ACTION_HOTKEY_PREVIOUS_VIEW)); - assert(m_pParent != nullptr); - if (m_pParent != nullptr) - { - m_pParent->addAction(m_pFocusPrevViewAction); - } - - isConnected = connect(m_pFocusPrevViewAction, &QAction::triggered, this, &rgViewManager::HandleFocusPrevViewAction); - assert(isConnected); -} - -void rgViewManager::AddView(rgViewContainer* pViewContainer, bool isActive) -{ - if (isActive) - { - m_viewContainers.push_back(pViewContainer); - } - else - { - m_inactiveViewContainers.push_back(pViewContainer); - } -} - -void rgViewManager::AddView(rgViewContainer* pViewContainer, bool isActive, int index) -{ - assert(index >= rgViewManagerViewContainerIndex::FileMenu); - assert(index < rgViewManagerViewContainerIndex::Count); - - if (index >= rgViewManagerViewContainerIndex::FileMenu && index < rgViewManagerViewContainerIndex::Count) - { - if (isActive) - { - m_viewContainers.insert(m_viewContainers.begin() + index, pViewContainer); - } - else - { - m_inactiveViewContainers.insert(m_inactiveViewContainers.begin() + index, pViewContainer); - } - } -} - -void rgViewManager::FocusNextView() -{ - if (m_focusViewIndex >= 0) - { - // If the current view is output window, and it is - // currently maximized, do not process this action. - rgViewContainer* pViewContainer = m_viewContainers.at(m_focusViewIndex); - bool focusNextView = !(pViewContainer->IsInMaximizedState() && (pViewContainer->objectName().compare(STR_RG_BUILD_OUTPUT_VIEW_CONTAINER) == 0)); - if (focusNextView) - { - // Increment focus index. - int newFocusIndex = m_focusViewIndex + 1; - - if (newFocusIndex >= m_viewContainers.size()) - { - newFocusIndex = 0; - } - - if (!m_isSourceViewCurrent) - { - if (m_currentFocusedView == rgCurrentFocusedIndex::FileMenuCurrent) - { - // Set the focus to the hidden disassembly view to remove - // focus from the file menu. - newFocusIndex = GetFocusIndex(rgViewManagerViewContainerIndex::DisassemblyView); - - // Change the view focus index. - SetFocusedViewIndex(newFocusIndex); - - // Apply the focus change. - ApplyViewFocus(); - - if (m_isBuildSettingsViewCurrent) - { - emit BuildSettingsWidgetFocusInSignal(); - m_currentFocusedView = rgCurrentFocusedIndex::BuildSettingsViewCurrent; - } - else if (m_isPSOEditorViewCurrent) - { - emit PSOEditorWidgetFocusInSignal(); - m_currentFocusedView = rgCurrentFocusedIndex::PSOEditorViewCurrent; - } - else - { - // Should not get here. - assert(false); - } - } - else if (m_currentFocusedView == rgCurrentFocusedIndex::BuildOutputViewCurrent) - { - emit BuildSettingsWidgetFocusOutSignal(); - emit PSOEditorWidgetFocusOutSignal(); - newFocusIndex = GetFocusIndex(rgViewManagerViewContainerIndex::FileMenu); - m_currentFocusedView = rgCurrentFocusedIndex::FileMenuCurrent; - - // Change the view focus index. - SetFocusedViewIndex(newFocusIndex); - - // Apply the focus change. - ApplyViewFocus(); - } - else if ((m_currentFocusedView == rgCurrentFocusedIndex::BuildSettingsViewCurrent) || - (m_currentFocusedView == rgCurrentFocusedIndex::PSOEditorViewCurrent)) - { - emit BuildSettingsWidgetFocusOutSignal(); - emit PSOEditorWidgetFocusOutSignal(); - newFocusIndex = GetFocusIndex(rgViewManagerViewContainerIndex::BuildOutputView); - m_currentFocusedView = rgCurrentFocusedIndex::BuildOutputViewCurrent; - - // Change the view focus index. - SetFocusedViewIndex(newFocusIndex); - - // Apply the focus change. - ApplyViewFocus(); - } - } - else - { - rgViewContainer* pViewContainer = m_viewContainers.at(newFocusIndex); - while (pViewContainer->IsInHiddenState() && newFocusIndex < m_viewContainers.size()) - { - newFocusIndex++; - if (newFocusIndex >= m_viewContainers.size()) - { - newFocusIndex = 0; - } - pViewContainer = m_viewContainers.at(newFocusIndex); - } - - // Change the view focus index. - SetFocusedViewIndex(newFocusIndex); - - // Apply the focus change. - ApplyViewFocus(); - } - } - } -} - -void rgViewManager::SwitchContainerSize() -{ - rgViewContainer* pViewContainer = m_viewContainers.at(m_focusViewIndex); - assert(pViewContainer != nullptr); - if (pViewContainer != nullptr) - { - pViewContainer->SwitchContainerSize(); - } -} - -void rgViewManager::SetSourceWindowFocus() -{ - // Change the view focus index. - SetFocusedViewIndex(rgViewManagerViewContainerIndex::SourceView); - - // Apply the focus change. - ApplyViewFocus(); -} - -void rgViewManager::SetOutputWindowFocus() -{ - // Change the view focus index. - SetFocusedViewIndex(rgViewManagerViewContainerIndex::BuildOutputView); - - // Apply the focus change. - ApplyViewFocus(); -} - -void rgViewManager::SetDisassemblyViewFocus() -{ - // Change the view focus index. - SetFocusedViewIndex(rgViewManagerViewContainerIndex::DisassemblyView); - - // Apply the focus change. - ApplyViewFocus(); -} - -void rgViewManager::FocusPrevView() -{ - // If the current view is output window, and it is - // currently maximized, do not process this action. - if (m_focusViewIndex >= 0) - { - rgViewContainer* pViewContainer = m_viewContainers.at(m_focusViewIndex); - bool focusPrevView = !(pViewContainer->IsInMaximizedState() && (pViewContainer->objectName().compare(STR_RG_BUILD_OUTPUT_VIEW_CONTAINER) == 0)); - if (focusPrevView) - { - int newFocusIndex = m_focusViewIndex - 1; - - if (!m_isSourceViewCurrent) - { - if (m_currentFocusedView == rgCurrentFocusedIndex::FileMenuCurrent) - { - emit BuildSettingsWidgetFocusOutSignal(); - emit PSOEditorWidgetFocusOutSignal(); - newFocusIndex = GetFocusIndex(rgViewManagerViewContainerIndex::BuildOutputView); - m_currentFocusedView = rgCurrentFocusedIndex::BuildOutputViewCurrent; - - // Change the view focus index. - SetFocusedViewIndex(newFocusIndex); - - // Apply the focus change. - ApplyViewFocus(); - } - else if (m_currentFocusedView == rgCurrentFocusedIndex::BuildOutputViewCurrent) - { - // Set the focus to the hidden disassembly view to remove - // focus from the file menu. - newFocusIndex = GetFocusIndex(rgViewManagerViewContainerIndex::DisassemblyView); - - // Change the view focus index. - SetFocusedViewIndex(newFocusIndex); - - // Apply the focus change. - ApplyViewFocus(); - - if (m_isBuildSettingsViewCurrent) - { - emit BuildSettingsWidgetFocusInSignal(); - m_currentFocusedView = rgCurrentFocusedIndex::BuildSettingsViewCurrent; - } - else if (m_isPSOEditorViewCurrent) - { - emit PSOEditorWidgetFocusInSignal(); - m_currentFocusedView = rgCurrentFocusedIndex::PSOEditorViewCurrent; - } - else - { - // Should not get here. - assert(false); - } - } - else if ((m_currentFocusedView == rgCurrentFocusedIndex::BuildSettingsViewCurrent) || - (m_currentFocusedView == rgCurrentFocusedIndex::PSOEditorViewCurrent)) - { - emit BuildSettingsWidgetFocusOutSignal(); - emit PSOEditorWidgetFocusOutSignal(); - newFocusIndex = GetFocusIndex(rgViewManagerViewContainerIndex::FileMenu); - m_currentFocusedView = rgCurrentFocusedIndex::FileMenuCurrent; - - // Change the view focus index. - SetFocusedViewIndex(newFocusIndex); - - // Apply the focus change. - ApplyViewFocus(); - } - } - else - { - // Decrement focus index. - if (newFocusIndex < 0) - { - newFocusIndex = static_cast(m_viewContainers.size()) - 1; - } - - rgViewContainer* pViewContainer = m_viewContainers.at(newFocusIndex); - while (pViewContainer->IsInHiddenState() && newFocusIndex < m_viewContainers.size()) - { - newFocusIndex--; - if (newFocusIndex < 0) - { - newFocusIndex = static_cast(m_viewContainers.size()) - 1; - } - pViewContainer = m_viewContainers.at(newFocusIndex); - } - - // Change the view focus index. - SetFocusedViewIndex(newFocusIndex); - - // Apply the focus change. - ApplyViewFocus(); - } - } - } -} - -void rgViewManager::SetFocusedView(rgViewContainer* pViewContainer) -{ - if (m_pFocusViewContainer != nullptr) - { - // Get old focused view container. - rgViewContainer* pOldFocusContainer = m_pFocusViewContainer; - - // Set focus state. - pOldFocusContainer->SetFocusedState(false); - } - - // Set new focused view container. - m_pFocusViewContainer = pViewContainer; - - // Set focus state. - assert(m_pFocusViewContainer != nullptr); - if (m_pFocusViewContainer != nullptr) - { - m_pFocusViewContainer->SetFocusedState(true); - - if ((m_pFocusViewContainer->objectName()).compare(STR_RG_ISA_DISASSEMBLY_VIEW_CONTAINER) != 0) - { - // Emit the frame out of focus signal. - emit FrameFocusOutSignal(); - } - } -} - -void rgViewManager::SetFocusedViewIndex(int index) -{ - if (index >= 0 && index < m_viewContainers.size()) - { - // Set focus index. - m_focusViewIndex = index; - - // Get container at the focus index. - rgViewContainer* pNewViewContainer = m_viewContainers[m_focusViewIndex]; - - // Set the focused view. - SetFocusedView(pNewViewContainer); - } -} - -void rgViewManager::ClearFocusedView() -{ - // Clear focused state of currently focused view container. - // Having this on Linux causes a crash, so leaving it out of Linux build. -#ifndef __linux - if (m_pFocusViewContainer != nullptr) - { - m_pFocusViewContainer->SetFocusedState(false); - } -#endif // __linux - - // Invalidate focus index. - m_focusViewIndex = -1; - m_pFocusViewContainer = nullptr; -} - -void rgViewManager::ApplyViewFocus() -{ - // Focus in on the widget. - if (m_pFocusViewContainer != nullptr) - { - // Get widget to focus on - QWidget* pFocusWidget = m_pFocusViewContainer->GetMainWidget(); - - if (pFocusWidget != nullptr) - { - pFocusWidget->setFocus(); - } - - // If the widget is disassembly view, also change the frame color. - rgIsaDisassemblyView* pView = qobject_cast(pFocusWidget); - if (pView != nullptr) - { - emit FrameFocusInSignal(); - } - } -} - -void rgViewManager::HandleApplicationAboutToQuit() -{ - // Remove all references to existing containers so widgets aren't re-polished during shutdown. - m_viewContainers.clear(); - m_inactiveViewContainers.clear(); -} - -void rgViewManager::SetCurrentFocusedView(rgCurrentFocusedIndex currentFocusIndex) -{ - m_currentFocusedView = currentFocusIndex; -} - -void rgViewManager::HandleFocusNextViewAction() -{ - FocusNextView(); -} - -void rgViewManager::HandleFocusPrevViewAction() -{ - FocusPrevView(); -} - -int FindAncestorContainerIndex(const QWidget* pWidget, const std::vector& containerList) -{ - int ret = -1; - - // Search the list to find a container that is an ancestor of the given widget. - for (int i = 0; i < containerList.size(); i++) - { - rgViewContainer* pViewContainer = containerList[i]; - - // If the focus widget is a child of a view container, give that container view focus. - if (pViewContainer->isAncestorOf(pWidget)) - { - ret = i; - break; - } - } - - return ret; -} - -void rgViewManager::HandleFocusObjectChanged(QObject* pObject) -{ - QWidget* pWidget = qobject_cast(pObject); - - if (pWidget != nullptr) - { - // Find appropriate view container to switch view focus to. - int focusIndex = FindAncestorContainerIndex(pWidget, m_viewContainers); - - if (focusIndex >= 0) - { - SetFocusedViewIndex(focusIndex); - } - else - { - // If no container in the main list exists, check the inactive container list. - int inactiveIndex = FindAncestorContainerIndex(pWidget, m_inactiveViewContainers); - - if (inactiveIndex >= 0) - { - // Get the view from the inactive view list. - rgViewContainer* pView = m_inactiveViewContainers[inactiveIndex]; - - // Set the focused view. - SetFocusedView(pView); - } - else - { - ClearFocusedView(); - } - } - } - else - { - ClearFocusedView(); - } -} - -void rgViewManager::SetIsSourceViewCurrent(bool value) -{ - m_isSourceViewCurrent = value; -} - -void rgViewManager::SetIsBuildSettingsViewCurrent(bool value) -{ - m_isBuildSettingsViewCurrent = value; -} - -void rgViewManager::SetIsPSOEditorViewCurrent(bool value) -{ - m_isPSOEditorViewCurrent = value; -} - -int rgViewManager::GetFocusIndex(rgViewManagerViewContainerIndex viewContainerIndex) -{ - int focusIndex = 0; - - QString matchContainer; - switch (viewContainerIndex) - { - case rgViewManagerViewContainerIndex::BuildOutputView: - matchContainer = STR_RG_BUILD_OUTPUT_VIEW_CONTAINER; - break; - case rgViewManagerViewContainerIndex::FileMenu: - matchContainer = STR_RG_FILE_MENU_VIEW_CONTAINER; - break; - case rgViewManagerViewContainerIndex::DisassemblyView: - matchContainer = STR_RG_ISA_DISASSEMBLY_VIEW_CONTAINER; - break; - case rgViewManagerViewContainerIndex::SourceView: - matchContainer = STR_RG_SOURCE_VIEW_CONTAINER; - break; - default: - assert(false); - } - - // Step through the view container vector and find the matching view container. - for (const rgViewContainer* pViewContainer : m_viewContainers) - { - QString containerName = pViewContainer->objectName(); - if (containerName.compare(matchContainer) == 0) - { - break; - } - focusIndex++; - } - - return focusIndex; -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgXMLSessionConfig.cpp b/RadeonGPUAnalyzerGUI/Src/rgXMLSessionConfig.cpp deleted file mode 100644 index 675f920..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgXMLSessionConfig.cpp +++ /dev/null @@ -1,427 +0,0 @@ -// C++. -#include -#include - -// XML. -#include - -// Local. -#include -#include -#include -#include -#include -#include -#include - -bool rgXMLSessionConfig::ReadSessionMetadataOpenCL(const std::string& sessionMetadataFilePath, std::shared_ptr& pCliOutput) -{ - bool ret = false; - - // Create the CLI output variable. - pCliOutput = std::make_shared(); - - // Load the XML document. - tinyxml2::XMLDocument doc; - tinyxml2::XMLError rc = doc.LoadFile(sessionMetadataFilePath.c_str()); - - if (rc == tinyxml2::XML_SUCCESS) - { - // Get the XML declaration node. - tinyxml2::XMLNode* pNode = doc.FirstChild(); - if (pNode != nullptr) - { - // Traverse to the program metadata root element. - pNode = pNode->NextSiblingElement(XML_NODE_METADATA); - if (pNode != nullptr) - { - // Parse the metadata contents, starting with the output binary and input files. - tinyxml2::XMLNode* pBinaryFilePathNode = pNode->FirstChildElement(XML_NODE_BINARY); - if (pBinaryFilePathNode != nullptr) - { - // Read the full file path to the compiled binary output. - std::string binaryFullFilePath; - ret = rgXMLUtils::ReadNodeTextString(pBinaryFilePathNode, binaryFullFilePath); - - if (ret) - { - // Set the output's binary path to what was read from the node text. - pCliOutput->m_projectBinary = binaryFullFilePath; - - // Parse the metadata contents, starting with the output binary and input files. - tinyxml2::XMLNode* pInputFileNode = pNode->FirstChildElement(XML_NODE_INPUT_FILE); - if (pInputFileNode != nullptr) - { - // Read all of the input file nodes. - ret = ReadInputFiles(pInputFileNode, pCliOutput); - assert(ret); - } - } - } - } - } - } - - return ret; -} - -bool rgXMLSessionConfig::ReadSessionMetadataVulkan(const std::string& sessionMetadataFilePath, std::shared_ptr& pCliOutput) -{ - bool ret = false; - - // Create the CLI output variable. - pCliOutput = std::make_shared(); - - // Load the XML document. - tinyxml2::XMLDocument doc; - tinyxml2::XMLError rc = doc.LoadFile(sessionMetadataFilePath.c_str()); - - if (rc == tinyxml2::XML_SUCCESS) - { - // Get the root pipeline metadata element. Pipeline outputs appear as children elements. - tinyxml2::XMLNode* pPipelineMetadataNode = doc.FirstChildElement(XML_NODE_METADATA_PIPELINE); - assert(pPipelineMetadataNode != nullptr); - if (pPipelineMetadataNode != nullptr) - { - // Get the XML declaration node. - tinyxml2::XMLNode* pPipelineNode = pPipelineMetadataNode->FirstChildElement(XML_NODE_PIPELINE); - if (pPipelineNode != nullptr) - { - // Determine the type of pipeline that was built. - tinyxml2::XMLNode* pPipelineTypeNode = pPipelineNode->FirstChildElement(XML_NODE_TYPE); - if (pPipelineTypeNode != nullptr) - { - // Read the pipeline type string. - std::string pipelineTypeString; - ret = rgXMLUtils::ReadNodeTextString(pPipelineTypeNode, pipelineTypeString); - - assert(ret); - if (ret) - { - // Set the pipeline type based on the node text. - pCliOutput->m_type = (pipelineTypeString.compare(XML_NODE_PIPELINE_TYPE_GRAPHICS) == 0) ? - rgPipelineType::Graphics : rgPipelineType::Compute; - - // Search for each stage element. - tinyxml2::XMLNode* pStageNode = pPipelineNode->FirstChildElement(XML_NODE_STAGE); - while (pStageNode != nullptr) - { - rgFileOutputs fileOutputs; - - rgEntryOutput stageEntry = {}; - stageEntry.m_entrypointName = STR_DEFAULT_VULKAN_GLSL_ENTRYPOINT_NAME; - - // Search for the stage type node. - tinyxml2::XMLNode* pStageTypeNode = pStageNode->FirstChildElement(XML_NODE_TYPE); - - assert(pStageTypeNode != nullptr); - if (pStageTypeNode != nullptr) - { - // Read the stage type node. - std::string pipelineStageTypeString; - ret = rgXMLUtils::ReadNodeTextString(pStageTypeNode, pipelineStageTypeString); - - assert(ret); - if (ret) - { - // Assign the stage type in the file's outputs struct. - stageEntry.m_kernelType = pipelineStageTypeString; - } - } - - assert(ret); - if (ret) - { - // Search for the input file node. - tinyxml2::XMLNode* pInputFileNode = pStageNode->FirstChildElement(XML_NODE_INPUT_FILE); - assert(pInputFileNode != nullptr); - if (pInputFileNode != nullptr) - { - pInputFileNode = pInputFileNode->FirstChildElement(XML_NODE_PATH); - assert(pInputFileNode != nullptr); - if (pInputFileNode != nullptr) - { - // Read the input file path. - std::string inputFilePathString; - ret = rgXMLUtils::ReadNodeTextString(pInputFileNode, inputFilePathString); - if (ret) - { - stageEntry.m_inputFilePath = inputFilePathString; - } - } - } - } - - assert(ret); - if (ret) - { - // Find the stage node's output node. - tinyxml2::XMLNode* pStageOutputNode = pStageNode->FirstChildElement(XML_NODE_OUTPUT); - assert(pStageOutputNode != nullptr); - if (pStageOutputNode != nullptr) - { - // Read the stage's output files. - ret = ret && ReadPipelineStageOutputs(pStageOutputNode, stageEntry); - } - } - - assert(ret); - if (ret) - { - fileOutputs.m_inputFilePath = stageEntry.m_inputFilePath; - - fileOutputs.m_outputs.push_back(stageEntry); - pCliOutput->m_perFileOutput[stageEntry.m_inputFilePath] = fileOutputs; - - // Search for the next stage node. - pStageNode = pStageNode->NextSiblingElement(XML_NODE_STAGE); - } - - - // If anything went wrong, end this loop. - if (!ret) - { - pStageNode = nullptr; - } - } - } - } - } - } - } - - return ret; -} - -bool rgXMLSessionConfig::ReadBuildOutputs(tinyxml2::XMLNode* pOutputsNode, std::vector& outputs) -{ - bool ret = false; - - // Extract the target GPU name. - tinyxml2::XMLNode* pTargetGpuNode = pOutputsNode->FirstChildElement(XML_NODE_TARGET); - - while (pOutputsNode != nullptr) - { - rgOutputItem outputItem = {}; - - if (pTargetGpuNode != nullptr) - { - // Read the target GPU that the output was generated for. - std::string targetAsic; - ret = rgXMLUtils::ReadNodeTextString(pTargetGpuNode, targetAsic); - assert(ret); - - if (ret) - { - // Find the ISA disassembly text file path node. - tinyxml2::XMLNode* pIsaDisassemblyTextNode = pOutputsNode->FirstChildElement(XML_NODE_ISA); - if (pIsaDisassemblyTextNode != nullptr) - { - // Read the file path to the disassembled ISA text. - std::string isaDisassemlyTextFilePath; - ret = rgXMLUtils::ReadNodeTextString(pIsaDisassemblyTextNode, isaDisassemlyTextFilePath); - assert(ret); - - if (ret) - { - rgOutputItem csvOutputItem = { isaDisassemlyTextFilePath, targetAsic, rgCliOutputFileType::IsaDisassemblyText }; - outputs.push_back(csvOutputItem); - } - } - - // Find the ISA disassembly CSV file path node. - tinyxml2::XMLNode* pIsaDisassemblyCsvNode = pOutputsNode->FirstChildElement(XML_NODE_CSV_ISA); - if (pIsaDisassemblyCsvNode != nullptr) - { - // Read the file path to the disassembled ISA CSV. - std::string isaDisassemlyCsvFilePath; - ret = rgXMLUtils::ReadNodeTextString(pIsaDisassemblyCsvNode, isaDisassemlyCsvFilePath); - assert(ret); - - if (ret) - { - rgOutputItem csvOutputItem = { isaDisassemlyCsvFilePath, targetAsic, rgCliOutputFileType::IsaDisassemblyCsv }; - outputs.push_back(csvOutputItem); - } - } - - // Find the resource usage CSV file path node. - tinyxml2::XMLNode* pResourceUsageCsvNode = pOutputsNode->FirstChildElement(XML_NODE_RES_USAGE); - if (pResourceUsageCsvNode != nullptr) - { - // Read the file path to the resource usage CSV file. - std::string resourceUsageCsvFilePath; - ret = rgXMLUtils::ReadNodeTextString(pResourceUsageCsvNode, resourceUsageCsvFilePath); - assert(ret); - - if (ret) - { - rgOutputItem csvOutputItem = { resourceUsageCsvFilePath, targetAsic, rgCliOutputFileType::HwResourceUsageFile }; - outputs.push_back(csvOutputItem); - } - } - } - } - - // Try to find additional output nodes to parse. - pOutputsNode = pOutputsNode->NextSibling(); - } - - return ret; -} - -bool rgXMLSessionConfig::ReadEntryOutputs(tinyxml2::XMLNode* pOutputEntryNode, rgFileOutputs& pOutputs) -{ - bool ret = false; - - // Add each output to the input file's list of outputs. - do - { - rgEntryOutput entry; - // Extract the compiled kernel name. - tinyxml2::XMLNode* pKernelNameNode = pOutputEntryNode->FirstChildElement(XML_NODE_NAME); - if (pKernelNameNode != nullptr) - { - // Read the full file path to the input file. - ret = rgXMLUtils::ReadNodeTextString(pKernelNameNode, entry.m_entrypointName); - assert(ret); - - if (ret) - { - // Extract the kernel type. - tinyxml2::XMLNode* pKernelTypeNode = pOutputEntryNode->FirstChildElement(XML_NODE_TYPE); - if (pKernelTypeNode != nullptr) - { - // Read the full file path to the input file. - ret = rgXMLUtils::ReadNodeTextString(pKernelTypeNode, entry.m_kernelType); - assert(ret); - - if (ret) - { - // Find the the compiled outputs node. - tinyxml2::XMLNode* pOutputsNode = pOutputEntryNode->FirstChildElement(XML_NODE_OUTPUT); - if (pOutputsNode != nullptr) - { - // Read all of the build outputs. - ret = ReadBuildOutputs(pOutputsNode, entry.m_outputs); - assert(ret); - - if (ret) - { - // Assign the input file path to each output entry so we know where it originated from. - entry.m_inputFilePath = pOutputs.m_inputFilePath; - - // Add the populated output structure to the array of outputs for the given file. - pOutputs.m_outputs.push_back(entry); - } - } - } - } - } - } - - // Move to the next output entry. - pOutputEntryNode = pOutputEntryNode->NextSibling(); - } while (pOutputEntryNode != nullptr); - - return ret; -} - -bool rgXMLSessionConfig::ReadInputFiles(tinyxml2::XMLNode* pInputFileNode, std::shared_ptr& pCliOutput) -{ - bool ret = false; - - // Loop over each input file's outputs. - do - { - // Parse the input file's info. - tinyxml2::XMLNode* pInputFilePathNode = pInputFileNode->FirstChildElement(XML_NODE_PATH); - if (pInputFilePathNode != nullptr) - { - // Read the full file path to the input file. - std::string inputFullFilePath; - ret = rgXMLUtils::ReadNodeTextString(pInputFilePathNode, inputFullFilePath); - - if (ret) - { - // Process the input file's output entry info. - tinyxml2::XMLNode* pOutputEntryNode = pInputFileNode->FirstChildElement(XML_NODE_ENTRY); - if (pOutputEntryNode != nullptr) - { - rgFileOutputs& fileOutputs = pCliOutput->m_perFileOutput[inputFullFilePath]; - fileOutputs.m_inputFilePath = inputFullFilePath; - ret = ReadEntryOutputs(pOutputEntryNode, fileOutputs); - assert(ret); - } - } - } - - // Find the next input file sibling node. - pInputFileNode = pInputFileNode->NextSibling(); - } while (pInputFileNode != nullptr); - - return ret; -} - -bool rgXMLSessionConfig::ReadPipelineStageOutputs(tinyxml2::XMLNode* pOutputsNode, rgEntryOutput& stageOutput) -{ - bool ret = false; - - // Search for the listed stage output node strings. - static const std::string s_STAGE_OUTPUT_NODES[] = - { - XML_NODE_ISA, - XML_NODE_CSV_ISA, - XML_NODE_RES_USAGE - }; - - // Loop to search for each possible output type. - for (auto outputIter = std::begin(s_STAGE_OUTPUT_NODES); - outputIter != std::end(s_STAGE_OUTPUT_NODES); ++outputIter) - { - // Search for given output type. - const std::string& outputTypeString = *outputIter; - tinyxml2::XMLNode* pOutputNode = pOutputsNode->FirstChildElement(outputTypeString.c_str()); - if (pOutputNode != nullptr) - { - rgOutputItem csvOutputItem = {}; - - // Read the output file path. - std::string outputFilePath; - ret = rgXMLUtils::ReadNodeTextString(pOutputNode, outputFilePath); - assert(ret); - if (ret) - { - // Assign the parsed file path into the output. - csvOutputItem.m_filePath = outputFilePath; - - // Assign the file path in the output object. - if (outputTypeString.compare(XML_NODE_ISA) == 0) - { - csvOutputItem.m_fileType = rgCliOutputFileType::IsaDisassemblyText; - } - else if (outputTypeString.compare(XML_NODE_CSV_ISA) == 0) - { - csvOutputItem.m_fileType = rgCliOutputFileType::IsaDisassemblyCsv; - } - else if (outputTypeString.compare(XML_NODE_RES_USAGE) == 0) - { - csvOutputItem.m_fileType = rgCliOutputFileType::HwResourceUsageFile; - } - else - { - // The node text wasn't recognized. - assert(false); - ret = false; - } - - if (ret) - { - stageOutput.m_outputs.push_back(csvOutputItem); - } - } - } - } - - return ret; -} diff --git a/RadeonGPUAnalyzerGUI/Src/rgXMLUtils.cpp b/RadeonGPUAnalyzerGUI/Src/rgXMLUtils.cpp deleted file mode 100644 index 91ad915..0000000 --- a/RadeonGPUAnalyzerGUI/Src/rgXMLUtils.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// XML. -#include - -// Local. -#include -#include -#include - -bool rgXMLUtils::ReadNodeTextString(tinyxml2::XMLNode* pNode, std::string& str) -{ - bool ret = false; - if (pNode != nullptr) - { - tinyxml2::XMLElement* pElem = pNode->ToElement(); - if (pElem != nullptr) - { - const char* pStr = pElem->GetText(); - if (pStr != nullptr) - { - str = pStr; - ret = true; - } - } - } - return ret; -} - -bool rgXMLUtils::ReadNodeTextUnsigned(tinyxml2::XMLNode* pNode, unsigned& val) -{ - bool ret = false; - val = 0; - if (pNode != nullptr) - { - tinyxml2::XMLElement* pElem = pNode->ToElement(); - if (pElem != nullptr) - { - ret = (pElem->QueryUnsignedText(&val) == tinyxml2::XML_SUCCESS); - } - } - return ret; -} - -bool rgXMLUtils::ReadNodeTextBool(tinyxml2::XMLNode* pNode, bool& val) -{ - bool ret = val = false; - if (pNode != nullptr) - { - tinyxml2::XMLElement* pElem = pNode->ToElement(); - if (pElem != nullptr) - { - ret = (pElem->QueryBoolText(&val) == tinyxml2::XML_SUCCESS); - } - } - return ret; -} - -std::string rgXMLUtils::GetRGADataModelVersion() -{ - return RGA_DATA_MODEL; -} diff --git a/Utils/DXR State Editor/DXR State Editor.sln b/Utils/DXR State Editor/DXR State Editor.sln deleted file mode 100644 index 9c3719c..0000000 --- a/Utils/DXR State Editor/DXR State Editor.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.1000 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DXR_State_Editor", "DXR State Editor\DXR_State_Editor.csproj", "{C13D6A00-A1C1-43CB-8C0D-E3222DD10263}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C13D6A00-A1C1-43CB-8C0D-E3222DD10263}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C13D6A00-A1C1-43CB-8C0D-E3222DD10263}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C13D6A00-A1C1-43CB-8C0D-E3222DD10263}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C13D6A00-A1C1-43CB-8C0D-E3222DD10263}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {7D3AD8B8-CD8C-4BC5-857D-0F14118944CB} - EndGlobalSection -EndGlobal diff --git a/Utils/DXR State Editor/DXR State Editor/App.config b/Utils/DXR State Editor/DXR State Editor/App.config deleted file mode 100644 index e23d7bc..0000000 --- a/Utils/DXR State Editor/DXR State Editor/App.config +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Utils/DXR State Editor/DXR State Editor/App.xaml b/Utils/DXR State Editor/DXR State Editor/App.xaml deleted file mode 100644 index e8f7e9e..0000000 --- a/Utils/DXR State Editor/DXR State Editor/App.xaml +++ /dev/null @@ -1,332 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Utils/DXR State Editor/DXR State Editor/ApplicationModeTools.cs b/Utils/DXR State Editor/DXR State Editor/ApplicationModeTools.cs deleted file mode 100644 index 20083d8..0000000 --- a/Utils/DXR State Editor/DXR State Editor/ApplicationModeTools.cs +++ /dev/null @@ -1,438 +0,0 @@ -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Media; - -namespace DXR_State_Editor -{ - public enum Mode - { - Welcome, - GeneralStateConfig, - Shader, - HitGroup, - LocalRootSignature, - GlobalRootSignature, - RaytracingPipeline, - ShaderPipeline, - Output, - ApplicationError - } - - public partial class MainWindow : Window - { - public Mode CurrentApplicationMode = Mode.Welcome; - - private Button GetApplicationModeButtonByApplicationMode(Mode mode) - { - if (mode == Mode.Welcome || - mode == Mode.Output || - mode == Mode.ApplicationError) - { - return null; - } - - Button appModeButton = null; - // Note: Strings in FindName() function are static. Do not change without - // also changing x:Name attributes in UniformGrid "buttonGrid" within MainWindow.xaml - switch (mode) - { - case Mode.Shader: - appModeButton = FindName("shaderButton") as Button; - break; - case Mode.HitGroup: - appModeButton = FindName("hitGroupsButton") as Button; - break; - case Mode.LocalRootSignature: - appModeButton = FindName("localRootSignaturesButton") as Button; - break; - case Mode.GlobalRootSignature: - appModeButton = FindName("globalRootSignaturesButton") as Button; - break; - case Mode.RaytracingPipeline: - appModeButton = FindName("RaytracingPipelineConfigButton") as Button; - break; - case Mode.ShaderPipeline: - appModeButton = FindName("shaderPipelineConfigButton") as Button; - break; - } - - return appModeButton; - } - - private String GetModeDescriptorText(Mode mode) - { - String retString = ""; - if (mode == Mode.Output || - mode == Mode.Output || - mode == Mode.Welcome || - mode == Mode.RaytracingPipeline || - mode == Mode.ApplicationError) - { - return retString; - } - - String description_part_one = "Click the Add new "; - String description_part_two = " button or use Ctrl+N to create a new "; - String modeString = GetModeAsText(mode); - - retString = description_part_one + modeString + - description_part_two + modeString + "."; - return retString; - } - - public void SetApplicationMode(Mode mode) - { - try - { - // Set global mode. - CurrentApplicationMode = mode; - - // Reset Button Styles (sending button will be Styled in click handler). - UniformGrid buttonGrid = FindName("buttonGrid") as UniformGrid; - if (buttonGrid != null) - { - int buttonCount = VisualTreeHelper.GetChildrenCount(buttonGrid); - for (int index = 0; index < buttonCount; index++) - { - Button modeButton = VisualTreeHelper.GetChild(buttonGrid, index) as Button; - if (modeButton != null) - { - - modeButton.Style = FindResource("AppModeButtonStyle") as Style; - } - } - } - else - { - postWarningMessage("Could not reset button styles. Unable to obtain reference to button grid."); - } - - // Decide if the general state configuration panel should be shown. - bool enableStateConfig = true; - bool enableStateConfigAddButton = true; - if (mode == Mode.Welcome) - { - enableStateConfig = false; - } - else if (mode == Mode.RaytracingPipeline) - { - enableStateConfigAddButton = false; - } - - Grid cGrid = FindName("contentGrid") as Grid; - if (cGrid == null) - { - postErrorMessage("A call to " + nameof(SetApplicationMode) + - " was unable to acquire the general content grid."); - return; - } - - Button addButton = FindName("addButton") as Button; - if (addButton == null) - { - postErrorMessage("A call to " + nameof(SetApplicationMode) + - " was unable to acquire the 'addButton' element from the General State Config."); - return; - } - - String buttonContentString = "Add new " + GetModeAsText(mode); - if (mode == Mode.ShaderPipeline) - { - buttonContentString += " config"; - } - - addButton.Content = buttonContentString; - addButton.Width = GetAddButtonWidthByMode(mode); - - TextBlock quickTitle = FindName("quickTitle") as TextBlock; - if (quickTitle == null) - { - postErrorMessage("Unalbe to set the quick title. The element cannot be found."); - return; - } - - // Hide all FrameworkElements not belonging to the current application mode. - foreach (var element in Master_MacroElementList) - { - Mode elementApplicationMode = element.applicationMode; - if (elementApplicationMode != mode) - { - if (element.applicationMode != Mode.Output) - { - element.rootElement.Visibility = Visibility.Collapsed; - } - - if (enableStateConfig && elementApplicationMode == Mode.GeneralStateConfig) - { - element.rootElement.Visibility = Visibility.Visible; - - String quickTitleText = GetModeAsText(mode); - if (mode != Mode.Shader) - { - quickTitleText += " config element"; - } - else - { - quickTitleText += "s element"; - } - quickTitleText = Char.ToUpper(quickTitleText[0]) + quickTitleText.Substring(1); - quickTitle.Text = quickTitleText; - if (enableStateConfigAddButton) - { - addButton.Visibility = Visibility.Visible; - addButton.Focus(); - } - else - { - addButton.Visibility = Visibility.Collapsed; - } - } - - DetermineQuickDescriptionVisibilityAndContentByApplicationMode(mode); - } - else - { - element.rootElement.Visibility = Visibility.Visible; - } - } - - CleanUpGridRows(cGrid, mode); - - // Set button style for application mode buttons - if (enableStateConfig) - { - setButtonStyleSelected(GetApplicationModeButtonByApplicationMode(mode)); - } - } - catch (System.Exception e) - { - postErrorMessage("An unhandled exception has been caught while attempting to set the application mode: " + - e.ToString()); - } - } - - // Note: C# default initializes to zero equivalent. - protected struct ModeCountStructure - { - public UInt32 ShaderCount; - public UInt32 HitGroupCount; - public UInt32 LocalRootSignatureCount; - public UInt32 GlobalRootSignatureCount; - public UInt32 ShaderPipelineCount; - public UInt32 InfoCount; - public UInt32 ApplicationErrorCount; - } - protected ModeCountStructure ModeCount = new ModeCountStructure() - { - ShaderCount = 0, - HitGroupCount = 0, - LocalRootSignatureCount = 0, - GlobalRootSignatureCount = 0, - ShaderPipelineCount = 0, - InfoCount = 0, - }; - - private int GetAddButtonWidthByMode(Mode mode) - { - try - { - int smallButton = 235; - int largeButton = 380; - int width = 0; - switch (mode) - { - case Mode.GeneralStateConfig: - width = smallButton; - break; - case Mode.Shader: - width = smallButton; - break; - case Mode.HitGroup: - width = smallButton; - break; - case Mode.LocalRootSignature: - width = largeButton; - break; - case Mode.GlobalRootSignature: - width = largeButton; - break; - case Mode.RaytracingPipeline: - width = largeButton; - break; - case Mode.ShaderPipeline: - width = largeButton; - break; - case Mode.ApplicationError: - postErrorMessage("A call to " + nameof(GetAddButtonWidthByMode) + - " has been initiated by an invalid mode: " + mode); - break; - } - - return width; - } - catch (System.Exception e) - { - postErrorMessage("An unhandled exception has been caught while attempting to get the 'add' button width by application mode: " + - e.ToString()); - return 0; - } - } - - private String GetModeAsText(Mode mode) - { - try - { - String modeAsText = ""; - switch (mode) - { - case Mode.Welcome: - modeAsText = "welcome"; - break; - case Mode.GeneralStateConfig: - modeAsText = "general"; - break; - case Mode.Shader: - modeAsText = "shader"; - break; - case Mode.HitGroup: - modeAsText = "hit group"; - break; - case Mode.LocalRootSignature: - modeAsText = "local root signature"; - break; - case Mode.GlobalRootSignature: - modeAsText = "global root signature"; - break; - case Mode.RaytracingPipeline: - modeAsText = "pipeline"; - break; - case Mode.ShaderPipeline: - modeAsText = "shader"; - break; - } - - return modeAsText; - } - catch (System.Exception e) - { - postErrorMessage("An unhandled exception has been caught while attempting to get the application mode as text: " + - e.ToString()); - return null; - } - } - - public bool VerifyModeCount(Mode mode) - { - bool retVal = true; - uint reportedModeCount= GetModeCount(mode); - uint empiricalModeCount = 0; - foreach (MacroElement macroElement in Master_MacroElementList) - { - if (macroElement.applicationMode == mode) - { - empiricalModeCount++; - } - } - - if (empiricalModeCount != reportedModeCount) - { - postErrorMessage("A call to " + nameof(VerifyModeCount) - + "has discovered errors in mode count calculation for mode: " + mode); - retVal = false; - } - - return retVal; - } - - private UInt32 GetModeCount(Mode mode) - { - try - { - UInt32 retVal = 0; - if (mode == Mode.Welcome || - mode == Mode.GeneralStateConfig || - mode == Mode.RaytracingPipeline || - mode == Mode.ApplicationError) - { - return retVal; - //postWarningMessage("A call to " + nameof(GetModeCount) + " received an invalid Mode: " + mode); - } - else - { - switch (mode) - { - case Mode.Shader: - retVal = ModeCount.ShaderCount; - break; - case Mode.HitGroup: - retVal = ModeCount.HitGroupCount; - break; - case Mode.LocalRootSignature: - retVal = ModeCount.LocalRootSignatureCount; - break; - case Mode.GlobalRootSignature: - retVal = ModeCount.GlobalRootSignatureCount; - break; - case Mode.ShaderPipeline: - retVal = ModeCount.ShaderPipelineCount; - break; - } - } - - return retVal; - } - catch (System.Exception e) - { - postErrorMessage("An unhandled exception has been caught while attempting to get the mode count: " + - e.ToString()); - return 0; - } - } - - private UInt32 DecrementModeCount(Mode mode) - { - try - { - UInt32 retVal = 0; - if (mode == Mode.Welcome || - mode == Mode.GeneralStateConfig || - mode == Mode.RaytracingPipeline || - mode == Mode.ApplicationError) - { - postWarningMessage("A call to " + nameof(DecrementModeCount) + " received an invalid Mode: " + mode); - } - else - { - switch (mode) - { - case Mode.Shader: - retVal = --ModeCount.ShaderCount; - break; - case Mode.HitGroup: - retVal = --ModeCount.HitGroupCount; - break; - case Mode.LocalRootSignature: - retVal = --ModeCount.LocalRootSignatureCount; - break; - case Mode.GlobalRootSignature: - retVal = --ModeCount.GlobalRootSignatureCount; - break; - case Mode.ShaderPipeline: - retVal = --ModeCount.ShaderPipelineCount; - break; - } - } - - return retVal; - } - catch (System.Exception e) - { - postErrorMessage("An unhandled exception has been caught while attempting to decrement the mode count: " + - e.ToString()); - return 0; - } - } - } -} diff --git a/Utils/DXR State Editor/DXR State Editor/ButtonEvents.cs b/Utils/DXR State Editor/DXR State Editor/ButtonEvents.cs deleted file mode 100644 index e27a529..0000000 --- a/Utils/DXR State Editor/DXR State Editor/ButtonEvents.cs +++ /dev/null @@ -1,399 +0,0 @@ -using Microsoft.Win32; -using System; -using System.Collections.Generic; -using System.Windows; -using System.Windows.Controls; - -namespace DXR_State_Editor -{ - public partial class MainWindow : Window - { - private void LoadJSON(String queryTitle) - { - MessageBoxResult userDeleteAllMacroElements = MessageBoxResult.None; - bool nonDefaultJsonAssociationFound = QueryJsonForNonDefaultAssociations(); - if (nonDefaultJsonAssociationFound) - { - userDeleteAllMacroElements = ResetMacroElementsQuery(queryTitle); - if (userDeleteAllMacroElements == MessageBoxResult.No) - { - // User has canceled loading file - return; - } - } - else - { - // The App is in the default state. We must clear the default elements such that - // only the file state is reflected. - RemoveDefaultUserLevelElements(); - } - - // Import data from file - OpenFileDialog fileDialog = new OpenFileDialog(); - fileDialog.Multiselect = true; - Nullable result = fileDialog.ShowDialog(); - String[] files = null; - if (result.Value) - { - files = fileDialog.FileNames; - } - - if (files != null && files.Length > 0) - { - List jsonFileDataList = new List(); - ReadJSONFileContents(files, jsonFileDataList); - if (jsonFileDataList.Count > 0) - { - if (userDeleteAllMacroElements == MessageBoxResult.Yes) - { - RemoveAllMacroElementGroups(); - } - - ConstructMacroElementsFromJSON(jsonFileDataList); - } - } - - // Determine quick description visibility and content - DetermineQuickDescriptionVisibilityAndContentByApplicationMode(CurrentApplicationMode); - } - - private void HandleResetJSONContextMenu(object sender, RoutedEventArgs e) - { - MessageBoxResult userDeleteAllMacroElements = MessageBoxResult.None; - bool nonDefaultJsonAssociationFound = QueryJsonForNonDefaultAssociations(); - if (nonDefaultJsonAssociationFound) - { - userDeleteAllMacroElements = ResetMacroElementsQuery("Reset All Data?"); - if (userDeleteAllMacroElements == MessageBoxResult.Yes) - { - RemoveAllMacroElementGroups(); - InitializeDefaultUserLevelElements(); - DetermineQuickDescriptionVisibilityAndContentByApplicationMode(CurrentApplicationMode); - - // Pipeline config has default state, but would not be in an accessible list as there - // is only one instance of this MacroElement. We must clean this state manually. - Mode previousMode = CurrentApplicationMode; - SetApplicationMode(Mode.RaytracingPipeline); - TextBox MaxTraceRecursionDepthTextBox = FindName("RaytracingPipelineMaxTraceRecursionDepthTextBox0") as TextBox; - if (MaxTraceRecursionDepthTextBox == null) - { - postErrorMessage("A call to " + nameof(HandleResetJSONContextMenu) + - " was unable to acquire the max trace recursion depth text box"); - return; - } - MaxTraceRecursionDepthTextBox.Text = "1"; - - TextBox ExportsTextBox = FindName("RaytracingPipelineExportsTextBox0") as TextBox; - if (ExportsTextBox == null) - { - postErrorMessage("A call to " + nameof(HandleResetJSONContextMenu) + - " was unable to acquire the exports text box"); - return; - } - ExportsTextBox.Text = null; - SetApplicationMode(previousMode); - } - } - - // Restore welcome screen - SetApplicationMode(Mode.Welcome); - } - - private void HandleLoadJSONButton(object sender, RoutedEventArgs e) - { - try - { - Button buSender = sender as Button; - if (buSender == null) - { - postErrorMessage("A call to " + nameof(HandleLoadJSONButton) + - "received a null Button object."); - return; - } - - String queryTitle = buSender.Tag as String; - if (queryTitle == null) - { - postErrorMessage("A call to " + nameof(HandleLoadJSONButton) + - "received a null queryTitle string [ tag ]."); - return; - } - - // Note: state clearing is handled in LoadJSON(); - LoadJSON(queryTitle); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to load JSON files via the file browse button: " + - ex.ToString()); - } - } - - public void BrowseForFilePath(object sender, RoutedEventArgs e) - { - try - { - Button senderButton = sender as Button; - if (senderButton == null) - { - postErrorMessage("A call to " + nameof(BrowseForFilePath) + " was initaited from an unauthorized source."); - return; - } - - String textBoxName = senderButton.Tag as String; - if ((textBoxName == null) || (textBoxName.Length == 0)) - { - postErrorMessage("A call to " + nameof(BrowseForFilePath) + " was unable to find the target TextBox ID string."); - return; - } - - TextBox targetTextBox = FindName(textBoxName) as TextBox; - if (targetTextBox == null) - { - postErrorMessage("A call to " + nameof(BrowseForFilePath) + " was unable to match an ID string with a valid TextBox."); - } - - OpenFileDialog fileDialog = new OpenFileDialog(); - Nullable result = fileDialog.ShowDialog(); - if (result.Value) - { - targetTextBox.Text = fileDialog.FileName; - } - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to browse for a file path: " + - ex.ToString()); - } - } - - private void AddButton_Click(object sender, RoutedEventArgs e) - { - try - { - // Ensure that the expected object is initiating this call. - Button addButton = sender as Button; - if (addButton != null && addButton.Name == "addButton") - { - CreateMacroElementByCurrentApplicationMode(); - } - else - { - postErrorMessage("A call to " + nameof(AddButton_Click) + " originated from an unauthorized source"); - } - - DetermineQuickDescriptionVisibilityAndContentByApplicationMode(CurrentApplicationMode); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to handle the 'add' button click event: " + - ex.ToString()); - } - } - - private MessageBoxResult ResetMacroElementsQuery(String queryTitle) - { - if (queryTitle == null) - { - postErrorMessage("A call to " + nameof(ResetMacroElementsQuery) + - " received a null queryTitle string."); - return MessageBoxResult.None; - } - - return MessageBox.Show("This will clear all data from your current workspace. Is this okay?", - queryTitle, - MessageBoxButton.YesNo, - MessageBoxImage.Warning); - } - - private void setButtonStyleSelected(Button buSender) - { - try - { - if (buSender == null) - { - postWarningMessage("Unable to style button on click event. Cannot cast sender to button."); - return; - } - - Style selectedStyle = FindResource("selectedButtonStyle") as Style; - if (selectedStyle == null) - { - postWarningMessage("Unable to style button on click event. Cannot obtain style definition."); - return; - } - - buSender.Style = selectedStyle; - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to re-style buttons: " + - ex.ToString()); - } - } - - private void ShaderButton_Click(object sender, RoutedEventArgs e) - { - try - { - SetApplicationMode(Mode.Shader); - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to handle the 'add shader' button click event: " + - ex.ToString()); - } - } - - private void HitGroupsButton_Click(object sender, RoutedEventArgs e) - { - try - { - SetApplicationMode(Mode.HitGroup); - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to handle the 'add hit group' button click event: " + - ex.ToString()); - } - } - - private void LocalRootSignaturesButton_Click(object sender, RoutedEventArgs e) - { - try - { - SetApplicationMode(Mode.LocalRootSignature); - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to handle the 'add local root signature' button click event: " + - ex.ToString()); - } - } - - private void GlobalRootSignaturesButton_Click(object sender, RoutedEventArgs e) - { - try - { - SetApplicationMode(Mode.GlobalRootSignature); - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to handle the 'add global root signature' button click event: " + - ex.ToString()); - } - } - - private void RaytracingPipelineConfigButton_Click(object sender, RoutedEventArgs e) - { - try - { - SetApplicationMode(Mode.RaytracingPipeline); - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caugh while attempting to handle the 'add raytraching pipeline' button click eventt: " + - ex.ToString()); - } - } - - private void ShaderPipelineConfigButton_Click(object sender, RoutedEventArgs e) - { - try - { - SetApplicationMode(Mode.ShaderPipeline); - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to handle the 'add shader pipeline/config' button click event: " + - ex.ToString()); - } - } - - private void SaveJSONAsRPSO() - { - TextBox jsonTextBox = FindName("jsonViewText") as TextBox; - if (jsonTextBox == null) - { - postErrorMessage("A call to " + nameof(SaveJSONAsRPSO) + " was unable to aquire the target text."); - } - - String validationstring = JSONInputIsValid(); - if (validationstring == null) - { - postErrorMessage("A call to " + nameof(SaveJSONAsRPSO) + " was unable to aquire a validation string."); - return; - } - - if (validationstring.Length > 0) - { - String msgString = validationstring + - "\nAre you sure you want to ignore this warning and save the file?"; - - MessageBoxResult msgBoxResult = MessageBox.Show(msgString, - "Invalid JSON State Detected", - MessageBoxButton.YesNo, - MessageBoxImage.Warning); - - if (msgBoxResult != MessageBoxResult.Yes) - { - return; - } - } - - // [ cfarvin::REMOVE ] - - SaveFileDialog fileDialog = new SaveFileDialog() - { - FileName = "DXRState", - DefaultExt = ".rpso" - }; - - Nullable result = fileDialog.ShowDialog(); - if (result.Value) - { - System.IO.File.WriteAllText(@fileDialog.FileName, jsonTextBox.Text); - } - } - - private void SaveButton_Click(object sender, RoutedEventArgs e) - { - try - { - SaveJSONAsRPSO(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to handle the 'save' button click event: " + - ex.ToString()); - } - } - - private void ClipboardButton_Click(object sender, RoutedEventArgs e) - { - try - { - TextBox jsonTextBox = FindName("jsonViewText") as TextBox; - if (jsonTextBox == null) - { - postErrorMessage(" A call to " + nameof(ClipboardButton_Click) + - " could not aquire the text source."); - return; - } - - Clipboard.SetText(jsonTextBox.Text); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to handle the 'copy to clipboard' button click event: " + - ex.ToString()); - } - } - } -} \ No newline at end of file diff --git a/Utils/DXR State Editor/DXR State Editor/DXR State Editor_TemporaryKey.pfx b/Utils/DXR State Editor/DXR State Editor/DXR State Editor_TemporaryKey.pfx deleted file mode 100644 index c2669d7..0000000 Binary files a/Utils/DXR State Editor/DXR State Editor/DXR State Editor_TemporaryKey.pfx and /dev/null differ diff --git a/Utils/DXR State Editor/DXR State Editor/DXR_State_Editor.csproj b/Utils/DXR State Editor/DXR State Editor/DXR_State_Editor.csproj deleted file mode 100644 index 76872ee..0000000 --- a/Utils/DXR State Editor/DXR State Editor/DXR_State_Editor.csproj +++ /dev/null @@ -1,286 +0,0 @@ - - - - - win;win-x64;win-x86;win-arm;win-arm64 - - C:\Users\cafarvin\Desktop\DXR State Editor Preview\DXR State Editor %28Published%29\ - true - Disk - false - Foreground - 7 - Days - false - false - true - RadeonGPUAnalyzer DXR State Editor - Advanced Micro Devices, Inc. - RadeonGPUAnaylzer DXR State Editor - false - 20 - 1.0.0.%2a - false - true - true - true - - - Debug - AnyCPU - {C13D6A00-A1C1-43CB-8C0D-E3222DD10263} - WinExe - DXR_State_Editor - RGA DXR State Editor - v4.8 - 512 - {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - true - true - true - false - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - DXR_State_Editor.App - - - ED49BAAEFA7267CD1D7843F8889A97279BDC4D37 - - - DXR State Editor_TemporaryKey.pfx - - - true - - - false - - - rgaDXRIcon.ico - - - - LocalIntranet - - - Properties\app.manifest - - - - - - - - - - - - - - 4.0 - - - - - - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - - - - - - - MainWindow.xaml - Code - - - - - Code - - - True - True - Resources.resx - - - True - Settings.settings - True - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - - - - - - - - False - Microsoft .NET Framework 4.8 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 - false - - - False - Visual C++ "14" Runtime Libraries %28x64%29 - true - - - False - Visual C++ "14" Runtime Libraries %28x86%29 - true - - - - - 4.7.1 - - - - - - - - - - - False - - - - - Include - True - Assembly - - - False - - - - - Include - True - Assembly - - - False - - - - - Include - True - Assembly - - - False - - - - - Include - True - Assembly - - - False - - - - - Include - True - Assembly - - - False - - - - - Include - True - Assembly - - - False - - - - - Include - True - Assembly - - - False - - - - - Include - True - Assembly - - - False - - - - - Prerequisite - True - Assembly - - - - - \ No newline at end of file diff --git a/Utils/DXR State Editor/DXR State Editor/ElementRegistrationTools.cs b/Utils/DXR State Editor/DXR State Editor/ElementRegistrationTools.cs deleted file mode 100644 index b20865a..0000000 --- a/Utils/DXR State Editor/DXR State Editor/ElementRegistrationTools.cs +++ /dev/null @@ -1,166 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Windows; -using System.Windows.Controls; - -namespace DXR_State_Editor -{ - public partial class MainWindow : Window - { - public String GenerateDynamicRowName(Grid grid, Mode mode, UInt32 nameModifier) - { - return grid.Name + "Row" + mode + nameModifier; - } - - public bool WPFAssignAndRegisterName(object element, String elementName) - { - return WPFAssignAndRegisterName(element, elementName, null); - } - - public bool WPFAssignAndRegisterName(object element, String elementName, List nameList) - { - try - { - bool wasSuccessful = true; - String methodName = nameof(WPFAssignAndRegisterName); - - if (String.IsNullOrEmpty(elementName)) - { - postWarningMessage("A call to " + methodName + " received a null or empty element name."); - wasSuccessful = false; - } - - if (element == null) - { - postWarningMessage("A call to " + methodName + " received a null FrameworkElement: " + elementName); - wasSuccessful = false; - } - - if (FindName(elementName) != null) - { - postWarningMessage("A call to " + methodName + - " received a duplicate register request for FrameworkElement: " - + elementName); - wasSuccessful = false; - } - - if (wasSuccessful) - { - // Also assign the name to the object itself, if possible. - FrameworkElement frameworkElement = element as FrameworkElement; - if (frameworkElement != null) - { - frameworkElement.Name = elementName; - } - - // Register the name with this class. - RegisterName(elementName, element); - if (FindName(elementName) == null) - { - postErrorMessage(methodName + " failed to register FrameworkElement: " + elementName); - wasSuccessful = false; - } - - // Add registered name to name List, if present. - if (nameList != null) - { - nameList.Add(elementName); - } - } - - return wasSuccessful; - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to assign and register an element name: " + - ex.ToString()); - return false; - } - } - - public List contentGridRowNames = new List(); - public void CleanUpGridRows(Grid grid, Mode mode) - { - try - { - if (mode == Mode.Welcome || - mode == Mode.GeneralStateConfig || - mode == Mode.RaytracingPipeline || - mode == Mode.ApplicationError) - { - return; - } - - if (grid == null) - { - postErrorMessage("A call to " + nameof(CleanUpGridRows) + " received a null Grid reference."); - return; - } - - // Delete all of the grid rows. - UInt32 numRegisteredRowNames = (UInt32)contentGridRowNames.Count; - UInt32 numRowsRemoved = 0; - foreach (String name in contentGridRowNames) - { - RowDefinition rowDef = FindName(name) as RowDefinition; - if (rowDef != null && name.Length > 0) - { - UnregisterName(name); - if (grid.RowDefinitions.Remove(rowDef)) numRowsRemoved++; - else - { - postErrorMessage("A call to " + nameof(CleanUpGridRows) + - " was unable to unregister macro element with name:" + name); - } - } - } - contentGridRowNames.Clear(); - if (numRegisteredRowNames != numRowsRemoved) - { - postErrorMessage("A call to " + nameof(CleanUpGridRows) + - " was unable to reconcile the number of registered and physical rows for mode: " + mode - + ". [ registered rows: " + numRegisteredRowNames + ", mode physical rows: " + numRowsRemoved + " ]"); - } - - // Make only as many rows as there are items for the given mode. - UInt32 modeNumber = GetModeCount(mode); - for (UInt32 index = 0; index < modeNumber; index++) - { - RowDefinition row = new RowDefinition() - { - Height = new GridLength(1.0, GridUnitType.Auto), - }; - String rowName = GenerateDynamicRowName(grid, mode, index); - if (WPFAssignAndRegisterName(row, rowName)) - { - contentGridRowNames.Add(rowName); - grid.RowDefinitions.Add(row); - } - } - - // Ensure that mode items match a correctly numbered row. - UInt32 rowNumber = 0; - foreach (MacroElement macroElement in Master_MacroElementList) - { - if (macroElement.applicationMode == mode && ((macroElement.targetElement as Grid) != null)) - { - macroElement.rootElement.SetValue(Grid.RowProperty, Convert.ToInt32(rowNumber)); - rowNumber++; - } - } - - if ((rowNumber > 0) && (rowNumber != modeNumber)) - { - postErrorMessage("A call to " + nameof(CleanUpGridRows) + - " was unable to reconcile the number of rows and macro elements of mode: " + mode - + ". [ rows: " + rowNumber + ", mode elements: " + modeNumber + " ]"); - } - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to clean up the content grid rows: " + - ex.ToString()); - } - } - } -} diff --git a/Utils/DXR State Editor/DXR State Editor/JsonTools.cs b/Utils/DXR State Editor/DXR State Editor/JsonTools.cs deleted file mode 100644 index 86182ae..0000000 --- a/Utils/DXR State Editor/DXR State Editor/JsonTools.cs +++ /dev/null @@ -1,3741 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text.Encodings.Web; -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Windows; -using System.Windows.Controls; -namespace DXR_State_Editor -{ - public struct ProcessedTargetText - { - public ProcessedTargetText(String ep, String ln) - { - if (ep != null) - { - entryPointName = ep.Trim(' '); - } - else - { - entryPointName = ""; - } - if (ln != null) - { - linkName = ln.Trim(' '); - } - else - { - linkName = ""; - } - } - public String entryPointName; - public String linkName; - }; - public partial class MainWindow : Window - { - public class DXR_JSON_STATE__RaytracingShaderConfig : DXR_JSON_ELEMENT - { - public int MaxPayloadSizeInBytes { get; set; } - public int MaxAttributeSizeInBytes { get; set; } - public IList Exports { get; set; } - } - public class DXR_JSON_STATE__RaytracingPipelineConfig : DXR_JSON_ELEMENT - { - public int MaxTraceRecursionDepth { get; set; } - // Reinstate if RaytracingPipeline->Flags is re-added - //public IList Flags { get; set; } - public IList Exports { get; set; } - } - public class DXR_JSON_STATE__RootSignature : DXR_JSON_ELEMENT - { - public String Type { get; set; } - public String FilePath { get; set; } - public String Name { get; set; } - public IList Exports { get; set; } - } - public class DXR_JSON_STATE__HitGroup : DXR_JSON_ELEMENT - { - public String Type { get; set; } - public String Name { get; set; } - public String IntersectionShader { get; set; } - public String AnyHitShader { get; set; } - public String ClosestHitShader { get; set; } - } - public class DXR_JSON_STATE__Shader__EntryPoints : DXR_JSON_ELEMENT - { - public String ExportName { get; set; } - public String LinkageName { get; set; } - } - public class DXR_JSON_STATE__Shader : DXR_JSON_ELEMENT - { - public String Type { get; set; } - public String FilePath { get; set; } - public IList EntryPoints { get; set; } - } - public class DXR_JSON_STATE : DXR_JSON_ELEMENT - { - // Note: force to 1.0 for now - public String SchemaVersion { get; set; } - public IList Shaders { get; set; } - public IList HitGroups { get; set; } - public IList LocalRootSignatures { get; set; } - public IList GlobalRootSignatures { get; set; } - public DXR_JSON_STATE__RaytracingPipelineConfig RaytracingPipelineConfig { get; set; } - public IList RaytracingShaderConfig { get; set; } - } - public class DXR_JSON_STATE_ROOT : DXR_JSON_ELEMENT - { - public DXR_JSON_STATE DXRState { get; set; } - } - public class DXR_JSON_ELEMENT - { - [JsonIgnore] - public String macroElementParentID { get; set; } - } - private List Master_ShadersByStringID = new List(); - private List Master_HitGroupsByStringID = new List(); - private List Master_LocalRootSignaturesByStringID = new List(); - private List Master_GlobalRootSignaturesByStringID = new List(); - private DXR_JSON_STATE__RaytracingPipelineConfig Master_RaytracingPipelineConfig = new DXR_JSON_STATE__RaytracingPipelineConfig(); - private List Master_ShaderPipelineConfigByStringID = new List(); - public struct JsonFileData - { - public String filePath; - public String fileContents; - public DXR_JSON_STATE_ROOT jsonRoot; - } - JsonSerializerOptions jsonOptions = new JsonSerializerOptions() - { - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - WriteIndented = true, - IgnoreNullValues = false, - AllowTrailingCommas = false - }; - // Note: populated in MainWindow.xaml.cs::MainWindow() - public static List invalidFilePathChars = new List(); - public static List invalidFileNameChars = new List(); - public bool QueryJsonForNonDefaultAssociations() - { - bool nonDefaultJsonAssociationFound = false; - foreach (MacroElement macroElement in Master_MacroElementList) - { - if (macroElement.applicationMode == Mode.Welcome || - macroElement.applicationMode == Mode.GeneralStateConfig || - macroElement.applicationMode == Mode.Output || - macroElement.applicationMode == Mode.ApplicationError) - { - continue; - } - if (CheckJSONAssociationByElementIDAndApplicationMode(macroElement.rootElement.Tag as String, - macroElement.applicationMode)) - { - nonDefaultJsonAssociationFound = true; - break; - } - } - return nonDefaultJsonAssociationFound; - } - public String JSONInputIsValid() - { - String retString = ""; - int error_number = 1; - // Validate required Shader fields - foreach (DXR_JSON_STATE__Shader shader in Master_ShadersByStringID) - { - if (!(shader != null && - (shader.FilePath != null && shader.FilePath.Length > 0))) - { - retString += error_number + - ". The 'File Path' field is required for all Shader components.\n"; - error_number++; - break; - } - if (InvalidShaderFilePathTextBoxesExist()) - { - retString += error_number + - ". One or more 'File Path' fields have invalid input.\n"; - error_number++; - } - } - if (InvalidShaderEntryPointTextBoxesExist()) - { - retString += error_number + - ". One or more 'Entry Point' fields have invalid input.\n"; - error_number++; - } - // Validate required HitGroup fields - foreach (DXR_JSON_STATE__HitGroup hitgroup in Master_HitGroupsByStringID) - { - if (!(hitgroup != null && - (hitgroup.Name != null && hitgroup.Name.Length > 0))) - { - retString += error_number + - ". The 'Name' field is required for all Hit Group components.\n"; - error_number++; - break; - } - } - // Validate required LocalRootSignature fields - foreach (DXR_JSON_STATE__RootSignature localRootSignature in Master_LocalRootSignaturesByStringID) - { - if (!(localRootSignature != null && - (localRootSignature.FilePath != null && localRootSignature.FilePath.Length > 0))) - { - retString += error_number + - ". The 'File Path' field is required for all Local Root Signature components.\n"; - error_number++; - break; - } - } - // Validate required GlobalRootSignature fields - foreach (DXR_JSON_STATE__RootSignature globalRootSignature in Master_GlobalRootSignaturesByStringID) - { - if (!(globalRootSignature != null && - (globalRootSignature.FilePath != null && globalRootSignature.FilePath.Length > 0))) - { - retString += error_number + - ". The 'File Path' field is required for all Global Root Signature components.\n"; - error_number++; - break; - } - } - // For the following, we must validate the textbox/combobox input widgets, not the JSON itself, - // as when the textboxes/comboboxes are null they are not represented in the JSON master lists. - // Validate required RaytracingPipeline fields - TextBox targetRayTracingTextBox = FindName("RaytracingPipelineMaxTraceRecursionDepthTextBox0") as TextBox; - if (!(targetRayTracingTextBox != null && - targetRayTracingTextBox.Text != null && - targetRayTracingTextBox.Text.Length > 0 && - int.TryParse(targetRayTracingTextBox.Text, out _))) - { - retString += error_number + - ". The integer 'Max Recursion depth' field is required for all Raytracing Pipeline components.\n"; - error_number++; - } - // Validate required ShaderPipeline fields - bool invalidPayloadSizeFound = false; - bool invalidMaxAttributeSizeFound = false; - for (int count = 0; count < GetModeCount(Mode.ShaderPipeline); count++) - { - if (invalidMaxAttributeSizeFound && invalidPayloadSizeFound) - { - break; - } - if (!invalidPayloadSizeFound) - { - { // scope - String textBoxName = "ShaderPipelinePayloadSizeTextBox" + count; - TextBox targetShaderPipelineTextBox = FindName(textBoxName) as TextBox; - if (targetShaderPipelineTextBox == null) - { - postErrorMessage("A call to " + nameof(JSONInputIsValid) + - " was unable to retreive a valid registered handle for the name: " + - textBoxName); - invalidPayloadSizeFound = true; - } - if (!(targetShaderPipelineTextBox.Text != null && - targetShaderPipelineTextBox.Text.Length > 0 && - int.TryParse(targetShaderPipelineTextBox.Text, out _))) - { - retString += error_number + - ". The integer 'Payload Size' field is required for all Shader Pipeline components.\n"; - error_number++; - invalidPayloadSizeFound = true; - } - } - } - if (!invalidMaxAttributeSizeFound) - { - { // scope - String textBoxName = "ShaderPipelinesMaxAttributeSizeTextBox" + count; - TextBox targetShaderPipelineTextBox = FindName(textBoxName) as TextBox; - if (targetShaderPipelineTextBox == null) - { - postErrorMessage("A call to " + nameof(JSONInputIsValid) + - " was unable to retreive a valid registered handle for the name: " + - textBoxName); - invalidMaxAttributeSizeFound = true; - } - if (!(targetShaderPipelineTextBox.Text != null && - targetShaderPipelineTextBox.Text.Length > 0 && - int.TryParse(targetShaderPipelineTextBox.Text, out _))) - { - retString += error_number + - ". The integer 'Max Attribute Size' field is required for all Shader Pipeline components.\n"; - error_number++; - invalidMaxAttributeSizeFound = true; - } - } - } - } - return retString; - } - public List CleanTargetText(String targetText) - { - try - { - List exports = new List(); - if (targetText == null || targetText.Length < 1) - { - return null; - } - List targetTextAsStringArray = - new List(targetText.Split(new String[] { "," }, StringSplitOptions.None)); - foreach (String str in targetTextAsStringArray) - { - if (str != null && - str != "") - { - exports.Add(str.Trim()); - } - } - if (exports.Count < 1) - { - return null; - } - return exports; - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to clean the export target text: " + - ex.ToString() + "."); - return null; - } - } - - public bool VerifyComboBoxType(ComboBox targetComboBox, String typeValue) - { - try - { - bool shouldContinue = true; - if (targetComboBox == null) - { - postErrorMessage("A call to " + nameof(VerifyComboBoxType) + - " was unable to acquire the target ComboBoxItem for sub element"); - shouldContinue = false; - } - - if (shouldContinue && typeValue == null) - { - postErrorMessage("A call to " + nameof(VerifyComboBoxType) + - " was unable to acquire the target ComboBoxItem for sub element"); - shouldContinue = false; - } - - bool typeIsValid = false; - foreach (ComboBoxItem cbItem in targetComboBox.Items) - { - if (shouldContinue && cbItem == null) - { - postErrorMessage("A call to " + nameof(VerifyComboBoxType) + - " was unable to acquire the target ComboBoxItem for sub element"); - shouldContinue = false; - } - - String cbItemString = cbItem.Content.ToString() as String; - if (shouldContinue && cbItemString == null) - { - postErrorMessage("A call to " + nameof(VerifyComboBoxType) + - " was unable to acquire the target ComboBoxItem content string for sub element"); - shouldContinue = false; - } - - if (shouldContinue && cbItemString == typeValue) - { - typeIsValid = true; - break; - } - } - - return typeIsValid; - } - catch - { - postErrorMessage("An unhandled exception occured during while attempting to verify a ComboBox type."); - return false; - } - } - - public void WriteDXRJSONtoViewGrid() - { - try - { - // Ensure the target text block is available. - TextBox jsonViewText = FindName("jsonViewText") as TextBox; - if (jsonViewText == null) - { - postErrorMessage("A call to " + nameof(WriteDXRJSONtoViewGrid) - + " was unable to acquire the jsonViewText TextBlock target."); - return; - } - jsonViewText.Clear(); - // Build root structure. - DXR_JSON_STATE_ROOT jsonRoot = new DXR_JSON_STATE_ROOT(); - jsonRoot.DXRState = new DXR_JSON_STATE(); - Int32 index = 0; - List indicesToRemove = new List(); - // SchemaVersion - // Note: force to 1.0 for now - jsonRoot.DXRState.SchemaVersion = "1.0"; - // Shaders - List DXRExportComboBoxItemSourceList = new List(); - jsonRoot.DXRState.Shaders = new List(); - if (Master_ShadersByStringID.Count > 0) - { - foreach (DXR_JSON_STATE__Shader shader in Master_ShadersByStringID) - { - if (shader == null) - { - index++; - continue; - } - if ((shader.FilePath != null && shader.FilePath.Length > 0) || - (shader.Type != null && shader.Type.Length > 0) || - (shader.EntryPoints != null && shader.EntryPoints.Count > 0)) - { - if (shader.Type != null && - (shader.Type == ConstStringBinaryDXILType || - shader.Type == ConstStringBinaryType)) - { - // Note: Purposeful discrepency between GUI text representation and JSON text representation - shader.Type = ConstStringBinaryType; - } - else if (shader.Type != null && - shader.Type == ConstStringHLSLType) - { - shader.Type = ConstStringHLSLType; - } - else - { - postWarningMessage("Was unable to parse Shader->Type from JSON file.\n"); - } - - // Trim user-editable simple string members - if (shader.FilePath != null) - { - shader.FilePath.Trim(' '); - } - jsonRoot.DXRState.Shaders.Add(shader); - } - else - { - indicesToRemove.Add(index); - } - index++; - } - } - foreach (Int32 removalIndex in indicesToRemove) - { - Master_ShadersByStringID.RemoveAt(removalIndex); - } - indicesToRemove.Clear(); - index = 0; - if (jsonRoot.DXRState.Shaders.Count < 1) - { - jsonRoot.DXRState.Shaders = null; - } - // Hit Groups - jsonRoot.DXRState.HitGroups = new List(); - if (Master_HitGroupsByStringID.Count > 0) - { - foreach (DXR_JSON_STATE__HitGroup hitGroup in Master_HitGroupsByStringID) - { - if (hitGroup == null) - { - index++; - continue; - } - if ((hitGroup.Type != null && hitGroup.Type.Length > 0) || - (hitGroup.Name != null && hitGroup.Name.Length > 0) || - (hitGroup.IntersectionShader != null && hitGroup.IntersectionShader.Length > 0) || - (hitGroup.ClosestHitShader != null && hitGroup.ClosestHitShader.Length > 0)) - { - if (hitGroup.Type != null && - hitGroup.Type == ConstStringBinaryDXILType) - { - // Note: Purposeful discrepency between GUI text representation and JSON text representation - hitGroup.Type = "Binary"; - } - - // Trim user-editable simple string members - if (hitGroup.AnyHitShader != null) - { - hitGroup.AnyHitShader.Trim(' '); - } - if (hitGroup.ClosestHitShader != null) - { - hitGroup.ClosestHitShader.Trim(' '); - } - if (hitGroup.IntersectionShader != null) - { - hitGroup.IntersectionShader.Trim(' '); - } - if (hitGroup.Name != null) - { - hitGroup.Name.Trim(' '); - } - jsonRoot.DXRState.HitGroups.Add(hitGroup); - } - else - { - indicesToRemove.Add(index); - } - index++; - } - } - foreach (Int32 removalIndex in indicesToRemove) - { - Master_HitGroupsByStringID.RemoveAt(removalIndex); - } - indicesToRemove.Clear(); - index = 0; - if (jsonRoot.DXRState.HitGroups.Count < 1) - { - jsonRoot.DXRState.HitGroups = null; - } - // Local Root Signature - jsonRoot.DXRState.LocalRootSignatures = new List(); - if (Master_LocalRootSignaturesByStringID.Count > 0) - { - foreach (DXR_JSON_STATE__RootSignature localRootSignature in Master_LocalRootSignaturesByStringID) - { - if (localRootSignature == null) - { - index++; - continue; - } - if ((localRootSignature.Type != null && localRootSignature.Type.Length > 0) || - // Reinstate if RootSignature->Name is re-enabled - //(localRootSignature.Name != null && localRootSignature.Name.Length > 0) || - (localRootSignature.FilePath != null && localRootSignature.FilePath.Length > 0) || - (localRootSignature.Exports != null && localRootSignature.Exports.Count > 0)) - { - if (localRootSignature.Type != null && - localRootSignature.Type == ConstStringBinaryDXILType) - { - // Note: Purposeful discrepency between GUI text representation and JSON text representation - localRootSignature.Type = "Binary"; - } - - // Note: temporary hard-coded macro name - if (localRootSignature.Name == null || localRootSignature.Name.Length < 1) - { - localRootSignature.Name = ""; - } - // Trim user-editable simple string members - if (localRootSignature.FilePath != null) - { - localRootSignature.FilePath.Trim(' '); - } - if (localRootSignature.Name != null) - { - localRootSignature.Name.Trim(' '); - } - if (localRootSignature.Exports != null) - { - int exportCount = localRootSignature.Exports.Count; - for (int exportIdx = 0; exportIdx < exportCount; exportIdx++) - { - localRootSignature.Exports[exportIdx].Trim(' '); - } - } - jsonRoot.DXRState.LocalRootSignatures.Add(localRootSignature); - } - else - { - indicesToRemove.Add(index); - } - index++; - } - } - foreach (Int32 removalIndex in indicesToRemove) - { - Master_LocalRootSignaturesByStringID.RemoveAt(removalIndex); - } - indicesToRemove.Clear(); - index = 0; - if (jsonRoot.DXRState.LocalRootSignatures.Count < 1) - { - jsonRoot.DXRState.LocalRootSignatures = null; - } - // Global Root Signature - jsonRoot.DXRState.GlobalRootSignatures = new List(); - if (Master_GlobalRootSignaturesByStringID.Count > 0) - { - foreach (DXR_JSON_STATE__RootSignature globalRootSignature in Master_GlobalRootSignaturesByStringID) - { - if (globalRootSignature == null) - { - index++; - continue; - } - if (globalRootSignature != null && - (globalRootSignature.Type != null && globalRootSignature.Type.Length > 0) || - // Reinstate if RootSignature->Name is re-enabled - //(globalRootSignature.Name != null && globalRootSignature.Name.Length > 0) || - (globalRootSignature.FilePath != null && globalRootSignature.FilePath.Length > 0) || - (globalRootSignature.Exports != null && globalRootSignature.Exports.Count > 0)) - { - if (globalRootSignature.Type != null && - globalRootSignature.Type == ConstStringBinaryDXILType) - { - // Note: Purposeful discrepency between GUI text representation and JSON text representation - globalRootSignature.Type = "Binary"; - } - - // Note: temporary hard-coded macro name - if (globalRootSignature.Name == null || globalRootSignature.Name.Length < 1) - { - globalRootSignature.Name = ""; - } - // Trim user-editable simple string members - if (globalRootSignature.FilePath != null) - { - globalRootSignature.FilePath.Trim(' '); - } - if (globalRootSignature.Name != null) - { - globalRootSignature.Name.Trim(' '); - } - if (globalRootSignature.Exports != null) - { - int exportCount = globalRootSignature.Exports.Count; - for (int exportIdx = 0; exportIdx < exportCount; exportIdx++) - { - globalRootSignature.Exports[exportIdx].Trim(' '); - } - } - jsonRoot.DXRState.GlobalRootSignatures.Add(globalRootSignature); - } - else - { - indicesToRemove.Add(index); - } - index++; - } - } - foreach (Int32 removalIndex in indicesToRemove) - { - Master_GlobalRootSignaturesByStringID.RemoveAt(removalIndex); - } - indicesToRemove.Clear(); - index = 0; - if (jsonRoot.DXRState.GlobalRootSignatures.Count < 1) - { - jsonRoot.DXRState.GlobalRootSignatures = null; - } - // Ray Tracing Shader Config - jsonRoot.DXRState.RaytracingShaderConfig = new List(); - if (Master_ShaderPipelineConfigByStringID.Count > 0) - { - foreach (DXR_JSON_STATE__RaytracingShaderConfig RaytracingShaderConfig in Master_ShaderPipelineConfigByStringID) - { - if (RaytracingShaderConfig == null) - { - index++; - continue; - } - if (RaytracingShaderConfig.MaxPayloadSizeInBytes.ToString().Length > 0 || - RaytracingShaderConfig.MaxAttributeSizeInBytes.ToString().Length > 0 || - (RaytracingShaderConfig.Exports != null && RaytracingShaderConfig.Exports.Count > 0)) - { - // Trim user-editable simple string members - if (RaytracingShaderConfig.Exports != null) - { - int exportCount = RaytracingShaderConfig.Exports.Count; - for (int exportIdx = 0; exportIdx < exportCount; exportIdx++) - { - RaytracingShaderConfig.Exports[exportIdx].Trim(' '); - } - } - jsonRoot.DXRState.RaytracingShaderConfig.Add(RaytracingShaderConfig); - } - else - { - indicesToRemove.Add(index); - } - index++; - } - } - foreach (Int32 removalIndex in indicesToRemove) - { - Master_ShaderPipelineConfigByStringID.RemoveAt(removalIndex); - } - indicesToRemove.Clear(); - index = 0; - if (jsonRoot.DXRState.RaytracingShaderConfig.Count < 1) - { - jsonRoot.DXRState.RaytracingShaderConfig = null; - } - // Ray Tracing Pipeline Config - // Trim user-editable simple string members - if (Master_RaytracingPipelineConfig != null && - Master_RaytracingPipelineConfig.Exports != null) - { - int exportCount = Master_RaytracingPipelineConfig.Exports.Count; - for (int exportIdx = 0; exportIdx < exportCount; exportIdx++) - { - Master_RaytracingPipelineConfig.Exports[exportIdx].Trim(' '); - } - } - jsonRoot.DXRState.RaytracingPipelineConfig = Master_RaytracingPipelineConfig; - // Write JSON - String jsonString = JsonSerializer.Serialize(jsonRoot, jsonOptions); - jsonViewText.Text = jsonString; - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to write the JSON data to the output grid: " + - ex.ToString() + "."); - } - } - public bool CheckJSONAssociationByElementIDAndApplicationMode(String macroElementParentID, Mode mode) - { - try - { - if (mode != Mode.RaytracingPipeline && macroElementParentID == null) - { - postErrorMessage("A call to " + nameof(CheckJSONAssociationByElementIDAndApplicationMode) + - " received a null macroElementParentID string with mode: " + mode - + "."); - return false; - } - bool associationFound = false; - switch (mode) - { - case Mode.Shader: - foreach (DXR_JSON_STATE__Shader shader in Master_ShadersByStringID) - { - if (shader == null) - { - continue; - } - if (shader.macroElementParentID == macroElementParentID) - { - associationFound = true; - break; - } - } - break; - case Mode.HitGroup: - foreach (DXR_JSON_STATE__HitGroup hitGroup in Master_HitGroupsByStringID) - { - if (hitGroup == null) - { - continue; - } - if (hitGroup.macroElementParentID == macroElementParentID) - { - associationFound = true; - break; - } - } - break; - case Mode.LocalRootSignature: - foreach (DXR_JSON_STATE__RootSignature localRootSignature in Master_LocalRootSignaturesByStringID) - { - if (localRootSignature == null) - { - continue; - } - if (localRootSignature.macroElementParentID == macroElementParentID) - { - associationFound = true; - break; - } - } - break; - case Mode.GlobalRootSignature: - foreach (DXR_JSON_STATE__RootSignature globalRootSignature in Master_GlobalRootSignaturesByStringID) - { - if (globalRootSignature == null) - { - continue; - } - if (globalRootSignature.macroElementParentID == macroElementParentID) - { - associationFound = true; - break; - } - } - break; - case Mode.RaytracingPipeline: - // This mode has default sate. - // Determine if the state has been altered. - if (Master_RaytracingPipelineConfig.Exports != null) - { - associationFound = true; - break; - } - if (Master_RaytracingPipelineConfig.MaxTraceRecursionDepth != 1) - { - associationFound = true; - break; - } - break; - case Mode.ShaderPipeline: - // This mode has default sate. - // Determine if the state has been altered. - if ((Master_ShaderPipelineConfigByStringID.Count != 1 && - Master_ShaderPipelineConfigByStringID[0] != null) || - Master_ShaderPipelineConfigByStringID[0].Exports != null || - Master_ShaderPipelineConfigByStringID[0].MaxAttributeSizeInBytes != 8 || - Master_ShaderPipelineConfigByStringID[0].MaxPayloadSizeInBytes != 16) - { - associationFound = true; - break; - } - break; - default: - postErrorMessage("A call to " + nameof(CheckJSONAssociationByElementIDAndApplicationMode) + - " received a call with an unauthorized application mode: " + mode + "."); - break; - } - return associationFound; - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to determine if there are JSON associations in the current dataset: " + - ex.ToString() + "."); - return false; - } - } - public void RemoveJSONDataByID(String macroElementParentID, Mode mode) - { - try - { - if (macroElementParentID == null) - { - postErrorMessage("A call to " + nameof(RemoveJSONDataByID) + - "received a null MacroElementParentID."); - return; - } - if (mode == Mode.GeneralStateConfig || - mode == Mode.Output || - mode == Mode.Welcome || - mode == Mode.ApplicationError) - { - postErrorMessage("A call to " + nameof(RemoveJSONDataByID) + - "received an invalid mode indicator."); - return; - } - bool successfullyRemoved = false; - switch (mode) - { - case Mode.Shader: - foreach (DXR_JSON_STATE__Shader shader in Master_ShadersByStringID) - { - if (shader.macroElementParentID == macroElementParentID) - { - Master_ShadersByStringID.Remove(shader); - successfullyRemoved = true; - break; - } - } - break; - case Mode.HitGroup: - foreach (DXR_JSON_STATE__HitGroup hitGroup in Master_HitGroupsByStringID) - { - if (hitGroup.macroElementParentID == macroElementParentID) - { - Master_HitGroupsByStringID.Remove(hitGroup); - successfullyRemoved = true; - break; - } - } - break; - case Mode.LocalRootSignature: - foreach (DXR_JSON_STATE__RootSignature localRootSignature in Master_LocalRootSignaturesByStringID) - { - if (localRootSignature.macroElementParentID == macroElementParentID) - { - Master_LocalRootSignaturesByStringID.Remove(localRootSignature); - successfullyRemoved = true; - break; - } - } - break; - case Mode.GlobalRootSignature: - foreach (DXR_JSON_STATE__RootSignature globalRootSignature in Master_GlobalRootSignaturesByStringID) - { - if (globalRootSignature.macroElementParentID == macroElementParentID) - { - Master_GlobalRootSignaturesByStringID.Remove(globalRootSignature); - successfullyRemoved = true; - break; - } - } - break; - case Mode.ShaderPipeline: - foreach (DXR_JSON_STATE__RaytracingShaderConfig RaytracingShaderConfig in Master_ShaderPipelineConfigByStringID) - { - if (RaytracingShaderConfig.macroElementParentID == macroElementParentID) - { - Master_ShaderPipelineConfigByStringID.Remove(RaytracingShaderConfig); - successfullyRemoved = true; - break; - } - } - break; - default: - postErrorMessage("A call to " + nameof(RemoveJSONDataByID) + - " received a call with an unauthorized application mode: " + mode + "."); - break; - } - if (!successfullyRemoved) - { - postErrorMessage("A call to " + nameof(RemoveJSONDataByID) + - " was unable to remove a MacroElement with mode: " + mode + "."); - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to remove JSON data by ID: " + - ex.ToString() + "."); - } - } - // - // Shader Element Construction - // - // Type - public void AddShaderTypeByID(object sender, RoutedEventArgs e) - { - try - { - ComboBox emitter = sender as ComboBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddShaderTypeByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddShaderTypeByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - - ComboBoxItem cbItem = emitter.SelectedItem as ComboBoxItem; - if (cbItem == null) - { - postErrorMessage("A call to " + nameof(AddShaderTypeByID) + - " received a null ComboBoxItem."); - WriteDXRJSONtoViewGrid(); - return; - } - - String targetText = cbItem.Content.ToString(); - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddShaderTypeByID) + - " received a null content string."); - WriteDXRJSONtoViewGrid(); - return; - } - - if (CurrentApplicationMode != Mode.Shader) - { - postErrorMessage("A call to " + nameof(AddShaderTypeByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode + "."); - WriteDXRJSONtoViewGrid(); - return; - } - - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__Shader jsonShader = null; - foreach (DXR_JSON_STATE__Shader Shader in Master_ShadersByStringID) - { - if (Shader.macroElementParentID == macroElementParentID) - { - jsonShader = Shader; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonShader == null) - { - jsonShader = new DXR_JSON_STATE__Shader() - { - macroElementParentID = macroElementParentID - }; - if (jsonShader == null) - { - postErrorMessage("A call to " + nameof(AddShaderTypeByID) + - " failed to find or create a valid DXR_JSON_STATE__Shader."); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_ShadersByStringID.Add(jsonShader); - } - if (targetText.Length > 0) - { - jsonShader.Type = targetText; - } - else - { - jsonShader.Type = null; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a shader type element by ID: " + - ex.ToString() + "."); - } - } - // Entry Point - public List InvalidShaderEntryPointTextBoxes = new List(); - public bool InvalidShaderEntryPointTextBoxesExist() - { - return (InvalidShaderEntryPointTextBoxes.Count == 0) ? false : true; - } - public void AddShaderEntryPointByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddShaderEntryPointByID) + - " received a null reference to the TextBox eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddShaderEntryPointByID) + - " received anull or zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddShaderEntryPointByID) + - " received a null content string."); - WriteDXRJSONtoViewGrid(); - return; - } - if (CurrentApplicationMode != Mode.Shader) - { - postErrorMessage("A call to " + nameof(AddShaderEntryPointByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode + "."); - WriteDXRJSONtoViewGrid(); - return; - } - const String malformedEntryPointCall = "A call to " + nameof(AddShaderEntryPointByID) + "received a malfomed entry point. "; - // Process target text. - String postProcessedCompoundEntryPointText = ""; - List processedTargetText = new List(); - // Extract the contents betwen compoundEntryPoints <>. All inputs must be well-formed. - String tmp_subString = ""; - int openingCompoundEntryPointPosition = -1; - int closingCompoundEntryPointPosition = -1; - Char[] charsToTrim = { '<', '>', ' ' }; - List tmp_strList = new List(); - HashSet uniqeCompoundEntryPointPositions = new HashSet(); - if (targetText.Length > 0 && - targetText[0] == ' ') - { - String errString = "The first character in this field cannot be whitespace."; - postErrorMessage(malformedEntryPointCall + errString); - InvalidateGeneralTextBox(emitter, errString, InvalidShaderEntryPointTextBoxes); - WriteDXRJSONtoViewGrid(); - return; - } - for (int strIdx = 0; strIdx < targetText.Length; strIdx++) - { - tmp_strList.Clear(); - if (targetText[strIdx] == '<') - { - openingCompoundEntryPointPosition = strIdx; - if (!uniqeCompoundEntryPointPositions.Add(strIdx)) - { - String errString = "An opening compoundEntryPoint '<' is referenced by multiple closing compoundEntryPoints '>'."; - postErrorMessage(malformedEntryPointCall + errString); - InvalidateGeneralTextBox(emitter, errString, InvalidShaderEntryPointTextBoxes); - WriteDXRJSONtoViewGrid(); - return; - } - } - else if (targetText[strIdx] == '>') - { - closingCompoundEntryPointPosition = strIdx; - if (closingCompoundEntryPointPosition < openingCompoundEntryPointPosition) - { - String errString = "A closing compoundEntryPoint '>' was provided before an opening compoundEntryPoint '<'."; - postErrorMessage(malformedEntryPointCall + errString); - InvalidateGeneralTextBox(emitter, errString, InvalidShaderEntryPointTextBoxes); - WriteDXRJSONtoViewGrid(); - return; - } - if (!uniqeCompoundEntryPointPositions.Add(strIdx)) - { - String errString = "A closing compoundEntryPoint '>' is referenced by multiple opening compoundEntryPoints '<'."; - postErrorMessage(malformedEntryPointCall + errString); - InvalidateGeneralTextBox(emitter, errString, InvalidShaderEntryPointTextBoxes); - WriteDXRJSONtoViewGrid(); - return; - } - int endSnip = (closingCompoundEntryPointPosition > openingCompoundEntryPointPosition) ? - closingCompoundEntryPointPosition - openingCompoundEntryPointPosition : openingCompoundEntryPointPosition - closingCompoundEntryPointPosition; - if (openingCompoundEntryPointPosition > closingCompoundEntryPointPosition) - { - String errString = "String breaks char indexing rules."; - postErrorMessage(malformedEntryPointCall + errString); - InvalidateGeneralTextBox(emitter, errString, InvalidShaderEntryPointTextBoxes); - WriteDXRJSONtoViewGrid(); - return; - } - if (openingCompoundEntryPointPosition < 0) - { - String errString = "String breaks char indexing rules."; - postErrorMessage(malformedEntryPointCall + errString); - InvalidateGeneralTextBox(emitter, errString, InvalidShaderEntryPointTextBoxes); - WriteDXRJSONtoViewGrid(); - return; - } - if (closingCompoundEntryPointPosition > targetText.Length) - { - String errString = "String breaks char indexing rules."; - postErrorMessage(malformedEntryPointCall + errString); - InvalidateGeneralTextBox(emitter, errString, InvalidShaderEntryPointTextBoxes); - WriteDXRJSONtoViewGrid(); - return; - } - tmp_subString = targetText.Substring(openingCompoundEntryPointPosition, endSnip); - tmp_strList.AddRange(tmp_subString.Split(',')); - if (tmp_strList.Count != 2) - { - String errString = " A pair must be split by ',' into exactly two substrings."; - postErrorMessage(malformedEntryPointCall + errString); - InvalidateGeneralTextBox(emitter, errString, InvalidShaderEntryPointTextBoxes); - WriteDXRJSONtoViewGrid(); - return; - } - if (strIdx < (targetText.Length - 1) && - strIdx + 1 < targetText.Length && - targetText[strIdx + 1] != ',') - { - String errString = "A pair must be the last element in a comma seperated list, or followed" + - " by a comma."; - postErrorMessage(malformedEntryPointCall + errString); - InvalidateGeneralTextBox(emitter, errString, InvalidShaderEntryPointTextBoxes); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the processed text to the list. - String cleanName = tmp_strList[0].Trim(charsToTrim); - String cleanLinkageName = tmp_strList[1].Trim(charsToTrim); - if (cleanName.Length > 0 && cleanLinkageName.Length > 0) - { - processedTargetText.Add(new ProcessedTargetText(cleanName, cleanLinkageName)); - } - openingCompoundEntryPointPosition = -1; - closingCompoundEntryPointPosition = -1; - } - else if (strIdx > 0 && - targetText[strIdx] == ' ' && - targetText[strIdx - 1] != ',') - { - // Explicitly allow multiple spaces - if (targetText[strIdx - 1] != ' ') - { - String errString = "Whtiespace must be predicated by a comma in the form \", \"."; - postErrorMessage(malformedEntryPointCall + errString); - InvalidateGeneralTextBox(emitter, errString, InvalidShaderEntryPointTextBoxes); - WriteDXRJSONtoViewGrid(); - return; - } - } - else if (openingCompoundEntryPointPosition == -1 && closingCompoundEntryPointPosition == -1) - { - postProcessedCompoundEntryPointText += targetText[strIdx]; - } - } - if (openingCompoundEntryPointPosition != -1 && closingCompoundEntryPointPosition == -1) - { - String errString = "A brace '<' was opened but never closed with '>'."; - postErrorMessage(malformedEntryPointCall + errString); - InvalidateGeneralTextBox(emitter, errString, InvalidShaderEntryPointTextBoxes); - WriteDXRJSONtoViewGrid(); - return; - } - if (openingCompoundEntryPointPosition == -1 && closingCompoundEntryPointPosition != -1) - { - String errString = "A brace '>' was closed but never opened with '<'."; - postErrorMessage(malformedEntryPointCall + errString); - InvalidateGeneralTextBox(emitter, errString, InvalidShaderEntryPointTextBoxes); - WriteDXRJSONtoViewGrid(); - return; - } - // From this point, the input text for Shader->EntryPoint is assumed valid. - InvalidShaderEntryPointTextBoxes.Remove(emitter); - // Restore proper tooltip - emitter.ToolTip = shaderEntryPointToolTipString; - // Add the remaining names (without linkage names) to the list. - tmp_strList.Clear(); - tmp_strList.AddRange(postProcessedCompoundEntryPointText.Split(new String[] { "," }, StringSplitOptions.None)); - foreach (String name in tmp_strList) - { - String cleanName = name.Trim(charsToTrim); - if (cleanName.Length > 0) - { - processedTargetText.Add(new ProcessedTargetText(cleanName, "")); - } - } - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__Shader jsonShader = null; - foreach (DXR_JSON_STATE__Shader shader in Master_ShadersByStringID) - { - if (shader.macroElementParentID == macroElementParentID) - { - jsonShader = shader; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonShader == null) - { - jsonShader = new DXR_JSON_STATE__Shader() - { - macroElementParentID = macroElementParentID - }; - if (jsonShader == null) - { - postErrorMessage("A call to " + nameof(AddShaderEntryPointByID) + - " failed to find or create a valid DXR_JSON_STATE__Shader"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_ShadersByStringID.Add(jsonShader); - } - //bool newEntryPointInstanceCreated = false; - if (jsonShader.EntryPoints == null) - { - jsonShader.EntryPoints = new List(); - } - else - { - jsonShader.EntryPoints.Clear(); - } - // Add values to JSON representation - foreach (ProcessedTargetText processedText in processedTargetText) - { - if (processedText.entryPointName != null && - processedText.linkName != null && - (processedText.entryPointName.Length > 0 || processedText.linkName.Length > 0)) - { - jsonShader.EntryPoints.Add(new DXR_JSON_STATE__Shader__EntryPoints - { - ExportName = processedText.entryPointName, - LinkageName = processedText.linkName, - macroElementParentID = macroElementParentID - }); - } - } - if (jsonShader.EntryPoints.Count <= 0) - { - jsonShader.EntryPoints = null; - } - // Restore default textbox style. - Style targetStyle = FindResource("baseTextBoxStyle") as Style; - if (targetStyle != null) - { - emitter.Style = targetStyle; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a shader entry point element by ID: " + - ex.ToString()); - } - } - // File Path - public void AddShaderFilePathByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddShaderFilePathByID) + - " received a null reference to the TextBox eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddShaderFilePathByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddShaderFilePathByID) + - " received a null content string."); - InvalidateGeneralTextBox(emitter); - WriteDXRJSONtoViewGrid(); - return; - } - if (targetText.Length < 1) - { - postErrorMessage("A call to " + nameof(AddShaderFilePathByID) + - " received an empty content string."); - // This field is input verified, thus we must be sure to remove the old - // value which may be in JSON view - { - foreach (DXR_JSON_STATE__Shader shader in Master_ShadersByStringID) - { - if (shader.macroElementParentID == macroElementParentID) - { - shader.FilePath = null; - break; - } - } - } - InvalidateGeneralTextBox(emitter); - WriteDXRJSONtoViewGrid(); - return; - } - String file_name = System.IO.Path.GetFileName(targetText); - String file_path = targetText.Remove(targetText.IndexOf(file_name), file_name.Length); - // Validate the file path - for (int pos = 0; pos < invalidFilePathChars.Count; pos++) - { - if (file_path.Contains(invalidFilePathChars[pos].ToString())) - { - String errString = "The following file path character is illegal: " + invalidFilePathChars[pos] + "."; - postErrorMessage("A call to " + nameof(AddShaderFilePathByID) + " received a malformed file path." + errString); - InvalidateGeneralTextBox(emitter, errString, InvalidShaderFilePathTextBoxes); - WriteDXRJSONtoViewGrid(); - return; - } - } - // Validate the file name - for (int pos = 0; pos < invalidFileNameChars.Count; pos++) - { - if (file_name.Contains(invalidFileNameChars[pos].ToString())) - { - String errString = "The following file name character is illegal: " + invalidFileNameChars[pos] + "."; - postErrorMessage("A call to " + nameof(AddShaderFilePathByID) + " received a malformed file name." + errString); - InvalidateGeneralTextBox(emitter, errString, InvalidShaderFilePathTextBoxes); - WriteDXRJSONtoViewGrid(); - return; - } - } - // From this point, the input text for Shader->FilePath is assumed valid. - InvalidShaderFilePathTextBoxes.Remove(emitter); - // Restore proper tooltip - emitter.ToolTip = shaderFilePathToolTipString; - if (CurrentApplicationMode != Mode.Shader) - { - postErrorMessage("A call to " + nameof(AddShaderFilePathByID) + - " was initiated from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__Shader jsonShader = null; - foreach (DXR_JSON_STATE__Shader shader in Master_ShadersByStringID) - { - if (shader.macroElementParentID == macroElementParentID) - { - jsonShader = shader; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonShader == null) - { - jsonShader = new DXR_JSON_STATE__Shader() - { - macroElementParentID = macroElementParentID - }; - if (jsonShader == null) - { - postErrorMessage("A call to " + nameof(AddShaderFilePathByID) + - " failed to find or create a valid DXR_JSON_STATE__Shader"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_ShadersByStringID.Add(jsonShader); - } - if (targetText.Length > 0) - { - jsonShader.FilePath = targetText; - } - else - { - jsonShader.FilePath = null; - } - // Restore default textbox style. - Style targetStyle = FindResource("baseTextBoxStyle") as Style; - if (targetStyle != null) - { - emitter.Style = targetStyle; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a shader file path element by ID: " + - ex.ToString()); - } - } - // - // Hit Group Element Construction - // - // Type - public void AddHitGroupTypeByID(object sender, RoutedEventArgs e) - { - try - { - ComboBox emitter = sender as ComboBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddHitGroupTypeByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddHitGroupTypeByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - - ComboBoxItem cbItem = emitter.SelectedItem as ComboBoxItem; - if (cbItem == null) - { - postErrorMessage("A call to " + nameof(AddShaderTypeByID) + - " received a null ComboBoxItem."); - WriteDXRJSONtoViewGrid(); - return; - } - - String targetText = cbItem.Content.ToString(); - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddShaderTypeByID) + - " received a null content string."); - WriteDXRJSONtoViewGrid(); - return; - } - - if (CurrentApplicationMode != Mode.HitGroup) - { - postErrorMessage("A call to " + nameof(AddHitGroupTypeByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__HitGroup jsonHitGroup = null; - foreach (DXR_JSON_STATE__HitGroup hitGroup in Master_HitGroupsByStringID) - { - if (hitGroup.macroElementParentID == macroElementParentID) - { - jsonHitGroup = hitGroup; - break; - } - } - - // Create new JSON element if one has not been created. - if (jsonHitGroup == null) - { - jsonHitGroup = new DXR_JSON_STATE__HitGroup() - { - macroElementParentID = macroElementParentID - }; - if (jsonHitGroup == null) - { - postErrorMessage("A call to " + nameof(AddHitGroupTypeByID) + - " failed to find or create a valid DXR_JSON_STATE__HitGroup"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_HitGroupsByStringID.Add(jsonHitGroup); - } - - if (targetText.Length > 0) - { - jsonHitGroup.Type = targetText; - } - else - { - jsonHitGroup.Type = null; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a hit group type element by ID: " + - ex.ToString()); - } - } - // Name - public void AddHitGroupNameByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddHitGroupNameByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddHitGroupNameByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddHitGroupNameByID) + - " received a null content string."); - InvalidateGeneralTextBox(emitter); - WriteDXRJSONtoViewGrid(); - return; - } - if (targetText.Length < 1) - { - postErrorMessage("A call to " + nameof(AddHitGroupNameByID) + - " received an empty content string."); - // This field is input verified, thus we must be sure to remove the old - // value which may be in JSON view - { - foreach (DXR_JSON_STATE__HitGroup hitGroup in Master_HitGroupsByStringID) - { - if (hitGroup.macroElementParentID == macroElementParentID) - { - hitGroup.Name = null; - break; - } - } - } - InvalidateGeneralTextBox(emitter); - WriteDXRJSONtoViewGrid(); - return; - } - if (CurrentApplicationMode != Mode.HitGroup) - { - postErrorMessage("A call to " + nameof(AddHitGroupNameByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__HitGroup jsonHitGroup = null; - foreach (DXR_JSON_STATE__HitGroup hitGroup in Master_HitGroupsByStringID) - { - if (hitGroup.macroElementParentID == macroElementParentID) - { - jsonHitGroup = hitGroup; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonHitGroup == null) - { - jsonHitGroup = new DXR_JSON_STATE__HitGroup() - { - macroElementParentID = macroElementParentID - }; - if (jsonHitGroup == null) - { - postErrorMessage("A call to " + nameof(AddHitGroupNameByID) + - " failed to find or create a valid DXR_JSON_STATE__HitGroup"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_HitGroupsByStringID.Add(jsonHitGroup); - } - if (targetText.Length > 0) - { - jsonHitGroup.Name = targetText; - } - else - { - jsonHitGroup.Name = null; - } - // Restore default text box style - Style targetStyle = FindResource("baseTextBoxStyle") as Style; - if (targetStyle != null) - { - emitter.Style = targetStyle; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a hit group name element by ID: " + - ex.ToString()); - } - } - // Intersection Shader - public void AddHitGroupIntersectionShaderByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddHitGroupIntersectionShaderByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddHitGroupIntersectionShaderByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddHitGroupIntersectionShaderByID) + - " received a null content string."); - WriteDXRJSONtoViewGrid(); - return; - } - if (CurrentApplicationMode != Mode.HitGroup) - { - postErrorMessage("A call to " + nameof(AddHitGroupIntersectionShaderByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__HitGroup jsonHitGroup = null; - foreach (DXR_JSON_STATE__HitGroup hitGroup in Master_HitGroupsByStringID) - { - if (hitGroup.macroElementParentID == macroElementParentID) - { - jsonHitGroup = hitGroup; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonHitGroup == null) - { - jsonHitGroup = new DXR_JSON_STATE__HitGroup() - { - macroElementParentID = macroElementParentID - }; - if (jsonHitGroup == null) - { - postErrorMessage("A call to " + nameof(AddHitGroupIntersectionShaderByID) + - " failed to find or create a valid DXR_JSON_STATE__HitGroup"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_HitGroupsByStringID.Add(jsonHitGroup); - } - if (targetText.Length > 0) - { - jsonHitGroup.IntersectionShader = targetText; - } - else - { - jsonHitGroup.IntersectionShader = null; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a hit group intersection shader element by ID: " + - ex.ToString()); - } - } - // Any Hit Shader - public void AddHitGroupAnyHitShaderByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddHitGroupAnyHitShaderByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddHitGroupAnyHitShaderByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddHitGroupAnyHitShaderByID) + - " received a null content string."); - WriteDXRJSONtoViewGrid(); - return; - } - if (CurrentApplicationMode != Mode.HitGroup) - { - postErrorMessage("A call to " + nameof(AddHitGroupAnyHitShaderByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__HitGroup jsonHitGroup = null; - foreach (DXR_JSON_STATE__HitGroup hitGroup in Master_HitGroupsByStringID) - { - if (hitGroup.macroElementParentID == macroElementParentID) - { - jsonHitGroup = hitGroup; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonHitGroup == null) - { - jsonHitGroup = new DXR_JSON_STATE__HitGroup() - { - macroElementParentID = macroElementParentID - }; - if (jsonHitGroup == null) - { - postErrorMessage("A call to " + nameof(AddHitGroupAnyHitShaderByID) + - " failed to find or create a valid DXR_JSON_STATE__HitGroup"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_HitGroupsByStringID.Add(jsonHitGroup); - } - if (targetText.Length > 0) - { - jsonHitGroup.AnyHitShader = targetText; - } - else - { - jsonHitGroup.AnyHitShader = null; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a hit group any hit shader element by ID: " + - ex.ToString()); - } - } - // Closest Hit Shader - public void AddHitGroupClosestHitShaderByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddHitGroupClosestHitShaderByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddHitGroupClosestHitShaderByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddHitGroupClosestHitShaderByID) + - " received a null content string."); - WriteDXRJSONtoViewGrid(); - return; - } - if (CurrentApplicationMode != Mode.HitGroup) - { - postErrorMessage("A call to " + nameof(AddHitGroupClosestHitShaderByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__HitGroup jsonHitGroup = null; - foreach (DXR_JSON_STATE__HitGroup hitGroup in Master_HitGroupsByStringID) - { - if (hitGroup.macroElementParentID == macroElementParentID) - { - jsonHitGroup = hitGroup; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonHitGroup == null) - { - jsonHitGroup = new DXR_JSON_STATE__HitGroup() - { - macroElementParentID = macroElementParentID - }; - if (jsonHitGroup == null) - { - postErrorMessage("A call to " + nameof(AddHitGroupClosestHitShaderByID) + - " failed to find or create a valid DXR_JSON_STATE__HitGroup"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_HitGroupsByStringID.Add(jsonHitGroup); - } - if (targetText.Length > 0) - { - jsonHitGroup.ClosestHitShader = targetText; - } - else - { - jsonHitGroup.ClosestHitShader = null; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a hit group closest hit shader element by ID: " + - ex.ToString()); - } - } - // - // Local Root Signature Element Construction - // - // Type - public void AddLocalRootSignatureTypeByID(object sender, RoutedEventArgs e) - { - try - { - ComboBox emitter = sender as ComboBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureTypeByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureTypeByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - - ComboBoxItem cbItem = emitter.SelectedItem as ComboBoxItem; - if (cbItem == null) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureTypeByID) + - " received a null ComboBoxItem."); - WriteDXRJSONtoViewGrid(); - return; - } - - String targetText = cbItem.Content.ToString(); - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureTypeByID) + - " received a null content string."); - WriteDXRJSONtoViewGrid(); - return; - } - - if (CurrentApplicationMode != Mode.LocalRootSignature) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureTypeByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__RootSignature jsonRootSignature = null; - foreach (DXR_JSON_STATE__RootSignature rootSignature in Master_LocalRootSignaturesByStringID) - { - if (rootSignature.macroElementParentID == macroElementParentID) - { - jsonRootSignature = rootSignature; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonRootSignature == null) - { - jsonRootSignature = new DXR_JSON_STATE__RootSignature() - { - macroElementParentID = macroElementParentID - }; - if (jsonRootSignature == null) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureTypeByID) + - " failed to find or create a valid DXR_JSON_STATE__HitGroup"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_LocalRootSignaturesByStringID.Add(jsonRootSignature); - } - if (targetText.Length > 0) - { - jsonRootSignature.Type = targetText; - } - else - { - jsonRootSignature.Type = null; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a local root signature type element by ID: " + - ex.ToString()); - } - } - // File Path - public List InvalidShaderFilePathTextBoxes = new List(); - public bool InvalidShaderFilePathTextBoxesExist() - { - return (InvalidShaderFilePathTextBoxes.Count != 0); - } - public void AddLocalRootSignatureFilePathByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureFilePathByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureFilePathByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureFilePathByID) + - " received a null content string."); - InvalidateGeneralTextBox(emitter); - WriteDXRJSONtoViewGrid(); - return; - } - if (targetText.Length < 1) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureFilePathByID) + - " received an empty content string."); - // This field is input verified, thus we must be sure to remove the old - // value which may be in JSON view - { - foreach (DXR_JSON_STATE__RootSignature rootSignature in Master_LocalRootSignaturesByStringID) - { - if (rootSignature.macroElementParentID == macroElementParentID) - { - rootSignature.FilePath = null; - break; - } - } - } - InvalidateGeneralTextBox(emitter); - WriteDXRJSONtoViewGrid(); - return; - } - if (CurrentApplicationMode != Mode.LocalRootSignature) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureFilePathByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__RootSignature jsonLocalRootSignature = null; - foreach (DXR_JSON_STATE__RootSignature rootSignature in Master_LocalRootSignaturesByStringID) - { - if (rootSignature.macroElementParentID == macroElementParentID) - { - jsonLocalRootSignature = rootSignature; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonLocalRootSignature == null) - { - jsonLocalRootSignature = new DXR_JSON_STATE__RootSignature() - { - macroElementParentID = macroElementParentID - }; - if (jsonLocalRootSignature == null) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureFilePathByID) + - " failed to find or create a valid DXR_JSON_STATE__RootSignature"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_LocalRootSignaturesByStringID.Add(jsonLocalRootSignature); - } - if (targetText.Length > 0) - { - jsonLocalRootSignature.FilePath = targetText; - } - else - { - jsonLocalRootSignature.FilePath = null; - } - // Restore default text box style - Style targetStyle = FindResource("baseTextBoxStyle") as Style; - if (targetStyle != null) - { - emitter.Style = targetStyle; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a local root signature file path element by ID: " + - ex.ToString()); - } - } - // Macro Name Shader - public void AddLocalRootSignatureMacroNameShaderByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureMacroNameShaderByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureMacroNameShaderByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureMacroNameShaderByID) + - " received a null content string."); - WriteDXRJSONtoViewGrid(); - return; - } - if (CurrentApplicationMode != Mode.LocalRootSignature) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureMacroNameShaderByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__RootSignature jsonLocalRootSignature = null; - foreach (DXR_JSON_STATE__RootSignature rootSignature in Master_LocalRootSignaturesByStringID) - { - if (rootSignature.macroElementParentID == macroElementParentID) - { - jsonLocalRootSignature = rootSignature; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonLocalRootSignature == null) - { - jsonLocalRootSignature = new DXR_JSON_STATE__RootSignature() - { - macroElementParentID = macroElementParentID - }; - if (jsonLocalRootSignature == null) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureMacroNameShaderByID) + - " failed to find or create a valid DXR_JSON_STATE__RootSignature"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_LocalRootSignaturesByStringID.Add(jsonLocalRootSignature); - } - if (targetText.Length > 0) - { - jsonLocalRootSignature.Name = targetText; - } - else - { - jsonLocalRootSignature.Name = null; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a local root signature macro name element by ID: " + - ex.ToString()); - } - } - // Exports - public void AddLocalRootSignatureExportByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureExportByID) + - " received a null reference to the TextBox eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureExportByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureExportByID) + - " received a null target text string."); - WriteDXRJSONtoViewGrid(); - return; - } - if (CurrentApplicationMode != Mode.LocalRootSignature) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureExportByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__RootSignature jsonLocalRootSignature = null; - foreach (DXR_JSON_STATE__RootSignature rootSignature in Master_LocalRootSignaturesByStringID) - { - if (rootSignature.macroElementParentID == macroElementParentID) - { - jsonLocalRootSignature = rootSignature; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonLocalRootSignature == null) - { - jsonLocalRootSignature = new DXR_JSON_STATE__RootSignature() - { - macroElementParentID = macroElementParentID - }; - if (jsonLocalRootSignature == null) - { - postErrorMessage("A call to " + nameof(AddLocalRootSignatureMacroNameShaderByID) + - " failed to find or create a valid DXR_JSON_STATE__RootSignature"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_LocalRootSignaturesByStringID.Add(jsonLocalRootSignature); - } - jsonLocalRootSignature.Exports = CleanTargetText(targetText); - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a local root signature export name element by ID: " + - ex.ToString()); - } - } - // - // Global Root Signature Element Construction - // - // Type - public void AddGlobalRootSignatureTypeByID(object sender, RoutedEventArgs e) - { - try - { - ComboBox emitter = sender as ComboBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureTypeByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureTypeByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - - ComboBoxItem cbItem = emitter.SelectedItem as ComboBoxItem; - if (cbItem == null) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureTypeByID) + - " received a null ComboBoxItem."); - WriteDXRJSONtoViewGrid(); - return; - } - - String targetText = cbItem.Content.ToString(); - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureTypeByID) + - " received a null content string."); - WriteDXRJSONtoViewGrid(); - return; - } - - if (CurrentApplicationMode != Mode.GlobalRootSignature) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureTypeByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__RootSignature jsonRootSignature = null; - foreach (DXR_JSON_STATE__RootSignature rootSignature in Master_GlobalRootSignaturesByStringID) - { - if (rootSignature.macroElementParentID == macroElementParentID) - { - jsonRootSignature = rootSignature; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonRootSignature == null) - { - jsonRootSignature = new DXR_JSON_STATE__RootSignature() - { - macroElementParentID = macroElementParentID - }; - if (jsonRootSignature == null) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureTypeByID) + - " failed to find or create a valid DXR_JSON_STATE__HitGroup"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_GlobalRootSignaturesByStringID.Add(jsonRootSignature); - } - if (targetText.Length > 0) - { - jsonRootSignature.Type = targetText; - } - else - { - jsonRootSignature.Type = null; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a global root signature type element by ID: " + - ex.ToString()); - } - } - // File Path - public void AddGlobalRootSignatureFilePathByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureFilePathByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureFilePathByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureFilePathByID) + - " received a null content string."); - InvalidateGeneralTextBox(emitter); - WriteDXRJSONtoViewGrid(); - return; - } - if (targetText.Length < 1) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureFilePathByID) + - " received an empty content string."); - // This field is input verified, thus we must be sure to remove the old - // value which may be in JSON view - { - foreach (DXR_JSON_STATE__RootSignature rootSignature in Master_GlobalRootSignaturesByStringID) - { - if (rootSignature.macroElementParentID == macroElementParentID) - { - rootSignature.FilePath = null; - break; - } - } - } - InvalidateGeneralTextBox(emitter); - WriteDXRJSONtoViewGrid(); - return; - } - if (CurrentApplicationMode != Mode.GlobalRootSignature) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureFilePathByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__RootSignature jsonGlobalRootSignature = null; - foreach (DXR_JSON_STATE__RootSignature rootSignature in Master_GlobalRootSignaturesByStringID) - { - if (rootSignature.macroElementParentID == macroElementParentID) - { - jsonGlobalRootSignature = rootSignature; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonGlobalRootSignature == null) - { - jsonGlobalRootSignature = new DXR_JSON_STATE__RootSignature() - { - macroElementParentID = macroElementParentID - }; - if (jsonGlobalRootSignature == null) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureFilePathByID) + - " failed to find or create a valid DXR_JSON_STATE__RootSignature"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_GlobalRootSignaturesByStringID.Add(jsonGlobalRootSignature); - } - if (targetText.Length > 0) - { - jsonGlobalRootSignature.FilePath = targetText; - } - else - { - jsonGlobalRootSignature.FilePath = null; - } - // Restore default text box style - Style targetStyle = FindResource("baseTextBoxStyle") as Style; - if (targetStyle != null) - { - emitter.Style = targetStyle; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a global root signature file path element by ID: " + - ex.ToString()); - } - } - // Macro Name Shader - public void AddGlobalRootSignatureMacroNameShaderByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureMacroNameShaderByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureMacroNameShaderByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureMacroNameShaderByID) + - " received a null content string."); - WriteDXRJSONtoViewGrid(); - return; - } - if (CurrentApplicationMode != Mode.GlobalRootSignature) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureMacroNameShaderByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__RootSignature jsonGlobalRootSignature = null; - foreach (DXR_JSON_STATE__RootSignature rootSignature in Master_GlobalRootSignaturesByStringID) - { - if (rootSignature.macroElementParentID == macroElementParentID) - { - jsonGlobalRootSignature = rootSignature; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonGlobalRootSignature == null) - { - jsonGlobalRootSignature = new DXR_JSON_STATE__RootSignature() - { - macroElementParentID = macroElementParentID - }; - if (jsonGlobalRootSignature == null) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureMacroNameShaderByID) + - " failed to find or create a valid DXR_JSON_STATE__RootSignature"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_GlobalRootSignaturesByStringID.Add(jsonGlobalRootSignature); - } - if (targetText.Length > 0) - { - jsonGlobalRootSignature.Name = targetText; - } - else - { - jsonGlobalRootSignature.Name = null; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a global root signature name element by ID: " + - ex.ToString()); - } - } - // Exports - public void AddGlobalRootSignatureExportByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureExportByID) + - " received a null reference to the TextBox eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureExportByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureExportByID) + - " received a null content string."); - WriteDXRJSONtoViewGrid(); - return; - } - if (CurrentApplicationMode != Mode.GlobalRootSignature) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureExportByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__RootSignature jsonGlobalRootSignature = null; - foreach (DXR_JSON_STATE__RootSignature rootSignature in Master_GlobalRootSignaturesByStringID) - { - if (rootSignature.macroElementParentID == macroElementParentID) - { - jsonGlobalRootSignature = rootSignature; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonGlobalRootSignature == null) - { - jsonGlobalRootSignature = new DXR_JSON_STATE__RootSignature() - { - macroElementParentID = macroElementParentID - }; - if (jsonGlobalRootSignature == null) - { - postErrorMessage("A call to " + nameof(AddGlobalRootSignatureMacroNameShaderByID) + - " failed to find or create a valid DXR_JSON_STATE__RootSignature"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_GlobalRootSignaturesByStringID.Add(jsonGlobalRootSignature); - } - jsonGlobalRootSignature.Exports = CleanTargetText(targetText); - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a global root signature exports element by ID: " + - ex.ToString()); - } - } - // - // Raytracing Pipeline Element Construction - // - // Max Recursion Depth - public void EditRaytracingPipelineMaxRecursionDepthByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(EditRaytracingPipelineMaxRecursionDepthByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(EditRaytracingPipelineMaxRecursionDepthByID) + - " received a null content string."); - WriteDXRJSONtoViewGrid(); - return; - } - if (CurrentApplicationMode != Mode.RaytracingPipeline) - { - postErrorMessage("A call to " + nameof(EditRaytracingPipelineMaxRecursionDepthByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - try - { - Int32 checked_target_text = Convert.ToInt32(targetText); - if (checked_target_text > 0) - { - Master_RaytracingPipelineConfig.MaxTraceRecursionDepth = checked_target_text; - } - } - catch (Exception ex) - { - if (ex is FormatException) - { - postErrorMessage("A call to " + nameof(EditRaytracingPipelineMaxRecursionDepthByID) + - " received a request to convert an invalid string to an int. The string must be a sequence of digits."); - InvalidateGeneralTextBox(emitter); - WriteDXRJSONtoViewGrid(); - return; - } - else if (ex is OverflowException) - { - postErrorMessage("A call to " + nameof(EditRaytracingPipelineMaxRecursionDepthByID) + - " received a request to convert an invalid string to an int." + - " The string must represent a number representable by a signed 32 bit integer."); - InvalidateGeneralTextBox(emitter); - WriteDXRJSONtoViewGrid(); - return; - } - } - // Restore default textbox style. - Style targetStyle = FindResource("baseTextBoxStyle") as Style; - if (targetStyle != null) - { - emitter.Style = targetStyle; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a raytracing pipeline max recursion depth element by ID: " + - ex.ToString()); - } - } - // Flags - public void EditRaytracingPipelineFlagsByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(EditRaytracingPipelineFlagsByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(EditRaytracingPipelineFlagsByID) + - " received a null content string."); - WriteDXRJSONtoViewGrid(); - return; - } - if (CurrentApplicationMode != Mode.RaytracingPipeline) - { - postErrorMessage("A call to " + nameof(EditRaytracingPipelineFlagsByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - List targetTextAsStringArray = - new List(targetText.Split(new String[] { ", " }, StringSplitOptions.None)); - foreach (String str in targetTextAsStringArray.ToArray()) - { - if (str == "" || str == null) - { - targetTextAsStringArray.Remove(str); - } - } - // Note: restore if RaytracingPipelienConfig->Flags member is reinstated. - //if (targetTextAsStringArray.Count > 0) - //{ - // Master_RaytracingPipelineConfig.Flags = targetTextAsStringArray; - //} - //else - //{ - // Master_RaytracingPipelineConfig.Flags = null; - //} - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a raytracing pipeline flags element by ID: " + - ex.ToString()); - } - } - // Exports - public void EditRaytracingPipelineExportsByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(EditRaytracingPipelineExportsByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(EditRaytracingPipelineExportsByID) + - " received a null content string."); - WriteDXRJSONtoViewGrid(); - return; - } - if (CurrentApplicationMode != Mode.RaytracingPipeline) - { - postErrorMessage("A call to " + nameof(EditRaytracingPipelineExportsByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - Master_RaytracingPipelineConfig.Exports = CleanTargetText(targetText); - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a raytracing pipeline exports element by ID: " + - ex.ToString()); - } - } - // - // Raytracing Shader Config Construction - // - // Max Payload Size - public void AddRaytracingShaderConfigMaxPayloadSizeByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigMaxPayloadSizeByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigMaxPayloadSizeByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigMaxPayloadSizeByID) + - " received a null content string."); - WriteDXRJSONtoViewGrid(); - return; - } - if (CurrentApplicationMode != Mode.ShaderPipeline) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigMaxPayloadSizeByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__RaytracingShaderConfig jsonRaytracingShaderConfig = null; - foreach (DXR_JSON_STATE__RaytracingShaderConfig rayTracingShaderConfig in Master_ShaderPipelineConfigByStringID) - { - if (rayTracingShaderConfig.macroElementParentID == macroElementParentID) - { - jsonRaytracingShaderConfig = rayTracingShaderConfig; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonRaytracingShaderConfig == null) - { - jsonRaytracingShaderConfig = new DXR_JSON_STATE__RaytracingShaderConfig() - { - macroElementParentID = macroElementParentID - }; - if (jsonRaytracingShaderConfig == null) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigMaxPayloadSizeByID) + - " failed to find or create a valid DXR_JSON_STATE__RootSignature"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_ShaderPipelineConfigByStringID.Add(jsonRaytracingShaderConfig); - } - try - { - Int32 checked_target_text = Convert.ToInt32(targetText); - if (checked_target_text > 0) - { - jsonRaytracingShaderConfig.MaxPayloadSizeInBytes = checked_target_text; - } - } - catch (Exception ex) - { - if (ex is FormatException) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigMaxPayloadSizeByID) + - " received a request to convert an invalid string to an int. The string must be a sequence of digits."); - InvalidateGeneralTextBox(emitter); - RemoveJSONDataByID(macroElementParentID, Mode.RaytracingPipeline); - WriteDXRJSONtoViewGrid(); - return; - } - else if (ex is OverflowException) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigMaxPayloadSizeByID) + - " received a request to convert an invalid string to an int." + - " The string must represent a number representable by a signed 32 bit integer."); - InvalidateGeneralTextBox(emitter); - RemoveJSONDataByID(macroElementParentID, Mode.RaytracingPipeline); - WriteDXRJSONtoViewGrid(); - return; - } - } - // Restore default textbox style. - Style targetStyle = FindResource("baseTextBoxStyle") as Style; - if (targetStyle != null) - { - emitter.Style = targetStyle; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a shader pipeline max payload size element by ID: " + - ex.ToString()); - } - } - // Max Attribute Size - public void AddRaytracingShaderConfigMaxAttributeSizeByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigMaxAttributeSizeByID) + - " received a null reference to the eimitter."); - WriteDXRJSONtoViewGrid(); - return; - } - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigMaxAttributeSizeByID) + - " received a zero length ID string."); - WriteDXRJSONtoViewGrid(); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigMaxAttributeSizeByID) + - " received a null content string."); - WriteDXRJSONtoViewGrid(); - return; - } - if (CurrentApplicationMode != Mode.ShaderPipeline) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigMaxAttributeSizeByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - WriteDXRJSONtoViewGrid(); - return; - } - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__RaytracingShaderConfig jsonRaytracingShaderConfig = null; - foreach (DXR_JSON_STATE__RaytracingShaderConfig raytracingShaderConfig in Master_ShaderPipelineConfigByStringID) - { - if (raytracingShaderConfig.macroElementParentID == macroElementParentID) - { - jsonRaytracingShaderConfig = raytracingShaderConfig; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonRaytracingShaderConfig == null) - { - jsonRaytracingShaderConfig = new DXR_JSON_STATE__RaytracingShaderConfig() - { - macroElementParentID = macroElementParentID - }; - if (jsonRaytracingShaderConfig == null) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigMaxAttributeSizeByID) + - " failed to find or create a valid DXR_JSON_STATE__RootSignature"); - WriteDXRJSONtoViewGrid(); - return; - } - // Add the new JSON element to the master list. - Master_ShaderPipelineConfigByStringID.Add(jsonRaytracingShaderConfig); - } - try - { - Int32 checked_target_text = Convert.ToInt32(targetText); - if (checked_target_text > 0) - { - jsonRaytracingShaderConfig.MaxAttributeSizeInBytes = checked_target_text; - } - } - catch (Exception ex) - { - if (ex is FormatException) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigMaxAttributeSizeByID) + - " received a request to convert an invalid string to an int. The string must be a sequence of digits."); - InvalidateGeneralTextBox(emitter); - RemoveJSONDataByID(macroElementParentID, Mode.ShaderPipeline); - WriteDXRJSONtoViewGrid(); - return; - } - else if (ex is OverflowException) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigMaxAttributeSizeByID) + - " received a request to convert an invalid string to an int." + - " The string must represent a number representable by a signed 32 bit integer."); - InvalidateGeneralTextBox(emitter); - RemoveJSONDataByID(macroElementParentID, Mode.ShaderPipeline); - WriteDXRJSONtoViewGrid(); - return; - } - } - // Restore default textbox style. - Style targetStyle = FindResource("baseTextBoxStyle") as Style; - if (targetStyle != null) - { - emitter.Style = targetStyle; - } - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a shader pipeline max attribute size element by ID: " + - ex.ToString()); - } - } - // Exports - public void AddRaytracingShaderConfigExportByID(object sender, RoutedEventArgs e) - { - try - { - TextBox emitter = sender as TextBox; - if (emitter == null) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigExportByID) + - " received a null reference to the TextBox eimitter."); - return; - } - String macroElementParentID = emitter.Tag as String; - if (macroElementParentID == null || macroElementParentID.Length == 0) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigExportByID) + - " received a zero length ID string."); - return; - } - String targetText = emitter.Text as String; - if (targetText == null) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigExportByID) + - " received a null content string."); - return; - } - if (CurrentApplicationMode != Mode.ShaderPipeline) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigExportByID) + - " was initaited from an invalid application mode: " + CurrentApplicationMode); - return; - } - // Find the JSON element with the correct ID, if it exists. - // If it doesn't exist, create it. - DXR_JSON_STATE__RaytracingShaderConfig jsonRaytracingShaderConfig = null; - foreach (DXR_JSON_STATE__RaytracingShaderConfig shaderConfig in Master_ShaderPipelineConfigByStringID) - { - if (shaderConfig.macroElementParentID == macroElementParentID) - { - jsonRaytracingShaderConfig = shaderConfig; - break; - } - } - // Create new JSON element if one has not been created. - if (jsonRaytracingShaderConfig == null) - { - jsonRaytracingShaderConfig = new DXR_JSON_STATE__RaytracingShaderConfig() - { - macroElementParentID = macroElementParentID - }; - if (jsonRaytracingShaderConfig == null) - { - postErrorMessage("A call to " + nameof(AddRaytracingShaderConfigExportByID) + - " failed to find or create a valid DXR_JSON_STATE__RaytracingShaderConfig"); - return; - } - // Add the new JSON element to the master list. - Master_ShaderPipelineConfigByStringID.Add(jsonRaytracingShaderConfig); - } - jsonRaytracingShaderConfig.Exports = CleanTargetText(targetText); - // Update JSON View - WriteDXRJSONtoViewGrid(); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to add a shader pipeline exports element by ID: " + - ex.ToString()); - } - } - private MacroElement JSONCreateMacroElementByApplicationMode(Mode mode) - { - SetApplicationMode(mode); - MacroElement macroElement = CreateMacroElementByApplicationMode(mode); - return macroElement; - } - private void ConstructMacroElementsFromJSON(List JsonFileData) - { - try - { - if (JsonFileData == null) - { - postErrorMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - " received a null JSON data list."); - return; - } - MacroElement macroElement; - foreach (JsonFileData jsonData in JsonFileData) - { - if (jsonData.jsonRoot == null) - { - postErrorMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - " received a null JsonData.jsonRoot from the JsonFileData list."); - continue; - } - if (jsonData.jsonRoot.DXRState == null) - { - // This would be a warning, possible but _may_ indicate issues with the underlying file. - postWarningMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - " received a null JsonData.jsonRoot.DXRState from the JsonFileData list."); - continue; - } - if (jsonData.jsonRoot.DXRState.Shaders != null) - { - IList jsonShaderObjList = jsonData.jsonRoot.DXRState.Shaders; - if (jsonShaderObjList != null) - { - uint expectedModeCount = GetModeCount(Mode.Shader); - // Create a new MacroElement of a particular mode. - macroElement = JSONCreateMacroElementByApplicationMode(Mode.Shader); - // Depending on the element type, set the element to reflect the JSON data. - foreach (String subElementName in macroElement.regiteredChildrenNames) - { - // Reset target text - String targetText = ""; - foreach (DXR_JSON_STATE__Shader jsonShaderObj in jsonShaderObjList) - { - if (jsonShaderObj == null) - { - continue; - } - // | Shader, Type | - if (subElementName == ("shaderTypeComboBox" + expectedModeCount)) - { - if (jsonShaderObj.Type != null && - jsonShaderObj.Type.Length > 0) - { - ComboBox targetComboBox = FindName(subElementName) as ComboBox; - if (targetComboBox == null) - { - postErrorMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - " was unable to acquire the target ComboBox for sub element " + expectedModeCount + - " for Shader::Type"); - return; - } - // Note: Purposeful discrepency between GUI text representation and JSON text representation - if (jsonShaderObj.Type == "Binary") - { - jsonShaderObj.Type = ConstStringBinaryDXILType; - } - - if (VerifyComboBoxType(targetComboBox, jsonShaderObj.Type)) - { - targetComboBox.Text = jsonShaderObj.Type; - continue; - } - else - { - postWarningMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - "received a request to add an invalid Shader::Type from a JSON source file."); - } - } - } - // | Shader, Entry Point | - if (jsonShaderObj.EntryPoints != null && - subElementName == ("shaderEntryPointTextBox" + expectedModeCount)) - { - foreach (DXR_JSON_STATE__Shader__EntryPoints entryPoint in jsonShaderObj.EntryPoints) - { - // Entry point values need to be parsed from a JSON array into a comma seperated string list. - if (targetText.Length > 0) - { - targetText += ", "; - } - if (entryPoint.ExportName != null && - entryPoint.ExportName.Length > 0 && - entryPoint.LinkageName != null && - entryPoint.LinkageName.Length > 0) - { - targetText += "<" + entryPoint.ExportName + ", " + entryPoint.LinkageName + ">"; - } - else if (entryPoint.ExportName != null && entryPoint.ExportName.Length > 0) - { - targetText += entryPoint.ExportName; - } - else - { - postWarningMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - " could not parse the Shader data of the provided JSON."); - } - } - } - // | Shader, File Path | - else if (subElementName == ("shaderFilePathTextBox" + expectedModeCount)) - { - if (jsonShaderObj.FilePath != null && - jsonShaderObj.FilePath.Length > 0) - { - targetText = jsonShaderObj.FilePath; - } - } - } - // | Shader, Write Data | - if (targetText.Length > 0) - { - TextBox targetTextBox = FindName(subElementName) as TextBox; - if (targetTextBox != null) - { - targetTextBox.Text = targetText; - } - else - { - postErrorMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - " was unable to find the resouce with name: " + - subElementName); - } - } - // Change the visibility of macro element separators based on mode count. - if (macroElement.hasItemSeperator) - { - SetMacroElementSeparatorVisibilityByModeCount(); - } - } - } - } - if (jsonData.jsonRoot.DXRState.HitGroups != null) - { - IList jsonHitGroupObjList = jsonData.jsonRoot.DXRState.HitGroups; - if (jsonHitGroupObjList != null) - { - uint expectedModeCount = GetModeCount(Mode.HitGroup); - // Create a new MacroElement of a particular mode. - macroElement = JSONCreateMacroElementByApplicationMode(Mode.HitGroup); - // Depending on the element type, set the element to reflect the JSON data. - foreach (String subElementName in macroElement.regiteredChildrenNames) - { - // Reset target text - String targetText = ""; - foreach (DXR_JSON_STATE__HitGroup jsonHitGroupObj in jsonHitGroupObjList) - { - if (jsonHitGroupObj == null) - { - continue; - } - // | HitGroup, Type | - if (subElementName == ("hitGroupTypeComboBox" + expectedModeCount)) - { - if (jsonHitGroupObj.Type != null && - jsonHitGroupObj.Type.Length > 0) - { - ComboBox targetComboBox = FindName(subElementName) as ComboBox; - if (targetComboBox == null) - { - postErrorMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - " was unable to acquire the target ComboBox for sub element " + expectedModeCount + - " for HitGroup::Type"); - return; - } - if (VerifyComboBoxType(targetComboBox, jsonHitGroupObj.Type)) - { - targetComboBox.Text = jsonHitGroupObj.Type; - continue; - } - else - { - postWarningMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - "received a request to add an invalid HitGroup::Type from a JSON source file."); - } - } - } - // | HitGroup, Name | - else if (subElementName == ("hitGroupNameTextBox" + expectedModeCount)) - { - if (jsonHitGroupObj.Name != null && - jsonHitGroupObj.Name.Length > 0) - { - targetText = jsonHitGroupObj.Name; - } - } - // | HitGroup, IntersectionShader | - else if (subElementName == ("hitGroupIntersectionShaderTextBox" + expectedModeCount)) - { - if (jsonHitGroupObj.IntersectionShader != null && - jsonHitGroupObj.IntersectionShader.Length > 0) - { - targetText = jsonHitGroupObj.IntersectionShader; - } - } - // | HitGroup, AnyHitShader | - else if (subElementName == ("hitGroupAnyHitShaderTextBox" + expectedModeCount)) - { - if (jsonHitGroupObj.AnyHitShader != null && - jsonHitGroupObj.AnyHitShader.Length > 0) - { - targetText = jsonHitGroupObj.AnyHitShader; - } - } - // | HitGroup, ClosestHitShader | - else if (subElementName == ("hitGroupClosestHitShaderTextBox" + expectedModeCount)) - { - if (jsonHitGroupObj.ClosestHitShader != null && - jsonHitGroupObj.ClosestHitShader.Length > 0) - { - targetText = jsonHitGroupObj.ClosestHitShader; - } - } - } - // | HitGroup, Write Data | - if (targetText.Length > 0) - { - TextBox targetTextBox = FindName(subElementName) as TextBox; - if (targetTextBox != null) - { - targetTextBox.Text = targetText; - } - else - { - postErrorMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - " was unable to find the resouce with name: " + - subElementName); - } - } - // Change the visibility of macro element separators based on mode count. - if (macroElement.hasItemSeperator) - { - SetMacroElementSeparatorVisibilityByModeCount(); - } - } - } - } - if (jsonData.jsonRoot.DXRState.LocalRootSignatures != null) - { - IList jsonLocalRootSignaturesObjList = - jsonData.jsonRoot.DXRState.LocalRootSignatures; - if (jsonLocalRootSignaturesObjList != null) - { - uint expectedModeCount = GetModeCount(Mode.LocalRootSignature); - // Create a new MacroElement of a particular mode. - macroElement = JSONCreateMacroElementByApplicationMode(Mode.LocalRootSignature); - // Depending on the element type, set the element to reflect the JSON data. - foreach (String subElementName in macroElement.regiteredChildrenNames) - { - // Reset target text - String targetText = ""; - foreach (DXR_JSON_STATE__RootSignature jsonLocalRootSignaturesObj in jsonLocalRootSignaturesObjList) - { - if (jsonLocalRootSignaturesObj == null) - { - continue; - } - // | LocalRootSignatures, Type | - if (subElementName == ("localRootSignaturesTypeComboBox" + expectedModeCount)) - { - if (jsonLocalRootSignaturesObj.Type != null && - jsonLocalRootSignaturesObj.Type.Length > 0) - { - ComboBox targetComboBox = FindName(subElementName) as ComboBox; - if (targetComboBox == null) - { - postErrorMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - " was unable to acquire the target ComboBox for sub element " + expectedModeCount + - " for LocalRootSignature::Type"); - return; - } - // Note: Purposeful discrepency between GUI text representation and JSON text representation - if (jsonLocalRootSignaturesObj.Type == "Binary") - { - jsonLocalRootSignaturesObj.Type = ConstStringBinaryDXILType; - } - - if (VerifyComboBoxType(targetComboBox, jsonLocalRootSignaturesObj.Type)) - { - targetComboBox.Text = jsonLocalRootSignaturesObj.Type; - continue; - } - else - { - postWarningMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - "received a request to add an invalid LocalRootSignature::Type from a JSON source file."); - } - } - } - // | LocalRootSignatures, FilePath | - if (subElementName == ("localRootSignaturesFilePathTextBox" + expectedModeCount)) - { - if (jsonLocalRootSignaturesObj.FilePath != null && - jsonLocalRootSignaturesObj.FilePath.Length > 0) - { - targetText = jsonLocalRootSignaturesObj.FilePath; - } - } - // | LocalRootSignatures, Name | - else if (subElementName == ("localRootSignaturesMacroNameShaderTextBox" + expectedModeCount)) - { - if (jsonLocalRootSignaturesObj.Name != null && - jsonLocalRootSignaturesObj.Name.Length > 0) - { - targetText = jsonLocalRootSignaturesObj.Name; - } - } - // | LocalRootSignatures, Exports | - else if (subElementName == ("localRootSignaturesExportsTextBox" + expectedModeCount)) - { - if (jsonLocalRootSignaturesObj.Exports == null) - { - continue; - } - foreach (String rootSignature in jsonLocalRootSignaturesObj.Exports) - { - if (jsonLocalRootSignaturesObj.Exports == null) - { - jsonLocalRootSignaturesObj.Exports = new List(); - } - if (rootSignature != null) - { - // Exports values need to be parsed from a JSON array into a comma seperated string list. - if (targetText.Length > 0) - { - targetText += ", "; - } - targetText += rootSignature; - } - } - } - } - // | LocalRootSignatures, Write Data | - if (targetText.Length > 0) - { - TextBox targetTextBox = FindName(subElementName) as TextBox; - if (targetTextBox != null) - { - targetTextBox.Text = targetText; - } - else - { - postErrorMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - " was unable to find the resouce with name: " + - subElementName); - } - } - // Change the visibility of macro element separators based on mode count. - if (macroElement.hasItemSeperator) - { - SetMacroElementSeparatorVisibilityByModeCount(); - } - } - } - } - if (jsonData.jsonRoot.DXRState.GlobalRootSignatures != null) - { - IList jsonGlobalRootSignaturesObjList = - jsonData.jsonRoot.DXRState.GlobalRootSignatures; - if (jsonGlobalRootSignaturesObjList != null) - { - uint expectedModeCount = GetModeCount(Mode.GlobalRootSignature); - // Create a new MacroElement of a particular mode. - macroElement = JSONCreateMacroElementByApplicationMode(Mode.GlobalRootSignature); - // Depending on the element type, set the element to reflect the JSON data. - foreach (String subElementName in macroElement.regiteredChildrenNames) - { - if (subElementName == null) - { - continue; - } - // Reset target text - String targetText = ""; - foreach (DXR_JSON_STATE__RootSignature jsonGlobalRootSignaturesObj in jsonGlobalRootSignaturesObjList) - { - if (jsonGlobalRootSignaturesObj == null) - { - continue; - } - // | GlobalRootSignatures, Type | - if (subElementName == ("globalRootSignaturesTypeComboBox" + expectedModeCount)) - { - if (jsonGlobalRootSignaturesObj.Type != null && - jsonGlobalRootSignaturesObj.Type.Length > 0) - { - ComboBox targetComboBox = FindName(subElementName) as ComboBox; - if (targetComboBox == null) - { - postErrorMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - " was unable to acquire the target ComboBox for sub element " + expectedModeCount + - " for GlobalRootSignature::Type"); - return; - } - // Note: Purposeful discrepency between GUI text representation and JSON text representation - if (jsonGlobalRootSignaturesObj.Type == "Binary") - { - jsonGlobalRootSignaturesObj.Type = ConstStringBinaryDXILType; - } - - if (VerifyComboBoxType(targetComboBox, jsonGlobalRootSignaturesObj.Type)) - { - targetComboBox.Text = jsonGlobalRootSignaturesObj.Type; - continue; - } - else - { - postWarningMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - "received a request to add an invalid GlobalRootSignature::Type from a JSON source file."); - } - } - } - // | GlobalRootSignatures, FilePath | - if (subElementName == ("globalRootSignaturesFilePathTextBox" + expectedModeCount)) - { - if (jsonGlobalRootSignaturesObj.FilePath != null && - jsonGlobalRootSignaturesObj.FilePath.Length > 0) - { - targetText = jsonGlobalRootSignaturesObj.FilePath; - } - } - // | GlobalRootSignatures, Name | - else if (subElementName == ("globalRootSignaturesMacroNameShaderTextBox" + expectedModeCount)) - { - if (jsonGlobalRootSignaturesObj.Name != null && - jsonGlobalRootSignaturesObj.Name.Length > 0) - { - targetText = jsonGlobalRootSignaturesObj.Name; - } - } - // | GlobalRootSignatures, Exports | - else if (subElementName == ("globalRootSignaturesExportsTextBox" + expectedModeCount)) - { - if (jsonGlobalRootSignaturesObj.Exports == null) - { - jsonGlobalRootSignaturesObj.Exports = new List(); - } - foreach (String rootSignature in jsonGlobalRootSignaturesObj.Exports) - { - if (rootSignature != null) - { - // Exports values need to be parsed from a JSON array into a comma seperated string list. - if (targetText.Length > 0) - { - targetText += ", "; - } - targetText += rootSignature; - } - } - } - } - // | GlobalRootSignatures, Write Data | - if (targetText.Length > 0) - { - TextBox targetTextBox = FindName(subElementName) as TextBox; - if (targetTextBox != null) - { - targetTextBox.Text = targetText; - } - else - { - postErrorMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - " was unable to find the resouce with name: " + - subElementName); - } - } - // Change the visibility of macro element separators based on mode count. - if (macroElement.hasItemSeperator) - { - SetMacroElementSeparatorVisibilityByModeCount(); - } - } - } - } - if (jsonData.jsonRoot.DXRState.RaytracingPipelineConfig != null) - { - SetApplicationMode(Mode.RaytracingPipeline); - uint elementsFound = 0; - foreach (MacroElement MacroElement in Master_MacroElementList) - { - if (MacroElement.applicationMode == Mode.RaytracingPipeline) - { - elementsFound++; - } - } - if (elementsFound > 1) - { - postErrorMessage("Found more than one instance of the RaytracingPipelienConfig MacroElement."); - } - // | RaytracingPipelineConfig, Max Trace Recursion Depth | - String subElementName = "RaytracingPipelineMaxTraceRecursionDepthTextBox0"; - TextBox targetTextBox = FindName(subElementName) as TextBox; - if (targetTextBox != null) - { - targetTextBox.Text = - jsonData.jsonRoot.DXRState.RaytracingPipelineConfig.MaxTraceRecursionDepth.ToString(); - } - else - { - postErrorMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - " was unable to find the resouce with name: " + - subElementName); - } - // | RaytracingPipelineConfig, Exports | - subElementName = "RaytracingPipelineExportsTextBox0"; - targetTextBox = FindName(subElementName) as TextBox; - if (targetTextBox != null) - { - String targetText = ""; - if (jsonData.jsonRoot.DXRState.RaytracingPipelineConfig.Exports != null) - { - foreach (String export in jsonData.jsonRoot.DXRState.RaytracingPipelineConfig.Exports) - { - if (export != null) - { - // Exports values need to be parsed from a JSON array into a comma seperated string list. - if (targetText.Length > 0) - { - targetText += ", "; - } - targetText += export; - } - } - targetTextBox.Text = targetText; - } - } - else - { - postErrorMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - " was unable to find the resouce with name: " + - subElementName); - } - } - if (jsonData.jsonRoot.DXRState.RaytracingShaderConfig != null) - { - IList jsonRaytracingShaderConfigObjList = - jsonData.jsonRoot.DXRState.RaytracingShaderConfig; - if (jsonRaytracingShaderConfigObjList != null) - { - uint expectedModeCount = GetModeCount(Mode.ShaderPipeline); - // Create a new MacroElement of a particular mode. - macroElement = JSONCreateMacroElementByApplicationMode(Mode.ShaderPipeline); - // Depending on the element type, set the element to reflect the JSON data. - foreach (String subElementName in macroElement.regiteredChildrenNames) - { - if (subElementName == null) - { - continue; - } - if (subElementName != null) - { - // Reset target text - String targetText = ""; - foreach (DXR_JSON_STATE__RaytracingShaderConfig jsonRaytracingShaderConfigObj - in jsonRaytracingShaderConfigObjList) - { - if (jsonRaytracingShaderConfigObj == null) - { - continue; - } - // | RaytracingShaderConfig, PayloadSizeInBytes | - if (subElementName == ("ShaderPipelinePayloadSizeTextBox" + expectedModeCount)) - { - targetText = jsonRaytracingShaderConfigObj.MaxPayloadSizeInBytes.ToString(); - } - // | RaytracingShaderConfig, MaxAttributeSizeInBytes | - else if (subElementName == ("ShaderPipelinesMaxAttributeSizeTextBox" + expectedModeCount)) - { - targetText = jsonRaytracingShaderConfigObj.MaxAttributeSizeInBytes.ToString(); - } - // | RaytracingShaderConfig, Exports | - else if (subElementName == ("ShaderPipelinesExportsTextBox" + expectedModeCount)) - { - if (jsonRaytracingShaderConfigObj.Exports == null) - { - jsonRaytracingShaderConfigObj.Exports = new List(); - } - foreach (String rtShaderConfigObj in jsonRaytracingShaderConfigObj.Exports) - { - if (rtShaderConfigObj != null) - { - // Exports values need to be parsed from a JSON array into a comma seperated string list. - if (targetText.Length > 0) - { - targetText += ", "; - } - targetText += rtShaderConfigObj; - } - } - } - } - // | RaytracingShaderConfig, Write Data | - if (targetText.Length > 0) - { - TextBox targetTextBox = FindName(subElementName) as TextBox; - if (targetTextBox != null) - { - targetTextBox.Text = targetText; - } - else - { - postErrorMessage("A call to " + nameof(ConstructMacroElementsFromJSON) + - " was unable to find the resouce with name: " + - subElementName); - } - } - // Change the visibility of macro element separators based on mode count. - if (macroElement.hasItemSeperator) - { - SetMacroElementSeparatorVisibilityByModeCount(); - } - } - } - } - } - } - } - catch (Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to construct macro elements from JSON data: " + - ex.ToString()); - } - } - private void ReadJSONFileContents(String[] files, List jsonFileDataList) - { - foreach (String file in files) - { - if (file != null) - { - if (System.IO.File.Exists(file)) - { - String tmpString = System.IO.File.ReadAllText(file); - if (tmpString.Length > 0) - { - JsonFileData data = new JsonFileData(); - data.filePath = file; - data.fileContents = tmpString; - try - { - data.jsonRoot = JsonSerializer.Deserialize(tmpString, jsonOptions); - } - catch (JsonException jex) - { - String errMsg = ""; - errMsg += "An error occured while parsing the follwowing JSON file:\n\n" + file + "\n\n"; - errMsg += "Offending line number: " + jex.LineNumber + "\n"; - errMsg += "Offending line byte offset: " + jex.BytePositionInLine + "\n\n"; - errMsg += "\nThis file's contents will not be added."; - MessageBoxResult msgBox = MessageBox.Show(errMsg, - "JSON Parsing Error", - MessageBoxButton.OK, - MessageBoxImage.Error); - } - jsonFileDataList.Add(data); - } - } - else - { - postErrorMessage("A call to " + nameof(ReadJSONFileContents) + - " received a file handle which does not correspond to an existing file."); - return; - } - } - } - } -#if false - // Reintroduce if drag and drop functionality is reinstated. - private void HandleJSONDragAndDrop(object sender, DragEventArgs e) - { - try - { - List jsonFileDataList = new List(); - String[] files = (String[])e.Data.GetData(DataFormats.FileDrop); - if (files != null && files.Length > 0) - { - ReadJSONFileContents(files, jsonFileDataList); - if (jsonFileDataList.Count > 0) - { - ConstructMacroElementsFromJSON(jsonFileDataList); - } - } - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to handle JSON file drag-and-drop: " + - ex.ToString()); - } - } -#endif - } -} \ No newline at end of file diff --git a/Utils/DXR State Editor/DXR State Editor/LogTools.cs b/Utils/DXR State Editor/DXR State Editor/LogTools.cs deleted file mode 100644 index 7cf1d5f..0000000 --- a/Utils/DXR State Editor/DXR State Editor/LogTools.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Windows; - -namespace DXR_State_Editor -{ - public partial class MainWindow : Window - { - // Todo: write to file on exit? - public List warningMessageLog = new List(); - public List errorMessageLog = new List(); - - public void postWarningMessage(String msgDetail) - { - String msg = "[ warning ] (" + System.DateTime.Now + "): " + msgDetail; - warningMessageLog.Add(msg); - Console.WriteLine(msg); - } - - public void postErrorMessage(String msgDetail) - { - String msg = "[ error ] (" + System.DateTime.Now + "): " + msgDetail; - errorMessageLog.Add(msg); - Console.Error.WriteLine(msg); - } - } -} diff --git a/Utils/DXR State Editor/DXR State Editor/MacroElements.cs b/Utils/DXR State Editor/DXR State Editor/MacroElements.cs deleted file mode 100644 index 0fae413..0000000 --- a/Utils/DXR State Editor/DXR State Editor/MacroElements.cs +++ /dev/null @@ -1,3448 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; -using System.Windows.Media; -namespace DXR_State_Editor -{ - // - // Macro Element Definition - // - public struct MacroElement - { - public Mode applicationMode; - public FrameworkElement rootElement; - public Panel targetElement; - public List regiteredChildrenNames; - public bool hasItemSeperator; - } - public class DXRScrollViewer : ScrollViewer - { - public enum ScrollCommandOrigin - { - UserInitiated, - SystemInitiated - }; - public bool shouldAutoScroll = true; - public ScrollCommandOrigin scrollCommandOrigin = ScrollCommandOrigin.UserInitiated; - } - public partial class MainWindow : Window - { - readonly String welcomeText = "Select a pipeline component on the left to start building your DXR state object," + - //Environment.NewLine + "or drag and drop a valid DXR state JSON file onto the button bar at the bottom " + - Environment.NewLine + "or use the 'Load JSON' button in the bottom right of the window."; - // Master Macro Element List - public List Master_MacroElementList = new List(); - // Content View Settings - public class ContentViewSettings - { - public const double ContentMinWidth = 950; - public const double ContentItemHeight = 35; - public const double ContentTextBoxMinWidth = 350; - public const double ContentTextBoxMaxWidth = 600; - public const double ContentTextBoxMargin_left = 5; - public const double ContentTextBoxMargin_top = 5; - public const double ContentTextBoxMargin_right = 5; - public const double ContentTextBoxMargin_bottom = 20; - public const double ContentComboBoxMinWidth = 350; - public const double ContentComboBoxMargin_left = 5; - public const double ContentComboBoxMargin_top = 5; - public const double ContentComboBoxMargin_right = 5; - public const double ContentComboBoxMargin_bottom = 20; - public const double ContentBrowseButtonWidth = 80; - public const double ContentBrowseButtonMargin_left = 5; - public const double ContentBrowseButtonMargin_top = 5; - public const double ContentBrowseButtonMargin_right = 5; - public const double ContentBrowseButtonMargin_bottom = 20; - public const double ContentRemoveButton_withBrowse_withTextBox_MarginLeft = ContentTextBoxMargin_right; - public const double ContentRemoveButton_withBrowse_withTextBox_MarginBottom = 20; - public const double ContentRemoveButton_withoutBrowse_withTextBox_MarginLeft = - ContentTextBoxMargin_right + ContentBrowseButtonWidth + ContentBrowseButtonMargin_left + ContentBrowseButtonMargin_right; - public const double ContentRemoveButton_withoutBrowse_withTextBox_MarginBottom = 20; - }; - const String ConstStringBinaryDXILType = "Binary (DXIL)"; - const String ConstStringBinaryType = "Binary"; - const String ConstStringHLSLType = "HLSL"; - const String defaultYetInvalidFilePathString = ""; - const String shaderFilePathToolTipString = "Full path to the shader on your device."; - const String shaderEntryPointToolTipString = "Accepts a comma separated list of entry points in the following forms:\n\n" - + "\"entry_point_1, entry_point_2, entry_point_3\"\n" - + "or\n" - + "\", \"\n" - + "or an unordered combination of these, such as:\n" - + "\", entry_point_2, \"\n\n" - + "The text will be colored red if an invalid entry is present."; - const String hitGroupNameToolTipString = "A name for this hit group."; - const String hitGroupIntersectionShaderToolTipString = "A name for this hit group's intersection shader."; - const String hitGroupAnyHitShaderToolTipString = "A name for this hit group's any hit shader."; - const String hitGroupClosestHitShaderToolTipString = "A name for this hit group's closest hit shader."; - const String localRootSignaturesFilePathToolTipString = "The full path to this local root signature."; - const String localRootSignaturesMacroNameShaderToolTipString = "A name for this local root signature's macro (HLSL)."; - const String localRootSignaturesExportsToolTipString = "A comma separated list of exports to be associated with this local root signature."; - const String globalRootSignaturesFilePathToolTipString = "The full path to this global root signature."; - const String globalRootSignaturesMacroNameShaderToolTipString = "A name for this global root signature's macro (HLSL)."; - const String globalRootSignaturesExportsToolTipString = "A comma separated list of exports to be associated with this global root signature."; - const String RaytracingPipelineMaxTraceRecursionDepthToolTipString = "The max trace recursion depth for this raytracing pipeline (1 means no recursion)."; - const String RaytracingPipelineExportsToolTipString = "A comma separated list of exports for this raytracing pipeline."; - const String ShaderPipelinePayloadSizeToolTipString = "The maximum storage for scalars in ray payloads."; - const String ShaderPipelinesMaxAttributeSizeToolTipString = "The maximum number of bytes that can be used for attributes in pipelines containing the relevant shader."; - const String ShaderPipelinesExportsToolTipString = "A comma separated list of exports to be associated with this shader config element."; - - public void InvalidateGeneralTextBox(TextBox targetTextBox) - { - if (targetTextBox == null) - { - postErrorMessage("A call to " + nameof(InvalidateGeneralTextBox) + - " was unable to aquire the target label."); - return; - } - Style errorStyle = FindResource("errorTextBoxStyle") as Style; - if (errorStyle == null) - { - postErrorMessage("A call to " + nameof(InvalidateGeneralTextBox) + - " was unable to aquire the target style."); - return; - } - targetTextBox.Style = errorStyle; - } - public void InvalidateGeneralTextBox(TextBox targetTextBox, String toolTip) - { - if (targetTextBox == null) - { - postErrorMessage("A call to " + nameof(InvalidateGeneralTextBox) + - " was unable to aquire the target label."); - return; - } - Style errorStyle = FindResource("errorTextBoxStyle") as Style; - if (errorStyle == null) - { - postErrorMessage("A call to " + nameof(InvalidateGeneralTextBox) + - " was unable to aquire the target style."); - return; - } - if (toolTip == null || toolTip.Length < 1) - { - postErrorMessage("A call to " + nameof(InvalidateGeneralTextBox) + - " was initaited with a null or empty tool tip string."); - return; - } - targetTextBox.Style = errorStyle; - targetTextBox.ToolTip = toolTip; - } - public void InvalidateGeneralTextBox(TextBox targetTextBox, - String toolTip, - List invalidatedTextboxes) - { - if (targetTextBox == null) - { - postErrorMessage("A call to " + nameof(InvalidateGeneralTextBox) + - " was unable to aquire the target label."); - return; - } - Style errorStyle = FindResource("errorTextBoxStyle") as Style; - if (errorStyle == null) - { - postErrorMessage("A call to " + nameof(InvalidateGeneralTextBox) + - " was unable to aquire the target style."); - return; - } - if (toolTip == null || toolTip.Length < 1) - { - postErrorMessage("A call to " + nameof(InvalidateGeneralTextBox) + - " was initaited with a null or empty tool tip string."); - return; - } - if (invalidatedTextboxes == null) - { - postErrorMessage("A call to " + nameof(InvalidateGeneralTextBox) + - " was initaited with a null invalidation List."); - return; - } - targetTextBox.Style = errorStyle; - targetTextBox.ToolTip = toolTip; - if (!invalidatedTextboxes.Contains(targetTextBox)) - { - invalidatedTextboxes.Add(targetTextBox); - } - } - public void ClearDefaultFilePathText(object sender, RoutedEventArgs e) - { - if (sender == null) - { - postErrorMessage("A call to " + nameof(InvalidateGeneralTextBox) + - " was passed a null sender object."); - return; - } - TextBox targetTextBox = sender as TextBox; - if (targetTextBox == null) - { - postErrorMessage("A call to " + nameof(InvalidateGeneralTextBox) + - " was unable to aquire the target label."); - return; - } - if (targetTextBox.Text == defaultYetInvalidFilePathString) - { - targetTextBox.Text = ""; - } - } - public static bool ValidateMacroElement(MacroElement macroElement) - { - bool isValid = true; - if (macroElement.targetElement == null || macroElement.targetElement == null) - { - isValid = false; - } - return isValid; - } - public void HandleDXRScrollViewerScrollChanged(object sender, ScrollChangedEventArgs e) - { - DXRScrollViewer scrollViewer = sender as DXRScrollViewer; - if (scrollViewer == null) - { - postWarningMessage("A call to " + nameof(HandleDXRScrollViewerScrollChanged) + - " was unable to acquire the DXRScrollViewer."); - return; - } - // Carry out user initiated scrolling and determine value of shouldAutoScroll member. - if (scrollViewer.scrollCommandOrigin == DXRScrollViewer.ScrollCommandOrigin.UserInitiated) - { - if (scrollViewer.VerticalOffset >= (0.98 * scrollViewer.ScrollableHeight)) - { - scrollViewer.shouldAutoScroll = true; - } - else - { - scrollViewer.shouldAutoScroll = false; - } - } - } - - public void SetComboBoxItemContent(ComboBox cBox, List comboBoxContentTextList) - { - bool shouldContinue = true; - if (cBox == null) - { - shouldContinue = false; - postErrorMessage("A call to " + nameof(SetComboBoxItemContent) + - " received a null ComboBox."); - } - else if (comboBoxContentTextList == null) - { - shouldContinue = false; - postErrorMessage("A call to " + nameof(SetComboBoxItemContent) + - " received a null ComboBox."); - } - - if (shouldContinue) - { - foreach (String contentString in comboBoxContentTextList) - { - if (contentString != null && - contentString.Length > 0) - { - ComboBoxItem cbItem = new ComboBoxItem(); - cbItem.Content = contentString; - cbItem.Tag = contentString; - cBox.Items.Add(cbItem); - cbItem.Cursor = Cursors.Hand; - } - else - { - postWarningMessage("A call to " + nameof(SetComboBoxItemContent) + - " was unable to add a content string to a ComboBoxItem widget."); - } - } - } - } - - public void RemoveMacroElement(MacroElement macroElement) - { - bool shouldContinue = true; - if (macroElement.applicationMode == Mode.Welcome || - macroElement.applicationMode == Mode.GeneralStateConfig || - macroElement.applicationMode == Mode.RaytracingPipeline || - macroElement.applicationMode == Mode.Output || - macroElement.applicationMode == Mode.ApplicationError) - { - shouldContinue = false; - } - Grid cGrid = FindName("contentGrid") as Grid; - if (cGrid == null) - { - postErrorMessage(" A call to " + nameof(RemoveMacroElement) + - " failed to aquire the main content grid."); - shouldContinue = false; - } - Grid rootGrid = macroElement.rootElement as Grid; - if (rootGrid == null) - { - postErrorMessage(" A call to " + nameof(RemoveMacroElement) - + " failed to aquire the root of the target MacroElement."); - shouldContinue = false; - } - if (shouldContinue) - { - // Unregister all associated names. - foreach (String name in macroElement.regiteredChildrenNames) - { - UnregisterName(name); - } - // Destroy all children items. - rootGrid.Children.Clear(); - cGrid.Children.Remove(rootGrid); - // Correct mode count. - if (GetModeCount(macroElement.applicationMode) > 0) - { - DecrementModeCount(macroElement.applicationMode); - } - // Remove the associated data from the JSON register lists - // The Global JSON view wil be updated by RemoveJSONDataByID() - RemoveJSONDataByID(macroElement.rootElement.Tag as String, - macroElement.applicationMode); - // Apply the correct macro separator visibility by mode count. - SetMacroElementSeparatorVisibilityByModeCount(); - // Remove from master list - Master_MacroElementList.Remove(macroElement); - } - } - public void RemoveAllMacroElementGroups() - { - try - { - Grid cGrid = FindName("contentGrid") as Grid; - if (cGrid == null) - { - postErrorMessage(" A call to " + nameof(RemoveAllMacroElementGroups) + - " failed to aquire the main content grid."); - return; - } - List removalQueue = new List(); - for (int index = 0; index < Master_MacroElementList.Count; index++) - { - MacroElement macroElement = Master_MacroElementList[index]; - if (macroElement.applicationMode == Mode.Welcome || - macroElement.applicationMode == Mode.GeneralStateConfig || - macroElement.applicationMode == Mode.RaytracingPipeline || - macroElement.applicationMode == Mode.Output || - macroElement.applicationMode == Mode.ApplicationError) - { - continue; - } - removalQueue.Add(macroElement); - Grid rootGrid = macroElement.rootElement as Grid; - if (rootGrid == null) - { - postErrorMessage(" A call to " + nameof(RemoveAllMacroElementGroups) - + " failed to aquire the root of the target MacroElement."); - return; - } - // Unregister all associated names. - foreach (String name in macroElement.regiteredChildrenNames) - { - UnregisterName(name); - } - rootGrid.Children.Clear(); - cGrid.Children.Remove(rootGrid); - // Correct mode count - if (GetModeCount(macroElement.applicationMode) > 0) - { - DecrementModeCount(macroElement.applicationMode); - } - // Remove the associated data from the JSON register lists - // The Global JSON view wil be updated by RemoveJSONDataByID() - RemoveJSONDataByID(macroElement.rootElement.Tag as String, - macroElement.applicationMode); - // Apply the correct macro separator visibility by mode count. - SetMacroElementSeparatorVisibilityByModeCount(); - } - foreach (MacroElement macroElement in removalQueue) - { - Master_MacroElementList.Remove(macroElement); - } - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to remove all macro element groups: " + - ex.ToString()); - } - } - public void HandleTrashcanIconClick(object sender, RoutedEventArgs e) - { - try - { - Button buSender = sender as Button; - if (buSender == null) - { - postErrorMessage(" A call to " + nameof(HandleTrashcanIconClick) - + " failed to cast the sending object as required."); - return; - } - String macroElementID = buSender.Tag as String; - if (macroElementID == null) - { - postErrorMessage(" A call to " + nameof(HandleTrashcanIconClick) - + " failed to aquire the necessary metadata to remove a MacroElement."); - return; - } - Grid cGrid = FindName("contentGrid") as Grid; - if (cGrid == null) - { - postErrorMessage(" A call to " + nameof(HandleTrashcanIconClick) - + " failed to aquire the main content grid."); - return; - } - Grid toRemove = FindName(macroElementID) as Grid; - if (toRemove == null) - { - postErrorMessage(" A call to " + nameof(HandleTrashcanIconClick) - + " failed to aquire the root of the target MacroElement."); - return; - } - // Use JSON representation to tell if the user has entered any data for a mode. - // If they have, ask if they are sure before proceeding. - if (CheckJSONAssociationByElementIDAndApplicationMode(macroElementID, CurrentApplicationMode)) - { - MessageBoxResult msgBoxResult = MessageBox.Show("Are you sure you want to remove this group?", - "JSON Data Association Detected", - MessageBoxButton.YesNo, - MessageBoxImage.Warning); - if (msgBoxResult == MessageBoxResult.No) - { - return; - } - } - bool foundElement = false; - MacroElement macroElement; - int toRemoveHashCode = toRemove.GetHashCode(); - for (int index = 0; index < Master_MacroElementList.Count; index++) - { - macroElement = Master_MacroElementList[index]; - if (macroElement.rootElement.GetHashCode() == toRemoveHashCode) - { - // Unregister all associated names. - foreach (String name in macroElement.regiteredChildrenNames) - { - UnregisterName(name); - } - // Remove from global element list. - Master_MacroElementList.RemoveAt(index); - foundElement = true; - break; - } - } - if (!foundElement) - { - postWarningMessage("A call to " + nameof(HandleTrashcanIconClick) + " attempted to remove an element not registered in the global element list."); - } - toRemove.Children.Clear(); - cGrid.Children.Remove(toRemove); - if (GetModeCount(CurrentApplicationMode) > 0) - { - DecrementModeCount(CurrentApplicationMode); - } - // Remove the associated data from the JSON register lists - // The Global JSON view wil be updated by RemoveJSONDataByID() - RemoveJSONDataByID(macroElementID, CurrentApplicationMode); - // Apply the correct macro separator visibility by mode count. - SetMacroElementSeparatorVisibilityByModeCount(); - // Determine quick description visibility and content - DetermineQuickDescriptionVisibilityAndContentByApplicationMode(CurrentApplicationMode); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to handle a 'trash can' icon click: " + - ex.ToString()); - } - } - private MacroElement CreateMacroElementByApplicationMode(Mode mode) - { - // Ensure tha the application is in a valid mode to initiate this call. - if (mode == Mode.Welcome || - mode == Mode.GeneralStateConfig || - mode == Mode.RaytracingPipeline || - mode == Mode.ApplicationError) - { - postErrorMessage("A call to " + - nameof(CreateMacroElementByApplicationMode) + " was issued from an invalid application mode: " + mode); - return new MacroElement(); - } - MacroElement macroElement = new MacroElement(); - UInt32 modeCount = GetModeCount(mode); - switch (mode) - { - case Mode.Shader: - macroElement = CreateShaderConfig(modeCount); - break; - case Mode.HitGroup: - macroElement = CreateHitGroupConfig(modeCount); - break; - case Mode.LocalRootSignature: - macroElement = CreateLocalRootSignatureConfig(modeCount); - break; - case Mode.GlobalRootSignature: - macroElement = CreateGlobalRootSignatureConfig(modeCount); - break; - case Mode.ShaderPipeline: - macroElement = CreateShaderPipelineConfig(modeCount); - break; - } - if (ValidateMacroElement(macroElement)) - { - // Add the newly created element to the GUI - macroElement.targetElement.Children.Add(macroElement.rootElement); - // Register the newly created element in the global list. - Master_MacroElementList.Add(macroElement); - } - else - { - postErrorMessage("A call to " + - nameof(CreateMacroElementByApplicationMode) + " found an invalid MacroElement of mode: " + mode); - return new MacroElement(); - } - // If the target element was a grid, clean up the rows. - Grid targetGrid = macroElement.targetElement as Grid; - if (targetGrid != null) - { - CleanUpGridRows(targetGrid, mode); - } - String[] dxrScrollViewerRegisteredNames = - { - "generalStateConfigScrollViewer", - "jsonConfigScrollViewer" - }; - foreach (String name in dxrScrollViewerRegisteredNames) - { - DXRScrollViewer scrollViewer = FindName(name) as DXRScrollViewer; - if (scrollViewer != null) - { - DXRScrollViewer.ScrollCommandOrigin previousScrollOrigin = scrollViewer.scrollCommandOrigin; - scrollViewer.scrollCommandOrigin = DXRScrollViewer.ScrollCommandOrigin.SystemInitiated; - if (scrollViewer.shouldAutoScroll) - { - scrollViewer.ScrollToBottom(); - } - scrollViewer.scrollCommandOrigin = previousScrollOrigin; - } - else - { - postErrorMessage("A call to " + nameof(CreateMacroElementByApplicationMode) + - "was unable to acquire the DXRScrollViewer with registered name" + name - + ". Smart scrolling failed."); - } - } - // Change the visibility of macro element separators based on mode count. - if (macroElement.hasItemSeperator) - { - SetMacroElementSeparatorVisibilityByModeCount(); - } - return macroElement; - } - private MacroElement CreateMacroElementByCurrentApplicationMode() - { - return CreateMacroElementByApplicationMode(CurrentApplicationMode); - } - private void DetermineQuickDescriptionVisibilityAndContentByApplicationMode(Mode mode) - { - TextBlock quickDescription = FindName("quickDescription") as TextBlock; - if (quickDescription == null) - { - postErrorMessage("A call to " + - nameof(DetermineQuickDescriptionVisibilityAndContentByApplicationMode) + - " was unable to acquire the quick description text block."); - return; - } - String description = GetModeDescriptorText(mode); - if (GetModeCount(mode) == 0 && - description.Length > 0) - { - quickDescription.Text = description; - quickDescription.Visibility = Visibility.Visible; - } - else - { - quickDescription.Text = ""; - quickDescription.Visibility = Visibility.Collapsed; - } - } - readonly List Master_MacroElementListeparatorNameList = new List(); - public void CreateMacroElementSeparator(StackPanel verticalStackPanel) - { - try - { - Style separatorStyle_invisible = FindResource("separatortStyle_invisible") as Style; - if (separatorStyle_invisible == null) - { - postErrorMessage("Unable to aquire separator style."); - return; - } - Separator macroElementSeparator = new Separator() - { - Style = separatorStyle_invisible - }; - if (!WPFAssignAndRegisterName(macroElementSeparator, - nameof(macroElementSeparator) + macroElementSeparator.GetHashCode().ToString(), - Master_MacroElementListeparatorNameList)) - { - postErrorMessage("Unable to create macro element separator."); - return; - } - verticalStackPanel.Children.Add(macroElementSeparator); - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to create a macro element separator: " + - ex.ToString()); - } - } - public void SetMacroElementSeparatorVisibilityByModeCount() - { - try - { - Style separatorStyle_visible = FindResource("separatortStyle_visible") as Style; - if (separatorStyle_visible == null) - { - postErrorMessage("A call to " + nameof(SetMacroElementSeparatorVisibilityByModeCount) + - " was unable to aquire the separator style (visible)."); - return; - } - Style separatorStyle_invisible = FindResource("separatortStyle_invisible") as Style; - if (separatorStyle_invisible == null) - { - postErrorMessage("A call to " + nameof(SetMacroElementSeparatorVisibilityByModeCount) + - " was unable to aquire separator style (invisible)."); - return; - } - foreach (String separatorID in Master_MacroElementListeparatorNameList) - { - Separator separator = FindName(separatorID) as Separator; - if (separator == null) - { - postErrorMessage("A call to " + nameof(SetMacroElementSeparatorVisibilityByModeCount) + - " was unable to aquire separator with ID: " + separatorID); - return; - } - if (GetModeCount(CurrentApplicationMode) > 1) - { - separator.Style = separatorStyle_visible; - } - else - { - separator.Style = separatorStyle_invisible; - } - } - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to set the visibility on a macro element separator: " + - ex.ToString()); - } - } - public String removeButtonToolTipPartialString = "Click to remove the associated "; - public Grid GetRemoveButtonTrashCanIcon() - { - try - { - ImageSource trashCanImageSource = FindResource("trashCanImageResource") as ImageSource; - if (trashCanImageSource == null) - { - postErrorMessage("A call to " + nameof(GetRemoveButtonTrashCanIcon) + - " was unable to aquire the image source."); - return null; - } - Image trashCanImage = new Image() - { - Source = trashCanImageSource, - Width = 30, - Height = 30, - Margin = new Thickness(0, 0, 0, 0) - }; - Grid trashCanImageGrid = new Grid(); - trashCanImageGrid.Children.Add(trashCanImage); - return trashCanImageGrid; - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to retrieve a 'trash can' icon button: " + - ex.ToString()); - return null; - } - } - public String CreateMacroElementButtonRow(Grid rootGrid, FrameworkElement buttonContainer) - { - try - { - if (rootGrid == null) - { - postErrorMessage("A call to " + nameof(CreateMacroElementButtonRow) + - " was unable to acquire the root grid."); - return null; - } - if (buttonContainer == null) - { - postErrorMessage("A call to " + nameof(CreateMacroElementButtonRow) + - " was unable to acquire the button target."); - return null; - } - buttonContainer.HorizontalAlignment = HorizontalAlignment.Right; - Style separatorStyle_visible = FindResource("separatortStyle_visible") as Style; - if (separatorStyle_visible == null) - { - postErrorMessage("A call to " + nameof(CreateMacroElementButtonRow) + - " was unable to aquire the separator style (visible)."); - return null; - } - RowDefinition buttonRow = new RowDefinition() - { - Height = new GridLength(50) - }; - if (!WPFAssignAndRegisterName(buttonRow, nameof(buttonRow) + buttonRow.GetHashCode().ToString())) - { - postErrorMessage("A call to " + nameof(CreateMacroElementButtonRow) + - " was unable to register or crate a row definition."); - return null; - } - Separator separator = new Separator() - { - MinHeight = 2.5, - MaxHeight = 10, - Margin = new Thickness(0, 0, 0, 0), - Padding = new Thickness(0, 0, 0, 0) - }; - if (WPFAssignAndRegisterName(separator, nameof(separator) + separator.GetHashCode().ToString())) - { - separator.Style = separatorStyle_visible; - } - else - { - postErrorMessage("A call to " + nameof(CreateMacroElementButtonRow) + - " was unable to register or crate a separator."); - return null; - } - StackPanel sPanel = new StackPanel() - { - Orientation = Orientation.Vertical, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Stretch, - Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF1A1A1A")), - //AllowDrop = true - }; - if (WPFAssignAndRegisterName(sPanel, nameof(sPanel) + sPanel.GetHashCode().ToString())) - { - sPanel.Children.Add(separator); - sPanel.Children.Add(buttonContainer); - // Drag and drop - //sPanel.Drop += new DragEventHandler(HandleJSONDragAndDrop); - } - else - { - postErrorMessage("A call to " + nameof(CreateMacroElementButtonRow) + - " was unable to register or crate a Stack Panel."); - return null; - } - rootGrid.RowDefinitions.Add(buttonRow); - sPanel.SetValue(Grid.RowProperty, rootGrid.RowDefinitions.Count - 1); - rootGrid.Children.Add(sPanel); - return sPanel.Name; - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to create a macro element button row: " + - ex.ToString()); - return null; - } - } - public MacroElement CreateWelcomePane() - { - try - { - List nameList = new List(); - bool success = true; - RowDefinition welcomeQuickTitleRow = new RowDefinition() - { - Height = new GridLength(80) - }; - if (!WPFAssignAndRegisterName(welcomeQuickTitleRow, nameof(welcomeQuickTitleRow), nameList)) - { - postErrorMessage("Unable to create " + nameof(welcomeQuickTitleRow)); - success = false; - } - RowDefinition welcomeContentRow = new RowDefinition(); - if (!WPFAssignAndRegisterName(welcomeContentRow, nameof(welcomeContentRow), nameList)) - { - postErrorMessage("Unable to create " + nameof(welcomeContentRow)); - success = false; - } - TextBlock welcomeQuickTitle = new TextBlock() - { - Style = FindResource("quickTitleStyle") as Style, - VerticalAlignment = VerticalAlignment.Center - }; - if (WPFAssignAndRegisterName(welcomeQuickTitle, nameof(welcomeQuickTitle), nameList)) - { - welcomeQuickTitle.SetValue(Grid.RowProperty, 0); - welcomeQuickTitle.SetValue(Grid.ColumnProperty, 1); - welcomeQuickTitle.Inlines.Add("RGA DXR state editor"); - } - else - { - postErrorMessage("Unable to create " + nameof(welcomeQuickTitle)); - success = false; - } - // Welcome Pane Text Block - TextBlock welcomePaneTextblock = new TextBlock() - { - Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFFFF")), - VerticalAlignment = VerticalAlignment.Top, - HorizontalAlignment = HorizontalAlignment.Left, - MinWidth = 705, - Margin = new Thickness(20), - FontSize = 15 - }; - if (WPFAssignAndRegisterName(welcomePaneTextblock, nameof(welcomePaneTextblock), nameList)) - { - welcomePaneTextblock.SetValue(Grid.RowProperty, 1); - welcomePaneTextblock.SetValue(Grid.ColumnProperty, 1); - welcomePaneTextblock.Inlines.Add(welcomeText); - } - else - { - postErrorMessage("Unable to create " + nameof(welcomePaneTextblock)); - success = false; - } - // Welcome Pane Grid - Grid welcomePaneGrid = new Grid(); - if (WPFAssignAndRegisterName(welcomePaneGrid, nameof(welcomePaneGrid), nameList)) - { - welcomePaneGrid.RowDefinitions.Add(welcomeQuickTitleRow); - welcomePaneGrid.RowDefinitions.Add(welcomeContentRow); - welcomePaneGrid.Children.Add(welcomeQuickTitle); - welcomePaneGrid.Children.Add(welcomePaneTextblock); - } - else - { - postErrorMessage("Unable to create " + nameof(welcomePaneGrid)); - success = false; - } - MacroElement macroElement; - if (success) - { - macroElement = new MacroElement - { - applicationMode = Mode.Welcome, - rootElement = welcomePaneGrid, - targetElement = FindName("viewGrid") as Panel, - regiteredChildrenNames = nameList, - hasItemSeperator = false - }; - } - else - { - postErrorMessage("Unable to create element for mode: " + nameof(Mode.Welcome)); - macroElement = new MacroElement - { - applicationMode = Mode.ApplicationError, - rootElement = null, - targetElement = null, - regiteredChildrenNames = null - }; - } - return macroElement; - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to create the welcome pane: " + - ex.ToString()); - return new MacroElement(); - } - } - public MacroElement CreateGeneralStateConfig() - { - try - { - //SetApplicationMode(Mode.GeneralStateConfig); - List nameList = new List(); - bool success = true; - RowDefinition quickTitleRow = new RowDefinition() - { - Height = new GridLength(80) - }; - if (!WPFAssignAndRegisterName(quickTitleRow, nameof(quickTitleRow), nameList)) - { - postErrorMessage("Unable to create " + nameof(quickTitleRow)); - success = false; - } - RowDefinition contentRow = new RowDefinition(); - if (!WPFAssignAndRegisterName(contentRow, nameof(contentRow), nameList)) - { - postErrorMessage("Unable to create " + nameof(contentRow)); - success = false; - } - TextBlock quickTitle = new TextBlock() - { - Style = FindResource("quickTitleStyle") as Style - }; - if (WPFAssignAndRegisterName(quickTitle, nameof(quickTitle), nameList)) - { - quickTitle.SetValue(Grid.RowProperty, 0); - quickTitle.SetValue(Grid.ColumnProperty, 1); - } - else - { - postErrorMessage("Unable to create " + nameof(quickTitle)); - success = false; - } - TextBlock quickDescription = new TextBlock() - { - Style = FindResource("quickDescriptionStyle") as Style - }; - if (WPFAssignAndRegisterName(quickDescription, nameof(quickDescription), nameList)) - { - quickDescription.SetValue(Grid.RowProperty, 1); - quickDescription.SetValue(Grid.ColumnProperty, 1); - } - else - { - postErrorMessage("Unable to create " + nameof(quickDescription)); - success = false; - } - // General State Config Button (Add ) - Button addButton = new Button() - { - Style = FindResource("primaryButtonStyle") as Style, - Margin = new Thickness(5, 5, 5, 5), - MinWidth = 135, - MinHeight = 35, - HorizontalAlignment = HorizontalAlignment.Right, - VerticalAlignment = VerticalAlignment.Center - }; - if (WPFAssignAndRegisterName(addButton, nameof(addButton), nameList)) - { - addButton.SetValue(Grid.RowProperty, 2); - addButton.Click += new RoutedEventHandler(AddButton_Click); - } - else - { - postErrorMessage("Unable to create " + nameof(addButton)); - success = false; - } - bool contentGridSuccess = true; - Grid contentGrid = new Grid() - { - VerticalAlignment = VerticalAlignment.Top, - HorizontalAlignment = HorizontalAlignment.Stretch, - MinWidth = ContentViewSettings.ContentMinWidth, - Margin = new Thickness(0, 0, 0, 0) - }; - if (WPFAssignAndRegisterName(contentGrid, nameof(contentGrid), nameList)) - { - contentGrid.SetValue(Grid.RowProperty, 0); - } - else - { - contentGridSuccess = false; - postErrorMessage("Unable to create " + nameof(contentGrid)); - success = false; - } - DXRScrollViewer generalStateConfigScrollViewer = new DXRScrollViewer() - { - HorizontalScrollBarVisibility = ScrollBarVisibility.Auto, - VerticalScrollBarVisibility = ScrollBarVisibility.Auto, - VerticalContentAlignment = VerticalAlignment.Top, - HorizontalContentAlignment = HorizontalAlignment.Left, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top, - MinWidth = ContentViewSettings.ContentMinWidth, - Margin = new Thickness(0, 0, 5, 0) - }; - if (WPFAssignAndRegisterName(generalStateConfigScrollViewer, nameof(generalStateConfigScrollViewer), nameList)) - { - generalStateConfigScrollViewer.SetValue(Grid.ColumnProperty, 1); - generalStateConfigScrollViewer.SetValue(Grid.RowProperty, 1); - if (contentGridSuccess) - { - generalStateConfigScrollViewer.Content = contentGrid; - generalStateConfigScrollViewer.ScrollChanged += - new ScrollChangedEventHandler(HandleDXRScrollViewerScrollChanged); - } - } - else - { - postErrorMessage("Unable to create " + nameof(generalStateConfigScrollViewer)); - success = false; - } - //General State Config Grid - Grid generalStateConfigGrid = new Grid() - { - Margin = new Thickness(0, 0, 0, 0), - MinWidth = ContentViewSettings.ContentMinWidth, - HorizontalAlignment = HorizontalAlignment.Stretch - }; - if (WPFAssignAndRegisterName(generalStateConfigGrid, nameof(generalStateConfigGrid), nameList)) - { - generalStateConfigGrid.SetValue(Grid.ColumnProperty, 1); - generalStateConfigGrid.RowDefinitions.Add(quickTitleRow); - generalStateConfigGrid.RowDefinitions.Add(contentRow); - generalStateConfigGrid.Children.Add(quickTitle); - generalStateConfigGrid.Children.Add(quickDescription); - generalStateConfigGrid.Children.Add(generalStateConfigScrollViewer); - // Add default button row. - CreateMacroElementButtonRow(generalStateConfigGrid, addButton); - } - else - { - postErrorMessage("Unable to create " + nameof(generalStateConfigGrid)); - success = false; - } - MacroElement macroElement; - if (success) - { - macroElement = new MacroElement - { - applicationMode = Mode.GeneralStateConfig, - rootElement = generalStateConfigGrid, - targetElement = FindName("viewGrid") as Panel, - regiteredChildrenNames = nameList, - hasItemSeperator = false - }; - } - else - { - postErrorMessage("Unable to create element for mode: " + nameof(Mode.GeneralStateConfig)); - macroElement = new MacroElement - { - applicationMode = Mode.ApplicationError, - rootElement = null, - targetElement = null, - regiteredChildrenNames = null - }; - } - return macroElement; - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to create the general state configuration pane: " + - ex.ToString()); - return new MacroElement(); - } - } - public MacroElement CreateShaderConfig() - { - return CreateShaderConfig(0); - } - public MacroElement CreateShaderConfig(UInt32 nameModifier) - { - try - { - List nameList = new List(); - bool success = true; - // - // Type elements. - // - bool shouldAssociateshaderTypeCobmoBoxToJSON = true; - ComboBox shaderTypeComboBox = new ComboBox() - { - Margin = new Thickness(ContentViewSettings.ContentComboBoxMargin_left, - ContentViewSettings.ContentComboBoxMargin_top, - ContentViewSettings.ContentComboBoxMargin_right, - ContentViewSettings.ContentComboBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MinWidth = ContentViewSettings.ContentComboBoxMinWidth - }; - if (WPFAssignAndRegisterName(shaderTypeComboBox, nameof(shaderTypeComboBox) + nameModifier, nameList)) - { - shaderTypeComboBox.SetValue(Grid.RowProperty, 0); - shaderTypeComboBox.SetValue(Grid.ColumnProperty, 1); - shaderTypeComboBox.Style = FindResource("baseComboBoxStyle") as Style; - List shaderTypeComboBoxItems = - new List(new String[] - { - ConstStringBinaryDXILType, - ConstStringHLSLType - }); - - SetComboBoxItemContent(shaderTypeComboBox, shaderTypeComboBoxItems); - } - else - { - postErrorMessage("Unable to create " + nameof(shaderTypeComboBox) + nameModifier); - shouldAssociateshaderTypeCobmoBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label shaderTypeLabel = new Label() - { - Content = "Type", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(shaderTypeComboBox)) as UIElement - }; - if (WPFAssignAndRegisterName(shaderTypeLabel, nameof(shaderTypeLabel) + nameModifier, nameList)) - { - shaderTypeLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(shaderTypeLabel) + nameModifier); - success = false; - } - StackPanel shaderTypeStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(shaderTypeStackPanel, nameof(shaderTypeStackPanel) + nameModifier, nameList)) - { - shaderTypeStackPanel.Children.Add(shaderTypeLabel); - shaderTypeStackPanel.Children.Add(shaderTypeComboBox); - } - else - { - postErrorMessage("Unable to create " + nameof(shaderTypeStackPanel) + nameModifier); - success = false; - } - // - // Entry point elements - // - bool shouldAssociateEntryPointTextBoxtoJSON = true; - TextBox shaderEntryPointTextBox = new TextBox() - { - Style = FindResource("baseTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - }; - if (WPFAssignAndRegisterName(shaderEntryPointTextBox, nameof(shaderEntryPointTextBox) + nameModifier, nameList)) - { - shaderEntryPointTextBox.SetValue(Grid.RowProperty, 0); - shaderEntryPointTextBox.SetValue(Grid.ColumnProperty, 1); - shaderEntryPointTextBox.ToolTip = shaderEntryPointToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(shaderEntryPointTextBox) + nameModifier); - shouldAssociateEntryPointTextBoxtoJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label shaderEntryPointLabel = new Label() - { - Content = "Entry point(s)", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(shaderEntryPointTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(shaderEntryPointLabel, nameof(shaderEntryPointLabel) + nameModifier, nameList)) - { - shaderEntryPointLabel.SetValue(Grid.ColumnProperty, 0); - shaderEntryPointLabel.ToolTip = shaderEntryPointToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(shaderEntryPointLabel) + nameModifier); - success = false; - } - StackPanel shaderEntryPointStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(shaderEntryPointStackPanel, nameof(shaderEntryPointStackPanel) + nameModifier, nameList)) - { - shaderEntryPointStackPanel.Children.Add(shaderEntryPointLabel); - shaderEntryPointStackPanel.Children.Add(shaderEntryPointTextBox); - } - else - { - postErrorMessage("Unable to create " + nameof(shaderEntryPointStackPanel) + nameModifier); - success = false; - } - // - // File path elements. - // - bool shouldAssociateFilePathTextBoxtoJSON = true; - bool shouldConnectShaderFilePathBrowseButton = true; - Button shaderFilePathBrowseButton = new Button() - { - Style = FindResource("browseButtonStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentBrowseButtonMargin_left, - ContentViewSettings.ContentBrowseButtonMargin_top, - ContentViewSettings.ContentBrowseButtonMargin_right, - ContentViewSettings.ContentBrowseButtonMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - Width = ContentViewSettings.ContentBrowseButtonWidth - }; - if (!WPFAssignAndRegisterName(shaderFilePathBrowseButton, nameof(shaderFilePathBrowseButton) + nameModifier, nameList)) - { - shouldConnectShaderFilePathBrowseButton = false; - postErrorMessage("Unable to create " + nameof(shaderFilePathBrowseButton) + nameModifier); - success = false; - } - TextBox shaderFilePathTextBox = new TextBox() - { - Style = FindResource("defaultYetInvalidTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - }; - if (WPFAssignAndRegisterName(shaderFilePathTextBox, nameof(shaderFilePathTextBox) + nameModifier, nameList)) - { - if (shouldConnectShaderFilePathBrowseButton) - { - shaderFilePathBrowseButton.Click += new RoutedEventHandler(BrowseForFilePath); - shaderFilePathBrowseButton.Tag = shaderFilePathTextBox.Name; - } - shaderFilePathTextBox.SetValue(Grid.ColumnProperty, 1); - shaderFilePathTextBox.ToolTip = shaderFilePathToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(shaderFilePathTextBox) + nameModifier); - success = false; - shouldAssociateFilePathTextBoxtoJSON = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label shaderFilePathLabel = new Label() - { - Content = "File path", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(shaderFilePathTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(shaderFilePathLabel, nameof(shaderFilePathLabel) + nameModifier, nameList)) - { - shaderFilePathLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(shaderFilePathLabel) + nameModifier); - success = false; - } - StackPanel shaderFilePathStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(shaderFilePathStackPanel, nameof(shaderFilePathStackPanel) + nameModifier, nameList)) - { - shaderFilePathStackPanel.Children.Add(shaderFilePathLabel); - shaderFilePathStackPanel.Children.Add(shaderFilePathTextBox); - shaderFilePathStackPanel.Children.Add(shaderFilePathBrowseButton); - } - else - { - postErrorMessage("Unable to create " + nameof(shaderFilePathStackPanel) + nameModifier); - success = false; - } - StackPanel shaderVerticalStackPanel = new StackPanel() - { - HorizontalAlignment = HorizontalAlignment.Stretch - }; - if (WPFAssignAndRegisterName(shaderVerticalStackPanel, nameof(shaderVerticalStackPanel) + nameModifier, nameList)) - { - // Add separator. - CreateMacroElementSeparator(shaderVerticalStackPanel); - shaderVerticalStackPanel.SetValue(Grid.ColumnProperty, 0); - shaderVerticalStackPanel.Children.Add(shaderTypeStackPanel); - shaderVerticalStackPanel.Children.Add(shaderFilePathStackPanel); - shaderVerticalStackPanel.Children.Add(shaderEntryPointStackPanel); - } - else - { - postErrorMessage("Unable to create " + nameof(shaderVerticalStackPanel) + nameModifier); - success = false; - } - // - // Top level elements. - // - bool shouldConnectButtonEvent = true; - Button shaderRemoveItemButton = new Button() - { - Style = FindResource("removeItemButtonStyle") as Style, - Content = GetRemoveButtonTrashCanIcon(), - Margin = new Thickness(ContentViewSettings.ContentRemoveButton_withoutBrowse_withTextBox_MarginLeft, 0, 0, - ContentViewSettings.ContentRemoveButton_withoutBrowse_withTextBox_MarginBottom) - }; - if (WPFAssignAndRegisterName(shaderRemoveItemButton, nameof(shaderRemoveItemButton) + nameModifier, nameList)) - { - shaderRemoveItemButton.SetValue(Grid.ColumnProperty, 1); - shaderRemoveItemButton.ToolTip = removeButtonToolTipPartialString + GetModeAsText(Mode.Shader); - } - else - { - shouldConnectButtonEvent = false; - postErrorMessage("Unable to create " + nameof(shaderRemoveItemButton) + nameModifier); - success = false; - } - ColumnDefinition shaderLabelAndTextboxCol = new ColumnDefinition() - { - Width = new GridLength(1.0, GridUnitType.Auto), - MinWidth = 100 - }; - if (!WPFAssignAndRegisterName(shaderLabelAndTextboxCol, nameof(shaderLabelAndTextboxCol) + nameModifier, nameList)) - { - postErrorMessage("Unable to create " + nameof(shaderLabelAndTextboxCol) + nameModifier); - success = false; - } - Grid shaderModeRootElement = new Grid() - { - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top, - }; - if (WPFAssignAndRegisterName(shaderModeRootElement, nameof(shaderModeRootElement) + nameModifier, nameList)) - { - String macroElementID = nameof(shaderModeRootElement) + nameModifier; - shaderModeRootElement.ColumnDefinitions.Add(shaderLabelAndTextboxCol); - shaderModeRootElement.Children.Add(shaderVerticalStackPanel); - shaderModeRootElement.Tag = macroElementID; - // Associate button mechanics. - if (shouldConnectButtonEvent) - { - // Tuple layout: - shaderRemoveItemButton.Tag = macroElementID; - shaderRemoveItemButton.Click += new RoutedEventHandler(HandleTrashcanIconClick); - shaderTypeStackPanel.Children.Add(shaderRemoveItemButton); - } - // Associate JSON mechanics - if (shouldAssociateEntryPointTextBoxtoJSON) - { - shaderEntryPointTextBox.Tag = macroElementID; - shaderEntryPointTextBox.TextChanged += - new TextChangedEventHandler(AddShaderEntryPointByID); - } - if (shouldAssociateFilePathTextBoxtoJSON) - { - shaderFilePathTextBox.Tag = macroElementID; - shaderFilePathTextBox.Text = defaultYetInvalidFilePathString; - shaderFilePathTextBox.TextChanged += - new TextChangedEventHandler(AddShaderFilePathByID); - shaderFilePathTextBox.GotFocus += ClearDefaultFilePathText; - } - if (shouldAssociateshaderTypeCobmoBoxToJSON) - { - shaderTypeComboBox.Tag = macroElementID; - shaderTypeComboBox.SelectionChanged += - new SelectionChangedEventHandler(AddShaderTypeByID); - Mode previousApplicationMode = CurrentApplicationMode; - SetApplicationMode(Mode.Shader); - shaderTypeComboBox.SelectedValue = shaderTypeComboBox.Items[0]; - SetApplicationMode(previousApplicationMode); - } - } - else - { - shouldConnectButtonEvent = false; - postErrorMessage("Unable to create " + nameof(shaderModeRootElement) + nameModifier); - success = false; - } - MacroElement macroElement; - if (success) - { - ModeCount.ShaderCount++; - macroElement = new MacroElement - { - applicationMode = Mode.Shader, - rootElement = shaderModeRootElement, - targetElement = FindName("contentGrid") as Panel, - regiteredChildrenNames = nameList, - hasItemSeperator = true - }; - } - else - { - postErrorMessage("Unable to create element for mode: " + nameof(Mode.Shader)); - macroElement = new MacroElement - { - applicationMode = Mode.ApplicationError, - rootElement = null, - targetElement = null, - regiteredChildrenNames = null - }; - } - return macroElement; - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to create the shader configuration pane: " + - ex.ToString()); - return new MacroElement(); - } - } - public MacroElement CreateHitGroupConfig() - { - return CreateHitGroupConfig(0); - } - public MacroElement CreateHitGroupConfig(UInt32 nameModifier) - { - try - { - List nameList = new List(); - bool success = true; - // - // Type elements. - // - bool shouldAssociateTypeComboBoxToJSON = true; - ComboBox hitGroupTypeComboBox = new ComboBox() - { - Margin = new Thickness(ContentViewSettings.ContentComboBoxMargin_left, - ContentViewSettings.ContentComboBoxMargin_top, - ContentViewSettings.ContentComboBoxMargin_right, - ContentViewSettings.ContentComboBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MinWidth = ContentViewSettings.ContentComboBoxMinWidth - }; - if (WPFAssignAndRegisterName(hitGroupTypeComboBox, nameof(hitGroupTypeComboBox) + nameModifier, nameList)) - { - hitGroupTypeComboBox.SetValue(Grid.RowProperty, 0); - hitGroupTypeComboBox.SetValue(Grid.ColumnProperty, 1); - hitGroupTypeComboBox.Style = FindResource("baseComboBoxStyle") as Style; - List hitGroupTypeComboBoxItems = - new List(new String[] - { - "D3D12_HIT_GROUP_TYPE_TRIANGLES" - }); - - SetComboBoxItemContent(hitGroupTypeComboBox, hitGroupTypeComboBoxItems); - } - else - { - postErrorMessage("Unable to create " + nameof(hitGroupTypeComboBox) + nameModifier); - shouldAssociateTypeComboBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label hitGroupTypeLabel = new Label() - { - Content = "Type", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(hitGroupTypeComboBox)) as UIElement - }; - if (WPFAssignAndRegisterName(hitGroupTypeLabel, nameof(hitGroupTypeLabel) + nameModifier, nameList)) - { - hitGroupTypeLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(hitGroupTypeLabel) + nameModifier); - success = false; - } - StackPanel hitGroupTypeStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(hitGroupTypeStackPanel, nameof(hitGroupTypeStackPanel) + nameModifier, nameList)) - { - hitGroupTypeStackPanel.Children.Add(hitGroupTypeLabel); - hitGroupTypeStackPanel.Children.Add(hitGroupTypeComboBox); - } - else - { - postErrorMessage("Unable to create " + nameof(hitGroupTypeStackPanel) + nameModifier); - success = false; - } - // - // Name elements. - // - bool shouldAssociateNameTextBoxToJSON = true; - TextBox hitGroupNameTextBox = new TextBox() - { - Style = FindResource("baseTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - }; - if (WPFAssignAndRegisterName(hitGroupNameTextBox, nameof(hitGroupNameTextBox) + nameModifier, nameList)) - { - hitGroupNameTextBox.SetValue(Grid.RowProperty, 0); - hitGroupNameTextBox.SetValue(Grid.ColumnProperty, 1); - hitGroupNameTextBox.ToolTip = hitGroupNameToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(hitGroupNameTextBox) + nameModifier); - shouldAssociateNameTextBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label hitGroupNameLabel = new Label() - { - Content = "Name", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(hitGroupNameTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(hitGroupNameLabel, nameof(hitGroupNameLabel) + nameModifier, nameList)) - { - hitGroupNameLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(hitGroupNameLabel) + nameModifier); - success = false; - } - StackPanel hitGroupNameStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(hitGroupNameStackPanel, nameof(hitGroupNameStackPanel) + nameModifier, nameList)) - { - hitGroupNameStackPanel.Children.Add(hitGroupNameLabel); - hitGroupNameStackPanel.Children.Add(hitGroupNameTextBox); - } - else - { - postErrorMessage("Unable to create " + nameof(hitGroupNameStackPanel) + nameModifier); - success = false; - } - // - // Intersection shader elements. - // - bool shouldAssociateIntersectionShaderTextBoxToJSON = true; - TextBox hitGroupIntersectionShaderTextBox = new TextBox() - { - Style = FindResource("baseTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - }; - if (WPFAssignAndRegisterName(hitGroupIntersectionShaderTextBox, nameof(hitGroupIntersectionShaderTextBox) + nameModifier, nameList)) - { - hitGroupIntersectionShaderTextBox.SetValue(Grid.RowProperty, 0); - hitGroupIntersectionShaderTextBox.SetValue(Grid.ColumnProperty, 1); - hitGroupIntersectionShaderTextBox.ToolTip = hitGroupIntersectionShaderToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(hitGroupIntersectionShaderTextBox) + nameModifier); - success = false; - shouldAssociateIntersectionShaderTextBoxToJSON = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label hitGroupIntersectionShaderLabel = new Label() - { - Content = "Intersection shader", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(hitGroupIntersectionShaderTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(hitGroupIntersectionShaderLabel, nameof(hitGroupIntersectionShaderLabel) + nameModifier, nameList)) - { - hitGroupIntersectionShaderLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(hitGroupIntersectionShaderLabel) + nameModifier); - success = false; - } - StackPanel hitGroupIntersectionShaderStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(hitGroupIntersectionShaderStackPanel, nameof(hitGroupIntersectionShaderStackPanel) + nameModifier, nameList)) - { - hitGroupIntersectionShaderStackPanel.Children.Add(hitGroupIntersectionShaderLabel); - hitGroupIntersectionShaderStackPanel.Children.Add(hitGroupIntersectionShaderTextBox); - } - else - { - postErrorMessage("Unable to create " + nameof(hitGroupIntersectionShaderStackPanel) + nameModifier); - success = false; - } - // - // Any hit shader elements. - // - bool shouldAssociateAnyHitShaderTextBoxToJSON = true; - TextBox hitGroupAnyHitShaderTextBox = new TextBox() - { - Style = FindResource("baseTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - }; - if (WPFAssignAndRegisterName(hitGroupAnyHitShaderTextBox, nameof(hitGroupAnyHitShaderTextBox) + nameModifier, nameList)) - { - hitGroupAnyHitShaderTextBox.SetValue(Grid.RowProperty, 0); - hitGroupAnyHitShaderTextBox.SetValue(Grid.ColumnProperty, 1); - hitGroupAnyHitShaderTextBox.ToolTip = hitGroupAnyHitShaderToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(hitGroupAnyHitShaderTextBox) + nameModifier); - success = false; - shouldAssociateAnyHitShaderTextBoxToJSON = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label hitGroupAnyHitShaderLabel = new Label() - { - Content = "Any hit shader", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(hitGroupAnyHitShaderTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(hitGroupAnyHitShaderLabel, nameof(hitGroupAnyHitShaderLabel) + nameModifier, nameList)) - { - hitGroupAnyHitShaderLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(hitGroupAnyHitShaderLabel) + nameModifier); - success = false; - } - StackPanel hitGroupAnyHitShaderStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(hitGroupAnyHitShaderStackPanel, nameof(hitGroupAnyHitShaderStackPanel) + nameModifier, nameList)) - { - hitGroupAnyHitShaderStackPanel.Children.Add(hitGroupAnyHitShaderLabel); - hitGroupAnyHitShaderStackPanel.Children.Add(hitGroupAnyHitShaderTextBox); - } - else - { - postErrorMessage("Unable to create " + nameof(hitGroupAnyHitShaderStackPanel) + nameModifier); - success = false; - } - // - // Closest hit shader elements. - // - bool shouldAssociateClosestHitShaderTextBoxToJSON = true; - TextBox hitGroupClosestHitShaderTextBox = new TextBox() - { - Style = FindResource("baseTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - }; - if (WPFAssignAndRegisterName(hitGroupClosestHitShaderTextBox, nameof(hitGroupClosestHitShaderTextBox) + nameModifier, nameList)) - { - hitGroupClosestHitShaderTextBox.SetValue(Grid.RowProperty, 0); - hitGroupClosestHitShaderTextBox.SetValue(Grid.ColumnProperty, 1); - hitGroupClosestHitShaderTextBox.ToolTip = hitGroupClosestHitShaderToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(hitGroupClosestHitShaderTextBox) + nameModifier); - shouldAssociateClosestHitShaderTextBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label hitGroupClosestHitShaderLabel = new Label() - { - Content = "Closest hit shader", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(hitGroupClosestHitShaderTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(hitGroupClosestHitShaderLabel, nameof(hitGroupClosestHitShaderLabel) + nameModifier, nameList)) - { - hitGroupClosestHitShaderLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(hitGroupClosestHitShaderLabel) + nameModifier); - success = false; - } - StackPanel hitGroupClosestHitShaderStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(hitGroupClosestHitShaderStackPanel, nameof(hitGroupClosestHitShaderStackPanel) + nameModifier, nameList)) - { - hitGroupClosestHitShaderStackPanel.Children.Add(hitGroupClosestHitShaderLabel); - hitGroupClosestHitShaderStackPanel.Children.Add(hitGroupClosestHitShaderTextBox); - } - else - { - postErrorMessage("Unable to create " + nameof(hitGroupClosestHitShaderStackPanel) + nameModifier); - success = false; - } - // - // Vertical Stack Panel - // - StackPanel hitGroupVerticalStackPanel = new StackPanel() - { - Orientation = Orientation.Vertical, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top, - MinWidth = ContentViewSettings.ContentMinWidth - }; - if (WPFAssignAndRegisterName(hitGroupVerticalStackPanel, nameof(hitGroupVerticalStackPanel) + nameModifier, nameList)) - { - // Add separator. - CreateMacroElementSeparator(hitGroupVerticalStackPanel); - hitGroupVerticalStackPanel.Children.Add(hitGroupTypeStackPanel); - hitGroupVerticalStackPanel.Children.Add(hitGroupNameStackPanel); - hitGroupVerticalStackPanel.Children.Add(hitGroupIntersectionShaderStackPanel); - hitGroupVerticalStackPanel.Children.Add(hitGroupAnyHitShaderStackPanel); - hitGroupVerticalStackPanel.Children.Add(hitGroupClosestHitShaderStackPanel); - hitGroupVerticalStackPanel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(hitGroupVerticalStackPanel) + nameModifier); - success = false; - } - // - // Top level elements. - // - bool shouldConnectButtonEvent = true; - Button hitGroupRemoveItemButton = new Button() - { - Style = FindResource("removeItemButtonStyle") as Style, - Content = GetRemoveButtonTrashCanIcon(), - Margin = new Thickness(ContentViewSettings.ContentRemoveButton_withoutBrowse_withTextBox_MarginLeft, 0, 0, - ContentViewSettings.ContentRemoveButton_withoutBrowse_withTextBox_MarginBottom) - }; - if (WPFAssignAndRegisterName(hitGroupRemoveItemButton, nameof(hitGroupRemoveItemButton) + nameModifier, nameList)) - { - hitGroupRemoveItemButton.SetValue(Grid.ColumnProperty, 1); - hitGroupRemoveItemButton.ToolTip = removeButtonToolTipPartialString + GetModeAsText(Mode.HitGroup); - } - else - { - shouldConnectButtonEvent = false; - postErrorMessage("Unable to create " + nameof(hitGroupRemoveItemButton) + nameModifier); - success = false; - } - ColumnDefinition hitGroupLabelAndTextboxCol = new ColumnDefinition() - { - Width = new GridLength(1.0, GridUnitType.Auto), - MinWidth = 100 - }; - if (!WPFAssignAndRegisterName(hitGroupLabelAndTextboxCol, nameof(hitGroupLabelAndTextboxCol) + nameModifier, nameList)) - { - postErrorMessage("Unable to create " + nameof(hitGroupLabelAndTextboxCol) + nameModifier); - success = false; - } - Grid hitGroupModeRootElement = new Grid() - { - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top, - }; - if (WPFAssignAndRegisterName(hitGroupModeRootElement, nameof(hitGroupModeRootElement) + nameModifier, nameList)) - { - String macroElementID = nameof(hitGroupModeRootElement) + nameModifier; - hitGroupModeRootElement.ColumnDefinitions.Add(hitGroupLabelAndTextboxCol); - hitGroupModeRootElement.Children.Add(hitGroupVerticalStackPanel); - hitGroupModeRootElement.Tag = macroElementID; - // Associate button mechanics. - if (shouldConnectButtonEvent) - { - // Tuple layout: - hitGroupRemoveItemButton.Tag = macroElementID; - hitGroupRemoveItemButton.Click += new RoutedEventHandler(HandleTrashcanIconClick); - hitGroupTypeStackPanel.Children.Add(hitGroupRemoveItemButton); - } - // Associate JSON mechanics. - if (shouldAssociateTypeComboBoxToJSON) - { - hitGroupTypeComboBox.Tag = macroElementID; - hitGroupTypeComboBox.SelectionChanged += new SelectionChangedEventHandler(AddHitGroupTypeByID); - Mode previousApplicationMode = CurrentApplicationMode; - SetApplicationMode(Mode.HitGroup); - hitGroupTypeComboBox.SelectedValue = hitGroupTypeComboBox.Items[0]; - SetApplicationMode(previousApplicationMode); - } - if (shouldAssociateNameTextBoxToJSON) - { - hitGroupNameTextBox.Tag = macroElementID; - hitGroupNameTextBox.TextChanged += - new TextChangedEventHandler(AddHitGroupNameByID); - hitGroupNameTextBox.Text = "HitGroup" + nameModifier; - } - if (shouldAssociateIntersectionShaderTextBoxToJSON) - { - hitGroupIntersectionShaderTextBox.Tag = macroElementID; - hitGroupIntersectionShaderTextBox.TextChanged += new TextChangedEventHandler(AddHitGroupIntersectionShaderByID); - } - if (shouldAssociateAnyHitShaderTextBoxToJSON) - { - hitGroupAnyHitShaderTextBox.Tag = macroElementID; - hitGroupAnyHitShaderTextBox.TextChanged += new TextChangedEventHandler(AddHitGroupAnyHitShaderByID); - } - if (shouldAssociateClosestHitShaderTextBoxToJSON) - { - hitGroupClosestHitShaderTextBox.Tag = macroElementID; - hitGroupClosestHitShaderTextBox.TextChanged += new TextChangedEventHandler(AddHitGroupClosestHitShaderByID); - } - } - else - { - shouldConnectButtonEvent = false; - postErrorMessage("Unable to create " + nameof(hitGroupModeRootElement) + nameModifier); - success = false; - } - MacroElement macroElement; - if (success) - { - ModeCount.HitGroupCount++; - macroElement = new MacroElement - { - applicationMode = Mode.HitGroup, - rootElement = hitGroupModeRootElement, - targetElement = FindName("contentGrid") as Panel, - regiteredChildrenNames = nameList, - hasItemSeperator = true - }; - } - else - { - postErrorMessage("Unable to create element for mode: " + nameof(Mode.HitGroup)); - macroElement = new MacroElement - { - applicationMode = Mode.ApplicationError, - rootElement = null, - targetElement = null, - regiteredChildrenNames = null - }; - } - return macroElement; - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to create the hit group configuration pane: " + - ex.ToString()); - return new MacroElement(); - } - } - public MacroElement CreateLocalRootSignatureConfig() - { - return CreateLocalRootSignatureConfig(0); - } - public MacroElement CreateLocalRootSignatureConfig(UInt32 nameModifier) - { - try - { - List nameList = new List(); - bool success = true; - // - // Type elements. - // - bool shouldAssociateLocalRootSignatureTypeCobmoBoxToJSON = true; - ComboBox localRootSignaturesTypeComboBox = new ComboBox() - { - Margin = new Thickness(ContentViewSettings.ContentComboBoxMargin_left, - ContentViewSettings.ContentComboBoxMargin_top, - ContentViewSettings.ContentComboBoxMargin_right, - ContentViewSettings.ContentComboBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MinWidth = ContentViewSettings.ContentComboBoxMinWidth - }; - if (WPFAssignAndRegisterName(localRootSignaturesTypeComboBox, nameof(localRootSignaturesTypeComboBox) + nameModifier, nameList)) - { - localRootSignaturesTypeComboBox.SetValue(Grid.RowProperty, 0); - localRootSignaturesTypeComboBox.SetValue(Grid.ColumnProperty, 1); - localRootSignaturesTypeComboBox.Style = FindResource("baseComboBoxStyle") as Style; - List localRootSignatureTypeComboBoxItems = - new List(new String[] - { - ConstStringBinaryDXILType - }); - - SetComboBoxItemContent(localRootSignaturesTypeComboBox, localRootSignatureTypeComboBoxItems); - } - else - { - postErrorMessage("Unable to create " + nameof(localRootSignaturesTypeComboBox) + nameModifier); - shouldAssociateLocalRootSignatureTypeCobmoBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label localRootSignaturesTypeLabel = new Label() - { - Content = "Type", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(localRootSignaturesTypeComboBox)) as UIElement - }; - if (WPFAssignAndRegisterName(localRootSignaturesTypeLabel, nameof(localRootSignaturesTypeLabel) + nameModifier, nameList)) - { - localRootSignaturesTypeLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(localRootSignaturesTypeLabel) + nameModifier); - success = false; - } - StackPanel localRootSignaturesTypeStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(localRootSignaturesTypeStackPanel, nameof(localRootSignaturesTypeStackPanel) + nameModifier, nameList)) - { - localRootSignaturesTypeStackPanel.Children.Add(localRootSignaturesTypeLabel); - localRootSignaturesTypeStackPanel.Children.Add(localRootSignaturesTypeComboBox); - } - else - { - postErrorMessage("Unable to create " + nameof(localRootSignaturesTypeStackPanel) + nameModifier); - success = false; - } - // - // File path elements. - // - bool shouldConnectlocalRootSignaturesFilePathBrowseButton = true; - Button localRootSignaturesFilePathBrowseButton = new Button() - { - Style = FindResource("browseButtonStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentBrowseButtonMargin_left, - ContentViewSettings.ContentBrowseButtonMargin_top, - ContentViewSettings.ContentBrowseButtonMargin_right, - ContentViewSettings.ContentBrowseButtonMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - Width = ContentViewSettings.ContentBrowseButtonWidth - }; - if (!WPFAssignAndRegisterName(localRootSignaturesFilePathBrowseButton, nameof(localRootSignaturesFilePathBrowseButton) + nameModifier, nameList)) - { - shouldConnectlocalRootSignaturesFilePathBrowseButton = false; - postErrorMessage("Unable to create " + nameof(localRootSignaturesFilePathBrowseButton) + nameModifier); - success = false; - } - bool shouldAssociateLocalRootSignatureFilepathTextBoxToJSON = true; - TextBox localRootSignaturesFilePathTextBox = new TextBox() - { - Style = FindResource("defaultYetInvalidTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - }; - if (WPFAssignAndRegisterName(localRootSignaturesFilePathTextBox, nameof(localRootSignaturesFilePathTextBox) + nameModifier, nameList)) - { - if (shouldConnectlocalRootSignaturesFilePathBrowseButton) - { - localRootSignaturesFilePathBrowseButton.Click += new RoutedEventHandler(BrowseForFilePath); - localRootSignaturesFilePathBrowseButton.Tag = localRootSignaturesFilePathTextBox.Name; - } - localRootSignaturesFilePathTextBox.SetValue(Grid.ColumnProperty, 1); - localRootSignaturesFilePathTextBox.ToolTip = localRootSignaturesFilePathToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(localRootSignaturesFilePathTextBox) + nameModifier); - shouldAssociateLocalRootSignatureFilepathTextBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label localRootSignaturesFilePathLabel = new Label() - { - Content = "File path", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(localRootSignaturesFilePathTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(localRootSignaturesFilePathLabel, nameof(localRootSignaturesFilePathLabel) + nameModifier, nameList)) - { - localRootSignaturesFilePathLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(localRootSignaturesFilePathLabel) + nameModifier); - success = false; - } - StackPanel localRootSignaturesFilePathStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(localRootSignaturesFilePathStackPanel, nameof(localRootSignaturesFilePathStackPanel) + nameModifier, nameList)) - { - localRootSignaturesFilePathStackPanel.Children.Add(localRootSignaturesFilePathLabel); - localRootSignaturesFilePathStackPanel.Children.Add(localRootSignaturesFilePathTextBox); - localRootSignaturesFilePathStackPanel.Children.Add(localRootSignaturesFilePathBrowseButton); - } - else - { - postErrorMessage("Unable to create " + nameof(localRootSignaturesFilePathStackPanel) + nameModifier); - success = false; - } - // - // Macro Name shader elements. - // - bool shouldAssociateLocalRootSignatureMacroNameShaderTextBoxToJSON = true; - TextBox localRootSignaturesMacroNameShaderTextBox = new TextBox() - { - Style = FindResource("baseTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - }; - if (WPFAssignAndRegisterName(localRootSignaturesMacroNameShaderTextBox, nameof(localRootSignaturesMacroNameShaderTextBox) + nameModifier, nameList)) - { - localRootSignaturesMacroNameShaderTextBox.SetValue(Grid.RowProperty, 0); - localRootSignaturesMacroNameShaderTextBox.SetValue(Grid.ColumnProperty, 1); - localRootSignaturesMacroNameShaderTextBox.ToolTip = localRootSignaturesMacroNameShaderToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(localRootSignaturesMacroNameShaderTextBox) + nameModifier); - shouldAssociateLocalRootSignatureMacroNameShaderTextBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label localRootSignaturesMacroNameShaderLabel = new Label() - { - Content = "Macro name (HLSL)", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(localRootSignaturesMacroNameShaderTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(localRootSignaturesMacroNameShaderLabel, nameof(localRootSignaturesMacroNameShaderLabel) + nameModifier, nameList)) - { - localRootSignaturesMacroNameShaderLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(localRootSignaturesMacroNameShaderLabel) + nameModifier); - success = false; - } - StackPanel localRootSignaturesMacroNameShaderStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top, - // Note: Needs to be visible/settable in the JSON representation, but not - // editable by the user for the time being. - Visibility = Visibility.Collapsed - }; - if (WPFAssignAndRegisterName(localRootSignaturesMacroNameShaderStackPanel, nameof(localRootSignaturesMacroNameShaderStackPanel) + nameModifier, nameList)) - { - localRootSignaturesMacroNameShaderStackPanel.Children.Add(localRootSignaturesMacroNameShaderLabel); - localRootSignaturesMacroNameShaderStackPanel.Children.Add(localRootSignaturesMacroNameShaderTextBox); - } - else - { - postErrorMessage("Unable to create " + nameof(localRootSignaturesMacroNameShaderStackPanel) + nameModifier); - success = false; - } - // - // Exports elements. - // - bool shouldAssociateLocalRootSignatureExportsTextBoxToJSON = true; - TextBox localRootSignaturesExportsTextBox = new TextBox() - { - Style = FindResource("baseTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - }; - if (WPFAssignAndRegisterName(localRootSignaturesExportsTextBox, nameof(localRootSignaturesExportsTextBox) + nameModifier, nameList)) - { - localRootSignaturesExportsTextBox.SetValue(Grid.RowProperty, 0); - localRootSignaturesExportsTextBox.SetValue(Grid.ColumnProperty, 1); - localRootSignaturesExportsTextBox.ToolTip = localRootSignaturesExportsToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(localRootSignaturesExportsTextBox) + nameModifier); - shouldAssociateLocalRootSignatureExportsTextBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label localRootSignaturesExportsLabel = new Label() - { - Content = "Exports", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(localRootSignaturesExportsTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(localRootSignaturesExportsLabel, nameof(localRootSignaturesExportsLabel) + nameModifier, nameList)) - { - localRootSignaturesExportsLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(localRootSignaturesExportsLabel) + nameModifier); - success = false; - } - StackPanel localRootSignaturesExportsStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(localRootSignaturesExportsStackPanel, nameof(localRootSignaturesExportsStackPanel) + nameModifier, nameList)) - { - localRootSignaturesExportsStackPanel.Children.Add(localRootSignaturesExportsLabel); - localRootSignaturesExportsStackPanel.Children.Add(localRootSignaturesExportsTextBox); - } - else - { - postErrorMessage("Unable to create " + nameof(localRootSignaturesExportsStackPanel) + nameModifier); - success = false; - } - // - // Vertical Stack Panel - // - StackPanel localRootSignaturesVerticalStackPanel = new StackPanel() - { - Orientation = Orientation.Vertical, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top, - MinWidth = ContentViewSettings.ContentMinWidth - }; - if (WPFAssignAndRegisterName(localRootSignaturesVerticalStackPanel, nameof(localRootSignaturesVerticalStackPanel) + nameModifier, nameList)) - { - // Add separator. - CreateMacroElementSeparator(localRootSignaturesVerticalStackPanel); - localRootSignaturesVerticalStackPanel.Children.Add(localRootSignaturesTypeStackPanel); - localRootSignaturesVerticalStackPanel.Children.Add(localRootSignaturesFilePathStackPanel); - localRootSignaturesVerticalStackPanel.Children.Add(localRootSignaturesMacroNameShaderStackPanel); - localRootSignaturesVerticalStackPanel.Children.Add(localRootSignaturesExportsStackPanel); - localRootSignaturesVerticalStackPanel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(localRootSignaturesVerticalStackPanel) + nameModifier); - success = false; - } - // - // Top level elements. - // - bool shouldConnectButtonEvent = true; - Button localRootSignaturesRemoveItemButton = new Button() - { - Style = FindResource("removeItemButtonStyle") as Style, - Content = GetRemoveButtonTrashCanIcon(), - Margin = new Thickness(ContentViewSettings.ContentRemoveButton_withoutBrowse_withTextBox_MarginLeft, 0, 0, - ContentViewSettings.ContentRemoveButton_withoutBrowse_withTextBox_MarginBottom) - }; - if (WPFAssignAndRegisterName(localRootSignaturesRemoveItemButton, nameof(localRootSignaturesRemoveItemButton) + nameModifier, nameList)) - { - localRootSignaturesRemoveItemButton.SetValue(Grid.ColumnProperty, 1); - localRootSignaturesRemoveItemButton.ToolTip = removeButtonToolTipPartialString + GetModeAsText(Mode.LocalRootSignature); - } - else - { - shouldConnectButtonEvent = false; - postErrorMessage("Unable to create " + nameof(localRootSignaturesRemoveItemButton) + nameModifier); - success = false; - } - ColumnDefinition localRootSignaturesLabelAndTextboxCol = new ColumnDefinition() - { - Width = new GridLength(1.0, GridUnitType.Auto), - MinWidth = 100 - }; - if (!WPFAssignAndRegisterName(localRootSignaturesLabelAndTextboxCol, nameof(localRootSignaturesLabelAndTextboxCol) + nameModifier, nameList)) - { - postErrorMessage("Unable to create " + nameof(localRootSignaturesLabelAndTextboxCol) + nameModifier); - success = false; - } - Grid localRootSignaturesModeRootElement = new Grid() - { - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(localRootSignaturesModeRootElement, nameof(localRootSignaturesModeRootElement) + nameModifier, nameList)) - { - String macroElementID = nameof(localRootSignaturesModeRootElement) + nameModifier; - localRootSignaturesModeRootElement.ColumnDefinitions.Add(localRootSignaturesLabelAndTextboxCol); - localRootSignaturesModeRootElement.Children.Add(localRootSignaturesVerticalStackPanel); - localRootSignaturesModeRootElement.Tag = macroElementID; - // Associate button mechanics. - if (shouldConnectButtonEvent) - { - // Tuple layout: - localRootSignaturesRemoveItemButton.Tag = macroElementID; - localRootSignaturesRemoveItemButton.Click += new RoutedEventHandler(HandleTrashcanIconClick); - localRootSignaturesTypeStackPanel.Children.Add(localRootSignaturesRemoveItemButton); - } - // Associate JSON mechanics. - if (shouldAssociateLocalRootSignatureFilepathTextBoxToJSON) - { - localRootSignaturesFilePathTextBox.Tag = macroElementID; - localRootSignaturesFilePathTextBox.Text = defaultYetInvalidFilePathString; - localRootSignaturesFilePathTextBox.TextChanged += - new TextChangedEventHandler(AddLocalRootSignatureFilePathByID); - localRootSignaturesFilePathTextBox.GotFocus += ClearDefaultFilePathText; - } - if (shouldAssociateLocalRootSignatureMacroNameShaderTextBoxToJSON) - { - localRootSignaturesMacroNameShaderTextBox.Tag = macroElementID; - localRootSignaturesMacroNameShaderTextBox.TextChanged += - new TextChangedEventHandler(AddLocalRootSignatureMacroNameShaderByID); - } - if (shouldAssociateLocalRootSignatureExportsTextBoxToJSON) - { - localRootSignaturesExportsTextBox.Tag = macroElementID; - localRootSignaturesExportsTextBox.TextChanged += - new TextChangedEventHandler(AddLocalRootSignatureExportByID); - } - if (shouldAssociateLocalRootSignatureTypeCobmoBoxToJSON) - { - localRootSignaturesTypeComboBox.Tag = macroElementID; - localRootSignaturesTypeComboBox.SelectionChanged += - new SelectionChangedEventHandler(AddLocalRootSignatureTypeByID); - Mode previousApplicationMode = CurrentApplicationMode; - SetApplicationMode(Mode.LocalRootSignature); - localRootSignaturesTypeComboBox.SelectedValue = localRootSignaturesTypeComboBox.Items[0]; - SetApplicationMode(previousApplicationMode); - } - } - else - { - shouldConnectButtonEvent = false; - postErrorMessage("Unable to create " + nameof(localRootSignaturesModeRootElement) + nameModifier); - success = false; - } - MacroElement macroElement; - if (success) - { - ModeCount.LocalRootSignatureCount++; - macroElement = new MacroElement - { - applicationMode = Mode.LocalRootSignature, - rootElement = localRootSignaturesModeRootElement, - targetElement = FindName("contentGrid") as Panel, - regiteredChildrenNames = nameList, - hasItemSeperator = true - }; - } - else - { - postErrorMessage("Unable to create element for mode: " + nameof(Mode.LocalRootSignature)); - macroElement = new MacroElement - { - applicationMode = Mode.ApplicationError, - rootElement = null, - targetElement = null, - regiteredChildrenNames = null - }; - } - return macroElement; - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to create the local root signature configuration pane: " + - ex.ToString()); - return new MacroElement(); - } - } - public MacroElement CreateGlobalRootSignatureConfig() - { - return CreateGlobalRootSignatureConfig(0); - } - public MacroElement CreateGlobalRootSignatureConfig(UInt32 nameModifier) - { - try - { - List nameList = new List(); - bool success = true; - // - // Type elements. - // - bool shouldAssociateGlobalRootSignaturesTypeComboBoxToJSON = true; - ComboBox globalRootSignaturesTypeComboBox = new ComboBox() - { - Margin = new Thickness(ContentViewSettings.ContentComboBoxMargin_left, - ContentViewSettings.ContentComboBoxMargin_top, - ContentViewSettings.ContentComboBoxMargin_right, - ContentViewSettings.ContentComboBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MinWidth = ContentViewSettings.ContentComboBoxMinWidth - }; - if (WPFAssignAndRegisterName(globalRootSignaturesTypeComboBox, nameof(globalRootSignaturesTypeComboBox) + nameModifier, nameList)) - { - globalRootSignaturesTypeComboBox.SetValue(Grid.RowProperty, 0); - globalRootSignaturesTypeComboBox.SetValue(Grid.ColumnProperty, 1); - globalRootSignaturesTypeComboBox.Style = FindResource("baseComboBoxStyle") as Style; - List globalRootSignatureTypeComboBoxItems = - new List(new String[] - { - ConstStringBinaryDXILType - }); - - SetComboBoxItemContent(globalRootSignaturesTypeComboBox, globalRootSignatureTypeComboBoxItems); - } - else - { - postErrorMessage("Unable to create " + nameof(globalRootSignaturesTypeComboBox) + nameModifier); - shouldAssociateGlobalRootSignaturesTypeComboBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label globalRootSignaturesTypeLabel = new Label() - { - Content = "Type", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(globalRootSignaturesTypeComboBox)) as UIElement - }; - if (WPFAssignAndRegisterName(globalRootSignaturesTypeLabel, nameof(globalRootSignaturesTypeLabel) + nameModifier, nameList)) - { - globalRootSignaturesTypeLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(globalRootSignaturesTypeLabel) + nameModifier); - success = false; - } - StackPanel globalRootSignaturesTypeStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(globalRootSignaturesTypeStackPanel, nameof(globalRootSignaturesTypeStackPanel) + nameModifier, nameList)) - { - globalRootSignaturesTypeStackPanel.Children.Add(globalRootSignaturesTypeLabel); - globalRootSignaturesTypeStackPanel.Children.Add(globalRootSignaturesTypeComboBox); - } - else - { - postErrorMessage("Unable to create " + nameof(globalRootSignaturesTypeStackPanel) + nameModifier); - success = false; - } - // - // File path elements. - // - bool shouldConnectglobalRootSignaturesFilePathBrowseButton = true; - Button globalRootSignaturesFilePathBrowseButton = new Button() - { - Style = FindResource("browseButtonStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentBrowseButtonMargin_left, - ContentViewSettings.ContentBrowseButtonMargin_top, - ContentViewSettings.ContentBrowseButtonMargin_right, - ContentViewSettings.ContentBrowseButtonMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - Width = ContentViewSettings.ContentBrowseButtonWidth - }; - if (!WPFAssignAndRegisterName(globalRootSignaturesFilePathBrowseButton, nameof(globalRootSignaturesFilePathBrowseButton) + nameModifier, nameList)) - { - shouldConnectglobalRootSignaturesFilePathBrowseButton = false; - postErrorMessage("Unable to create " + nameof(globalRootSignaturesFilePathBrowseButton) + nameModifier); - success = false; - } - bool shouldAssociateGlobalRootSignatureFilepathTextBoxToJSON = true; - TextBox globalRootSignaturesFilePathTextBox = new TextBox() - { - Style = FindResource("defaultYetInvalidTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth - }; - if (WPFAssignAndRegisterName(globalRootSignaturesFilePathTextBox, nameof(globalRootSignaturesFilePathTextBox) + nameModifier, nameList)) - { - if (shouldConnectglobalRootSignaturesFilePathBrowseButton) - { - globalRootSignaturesFilePathBrowseButton.Click += new RoutedEventHandler(BrowseForFilePath); - globalRootSignaturesFilePathBrowseButton.Tag = globalRootSignaturesFilePathTextBox.Name; - } - globalRootSignaturesFilePathTextBox.SetValue(Grid.ColumnProperty, 1); - globalRootSignaturesFilePathTextBox.ToolTip = globalRootSignaturesFilePathToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(globalRootSignaturesFilePathTextBox) + nameModifier); - shouldAssociateGlobalRootSignatureFilepathTextBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label globalRootSignaturesFilePathLabel = new Label() - { - Content = "File path", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(globalRootSignaturesFilePathTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(globalRootSignaturesFilePathLabel, nameof(globalRootSignaturesFilePathLabel) + nameModifier, nameList)) - { - globalRootSignaturesFilePathLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(globalRootSignaturesFilePathLabel) + nameModifier); - success = false; - } - StackPanel globalRootSignaturesFilePathStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(globalRootSignaturesFilePathStackPanel, nameof(globalRootSignaturesFilePathStackPanel) + nameModifier, nameList)) - { - globalRootSignaturesFilePathStackPanel.Children.Add(globalRootSignaturesFilePathLabel); - globalRootSignaturesFilePathStackPanel.Children.Add(globalRootSignaturesFilePathTextBox); - globalRootSignaturesFilePathStackPanel.Children.Add(globalRootSignaturesFilePathBrowseButton); - } - else - { - postErrorMessage("Unable to create " + nameof(globalRootSignaturesFilePathStackPanel) + nameModifier); - success = false; - } - // - // Macro Name shader elements. - // - bool shouldAssociateGlobalRootSignatureMacroNameShaderTextBoxToJSON = true; - TextBox globalRootSignaturesMacroNameShaderTextBox = new TextBox() - { - Style = FindResource("baseTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth - }; - if (WPFAssignAndRegisterName(globalRootSignaturesMacroNameShaderTextBox, nameof(globalRootSignaturesMacroNameShaderTextBox) + nameModifier, nameList)) - { - globalRootSignaturesMacroNameShaderTextBox.SetValue(Grid.RowProperty, 0); - globalRootSignaturesMacroNameShaderTextBox.SetValue(Grid.ColumnProperty, 1); - globalRootSignaturesMacroNameShaderTextBox.ToolTip = globalRootSignaturesMacroNameShaderToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(globalRootSignaturesMacroNameShaderTextBox) + nameModifier); - shouldAssociateGlobalRootSignatureMacroNameShaderTextBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label globalRootSignaturesMacroNameShaderLabel = new Label() - { - Content = "Macro name (HLSL)", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(globalRootSignaturesMacroNameShaderTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(globalRootSignaturesMacroNameShaderLabel, nameof(globalRootSignaturesMacroNameShaderLabel) + nameModifier, nameList)) - { - globalRootSignaturesMacroNameShaderLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(globalRootSignaturesMacroNameShaderLabel) + nameModifier); - success = false; - } - StackPanel globalRootSignaturesMacroNameShaderStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top, - // Note: Needs to be visible/settable in the JSON representation, but not - // editable by the user for the time being. - Visibility = Visibility.Collapsed - }; - if (WPFAssignAndRegisterName(globalRootSignaturesMacroNameShaderStackPanel, nameof(globalRootSignaturesMacroNameShaderStackPanel) + nameModifier, nameList)) - { - globalRootSignaturesMacroNameShaderStackPanel.Children.Add(globalRootSignaturesMacroNameShaderLabel); - globalRootSignaturesMacroNameShaderStackPanel.Children.Add(globalRootSignaturesMacroNameShaderTextBox); - } - else - { - postErrorMessage("Unable to create " + nameof(globalRootSignaturesMacroNameShaderStackPanel) + nameModifier); - success = false; - } - // - // Exports elements. - // - bool shouldAssociateGlobalRootSignatureExportsTextBoxToJSON = true; - TextBox globalRootSignaturesExportsTextBox = new TextBox() - { - Style = FindResource("baseTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth - }; - if (WPFAssignAndRegisterName(globalRootSignaturesExportsTextBox, nameof(globalRootSignaturesExportsTextBox) + nameModifier, nameList)) - { - globalRootSignaturesExportsTextBox.SetValue(Grid.RowProperty, 0); - globalRootSignaturesExportsTextBox.SetValue(Grid.ColumnProperty, 1); - globalRootSignaturesExportsTextBox.ToolTip = globalRootSignaturesExportsToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(globalRootSignaturesExportsTextBox) + nameModifier); - shouldAssociateGlobalRootSignatureExportsTextBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label globalRootSignaturesExportsLabel = new Label() - { - Content = "Exports", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(globalRootSignaturesExportsTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(globalRootSignaturesExportsLabel, nameof(globalRootSignaturesExportsLabel) + nameModifier, nameList)) - { - globalRootSignaturesExportsLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(globalRootSignaturesExportsLabel) + nameModifier); - success = false; - } - StackPanel globalRootSignaturesExportsStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(globalRootSignaturesExportsStackPanel, nameof(globalRootSignaturesExportsStackPanel) + nameModifier, nameList)) - { - globalRootSignaturesExportsStackPanel.Children.Add(globalRootSignaturesExportsLabel); - globalRootSignaturesExportsStackPanel.Children.Add(globalRootSignaturesExportsTextBox); - } - else - { - postErrorMessage("Unable to create " + nameof(globalRootSignaturesExportsStackPanel) + nameModifier); - success = false; - } - // - // Vertical Stack Panel - // - StackPanel globalRootSignaturesVerticalStackPanel = new StackPanel() - { - Orientation = Orientation.Vertical, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top, - MinWidth = ContentViewSettings.ContentMinWidth - }; - if (WPFAssignAndRegisterName(globalRootSignaturesVerticalStackPanel, nameof(globalRootSignaturesVerticalStackPanel) + nameModifier, nameList)) - { - // Add separator. - CreateMacroElementSeparator(globalRootSignaturesVerticalStackPanel); - globalRootSignaturesVerticalStackPanel.Children.Add(globalRootSignaturesTypeStackPanel); - globalRootSignaturesVerticalStackPanel.Children.Add(globalRootSignaturesFilePathStackPanel); - globalRootSignaturesVerticalStackPanel.Children.Add(globalRootSignaturesMacroNameShaderStackPanel); - globalRootSignaturesVerticalStackPanel.Children.Add(globalRootSignaturesExportsStackPanel); - globalRootSignaturesVerticalStackPanel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(globalRootSignaturesVerticalStackPanel) + nameModifier); - success = false; - } - // - // Top level elements. - // - bool shouldConnectButtonEvent = true; - Button globalRootSignaturesRemoveItemButton = new Button() - { - Style = FindResource("removeItemButtonStyle") as Style, - Content = GetRemoveButtonTrashCanIcon(), - Margin = new Thickness(ContentViewSettings.ContentRemoveButton_withoutBrowse_withTextBox_MarginLeft, 0, 0, - ContentViewSettings.ContentRemoveButton_withoutBrowse_withTextBox_MarginBottom) - }; - if (WPFAssignAndRegisterName(globalRootSignaturesRemoveItemButton, nameof(globalRootSignaturesRemoveItemButton) + nameModifier, nameList)) - { - globalRootSignaturesRemoveItemButton.SetValue(Grid.ColumnProperty, 1); - globalRootSignaturesRemoveItemButton.ToolTip = removeButtonToolTipPartialString + GetModeAsText(Mode.GlobalRootSignature); - } - else - { - shouldConnectButtonEvent = false; - postErrorMessage("Unable to create " + nameof(globalRootSignaturesRemoveItemButton) + nameModifier); - success = false; - } - ColumnDefinition globalRootSignaturesLabelAndTextboxCol = new ColumnDefinition() - { - Width = new GridLength(1.0, GridUnitType.Auto), - MinWidth = 100 - }; - if (!WPFAssignAndRegisterName(globalRootSignaturesLabelAndTextboxCol, nameof(globalRootSignaturesLabelAndTextboxCol) + nameModifier, nameList)) - { - postErrorMessage("Unable to create " + nameof(globalRootSignaturesLabelAndTextboxCol) + nameModifier); - success = false; - } - Grid globalRootSignaturesModeRootElement = new Grid() - { - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(globalRootSignaturesModeRootElement, nameof(globalRootSignaturesModeRootElement) + nameModifier, nameList)) - { - String macroElementID = nameof(globalRootSignaturesModeRootElement) + nameModifier; - globalRootSignaturesModeRootElement.ColumnDefinitions.Add(globalRootSignaturesLabelAndTextboxCol); - globalRootSignaturesModeRootElement.Children.Add(globalRootSignaturesVerticalStackPanel); - globalRootSignaturesModeRootElement.Tag = macroElementID; - // Associate button mechanics. - if (shouldConnectButtonEvent) - { - // Tuple layout: - globalRootSignaturesRemoveItemButton.Tag = macroElementID; - globalRootSignaturesRemoveItemButton.Click += new RoutedEventHandler(HandleTrashcanIconClick); - globalRootSignaturesTypeStackPanel.Children.Add(globalRootSignaturesRemoveItemButton); - } - // Associate JSON mechanics. - if (shouldAssociateGlobalRootSignatureFilepathTextBoxToJSON) - { - globalRootSignaturesFilePathTextBox.Tag = macroElementID; - globalRootSignaturesFilePathTextBox.Text = defaultYetInvalidFilePathString; - globalRootSignaturesFilePathTextBox.TextChanged += - new TextChangedEventHandler(AddGlobalRootSignatureFilePathByID); - globalRootSignaturesFilePathTextBox.GotFocus += ClearDefaultFilePathText; - } - if (shouldAssociateGlobalRootSignatureMacroNameShaderTextBoxToJSON) - { - globalRootSignaturesMacroNameShaderTextBox.Tag = macroElementID; - globalRootSignaturesMacroNameShaderTextBox.TextChanged += - new TextChangedEventHandler(AddGlobalRootSignatureMacroNameShaderByID); - } - if (shouldAssociateGlobalRootSignatureExportsTextBoxToJSON) - { - globalRootSignaturesExportsTextBox.Tag = macroElementID; - globalRootSignaturesExportsTextBox.TextChanged += - new TextChangedEventHandler(AddGlobalRootSignatureExportByID); - } - if (shouldAssociateGlobalRootSignaturesTypeComboBoxToJSON) - { - globalRootSignaturesTypeComboBox.Tag = macroElementID; - globalRootSignaturesTypeComboBox.SelectionChanged += - new SelectionChangedEventHandler(AddGlobalRootSignatureTypeByID); - Mode previousApplicationMode = CurrentApplicationMode; - SetApplicationMode(Mode.GlobalRootSignature); - globalRootSignaturesTypeComboBox.SelectedValue = globalRootSignaturesTypeComboBox.Items[0]; - SetApplicationMode(previousApplicationMode); - } - } - else - { - shouldConnectButtonEvent = false; - postErrorMessage("Unable to create " + nameof(globalRootSignaturesModeRootElement) + nameModifier); - success = false; - } - MacroElement macroElement; - if (success) - { - ModeCount.GlobalRootSignatureCount++; - macroElement = new MacroElement - { - applicationMode = Mode.GlobalRootSignature, - rootElement = globalRootSignaturesModeRootElement, - targetElement = FindName("contentGrid") as Panel, - regiteredChildrenNames = nameList, - hasItemSeperator = true - }; - } - else - { - postErrorMessage("Unable to create element for mode: " + nameof(Mode.GlobalRootSignature)); - macroElement = new MacroElement - { - applicationMode = Mode.ApplicationError, - rootElement = null, - targetElement = null, - regiteredChildrenNames = null - }; - } - return macroElement; - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to create the global root signature configuration pane: " + - ex.ToString()); - return new MacroElement(); - } - } - public MacroElement CreateRaytracingPipelineConfig() - { - return CreateRaytracingPipelineConfig(0); - } - public MacroElement CreateRaytracingPipelineConfig(UInt32 nameModifier) - { - try - { - //SetApplicationMode(Mode.RaytracingPipeline); - List nameList = new List(); - bool success = true; - // - // Max Trace Recursion Depth elements. - // - bool shouldAssociateRaytracingPipelineMaxTraceRecursionTextBoxToJSON = true; - TextBox RaytracingPipelineMaxTraceRecursionDepthTextBox = new TextBox() - { - Style = FindResource("baseTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth - }; - if (WPFAssignAndRegisterName(RaytracingPipelineMaxTraceRecursionDepthTextBox, nameof(RaytracingPipelineMaxTraceRecursionDepthTextBox) + nameModifier, nameList)) - { - RaytracingPipelineMaxTraceRecursionDepthTextBox.SetValue(Grid.RowProperty, 0); - RaytracingPipelineMaxTraceRecursionDepthTextBox.SetValue(Grid.ColumnProperty, 1); - RaytracingPipelineMaxTraceRecursionDepthTextBox.ToolTip = RaytracingPipelineMaxTraceRecursionDepthToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(RaytracingPipelineMaxTraceRecursionDepthTextBox) + nameModifier); - shouldAssociateRaytracingPipelineMaxTraceRecursionTextBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label RaytracingPipelineMaxTraceRecursionDepthLabel = new Label() - { - Content = "Max trace recursion depth", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(RaytracingPipelineMaxTraceRecursionDepthTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(RaytracingPipelineMaxTraceRecursionDepthLabel, nameof(RaytracingPipelineMaxTraceRecursionDepthLabel) + nameModifier, nameList)) - { - RaytracingPipelineMaxTraceRecursionDepthLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(RaytracingPipelineMaxTraceRecursionDepthLabel) + nameModifier); - success = false; - } - StackPanel RaytracingPipelineMaxTraceRecursionDepthStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(RaytracingPipelineMaxTraceRecursionDepthStackPanel, nameof(RaytracingPipelineMaxTraceRecursionDepthStackPanel) + nameModifier, nameList)) - { - RaytracingPipelineMaxTraceRecursionDepthStackPanel.Children.Add(RaytracingPipelineMaxTraceRecursionDepthLabel); - RaytracingPipelineMaxTraceRecursionDepthStackPanel.Children.Add(RaytracingPipelineMaxTraceRecursionDepthTextBox); - } - else - { - postErrorMessage("Unable to create " + nameof(RaytracingPipelineMaxTraceRecursionDepthStackPanel) + nameModifier); - success = false; - } - - // - // Exports elements. - // - bool shouldAssociateRaytracingPipelineExportsTextBoxToJSON = true; - TextBox RaytracingPipelineExportsTextBox = new TextBox() - { - Style = FindResource("baseTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth - }; - if (WPFAssignAndRegisterName(RaytracingPipelineExportsTextBox, nameof(RaytracingPipelineExportsTextBox) + nameModifier, nameList)) - { - RaytracingPipelineExportsTextBox.SetValue(Grid.RowProperty, 0); - RaytracingPipelineExportsTextBox.SetValue(Grid.ColumnProperty, 1); - RaytracingPipelineExportsTextBox.ToolTip = RaytracingPipelineExportsToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(RaytracingPipelineExportsTextBox) + nameModifier); - shouldAssociateRaytracingPipelineExportsTextBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label RaytracingPipelineExportsLabel = new Label() - { - Content = "Exports", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(RaytracingPipelineExportsTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(RaytracingPipelineExportsLabel, nameof(RaytracingPipelineExportsLabel) + nameModifier, nameList)) - { - RaytracingPipelineExportsLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(RaytracingPipelineExportsLabel) + nameModifier); - success = false; - } - StackPanel RaytracingPipelineExportsStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(RaytracingPipelineExportsStackPanel, nameof(RaytracingPipelineExportsStackPanel) + nameModifier, nameList)) - { - RaytracingPipelineExportsStackPanel.Children.Add(RaytracingPipelineExportsLabel); - RaytracingPipelineExportsStackPanel.Children.Add(RaytracingPipelineExportsTextBox); - } - else - { - postErrorMessage("Unable to create " + nameof(RaytracingPipelineExportsStackPanel) + nameModifier); - success = false; - } - // - // Vertical Stack Panel - // - StackPanel RaytracingPipelineVerticalStackPanel = new StackPanel() - { - Orientation = Orientation.Vertical, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top, - MinWidth = ContentViewSettings.ContentMinWidth - }; - if (WPFAssignAndRegisterName(RaytracingPipelineVerticalStackPanel, nameof(RaytracingPipelineVerticalStackPanel) + nameModifier, nameList)) - { - RaytracingPipelineVerticalStackPanel.Children.Add(RaytracingPipelineMaxTraceRecursionDepthStackPanel); - // Note: Restore if RaytracingPipelineConfig->Flags element is reinstated. - //RaytracingPipelineVerticalStackPanel.Children.Add(RaytracingPipelineFlagsStackPanel); - RaytracingPipelineVerticalStackPanel.Children.Add(RaytracingPipelineExportsStackPanel); - RaytracingPipelineVerticalStackPanel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(RaytracingPipelineVerticalStackPanel) + nameModifier); - success = false; - } - // - // Top level elements. - // - ColumnDefinition RaytracingPipelineLabelAndTextboxCol = new ColumnDefinition() - { - Width = new GridLength(1.0, GridUnitType.Auto), - MinWidth = 100 - }; - if (!WPFAssignAndRegisterName(RaytracingPipelineLabelAndTextboxCol, nameof(RaytracingPipelineLabelAndTextboxCol) + nameModifier, nameList)) - { - postErrorMessage("Unable to create " + nameof(RaytracingPipelineLabelAndTextboxCol) + nameModifier); - success = false; - } - Grid RaytracingPipelineModeRootElement = new Grid() - { - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(RaytracingPipelineModeRootElement, nameof(RaytracingPipelineModeRootElement) + nameModifier, nameList)) - { - RaytracingPipelineModeRootElement.ColumnDefinitions.Add(RaytracingPipelineLabelAndTextboxCol); - RaytracingPipelineModeRootElement.Children.Add(RaytracingPipelineVerticalStackPanel); - // Associate JSON Mechanics - if (shouldAssociateRaytracingPipelineMaxTraceRecursionTextBoxToJSON) - { - RaytracingPipelineMaxTraceRecursionDepthTextBox.TextChanged += - new TextChangedEventHandler(EditRaytracingPipelineMaxRecursionDepthByID); - Mode previousApplicationMode = CurrentApplicationMode; - SetApplicationMode(Mode.RaytracingPipeline); - RaytracingPipelineMaxTraceRecursionDepthTextBox.Text = "1"; - SetApplicationMode(previousApplicationMode); - } - // Note: Restore if RaytracingPipelineConfig->Flags element is reinstated. - //if (shouldAssociateRaytracingPipelineFlagsTextBoxToJSON) - //{ - // RaytracingPipelineFlagsTextBox.TextChanged += - // new TextChangedEventHandler(EditRaytracingPipelineFlagsByID); - //} - if (shouldAssociateRaytracingPipelineExportsTextBoxToJSON) - { - RaytracingPipelineExportsTextBox.TextChanged += - new TextChangedEventHandler(EditRaytracingPipelineExportsByID); - } - } - else - { - postErrorMessage("Unable to create " + nameof(RaytracingPipelineModeRootElement) + nameModifier); - success = false; - } - MacroElement macroElement; - if (success) - { - macroElement = new MacroElement - { - applicationMode = Mode.RaytracingPipeline, - rootElement = RaytracingPipelineModeRootElement, - targetElement = FindName("contentGrid") as Panel, - regiteredChildrenNames = nameList - }; - } - else - { - postErrorMessage("Unable to create element for mode: " + nameof(Mode.RaytracingPipeline)); - macroElement = new MacroElement - { - applicationMode = Mode.ApplicationError, - rootElement = null, - targetElement = null, - regiteredChildrenNames = null, - hasItemSeperator = false - }; - } - return macroElement; - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to create the raytracing pipeline configuration pane: " + - ex.ToString()); - return new MacroElement(); - } - } - public MacroElement CreateShaderPipelineConfig() - { - return CreateShaderPipelineConfig(0); - } - public MacroElement CreateShaderPipelineConfig(UInt32 nameModifier) - { - try - { - List nameList = new List(); - bool success = true; - // - // Payload Size elements. - // - bool shouldAssociateShaderPipelineTextBoxToJSON = true; - TextBox ShaderPipelinePayloadSizeTextBox = new TextBox() - { - Style = FindResource("baseTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth - }; - if (WPFAssignAndRegisterName(ShaderPipelinePayloadSizeTextBox, nameof(ShaderPipelinePayloadSizeTextBox) + nameModifier, nameList)) - { - ShaderPipelinePayloadSizeTextBox.SetValue(Grid.ColumnProperty, 1); - ShaderPipelinePayloadSizeTextBox.ToolTip = ShaderPipelinePayloadSizeToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(ShaderPipelinePayloadSizeTextBox) + nameModifier); - shouldAssociateShaderPipelineTextBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label ShaderPipelinePayloadSizeLabel = new Label() - { - Content = "Payload size (bytes)", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(ShaderPipelinePayloadSizeTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(ShaderPipelinePayloadSizeLabel, nameof(ShaderPipelinePayloadSizeLabel) + nameModifier, nameList)) - { - ShaderPipelinePayloadSizeLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(ShaderPipelinePayloadSizeLabel) + nameModifier); - success = false; - } - StackPanel ShaderPipelinePayloadSizeStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(ShaderPipelinePayloadSizeStackPanel, nameof(ShaderPipelinePayloadSizeStackPanel) + nameModifier, nameList)) - { - ShaderPipelinePayloadSizeStackPanel.Children.Add(ShaderPipelinePayloadSizeLabel); - ShaderPipelinePayloadSizeStackPanel.Children.Add(ShaderPipelinePayloadSizeTextBox); - } - else - { - postErrorMessage("Unable to create " + nameof(ShaderPipelinePayloadSizeStackPanel) + nameModifier); - success = false; - } - // - // Max AttributeSize elements. - // - bool shouldAssociateShaderPipelineMaxAttributeSizeTextBoxToJSON = true; - TextBox ShaderPipelinesMaxAttributeSizeTextBox = new TextBox() - { - Style = FindResource("baseTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth - }; - if (WPFAssignAndRegisterName(ShaderPipelinesMaxAttributeSizeTextBox, nameof(ShaderPipelinesMaxAttributeSizeTextBox) + nameModifier, nameList)) - { - ShaderPipelinesMaxAttributeSizeTextBox.SetValue(Grid.RowProperty, 0); - ShaderPipelinesMaxAttributeSizeTextBox.SetValue(Grid.ColumnProperty, 1); - ShaderPipelinesMaxAttributeSizeTextBox.ToolTip = ShaderPipelinesMaxAttributeSizeToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(ShaderPipelinesMaxAttributeSizeTextBox) + nameModifier); - shouldAssociateShaderPipelineMaxAttributeSizeTextBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label ShaderPipelinesMaxAttributeSizeLabel = new Label() - { - Content = "Max attribute size (bytes)", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(ShaderPipelinesMaxAttributeSizeTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(ShaderPipelinesMaxAttributeSizeLabel, nameof(ShaderPipelinesMaxAttributeSizeLabel) + nameModifier, nameList)) - { - ShaderPipelinesMaxAttributeSizeLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(ShaderPipelinesMaxAttributeSizeLabel) + nameModifier); - success = false; - } - StackPanel ShaderPipelinesMaxAttributeSizeStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(ShaderPipelinesMaxAttributeSizeStackPanel, nameof(ShaderPipelinesMaxAttributeSizeStackPanel) + nameModifier, nameList)) - { - ShaderPipelinesMaxAttributeSizeStackPanel.Children.Add(ShaderPipelinesMaxAttributeSizeLabel); - ShaderPipelinesMaxAttributeSizeStackPanel.Children.Add(ShaderPipelinesMaxAttributeSizeTextBox); - } - else - { - postErrorMessage("Unable to create " + nameof(ShaderPipelinesMaxAttributeSizeStackPanel) + nameModifier); - success = false; - } - // - // Exports elements. - // - bool shouldAssociateRaytracingPipelineExportsTextBoxToJSON = true; - TextBox ShaderPipelinesExportsTextBox = new TextBox() - { - Style = FindResource("baseTextBoxStyle") as Style, - Margin = new Thickness(ContentViewSettings.ContentTextBoxMargin_left, - ContentViewSettings.ContentTextBoxMargin_top, - ContentViewSettings.ContentTextBoxMargin_right, - ContentViewSettings.ContentTextBoxMargin_bottom), - Height = ContentViewSettings.ContentItemHeight, - MaxWidth = ContentViewSettings.ContentTextBoxMaxWidth, - MinWidth = ContentViewSettings.ContentTextBoxMinWidth - }; - if (WPFAssignAndRegisterName(ShaderPipelinesExportsTextBox, nameof(ShaderPipelinesExportsTextBox) + nameModifier, nameList)) - { - ShaderPipelinesExportsTextBox.SetValue(Grid.RowProperty, 0); - ShaderPipelinesExportsTextBox.SetValue(Grid.ColumnProperty, 1); - ShaderPipelinesExportsTextBox.ToolTip = ShaderPipelinesExportsToolTipString; - } - else - { - postErrorMessage("Unable to create " + nameof(ShaderPipelinesExportsTextBox) + nameModifier); - shouldAssociateRaytracingPipelineExportsTextBoxToJSON = false; - success = false; - } - // Note: Must build and register corresponding text box first, - // in order to set the target of this label. - Label ShaderPipelinesExportsLabel = new Label() - { - Content = "Exports", - Style = FindResource("baseLabelStyle") as Style, - Target = FindName(nameof(ShaderPipelinesExportsTextBox)) as UIElement - }; - if (WPFAssignAndRegisterName(ShaderPipelinesExportsLabel, nameof(ShaderPipelinesExportsLabel) + nameModifier, nameList)) - { - ShaderPipelinesExportsLabel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(ShaderPipelinesExportsLabel) + nameModifier); - success = false; - } - StackPanel ShaderPipelinesExportsStackPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(ShaderPipelinesExportsStackPanel, nameof(ShaderPipelinesExportsStackPanel) + nameModifier, nameList)) - { - ShaderPipelinesExportsStackPanel.Children.Add(ShaderPipelinesExportsLabel); - ShaderPipelinesExportsStackPanel.Children.Add(ShaderPipelinesExportsTextBox); - } - else - { - postErrorMessage("Unable to create " + nameof(ShaderPipelinesExportsStackPanel) + nameModifier); - success = false; - } - // - // Vertical Stack Panel - // - StackPanel ShaderPipelinesVerticalStackPanel = new StackPanel() - { - Orientation = Orientation.Vertical, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top, - MinWidth = ContentViewSettings.ContentMinWidth - }; - if (WPFAssignAndRegisterName(ShaderPipelinesVerticalStackPanel, nameof(ShaderPipelinesVerticalStackPanel) + nameModifier, nameList)) - { - // Add separator. - CreateMacroElementSeparator(ShaderPipelinesVerticalStackPanel); - ShaderPipelinesVerticalStackPanel.Children.Add(ShaderPipelinePayloadSizeStackPanel); - ShaderPipelinesVerticalStackPanel.Children.Add(ShaderPipelinesMaxAttributeSizeStackPanel); - ShaderPipelinesVerticalStackPanel.Children.Add(ShaderPipelinesExportsStackPanel); - ShaderPipelinesVerticalStackPanel.SetValue(Grid.ColumnProperty, 0); - } - else - { - postErrorMessage("Unable to create " + nameof(ShaderPipelinesVerticalStackPanel) + nameModifier); - success = false; - } - // - // Top level elements. - // - bool shouldConnectButtonEvent = true; - Button ShaderPipelinesRemoveItemButton = new Button() - { - Style = FindResource("removeItemButtonStyle") as Style, - Content = GetRemoveButtonTrashCanIcon(), - Margin = new Thickness(ContentViewSettings.ContentRemoveButton_withoutBrowse_withTextBox_MarginLeft, 0, 0, - ContentViewSettings.ContentRemoveButton_withoutBrowse_withTextBox_MarginBottom) - }; - if (WPFAssignAndRegisterName(ShaderPipelinesRemoveItemButton, nameof(ShaderPipelinesRemoveItemButton) + nameModifier, nameList)) - { - ShaderPipelinesRemoveItemButton.SetValue(Grid.ColumnProperty, 1); - ShaderPipelinesRemoveItemButton.ToolTip = removeButtonToolTipPartialString + GetModeAsText(Mode.ShaderPipeline) + " config"; - } - else - { - shouldConnectButtonEvent = false; - postErrorMessage("Unable to create " + nameof(ShaderPipelinesRemoveItemButton) + nameModifier); - success = false; - } - ColumnDefinition ShaderPipelinesLabelAndTextboxCol = new ColumnDefinition() - { - Width = new GridLength(1.0, GridUnitType.Auto), - MinWidth = 100 - }; - if (!WPFAssignAndRegisterName(ShaderPipelinesLabelAndTextboxCol, nameof(ShaderPipelinesLabelAndTextboxCol) + nameModifier, nameList)) - { - postErrorMessage("Unable to create " + nameof(ShaderPipelinesLabelAndTextboxCol) + nameModifier); - success = false; - } - Grid ShaderPipelinesModeRootElement = new Grid() - { - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top - }; - if (WPFAssignAndRegisterName(ShaderPipelinesModeRootElement, nameof(ShaderPipelinesModeRootElement) + nameModifier, nameList)) - { - String macroElementID = nameof(ShaderPipelinesModeRootElement) + nameModifier; - ShaderPipelinesModeRootElement.ColumnDefinitions.Add(ShaderPipelinesLabelAndTextboxCol); - ShaderPipelinesModeRootElement.Children.Add(ShaderPipelinesVerticalStackPanel); - ShaderPipelinesModeRootElement.Tag = macroElementID; - // Associate button mechanics. - if (shouldConnectButtonEvent) - { - // Tuple layout: - ShaderPipelinesRemoveItemButton.Tag = macroElementID; - ShaderPipelinesRemoveItemButton.Click += new RoutedEventHandler(HandleTrashcanIconClick); - ShaderPipelinePayloadSizeStackPanel.Children.Add(ShaderPipelinesRemoveItemButton); - } - // Associate JSON Mechanics - if (shouldAssociateShaderPipelineTextBoxToJSON) - { - ShaderPipelinePayloadSizeTextBox.Tag = macroElementID; - ShaderPipelinePayloadSizeTextBox.TextChanged += - new TextChangedEventHandler(AddRaytracingShaderConfigMaxPayloadSizeByID); - Mode previousApplicationMode = CurrentApplicationMode; - SetApplicationMode(Mode.ShaderPipeline); - ShaderPipelinePayloadSizeTextBox.Text = "16"; - SetApplicationMode(previousApplicationMode); - } - if (shouldAssociateShaderPipelineMaxAttributeSizeTextBoxToJSON) - { - ShaderPipelinesMaxAttributeSizeTextBox.Tag = macroElementID; - ShaderPipelinesMaxAttributeSizeTextBox.TextChanged += - new TextChangedEventHandler(AddRaytracingShaderConfigMaxAttributeSizeByID); - Mode previousApplicationMode = CurrentApplicationMode; - SetApplicationMode(Mode.ShaderPipeline); - ShaderPipelinesMaxAttributeSizeTextBox.Text = "8"; - SetApplicationMode(previousApplicationMode); - } - if (shouldAssociateRaytracingPipelineExportsTextBoxToJSON) - { - ShaderPipelinesExportsTextBox.Tag = macroElementID; - ShaderPipelinesExportsTextBox.TextChanged += - new TextChangedEventHandler(AddRaytracingShaderConfigExportByID); - } - } - else - { - shouldConnectButtonEvent = false; - postErrorMessage("Unable to create " + nameof(ShaderPipelinesModeRootElement) + nameModifier); - success = false; - } - MacroElement macroElement; - if (success) - { - ModeCount.ShaderPipelineCount++; - macroElement = new MacroElement - { - applicationMode = Mode.ShaderPipeline, - rootElement = ShaderPipelinesModeRootElement, - targetElement = FindName("contentGrid") as Panel, - regiteredChildrenNames = nameList, - hasItemSeperator = true - }; - } - else - { - postErrorMessage("Unable to create element for mode: " + nameof(Mode.ShaderPipeline)); - macroElement = new MacroElement - { - applicationMode = Mode.ApplicationError, - rootElement = null, - targetElement = null, - regiteredChildrenNames = null - }; - } - return macroElement; - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to create the shader pipeline configuration pane: " + - ex.ToString()); - return new MacroElement(); - } - } - public MacroElement CreateOutputConfig() - { - try - { - //SetApplicationMode(Mode.Output); - List nameList = new List(); - bool success = true; - RowDefinition jsonRow = new RowDefinition(); - if (!WPFAssignAndRegisterName(jsonRow, nameof(jsonRow), nameList)) - { - postErrorMessage("Unable to create " + nameof(jsonRow)); - success = false; - } - // JSON Save Button - Button saveButton = new Button() - { - Content = "Save as", - Style = FindResource("primaryButtonStyle") as Style, - MinWidth = 135, - MinHeight = 35, - Margin = new Thickness(5, 5, 5, 5), - HorizontalAlignment = HorizontalAlignment.Right - }; - if (WPFAssignAndRegisterName(saveButton, nameof(saveButton), nameList)) - { - saveButton.Click += new RoutedEventHandler(SaveButton_Click); - } - else - { - postErrorMessage("Unable to create " + nameof(saveButton)); - success = false; - } - // JSON Load File Button - Button loadJsonFileButton = new Button() - { - Content = "Load", - Style = FindResource("primaryButtonStyle") as Style, - MinWidth = 135, - MinHeight = 35, - Margin = new Thickness(5, 5, 5, 5), - HorizontalAlignment = HorizontalAlignment.Right - }; - if (WPFAssignAndRegisterName(loadJsonFileButton, nameof(loadJsonFileButton), nameList)) - { - loadJsonFileButton.Tag = "Load JSON From File"; - loadJsonFileButton.Click += new RoutedEventHandler(HandleLoadJSONButton); - } - else - { - postErrorMessage("Unable to create " + nameof(loadJsonFileButton)); - success = false; - } - StackPanel buttonPanel = new StackPanel() - { - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Stretch - }; - if (WPFAssignAndRegisterName(buttonPanel, nameof(buttonPanel), nameList)) - { - buttonPanel.SetValue(Grid.RowProperty, 1); - //buttonPanel.Children.Add(resetJsonButton); - buttonPanel.Children.Add(saveButton); - buttonPanel.Children.Add(loadJsonFileButton); - } - else - { - postErrorMessage("Unable to create " + nameof(loadJsonFileButton)); - success = false; - } - TextBox jsonViewText = new TextBox() - { - Style = FindResource("jsonTextStyle") as Style, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Stretch, - HorizontalContentAlignment = HorizontalAlignment.Left, - VerticalContentAlignment = VerticalAlignment.Top, - TextWrapping = TextWrapping.Wrap, - IsReadOnly = true, - }; - if (WPFAssignAndRegisterName(jsonViewText, nameof(jsonViewText), nameList)) - { - jsonViewText.SetValue(Grid.RowProperty, 0); - //jsonViewText.Drop += new DragEventHandler(HandleJSONDragAndDrop); - } - else - { - postErrorMessage("Unable to create " + nameof(jsonViewText)); - success = false; - } - bool contentGridSuccess = true; - Grid jsonContentGrid = new Grid() - { - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top, - }; - if (WPFAssignAndRegisterName(jsonContentGrid, nameof(jsonContentGrid), nameList)) - { - jsonContentGrid.SetValue(Grid.RowProperty, 0); - jsonContentGrid.Children.Add(jsonViewText); - } - else - { - contentGridSuccess = false; - postErrorMessage("Unable to create " + nameof(jsonContentGrid)); - success = false; - } - DXRScrollViewer jsonConfigScrollViewer = new DXRScrollViewer() - { - HorizontalScrollBarVisibility = ScrollBarVisibility.Auto, - VerticalScrollBarVisibility = ScrollBarVisibility.Auto, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Stretch, - VerticalContentAlignment = VerticalAlignment.Top, - Margin = new Thickness(0, 0, 0, 0) - }; - if (WPFAssignAndRegisterName(jsonConfigScrollViewer, nameof(jsonConfigScrollViewer), nameList)) - { - jsonConfigScrollViewer.SetValue(Grid.ColumnProperty, 2); - jsonConfigScrollViewer.SetValue(Grid.RowProperty, 0); - if (contentGridSuccess) - { - jsonConfigScrollViewer.Content = jsonContentGrid; - jsonConfigScrollViewer.ScrollChanged += - new ScrollChangedEventHandler(HandleDXRScrollViewerScrollChanged); - } - } - else - { - postErrorMessage("Unable to create " + nameof(jsonConfigScrollViewer)); - success = false; - } - Grid outputGrid = new Grid() - { - Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF333333")) - }; - if (WPFAssignAndRegisterName(outputGrid, nameof(outputGrid), nameList)) - { - outputGrid.SetValue(Grid.ColumnProperty, 2); - outputGrid.RowDefinitions.Add(jsonRow); - outputGrid.Children.Add(jsonConfigScrollViewer); - // Add default button row. - CreateMacroElementButtonRow(outputGrid, buttonPanel); - } - else - { - postErrorMessage("Unable to create " + nameof(outputGrid)); - success = false; - } - MacroElement macroElement; - if (success) - { - macroElement = new MacroElement - { - applicationMode = Mode.Output, - rootElement = outputGrid, - targetElement = FindName("jsonViewGrid") as Panel, - regiteredChildrenNames = nameList - }; - } - else - { - postErrorMessage("Unable to create element for mode: " + nameof(Mode.Output)); - macroElement = new MacroElement - { - applicationMode = Mode.ApplicationError, - rootElement = null, - targetElement = null, - regiteredChildrenNames = null - }; - } - return macroElement; - } - catch (System.Exception ex) - { - postErrorMessage("An unhandled exception has been caught while attempting to create the output pane: " + - ex.ToString()); - return new MacroElement(); - } - } - } -} \ No newline at end of file diff --git a/Utils/DXR State Editor/DXR State Editor/MainWindow.xaml b/Utils/DXR State Editor/DXR State Editor/MainWindow.xaml deleted file mode 100644 index 343a978..0000000 --- a/Utils/DXR State Editor/DXR State Editor/MainWindow.xaml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - -