diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a8ce46a79..4c63a2180 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,6 +26,7 @@ jobs: git branch -a sudo apt-get update --yes sudo apt-get install --yes git clang-format-14 + sudo apt-get install python3-mako --yes - name: Run lint script run: ./scripts/clangformat.sh @@ -51,6 +52,10 @@ jobs: version: 1.10.0 - uses: ilammy/msvc-dev-cmd@v1 - uses: ilammy/setup-nasm@v1 + - name: Install dependency + run: | + C:/hostedtoolcache/windows/Python/3.11.6/x64/python3.exe -m pip install mako + C:/hostedtoolcache/windows/Python/3.12.0/x64/python3.exe -m pip install mako - name: Build the UI run: | mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Debug -G "Visual Studio 16 2019" -A x64 .. @@ -77,6 +82,10 @@ jobs: version: 1.10.0 - uses: ilammy/msvc-dev-cmd@v1 - uses: ilammy/setup-nasm@v1 + - name: Install dependency + run: | + C:/hostedtoolcache/windows/Python/3.11.6/x64/python3.exe -m pip install mako + C:/hostedtoolcache/windows/Python/3.12.0/x64/python3.exe -m pip install mako - name: Build the UI run: | mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 16 2019" -A x64 .. @@ -96,6 +105,8 @@ jobs: run: | sudo apt-get update --yes sudo apt-get install --yes cmake gcc-10 clang-14 libsystemd-dev libbsd-dev ninja-build + /opt/hostedtoolcache/Python/3.11.6/x64/bin/pip install mako + /opt/hostedtoolcache/Python/3.12.0/x64/bin/pip install mako which gcc-10 which clang-14 - name: Prepare Vulkan SDK @@ -120,6 +131,8 @@ jobs: run: | sudo apt-get update --yes sudo apt-get install --yes cmake gcc-10 clang-14 libsystemd-dev libbsd-dev ninja-build + /opt/hostedtoolcache/Python/3.11.6/x64/bin/pip install mako + /opt/hostedtoolcache/Python/3.12.0/x64/bin/pip install mako which gcc-10 which clang-14 - name: Prepare Vulkan SDK @@ -142,6 +155,7 @@ jobs: run: | sudo apt-get update --yes sudo apt-get install --yes cmake ninja-build + sudo apt-get install python3-mako --yes - uses: nttld/setup-ndk@v1 id: setup-ndk with: diff --git a/dive_core/CMakeLists.txt b/dive_core/CMakeLists.txt index 004e4c477..a5ff1ed66 100644 --- a/dive_core/CMakeLists.txt +++ b/dive_core/CMakeLists.txt @@ -29,6 +29,9 @@ else() set(NATVIS_FILES "") endif() +# Disable following warnings for compiling .c files in mesa +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-override-init -Wno-sign-compare") + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) @@ -37,6 +40,8 @@ set(PM4_INFO_FILE "${DIVE_CORE_GENERATED_FILE_DIR}/pm4_info") set(PM4_GENERATED_SRC_FILE "${DIVE_CORE_GENERATED_FILE_DIR}/pm4_info.cpp") set(PM4_GENERATED_HDR_FILE "${DIVE_CORE_GENERATED_FILE_DIR}/pm4_info.h") set(ADRENO_HDR_FILE "${DIVE_CORE_GENERATED_FILE_DIR}/adreno.h") +set(A6XX_PY_FILE "${DIVE_CORE_GENERATED_FILE_DIR}/a6xx.py") +set(FREEDRENO_DEVICES_HDR_FILE "${DIVE_CORE_GENERATED_FILE_DIR}/freedreno_devices.h") if(${CMAKE_VERSION} VERSION_LESS "3.12.0") find_program (Python3_EXECUTABLE python3) @@ -72,6 +77,33 @@ add_custom_command( ) add_custom_target(adreno_header ALL DEPENDS ${ADRENO_HDR_FILE}) +add_custom_command( + OUTPUT ${A6XX_PY_FILE} + COMMAND ${Python3_EXECUTABLE} ${THIRDPARTY_DIRECTORY}/mesa/src/freedreno/registers/gen_header.py + "--rnn" + "${THIRDPARTY_DIRECTORY}/mesa/src/freedreno/registers" + "--xml" + "${THIRDPARTY_DIRECTORY}/mesa/src/freedreno/registers/adreno/a6xx.xml" + "py-defines" + > ${A6XX_PY_FILE} + DEPENDS "${THIRDPARTY_DIRECTORY}/mesa/src/freedreno/registers/gen_header.py" + WORKING_DIRECTORY ${THIRDPARTY_DIRECTORY}/mesa/src/freedreno/registers + VERBATIM +) +add_custom_target(a6xx_py ALL DEPENDS ${A6XX_PY_FILE}) + +add_custom_command( + OUTPUT ${FREEDRENO_DEVICES_HDR_FILE} + COMMAND ${Python3_EXECUTABLE} ${THIRDPARTY_DIRECTORY}/mesa/src/freedreno/common/freedreno_devices.py + "-p" + "${DIVE_CORE_GENERATED_FILE_DIR}" + > ${FREEDRENO_DEVICES_HDR_FILE} + DEPENDS "${THIRDPARTY_DIRECTORY}/mesa/src/freedreno/common/freedreno_devices.py" + "${A6XX_PY_FILE}" + VERBATIM +) +add_custom_target(freedreno_devices_header ALL DEPENDS ${FREEDRENO_DEVICES_HDR_FILE}) + file(GLOB_RECURSE HDR_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.h") file(GLOB_RECURSE SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") list(FILTER SRC_FILES EXCLUDE REGEX "_tests.cpp$") @@ -85,20 +117,27 @@ endif() file(GLOB_RECURSE COMMON_HDR_FILES "${CMAKE_SOURCE_DIR}/dive_core/common/*.h") file(GLOB_RECURSE COMMON_SRC_FILES "${CMAKE_SOURCE_DIR}/dive_core/common/*.cpp") +file(GLOB_RECURSE FREEDRENO_SRC_FILES "${THIRDPARTY_DIRECTORY}/mesa/src/freedreno/common/freedreno_dev_info.c") + include_directories(${THIRDPARTY_DIRECTORY}/Vulkan-Headers/include ${CMAKE_SOURCE_DIR} ${DIVE_CORE_GENERATED_FILE_DIR}) include_directories(${CMAKE_SOURCE_DIR}/capture_layer) include_directories(${CMAKE_SOURCE_DIR}/capture_layer/generated) +include_directories(${THIRDPARTY_DIRECTORY}/mesa/src/freedreno/common) +include_directories(${THIRDPARTY_DIRECTORY}/mesa/src/) + add_definitions(-DLITTLEENDIAN_CPU) # Required for some PAL files add_library(${PROJECT_NAME} STATIC ${HDR_FILES} ${SRC_FILES} - ${COMMON_HDR_FILES} ${COMMON_SRC_FILES} ${PM4_GENERATED_SRC_FILE} ${NATVIS_FILES} + ${COMMON_HDR_FILES} ${COMMON_SRC_FILES} ${PM4_GENERATED_SRC_FILE} ${NATVIS_FILES} ${FREEDRENO_SRC_FILES} "${CMAKE_SOURCE_DIR}/capture_layer/generated/command_printer.cpp" "${CMAKE_SOURCE_DIR}/capture_layer/command_printer_brief.cpp" "${CMAKE_SOURCE_DIR}/capture_layer/generated/command_decoder.cpp" ) add_dependencies(${PROJECT_NAME} pm4_info) add_dependencies(${PROJECT_NAME} adreno_header) +add_dependencies(${PROJECT_NAME} a6xx_py) +add_dependencies(${PROJECT_NAME} freedreno_devices_header) if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") diff --git a/dive_core/capture_data.cpp b/dive_core/capture_data.cpp index 78fc0d6ca..d4d399951 100644 --- a/dive_core/capture_data.cpp +++ b/dive_core/capture_data.cpp @@ -22,6 +22,8 @@ #include "capture_layer/generated/command_decoder.h" #include "capture_layer/generated/command_printer.h" #include "dive_core/command_hierarchy.h" +#include "freedreno_dev_info.h" +#include "pm4_info.h" namespace Dive { @@ -946,18 +948,30 @@ CaptureData::LoadResult CaptureData::LoadAdrenoRdFile(std::istream &capture_file case RD_NONE: case RD_TEST: case RD_CMD: - // case RD_GPUADDR: case RD_CONTEXT: case RD_CMDSTREAM: - // case RD_CMDSTREAM_ADDR: case RD_PARAM: case RD_FLUSH: case RD_PROGRAM: case RD_VERT_SHADER: - case RD_FRAG_SHADER: - // case RD_BUFFER_CONTENTS: + case RD_FRAG_SHADER: capture_file.seekg(block_info.m_data_size, std::ios::cur); break; case RD_GPU_ID: - case RD_CHIP_ID: capture_file.seekg(block_info.m_data_size, std::ios::cur); + { + DIVE_ASSERT(block_info.m_data_size == 4); + uint32_t gpu_id = 0; + capture_file.read(reinterpret_cast(&gpu_id), block_info.m_data_size); + SetGPUID(gpu_id / 100); + } + break; + case RD_CHIP_ID: + { + DIVE_ASSERT(block_info.m_data_size == 8); + fd_dev_id dev_id; + capture_file.read(reinterpret_cast(&dev_id.chip_id), block_info.m_data_size); + auto info = fd_dev_info(&dev_id); + SetGPUID(info->chip); + } + break; } } m_memory.Finalize(true, true); diff --git a/dive_core/common.py b/dive_core/common.py index 7cedb7546..1aa78fd54 100644 --- a/dive_core/common.py +++ b/dive_core/common.py @@ -1,4 +1,72 @@ # Common functions +import ctypes +import re +c_uint8 = ctypes.c_uint8 + +class BitfieldsBits(ctypes.LittleEndianStructure): + _fields_ = [ + ("A2XX", c_uint8, 1), + ("A3XX", c_uint8, 1), + ("A4XX", c_uint8, 1), + ("A5XX", c_uint8, 1), + ("A6XX", c_uint8, 1), + ("A7XX", c_uint8, 1), + ] + +class Bitfields(ctypes.Union): + _fields_ = [("bits", BitfieldsBits), + ("asbyte", c_uint8)] + +# convert "variants" string to bitfield +def GetGPUVariantsBitField(str): + pattern = r"A\d{1}XX" + gpu_list = re.findall(pattern, str) + bitfields = Bitfields() + bitfields.asbyte = 0 + a_count = len(gpu_list) + if a_count == 0: + return 0 + dash_count = len(re.findall(r"-", str)) + + # if there is a "-"" + # 1. if there are 2 A?xx, we need to add the ones between the 2 + # 2. if there is only 1 A?XX, we need to add all following ones + if dash_count != 0: + begin = end = gpu_list[0] + skip = False + if a_count == 2: + end = gpu_list[1] + else: + end = bitfields._fields_[0][1]._fields_[-1][0] + if end != begin: + gpu_list.append(end) + else: + skip = True + + # iterate all elements in BitfieldsBits to add the missing ones into "gpu_list" + # note that the begin and end have already added to "gpu_list" + if not skip: + need_add = False + for e in bitfields._fields_[0][1]._fields_: + if e[0] == end: + need_add = False + break + + if need_add: + gpu_list.append(e[0]) + + if e[0] == begin: + need_add = True + + for var in gpu_list: + match var: + case "A2XX": bitfields.bits.A2XX = 1 + case "A3XX": bitfields.bits.A3XX = 1 + case "A4XX": bitfields.bits.A4XX = 1 + case "A5XX": bitfields.bits.A5XX = 1 + case "A6XX": bitfields.bits.A6XX = 1 + case "A7XX": bitfields.bits.A7XX = 1 + return bitfields.asbyte # --------------------------------------------------------------------------------------- def isBuiltInType(type): diff --git a/dive_core/data_core.cpp b/dive_core/data_core.cpp index 9cacdfae4..17389b78c 100644 --- a/dive_core/data_core.cpp +++ b/dive_core/data_core.cpp @@ -713,13 +713,17 @@ void CaptureMetadataCreator::FillHardwareSpecificStates(EventStateInfo::Iterator const uint32_t binw = bitfields.BINW << reg_field_w->m_shr; const uint32_t binh = bitfields.BINH << reg_field_h->m_shr; const a6xx_render_mode render_mode = bitfields.RENDER_MODE; - // TODO(wangra): this is only available on a6xx, should disable this on a7xx captures - const a6xx_buffers_location buffers_location = bitfields.BUFFERS_LOCATION; event_state_it->SetBinW(binw); event_state_it->SetBinH(binh); event_state_it->SetRenderMode(render_mode); - event_state_it->SetBuffersLocation(buffers_location); + + // this is only available on a6xx + if (IsFieldEnabled(GetRegFieldByName("BUFFERS_LOCATION", reg_info))) + { + const a6xx_buffers_location buffers_location = bitfields.BUFFERS_LOCATION; + event_state_it->SetBuffersLocation(buffers_location); + } } // helper lane related diff --git a/dive_core/generatePm4Info_adreno.py b/dive_core/generatePm4Info_adreno.py index 411ccf7a3..edb379177 100644 --- a/dive_core/generatePm4Info_adreno.py +++ b/dive_core/generatePm4Info_adreno.py @@ -6,6 +6,7 @@ from common import isBuiltInType from common import gatherAllEnums +from common import GetGPUVariantsBitField # --------------------------------------------------------------------------------------- @@ -48,14 +49,26 @@ def outputH(pm4_info_file): enum ValueType { kBoolean, kUint, kInt, kFloat, kFixed, kAddress, kWaddress, kHex, kOther }; +enum GPUVariantType +{ + kGPUVariantNone = 0x0, + kA2XX = 0x1, + kA3XX = 0x2, + kA4XX = 0x4, + kA5XX = 0x8, + kA6XX = 0x10, + kA7XX = 0x20, +}; + static const uint32_t kInvalidRegOffset = UINT32_MAX; struct RegField { - uint32_t m_type : 8; // ValueType enum + uint32_t m_type : 4; // ValueType enum, range [0, 15] uint32_t m_enum_handle : 8; uint32_t m_shift : 6; - uint32_t m_shr : 5; // used to shift left to extract the "original" value, range: [0, 31] - uint32_t : 5; + uint32_t m_shr : 5; // used to shift left to extract the "original" value, range: [0, 31] + uint32_t m_gpu_variants : 6; // only 6 bits are used for now, see GPUVariantType + uint32_t : 3; uint64_t m_mask; const char* m_name; }; @@ -63,9 +76,10 @@ def outputH(pm4_info_file): struct RegInfo { const char* m_name; uint32_t m_is_64_bit : 1; // Either 32 or 64 bit - uint32_t m_type : 8; // ValueType enum + uint32_t m_type : 4; // ValueType enum, range [0, 15] uint32_t m_enum_handle : 8; - uint32_t : 5; + uint32_t m_gpu_variants : 6; // only 6 bits are used for now, see GPUVariantType + uint32_t : 13; std::vector m_fields; }; @@ -73,10 +87,10 @@ def outputH(pm4_info_file): const char* m_name; uint32_t m_is_variant_opcode : 1; // If 1, then is used to indicate variant uint32_t m_dword : 8; - uint32_t m_type : 8; // ValueType enum + uint32_t m_type : 4; // ValueType enum, range [0, 15] uint32_t m_enum_handle : 8; uint32_t m_shift : 6; - uint32_t : 1; + uint32_t : 5; uint32_t m_mask; }; @@ -97,6 +111,8 @@ def outputH(pm4_info_file): const char *GetEnumString(uint32_t enum_handle, uint32_t val); const PacketInfo *GetPacketInfo(uint32_t op_code); const PacketInfo *GetPacketInfo(uint32_t op_code, const char *name); +void SetGPUID(uint32_t gpu_id); +bool IsFieldEnabled(const RegField *field); """) # --------------------------------------------------------------------------------------- @@ -104,24 +120,47 @@ def outputHeaderCpp(pm4_info_header_file_name, pm4_info_file): outputHeader(pm4_info_file) pm4_info_file.write("#include \"%s\"\n" % (pm4_info_header_file_name)) pm4_info_file.writelines(""" +#include #include #include #include +#include #include -#include +#include "dive_core/common/common.h" static std::map g_sOpCodeToString; static std::map g_sRegInfo; struct cmp_str { - bool operator()(char const *a, char const *b) const + bool operator()(const std::string& a, const std::string& b) const { - return std::strcmp(a, b) < 0; + return std::strcmp(a.c_str(), b.c_str()) < 0; } }; -static std::map g_sRegNameToIndex; +static std::map g_sRegNameToIndex; static std::vector> g_sEnumReflection; static std::multimap g_sPacketInfo; +static GPUVariantType g_sGPU_variant = kGPUVariantNone; + +std::string GetGPUStr(GPUVariantType variant) +{ + std::string s; + switch(variant) + { + case kA2XX: s = "A2XX"; break; + case kA3XX: s = "A3XX"; break; + case kA4XX: s = "A4XX"; break; + case kA5XX: s = "A5XX"; break; + case kA6XX: s = "A6XX"; break; + case kA7XX: s = "A7XX"; break; + case kGPUVariantNone: + default: + DIVE_ASSERT(false); + break; + } + return s; +} + """ ) @@ -181,7 +220,7 @@ def getTypeEnumString(type): return type_string # --------------------------------------------------------------------------------------- -def outputSingleRegister(pm4_info_file, registers_et_root, a6xx_domain, offset, name, bitfields, type, enum_index_dict, is_64): +def outputSingleRegister(pm4_info_file, registers_et_root, a6xx_domain, offset, name, bitfields, type, enum_index_dict, is_64, variants): is_64_string = "0" if is_64 is True: is_64_string = "1" @@ -210,7 +249,8 @@ def outputSingleRegister(pm4_info_file, registers_et_root, a6xx_domain, offset, raise Exception("Enumeration handle %d is too big! The bitfield storing this is only 8-bits!" % enum_index_dict[type]) enum_handle = str(enum_index_dict[type]) - pm4_info_file.write(" g_sRegInfo[0x%x] = { \"%s\", %s, %s, %s, {" % (offset, name, is_64_string, getTypeEnumString(type), enum_handle)) + variants_bitfield = GetGPUVariantsBitField(variants) + pm4_info_file.write(" g_sRegInfo[0x%x] = { \"%s\", %s, %s, %s, %s, {" % (offset, name, is_64_string, getTypeEnumString(type), enum_handle, variants_bitfield)) # Iterate through optional bitfields for bitfield in bitfields: @@ -249,11 +289,16 @@ def outputSingleRegister(pm4_info_file, registers_et_root, a6xx_domain, offset, else: raise Exception("Encountered a bitfield with no pos/low/high!") - pm4_info_file.write(" { %s, %s, %d, %d, 0x%x, \"%s\" }, " % ( + variants_bitfield = 0 + if 'variants' in bitfield.attrib: + variants_bitfield = GetGPUVariantsBitField(bitfield.attrib['variants']) + + pm4_info_file.write(" { %s, %s, %d, %d, %d, 0x%x, \"%s\" }, " % ( getTypeEnumString(bitfield_type), enum_handle, shift, shr, + variants_bitfield, mask, name )) @@ -282,7 +327,10 @@ def outputRegisterInfo(pm4_info_file, registers_et_root, enum_index_dict): is_64 = False if reg.tag == '{http://nouveau.freedesktop.org/}reg64': is_64 = True - outputSingleRegister(pm4_info_file, registers_et_root, a6xx_domain, offset, name, bitfields, type, enum_index_dict, is_64) + variants = "" + if 'variants' in reg.attrib: + variants = reg.attrib['variants'] + outputSingleRegister(pm4_info_file, registers_et_root, a6xx_domain, offset, name, bitfields, type, enum_index_dict, is_64, variants) # Iterate and output the arrays as a sequence of reg32s with an index as a suffix arrays = a6xx_domain.findall('{http://nouveau.freedesktop.org/}array') @@ -294,11 +342,16 @@ def outputRegisterInfo(pm4_info_file, registers_et_root, enum_index_dict): # Create a list of 32-bit and 64-bit registers array_regs = [] + reg_variants = [] for element in array: is_reg_32 = (element.tag == '{http://nouveau.freedesktop.org/}reg32') is_reg_64 = (element.tag == '{http://nouveau.freedesktop.org/}reg64') if is_reg_32 or is_reg_64: array_regs.append(element) + variants = "" + if 'variants' in element.attrib: + variants = element.attrib['variants'] + reg_variants.append(variants) # Arrays with stride==1 just generate a series of registers with index suffixes # Arrays with stride==2 and no reg32s/reg64s are going to generate a 64-bit register entry @@ -308,10 +361,10 @@ def outputRegisterInfo(pm4_info_file, registers_et_root, enum_index_dict): for i in range(0,length): if stride == 1: outputSingleRegister(pm4_info_file, registers_et_root, a6xx_domain, \ - offset+i, array_name+str(i), [], None, enum_index_dict, False) + offset+i, array_name+str(i), [], None, enum_index_dict, False, "") elif stride == 2 and not array_regs: outputSingleRegister(pm4_info_file, registers_et_root, a6xx_domain, \ - offset+i*stride, array_name+"_LO", [], None, enum_index_dict, True) + offset+i*stride, array_name+"_LO", [], None, enum_index_dict, True, "") else: for reg_idx, reg in enumerate(array_regs): reg_name = reg.attrib['name'] @@ -325,7 +378,7 @@ def outputRegisterInfo(pm4_info_file, registers_et_root, enum_index_dict): is_64 = True outputSingleRegister(pm4_info_file, registers_et_root, a6xx_domain, \ offset+i*stride+reg_offset, array_name+str(i)+"_"+reg_name, \ - bitfields, type, enum_index_dict, is_64) + bitfields, type, enum_index_dict, is_64, reg_variants[reg_idx]) return # --------------------------------------------------------------------------------------- @@ -562,10 +615,32 @@ def outputPacketInfo(pm4_info_file, registers_et_root, enum_index_dict): pm4_info_file.write(" } }));\n") pm4_info_file.write("\n") - pm4_info_file.write(" for (auto ® : g_sRegInfo)\n") - pm4_info_file.write(" {\n") - pm4_info_file.write(" g_sRegNameToIndex[reg.second.m_name] = reg.first;\n") - pm4_info_file.write(" }\n") + # Append _A?XX to the name if there is any variant + # This is to handle the cases where the regsiters have the same name + # but different offset for different variants, like PC_POLYGON_MODE + pm4_info_file.write("\tfor (auto ® : g_sRegInfo)\n") + pm4_info_file.write("\t{\n") + pm4_info_file.write("\t\tconst std::string& name = reg.second.m_name;\n") + pm4_info_file.write("\t\tuint32_t gpu_variants = reg.second.m_gpu_variants;\n") + pm4_info_file.write("\t\tif (gpu_variants != 0)\n") + pm4_info_file.write("\t\t{\n") + pm4_info_file.write("\t\t\tuint32_t bit_offset = 0;\n") + pm4_info_file.write("\t\t\twhile(gpu_variants != 0)\n") + pm4_info_file.write("\t\t\t{ \n") + pm4_info_file.write("\t\t\t\tif ((gpu_variants & 0x1) != 0)\n") + pm4_info_file.write("\t\t\t\t{\n") + pm4_info_file.write("\t\t\t\t\tconst std::string name_with_variant = name + \"_\" + GetGPUStr(static_cast(1 << (bit_offset)));\n") + pm4_info_file.write("\t\t\t\t\tg_sRegNameToIndex[name_with_variant] = reg.first;\n") + pm4_info_file.write("\t\t\t\t}\n") + pm4_info_file.write("\t\t\t\tgpu_variants = gpu_variants>>1;\n") + pm4_info_file.write("\t\t\t\t++bit_offset;\n") + pm4_info_file.write("\t\t\t}\n") + pm4_info_file.write("\t\t}\n") + pm4_info_file.write("\t\telse\n") + pm4_info_file.write("\t\t{\n") + pm4_info_file.write("\t\t\tg_sRegNameToIndex[name] = reg.first;\n") + pm4_info_file.write("\t\t}\n") + pm4_info_file.write("\t}\n") # --------------------------------------------------------------------------------------- @@ -587,10 +662,12 @@ def outputFunctionsCpp(pm4_info_file): const RegInfo *GetRegByName(const char *name) { - auto i = g_sRegNameToIndex.find(name); - if (i == g_sRegNameToIndex.end()) + uint32_t offset = GetRegOffsetByName(name); + if(offset == kInvalidRegOffset) + { return nullptr; - return GetRegInfo(i->second); + } + return GetRegInfo(offset); } const RegField *GetRegFieldByName(const char *name, const RegInfo *info) @@ -610,9 +687,18 @@ def outputFunctionsCpp(pm4_info_file): uint32_t GetRegOffsetByName(const char *name) { - auto i = g_sRegNameToIndex.find(name); + DIVE_ASSERT(g_sGPU_variant != kGPUVariantNone); + std::string str = std::string(name); + auto i = g_sRegNameToIndex.find(str); if (i == g_sRegNameToIndex.end()) - return kInvalidRegOffset; + { + std::string name_with_variant = str + "_" + GetGPUStr(g_sGPU_variant); + i = g_sRegNameToIndex.find(name_with_variant); + if (i == g_sRegNameToIndex.end()) + { + return kInvalidRegOffset; + } + } return i->second; } @@ -644,6 +730,24 @@ def outputFunctionsCpp(pm4_info_file): } return nullptr; } + +void SetGPUID(uint32_t gpu_id) +{ + if((gpu_id >= 2) && (gpu_id <= 7)) + { + g_sGPU_variant = static_cast(1 << (gpu_id - 2)); + } + else + { + g_sGPU_variant = kGPUVariantNone; + } +} + +bool IsFieldEnabled(const RegField* field) +{ + DIVE_ASSERT(g_sGPU_variant != kGPUVariantNone); + return (g_sGPU_variant & field->m_gpu_variants) != 0; +} """ )