Add code to disassemble SPIR-V, glsl and DXBC into GCN ISA.

* Requires binary plugins to function from the RGA repository. These
  will be included with distributions (nightly and stable builds) where
  possible, however D3D disassembly currently requires the AMD driver
  DLL which cannot be distributed. Placing it in the folder with the
  other files will automatically work.
This commit is contained in:
baldurk
2017-07-05 15:35:41 +01:00
parent 13bf08a99e
commit ecf88787d7
25 changed files with 2835 additions and 2 deletions
+6
View File
@@ -36,6 +36,7 @@ option(BUILD_VERSION_STABLE "If this is a stable build. See RENDERDOC_STABLE_BUI
set(BUILD_VERSION_DIST_NAME "" CACHE STRING "The name of the distribution. See DISTRIBUTION_NAME in renderdoc/api/replay/version.h")
set(BUILD_VERSION_DIST_VER "" CACHE STRING "The distribution-specific version number. See DISTRIBUTION_VERSION in renderdoc/api/replay/version.h")
set(BUILD_VERSION_DIST_CONTACT "" CACHE STRING "The URL or email to contact with issues. See DISTRIBUTION_CONTACT in renderdoc/api/replay/version.h")
set(RENDERDOC_PLUGINS_PATH "" CACHE STRING "Path to RenderDoc plugins folder after installation of RenderDoc (either absolute or relative to binary)")
set(RENDERDOC_APK_PATH "" CACHE STRING "Path to RenderDocCmd.apk after installation of RenderDoc on host (either absolute or relative to binary)")
if(BUILD_VERSION_STABLE)
@@ -54,6 +55,11 @@ if(NOT BUILD_VERSION_DIST_CONTACT STREQUAL "")
add_definitions(-DDISTRIBUTION_CONTACT="${BUILD_VERSION_DIST_CONTACT}")
endif()
if(NOT RENDERDOC_PLUGINS_PATH STREQUAL "")
message(STATUS "Detected custom path to RenderDoc plugins: ${RENDERDOC_PLUGINS_PATH}")
add_definitions(-DRENDERDOC_PLUGINS_PATH="${RENDERDOC_PLUGINS_PATH}")
endif()
if(NOT RENDERDOC_APK_PATH STREQUAL "")
message(STATUS "Detected custom path to RenderDocCmd.apk: ${RENDERDOC_APK}")
add_definitions(-DRENDERDOC_APK_PATH="${RENDERDOC_APK_PATH}")
+4
View File
@@ -92,6 +92,10 @@ The following libraries and components are incorporated into RenderDoc, listed h
Providing higher-resolution icons than the famfamfam Silk set, these icons allow scaling to those using high-DPI displays.
* `AMD Radeon GPU Analyzer <https://github.com/GPUOpen-Tools/RGA>`_ - Copyright (c) 2015 Advanced Micro Devices, Inc., distributed under the MIT license.
Provides the ability to disassemble shaders from any API representation into compiled GCN ISA for lower level analysis.
Thanks
------
+3
View File
@@ -292,6 +292,9 @@ endif()
if(ENABLE_GL OR ENABLE_GLES OR ENABLE_VULKAN)
add_subdirectory(driver/shaders/spirv)
list(APPEND renderdoc_objects $<TARGET_OBJECTS:rdoc_spirv>)
add_subdirectory(driver/ihv/amd)
list(APPEND renderdoc_objects $<TARGET_OBJECTS:rdoc_amd>)
endif()
# rdoc must be after its drivers because of linux_libentry.cpp
+16 -1
View File
@@ -25,6 +25,7 @@
#include "d3d11_replay.h"
#include "driver/dx/official/d3dcompiler.h"
#include "driver/ihv/amd/amd_isa.h"
#include "driver/shaders/dxbc/dxbc_debug.h"
#include "serialise/string_utils.h"
#include "d3d11_context.h"
@@ -319,6 +320,17 @@ vector<string> D3D11Replay::GetDisassemblyTargets()
{
vector<string> ret;
std::string err;
if(GCNISA::IsSupported(GraphicsAPI::D3D11, err))
{
GCNISA::GetTargets(GraphicsAPI::D3D11, ret);
}
else
{
RDCLOG("AMD ISA Not available:\n%s", err.c_str());
}
// DXBC is always first
ret.insert(ret.begin(), "DXBC");
return ret;
@@ -333,7 +345,10 @@ string D3D11Replay::DisassembleShader(const ShaderReflection *refl, const string
DXBC::DXBCFile *dxbc = it->second->GetDXBC();
return dxbc->GetDisassembly();
if(target == "DXBC" || target.empty())
return dxbc->GetDisassembly();
return GCNISA::Disassemble(dxbc, target);
}
void D3D11Replay::FreeTargetResource(ResourceId id)
+16 -1
View File
@@ -25,6 +25,7 @@
#include "d3d12_replay.h"
#include "driver/dx/official/d3dcompiler.h"
#include "driver/dxgi/dxgi_common.h"
#include "driver/ihv/amd/amd_isa.h"
#include "d3d12_command_queue.h"
#include "d3d12_device.h"
#include "d3d12_resources.h"
@@ -259,6 +260,17 @@ vector<string> D3D12Replay::GetDisassemblyTargets()
{
vector<string> ret;
std::string err;
if(GCNISA::IsSupported(GraphicsAPI::D3D12, err))
{
GCNISA::GetTargets(GraphicsAPI::D3D12, ret);
}
else
{
RDCLOG("AMD ISA Not available:\n%s", err.c_str());
}
// DXBC is always first
ret.insert(ret.begin(), "DXBC");
return ret;
@@ -273,7 +285,10 @@ string D3D12Replay::DisassembleShader(const ShaderReflection *refl, const string
DXBC::DXBCFile *dxbc = sh->GetDXBC();
return dxbc->GetDisassembly();
if(target == "DXBC" || target.empty())
return dxbc->GetDisassembly();
return GCNISA::Disassemble(dxbc, target);
}
void D3D12Replay::FreeTargetResource(ResourceId id)
+20
View File
@@ -24,6 +24,7 @@
******************************************************************************/
#include "gl_replay.h"
#include "driver/ihv/amd/amd_isa.h"
#include "maths/matrix.h"
#include "serialise/string_utils.h"
#include "gl_driver.h"
@@ -836,6 +837,17 @@ vector<string> GLReplay::GetDisassemblyTargets()
{
vector<string> ret;
std::string err;
if(GCNISA::IsSupported(GraphicsAPI::OpenGL, err))
{
GCNISA::GetTargets(GraphicsAPI::OpenGL, ret);
}
else
{
RDCLOG("AMD ISA Not available:\n%s", err.c_str());
}
// default is always first
ret.insert(ret.begin(), "SPIR-V (RenderDoc)");
return ret;
@@ -848,6 +860,7 @@ string GLReplay::DisassembleShader(const ShaderReflection *refl, const string &t
if(shaderDetails.sources.empty())
return "Invalid Shader Specified";
if(target == "SPIR-V (RenderDoc)" || target.empty())
{
std::string &disasm = shaderDetails.disassembly;
@@ -856,6 +869,13 @@ string GLReplay::DisassembleShader(const ShaderReflection *refl, const string &t
return disasm;
}
ShaderStage stages[] = {
ShaderStage::Vertex, ShaderStage::Tess_Control, ShaderStage::Tess_Eval,
ShaderStage::Geometry, ShaderStage::Fragment, ShaderStage::Compute,
};
return GCNISA::Disassemble(stages[ShaderIdx(shaderDetails.type)], shaderDetails.sources, target);
}
void GLReplay::SavePipelineState()
+12
View File
@@ -94,9 +94,17 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="amd_counters.cpp" />
<ClCompile Include="amd_isa.cpp" />
<ClCompile Include="amd_isa_devices.cpp" />
<ClCompile Include="amd_isa_posix.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="amd_isa_win32.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="amd_counters.h" />
<ClInclude Include="amd_isa.h" />
<ClInclude Include="amd_isa_devices.h" />
<ClInclude Include="official\DXExt\AmdDxExt.h" />
<ClInclude Include="official\DXExt\AmdDxExtApi.h" />
<ClInclude Include="official\DXExt\AmdDxExtIface.h" />
@@ -112,6 +120,10 @@
<ClInclude Include="official\GPUPerfAPI\Include\GPUPerfAPIFunctionTypes.h" />
<ClInclude Include="official\GPUPerfAPI\Include\GPUPerfAPITypes-Private.h" />
<ClInclude Include="official\GPUPerfAPI\Include\GPUPerfAPITypes.h" />
<ClInclude Include="official\RGA\Common\AmdDxGsaCompile.h" />
<ClInclude Include="official\RGA\Common\asic_reg\devices.h" />
<ClInclude Include="official\RGA\elf\elf32.h" />
<ClInclude Include="official\RGA\elf\elf_common.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
@@ -13,11 +13,35 @@
<Filter Include="official\DXExt">
<UniqueIdentifier>{310145c9-318c-4c14-ac19-1bb04a050349}</UniqueIdentifier>
</Filter>
<Filter Include="ISA">
<UniqueIdentifier>{54c2d261-eb6a-48cc-a741-2857a8148559}</UniqueIdentifier>
</Filter>
<Filter Include="official\RGA">
<UniqueIdentifier>{b6dd5672-5467-4d86-8d48-685a9751f1b5}</UniqueIdentifier>
</Filter>
<Filter Include="official\RGA\elf">
<UniqueIdentifier>{2d5a0ef9-0cd2-4354-88e2-f7ab466308bd}</UniqueIdentifier>
</Filter>
<Filter Include="official\RGA\Common">
<UniqueIdentifier>{47a6fd91-f76e-4faa-9e5c-4bb899be9796}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="amd_counters.cpp">
<Filter>Counters</Filter>
</ClCompile>
<ClCompile Include="amd_isa.cpp">
<Filter>ISA</Filter>
</ClCompile>
<ClCompile Include="amd_isa_win32.cpp">
<Filter>ISA</Filter>
</ClCompile>
<ClCompile Include="amd_isa_posix.cpp">
<Filter>ISA</Filter>
</ClCompile>
<ClCompile Include="amd_isa_devices.cpp">
<Filter>ISA</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="amd_counters.h">
@@ -68,5 +92,23 @@
<ClInclude Include="official\GPUPerfAPI\Include\GPUPerfAPITypes-Private.h">
<Filter>official\GPUPerfAPI</Filter>
</ClInclude>
<ClInclude Include="amd_isa.h">
<Filter>ISA</Filter>
</ClInclude>
<ClInclude Include="official\RGA\elf\elf_common.h">
<Filter>official\RGA\elf</Filter>
</ClInclude>
<ClInclude Include="official\RGA\elf\elf32.h">
<Filter>official\RGA\elf</Filter>
</ClInclude>
<ClInclude Include="official\RGA\Common\AmdDxGsaCompile.h">
<Filter>official\RGA\Common</Filter>
</ClInclude>
<ClInclude Include="official\RGA\Common\asic_reg\devices.h">
<Filter>official\RGA\Common</Filter>
</ClInclude>
<ClInclude Include="amd_isa_devices.h">
<Filter>ISA</Filter>
</ClInclude>
</ItemGroup>
</Project>
+10
View File
@@ -0,0 +1,10 @@
set(sources
amd_isa.cpp
amd_isa.h
amd_isa_devices.cpp
amd_isa_devices.h
amd_isa_posix.cpp)
add_library(rdoc_amd OBJECT ${sources})
target_compile_definitions(rdoc_amd ${RDOC_DEFINITIONS})
target_include_directories(rdoc_amd ${RDOC_INCLUDES})
+394
View File
@@ -0,0 +1,394 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2017 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* 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 Software.
*
* THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "amd_isa.h"
#include "common/common.h"
#include "driver/shaders/spirv/spirv_common.h"
#include "serialise/string_utils.h"
#include "amd_isa_devices.h"
namespace GCNISA
{
#if ENABLED(RDOC_WIN32)
static const std::string amdspv_name = "amdspv.exe";
static const std::string virtualcontext_name = "VirtualContext.exe";
#else
static const std::string amdspv_name = "amdspv.sh";
static const std::string virtualcontext_name = "VirtualContext";
#endif
std::string LocatePlugin(const std::string &fileName)
{
std::string ret;
std::string exepath;
FileIO::GetExecutableFilename(exepath);
exepath = dirname(exepath);
std::vector<std::string> paths;
#if defined(RENDERDOC_PLUGINS_PATH)
string customPath(RENDERDOC_PLUGINS_PATH);
if(FileIO::IsRelativePath(customPath))
customPath = exepath + "/" + customPath;
paths.push_back(customPath);
#endif
// windows installation
paths.push_back(exepath + "/plugins");
// linux installation
paths.push_back(exepath + "/../share/renderdoc/plugins");
// there is no standard path for local builds as we don't provide these plugins in the repository
// directly. As a courtesy we search the root of the build, from the executable. The user can
// always put the plugins folder relative to the exe where it would be in an installation too.
paths.push_back(exepath + "/../../plugins");
// in future maybe we want to search a user-specific plugins folder? Like ~/.renderdoc/ on linux
// or %APPDATA%/renderdoc on windows?
for(uint32_t i = 0; i < paths.size(); i++)
{
std::string check = paths[i] + "/amd/isa/" + fileName;
if(FileIO::exists(check.c_str()))
{
ret = check;
break;
}
}
// if we didn't find it anywhere, just try running it directly in case it's in the PATH
if(ret.empty())
ret = fileName;
return ret;
}
bool IsSupported(GraphicsAPI api, std::string &userMessage)
{
if(api == GraphicsAPI::Vulkan)
{
std::string vc = LocatePlugin(virtualcontext_name);
Process::ProcessResult result = {};
Process::LaunchProcess(vc.c_str(), dirname(vc).c_str(), "", &result);
// running with no parameters produces an error, so if there's no output something went wrong.
if(result.strStdout.empty())
return false;
return true;
}
if(api == GraphicsAPI::OpenGL)
{
// TODO need to check if an AMD context is running
std::string amdspv = LocatePlugin(amdspv_name);
Process::ProcessResult result = {};
Process::LaunchProcess(amdspv.c_str(), dirname(amdspv).c_str(), "", &result);
// running with no parameters produces help text, so if there's no output something went wrong.
if(result.strStdout.empty())
return false;
return true;
}
// we only need to check if we can get atidxx64.dll
if(api == GraphicsAPI::D3D11 || api == GraphicsAPI::D3D12)
{
DXBC::DXBCFile *dummy = NULL;
userMessage = Disassemble(dummy, "");
return userMessage.empty();
}
return false;
}
void GetTargets(GraphicsAPI api, std::vector<std::string> &targets)
{
targets.reserve(ARRAY_COUNT(asicInfo) + 1);
// OpenGL doesn't support AMDIL
if(api != GraphicsAPI::OpenGL)
targets.push_back("AMDIL");
for(const asic &a : asicInfo)
targets.push_back(a.name);
}
std::string Disassemble(const SPVModule *spv, const std::string &entry, const std::string &target)
{
std::string cmdLine = "-set spirvDasmLegacyFormat=1 -Dall -l";
bool found = false;
for(const asic &a : asicInfo)
{
if(target == a.name)
{
cmdLine += " -gfxip ";
cmdLine += a.gfxIpString;
found = true;
break;
}
}
bool amdil = false;
if(!found && target == "AMDIL")
{
cmdLine += " -gfxip 8";
found = true;
amdil = true;
}
if(!found)
return "; Invalid ISA Target specified";
ShaderStage stage = spv->StageForEntry(entry);
const char *stageName = "unk";
switch(stage)
{
case ShaderStage::Vertex: stageName = "vert"; break;
case ShaderStage::Tess_Control: stageName = "tesc"; break;
case ShaderStage::Tess_Eval: stageName = "tese"; break;
case ShaderStage::Geometry: stageName = "geom"; break;
case ShaderStage::Fragment: stageName = "frag"; break;
case ShaderStage::Compute: stageName = "comp"; break;
case ShaderStage::Count: return "; Cannot identify shader type";
}
std::string tempPath = FileIO::GetTempFolderFilename() + "rdoc_isa__";
std::string inPath = StringFormat::Fmt("%sin.spv", tempPath.c_str());
cmdLine += StringFormat::Fmt(
" -set in.spv=\"%sin.spv\" out.%s.palIlText=\"%sout.il\" out.%s.isa=\"%sout.bin\" "
"out.%s.isaText=\"%sout.txt\" out.%s.isaInfo=\"%sstats.txt\" "
"out.glslLog=\"%sout.log\" defaultOutput=0",
tempPath.c_str(), stageName, tempPath.c_str(), stageName, tempPath.c_str(), stageName,
tempPath.c_str(), stageName, tempPath.c_str(), tempPath.c_str());
FileIO::dump(inPath.c_str(), spv->spirv.data(), spv->spirv.size() * sizeof(uint32_t));
// try to locate the amdspv relative to our running program
std::string amdspv = LocatePlugin(amdspv_name);
Process::ProcessResult result = {};
Process::LaunchProcess(amdspv.c_str(), dirname(amdspv).c_str(), cmdLine.c_str(), &result);
if(result.strStdout.find("SUCCESS") == std::string::npos)
{
return "; Failed to Disassemble - " + result.strStdout;
}
// remove artifacts we don't need
FileIO::Delete(StringFormat::Fmt("%sin.spv", tempPath.c_str()).c_str());
FileIO::Delete(StringFormat::Fmt("%sout.log", tempPath.c_str()).c_str());
FileIO::Delete(StringFormat::Fmt("%sout.bin", tempPath.c_str()).c_str());
std::string ret;
if(amdil)
{
vector<byte> data;
FileIO::slurp(StringFormat::Fmt("%sout.il", tempPath.c_str()).c_str(), data);
ret = std::string(data.data(), data.data() + data.size());
}
else
{
vector<byte> data;
FileIO::slurp(StringFormat::Fmt("%sout.txt", tempPath.c_str()).c_str(), data);
ret = std::string(data.data(), data.data() + data.size());
std::string statsfile = StringFormat::Fmt("%sstats.txt", tempPath.c_str());
if(FileIO::exists(statsfile.c_str()))
{
FileIO::slurp(statsfile.c_str(), data);
ret += std::string(data.data(), data.data() + data.size());
}
}
FileIO::Delete(StringFormat::Fmt("%sout.il", tempPath.c_str()).c_str());
FileIO::Delete(StringFormat::Fmt("%sout.txt", tempPath.c_str()).c_str());
FileIO::Delete(StringFormat::Fmt("%sstats.txt", tempPath.c_str()).c_str());
std::string header = StringFormat::Fmt("; Disassembly for %s\n\n", target.c_str());
ret.insert(ret.begin(), header.begin(), header.end());
return ret;
}
std::string Disassemble(ShaderStage stage, const std::vector<std::string> &glsl,
const std::string &target)
{
const char *stageName = "unk";
int stageIndex = 0;
switch(stage)
{
case ShaderStage::Vertex:
stageIndex = 0;
stageName = "vert";
break;
case ShaderStage::Tess_Control:
stageIndex = 1;
stageName = "tesc";
break;
case ShaderStage::Tess_Eval:
stageIndex = 2;
stageName = "tese";
break;
case ShaderStage::Geometry:
stageIndex = 3;
stageName = "geom";
break;
case ShaderStage::Fragment:
stageIndex = 4;
stageName = "frag";
break;
case ShaderStage::Compute:
stageIndex = 5;
stageName = "comp";
break;
case ShaderStage::Count: return "; Cannot identify shader type";
}
std::string tempPath = FileIO::GetTempFolderFilename() + "rdoc_isa__";
std::string inPath = StringFormat::Fmt("%sin.%s", tempPath.c_str(), stageName);
std::string outPath = StringFormat::Fmt("%sout.txt", tempPath.c_str());
std::string binPath = StringFormat::Fmt("%sout.bin", tempPath.c_str());
std::string statsPath = StringFormat::Fmt("%sstats.txt", tempPath.c_str());
std::string cmdLine = "\"";
// ISA disassembly
for(int i = 0; i < 6; i++)
{
if(i == stageIndex)
cmdLine += outPath;
cmdLine += ';';
}
// ISA binary, we don't care about this
cmdLine += binPath + ";";
// statistics
for(int i = 0; i < 6; i++)
{
if(i == stageIndex)
cmdLine += statsPath;
cmdLine += ';';
}
bool found = false;
for(const asic &a : asicInfo)
{
if(target == a.name)
{
cmdLine += StringFormat::Fmt("%d;%d;", a.chipFamily, a.chipRevision);
found = true;
break;
}
}
// input files
for(int i = 0; i < 6; i++)
{
if(i == stageIndex)
cmdLine += inPath;
cmdLine += ';';
}
if(!found)
return "; Invalid ISA Target specified";
cmdLine += ";\"";
std::string source;
// concatenate the source files together
for(const std::string &s : glsl)
{
source += s;
source += "\n";
}
FileIO::dump(inPath.c_str(), source.data(), source.size());
// try to locate the amdspv relative to our running program
std::string vc = LocatePlugin(virtualcontext_name);
Process::ProcessResult result = {};
Process::LaunchProcess(vc.c_str(), dirname(vc).c_str(), cmdLine.c_str(), &result);
if(result.retCode != 0)
{
return "; Failed to Disassemble - " + result.strStdout;
}
// remove artifacts we don't need
FileIO::Delete(inPath.c_str());
FileIO::Delete(binPath.c_str());
std::string ret;
{
vector<byte> data;
FileIO::slurp(outPath.c_str(), data);
ret = std::string(data.data(), data.data() + data.size());
if(FileIO::exists(statsPath.c_str()))
{
FileIO::slurp(statsPath.c_str(), data);
ret += "\n\n";
ret += std::string(data.data(), data.data() + data.size());
}
}
FileIO::Delete(outPath.c_str());
FileIO::Delete(statsPath.c_str());
std::string header = StringFormat::Fmt("; Disassembly for %s\n\n", target.c_str());
ret.insert(ret.begin(), header.begin(), header.end());
return ret;
}
}; // namespace GCNISA
+46
View File
@@ -0,0 +1,46 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2017 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* 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 Software.
*
* THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#pragma once
#include <vector>
#include "api/replay/renderdoc_replay.h"
namespace DXBC
{
class DXBCFile;
};
struct SPVModule;
namespace GCNISA
{
bool IsSupported(GraphicsAPI api, std::string &userMessage);
void GetTargets(GraphicsAPI api, std::vector<std::string> &targets);
std::string Disassemble(const DXBC::DXBCFile *dxbc, const std::string &target);
std::string Disassemble(const SPVModule *spv, const std::string &entry, const std::string &target);
std::string Disassemble(ShaderStage stage, const std::vector<std::string> &glsl,
const std::string &target);
};
@@ -0,0 +1,55 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2017 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* 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 Software.
*
* THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "amd_isa_devices.h"
#include "official/RGA/Common/asic_reg/devices.h"
GCNISA::asic GCNISA::asicInfo[22] = {
// Southern Islands
{"GCN (Tahiti)", "6", FAMILY_SI, SI_TAHITI_P_B1},
{"GCN (Pitcairn)", "6", FAMILY_SI, SI_PITCAIRN_PM_A1},
{"GCN (Capeverde)", "6", FAMILY_SI, SI_CAPEVERDE_M_A1},
{"GCN (Capeverde)", "6", FAMILY_SI, SI_CAPEVERDE_M_A1},
{"GCN (Oland)", "6", FAMILY_SI, SI_OLAND_M_A0},
{"GCN (Hainan)", "6", FAMILY_SI, SI_HAINAN_V_A0},
// Sea Islands
{"GCN (Bonaire)", "7", FAMILY_CI, CI_BONAIRE_M_A0},
{"GCN (Hawaii)", "7", FAMILY_CI, CI_HAWAII_P_A0},
{"GCN (Spectre)", "7", FAMILY_CI, KV_SPECTRE_A0},
{"GCN (Spooky)", "7", FAMILY_CI, KV_SPOOKY_A0},
{"GCN (Kalindi)", "7.x", FAMILY_CI, CI_BONAIRE_M_A0},
{"GCN (Mullins)", "7", FAMILY_CI, CI_BONAIRE_M_A0},
// Volcanic Islands
{"GCN (Iceland)", "8", FAMILY_VI, VI_ICELAND_M_A0},
{"GCN (Tonga)", "8", FAMILY_VI, VI_TONGA_P_A0},
{"GCN (Carrizo)", "8", FAMILY_VI, CARRIZO_A0},
{"GCN (Bristol Ridge)", "8", FAMILY_VI, CARRIZO_A0},
{"GCN (Carrizo)", "8", FAMILY_VI, CARRIZO_A0},
{"GCN (Fiji)", "8", FAMILY_VI, VI_FIJI_P_A0},
{"GCN (Stoney)", "8.1", FAMILY_VI, STONEY_A0},
{"GCN (Ellesmere)", "8", FAMILY_VI, VI_ELLESMERE_P_A0},
{"GCN (Baffin)", "8", FAMILY_VI, VI_BAFFIN_M_A0},
{"GCN (gfx804)", "8", FAMILY_VI, VI_LEXA_V_A0},
// GDT_HW_GENERATION_GFX9 goes here, when it's supported by amdspv.
};
@@ -0,0 +1,39 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2017 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* 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 Software.
*
* THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#pragma once
namespace GCNISA
{
struct asic
{
const char *name;
const char *gfxIpString;
int chipFamily;
int chipRevision;
};
extern asic asicInfo[22];
}; // namespace GCNISA
@@ -0,0 +1,30 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2017 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* 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 Software.
*
* THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "amd_isa.h"
std::string GCNISA::Disassemble(const DXBC::DXBCFile *dxbc, const std::string &target)
{
return "Disassembling D3D shaders is only supported on windows";
}
+182
View File
@@ -0,0 +1,182 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2017 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* 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 Software.
*
* THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "amd_isa.h"
#include "driver/shaders/dxbc/dxbc_inspect.h"
#include "official/RGA/Common/AmdDxGsaCompile.h"
#include "official/RGA/elf/elf32.h"
#include "amd_isa_devices.h"
static const char *driverDllErrorMessage = R"(Error loading atidxx64.dll.
Currently atidxx64.dll from AMD's driver package is required for GCN disassembly and it cannot be
distributed with RenderDoc.
To see instructions on how to download and configure it on your system, go to:
https://github.com/baldurk/renderdoc/wiki/GCN_ISA)";
namespace GCNISA
{
std::string LocatePlugin(const std::string &fileName);
};
static HMODULE GetAMDModule()
{
// first try in the plugin locations
HMODULE module = LoadLibraryA(GCNISA::LocatePlugin("atidxx64.dll").c_str());
// if that failed then try checking for it just in the default search path
if(module == NULL)
module = LoadLibraryA("atidxx64.dll");
return module;
}
std::string GCNISA::Disassemble(const DXBC::DXBCFile *dxbc, const std::string &target)
{
HMODULE mod = GetAMDModule();
if(mod == NULL)
return driverDllErrorMessage;
// if DXBC is NULL we're testing support, so return empty string - indicating no error
// initialising
if(dxbc == NULL || target == "")
return "";
PfnAmdDxGsaCompileShader compileShader =
(PfnAmdDxGsaCompileShader)GetProcAddress(mod, "AmdDxGsaCompileShader");
PfnAmdDxGsaFreeCompiledShader freeShader =
(PfnAmdDxGsaFreeCompiledShader)GetProcAddress(mod, "AmdDxGsaFreeCompiledShader");
AmdDxGsaCompileShaderInput in = {};
AmdDxGsaCompileShaderOutput out = {};
AmdDxGsaCompileOption opts[1] = {};
in.inputType = GsaInputDxAsmBin;
in.numCompileOptions = 0;
in.pCompileOptions = opts;
for(const asic &a : asicInfo)
{
if(target == a.name)
{
in.chipFamily = a.chipFamily;
in.chipRevision = a.chipRevision;
break;
}
}
bool amdil = false;
if(target == "AMDIL")
{
in.chipFamily = asicInfo[0].chipFamily;
in.chipRevision = asicInfo[0].chipRevision;
amdil = true;
}
if(in.chipFamily == 0)
return "; Invalid ISA Target specified";
in.pShaderByteCode = dxbc->m_HexDump.data();
in.byteCodeLength = dxbc->m_HexDump.size();
out.size = sizeof(out);
compileShader(&in, &out);
const uint8_t *elf = (const uint8_t *)out.pShaderBinary;
const Elf32_Ehdr *elfHeader = (const Elf32_Ehdr *)elf;
std::string ret;
// minimal code to extract data from ELF. We assume the ELF we got back is well-formed.
if(IS_ELF(*elfHeader) && elfHeader->e_ident[EI_CLASS] == ELFCLASS32)
{
const Elf32_Shdr *strtab =
(const Elf32_Shdr *)(elf + elfHeader->e_shoff + sizeof(Elf32_Shdr) * elfHeader->e_shstrndx);
const uint8_t *strtabData = elf + strtab->sh_offset;
const AmdDxGsaCompileStats *stats = NULL;
for(int section = 1; section < elfHeader->e_shnum; section++)
{
if(section == elfHeader->e_shstrndx)
continue;
const Elf32_Shdr *sectHeader =
(const Elf32_Shdr *)(elf + elfHeader->e_shoff + sizeof(Elf32_Shdr) * section);
const char *name = (const char *)(strtabData + sectHeader->sh_name);
const uint8_t *data = elf + sectHeader->sh_offset;
if(!strcmp(name, ".stats"))
{
stats = (const AmdDxGsaCompileStats *)data;
}
else if(amdil && !strcmp(name, ".amdil_disassembly"))
{
ret.insert(0, (const char *)data, (size_t)sectHeader->sh_size);
}
else if(!amdil && !strcmp(name, ".disassembly"))
{
ret.insert(0, (const char *)data, (size_t)sectHeader->sh_size);
}
}
if(stats && !amdil)
{
std::string statStr = StringFormat::Fmt(
R"(; -------- Statistics ---------------------
; SGPRs: %u out of %u used
; VGPRs: %u out of %u used
; LDS: %u out of %u bytes used
; %u bytes scratch space used
; Instructions: %u ALU, %u Control Flow, %u TFETCH
)",
stats->numSgprsUsed, stats->availableSgprs, stats->numVgprsUsed, stats->availableVgprs,
stats->usedLdsBytes, stats->availableLdsBytes, stats->usedScratchBytes, stats->numAluInst,
stats->numControlFlowInst, stats->numTfetchInst);
ret.insert(ret.begin(), statStr.begin(), statStr.end());
}
std::string header = StringFormat::Fmt("; Disassembly for %s\n\n", target.c_str());
ret.insert(ret.begin(), header.begin(), header.end());
}
else
{
ret = "; Invalid ELF file generated";
}
freeShader(out.pShaderBinary);
return ret;
}
@@ -0,0 +1,150 @@
//=================================================================
// Copyright 2017 Advanced Micro Devices, Inc. All rights reserved.
//=================================================================
/**
***************************************************************************************************
* @file AmdDxGsaCompile.h
* @brief Backdoor GSA compile extension include file.
***************************************************************************************************
*/
#ifndef _AMDDXGSACOMPILE_H_
#define _AMDDXGSACOMPILE_H_
#include <windows.h>
#if defined(__cplusplus)
extern "C"
{
#endif
/**
***************************************************************************************************
* @brief Identifies compile options to be modified in AmdDxGsaCompileShader() call.
***************************************************************************************************
*/
typedef enum _AmdDxGsaCompileOptionEnum
{
AmdDxGsaBiasScheduleToMinimizeRegs,
AmdDxGsaNoIfConversion,
AmdDxGsaIfConversionGuarantee,
AmdDxGsaIfConversionHeuristic,
AmdDxGsaIfConversionHeuristicOgl,
AmdDxGsaIfConversionAlways,
AmdDxGsaEnableShaderIntrinsics,
AmdDxGsaShaderIntrinsicsUAVSlot,
AmdDxGsaCompileOptionLast
} AmdDxGsaCompileOptionEnum;
/**
***************************************************************************************************
* @brief Compiler settings/value pair specified in AmdDxGsaCompileShader() calls.
***************************************************************************************************
*/
typedef struct _AmdDxGsaCompileOption
{
AmdDxGsaCompileOptionEnum setting;
INT value;
} AmdDxGsaCompileOption;
/**
***************************************************************************************************
* @brief Stats about the compiled shader. This structure will be stored in the .stats ELF section
***************************************************************************************************
*/
typedef struct _AmdDxGsaCompileStats
{
UINT numSgprsUsed; ///< Number of SGPRs used by the shader
UINT availableSgprs; ///< Number of SGPRs available
UINT numVgprsUsed; ///< Number of VGPRs used by the shader
UINT availableVgprs; ///< Number of VGPRs available
UINT usedLdsBytes; ///< Bytes of LDS used by a thread group
UINT availableLdsBytes; ///< Bytes of LDS available to a thread group
UINT usedScratchBytes; ///< Bytes of scratch space used by the shader
UINT numAluInst; ///< Number of ALU instructions in the shader
UINT numControlFlowInst; ///< Number of control flow instructions in the shader
UINT numTfetchInst; ///< Number of HW TFETCHinstructions / Tx Units used
UINT reserved[6];
} AmdDxGsaCompileStats;
/**
***************************************************************************************************
* @brief Input type of shader code
***************************************************************************************************
*/
enum AmdDxGsaInputType
{
GsaInputDxAsmBin = 0, ///< DXASM binary
GsaInputIlText = 1 ///< IL text
};
/**
***************************************************************************************************
* @brief AmdDxGsaCompileShader() input structure.
***************************************************************************************************
*/
typedef struct _AmdDxGsaCompileShaderInput
{
/// Target GPU chip family (defined in atiid.h, e.g. FAMILY_SI). Only FAMILY_SI and later are
/// currently supported.
UINT chipFamily;
/// Target GPU chip revision (defined in hardware-specific chip headers, e.g. si_id.h).
UINT chipRevision;
/// Pointer to DXASM binary or IL text to be compiled.
const VOID* pShaderByteCode;
/// Length of pShaderByteCode in bytes.
SIZE_T byteCodeLength;
/// An array of setting/value pairs to control compilation options. NULL is valid, if all
/// default options are desired.
const AmdDxGsaCompileOption* pCompileOptions;
/// Length of pCompileOptions array.
UINT numCompileOptions;
/// Input type
AmdDxGsaInputType inputType;
/// Reserved entry must be set to all 0s.
UINT reserved[6];
} AmdDxGsaCompileShaderInput;
/**
***************************************************************************************************
* @brief AmdDxGsaCompileShader() output structure.
***************************************************************************************************
*/
typedef struct _AmdDxGsaCompileShaderOutput
{
/// Must be set to sizeof(AmdDxGsaCompileShaderOutput).
SIZE_T size;
/// Output ELF object. Contains the following sections:
// .amdil - IL binary
// .amdil_disassembly - IL text string
// .text - ISA binary
// .disassembly - ISA text string
// .stats - AmdDxGsaCompileStats structure
VOID* pShaderBinary;
/// Size of the ELF object in bytes.
SIZE_T shaderBinarySize;
} AmdDxGsaCompileShaderOutput;
HRESULT __cdecl AmdDxGsaCompileShader(const AmdDxGsaCompileShaderInput* pIn,
AmdDxGsaCompileShaderOutput* pOut);
typedef HRESULT (__cdecl *PfnAmdDxGsaCompileShader)(const AmdDxGsaCompileShaderInput*,
AmdDxGsaCompileShaderOutput*);
VOID __cdecl AmdDxGsaFreeCompiledShader(VOID* pShaderBinary);
typedef VOID (__cdecl *PfnAmdDxGsaFreeCompiledShader)(VOID*);
#if defined(__cplusplus)
}
#endif
#endif // _AMDDXGSACOMPILE_H_
@@ -0,0 +1,20 @@
Copyright (c) 2015 Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
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 Software.
THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@@ -0,0 +1,2 @@
Taken from https://github.com/GPUOpen-Tools/RGA in RadeonGPUAnalyzerBackend/include @ 1507bb1ddbca5872fd5e30f7a26240fe674f428f
@@ -0,0 +1,143 @@
//=================================================================
// Copyright 2017 Advanced Micro Devices, Inc. All rights reserved.
//=================================================================
#ifndef _CI_ID_H
#define _CI_ID_H
enum
{
CI_BONAIRE_M_A0 = 20,
CI_BONAIRE_M_A1 = 21,
CI_HAWAII_P_A0 = 40,
CI_MAUI_P_A0 = 60,
CI_UNKNOWN = 0xFF
};
#endif // _CI_ID_H
#ifndef _CZ_ID_H
#define _CZ_ID_H
enum
{
CARRIZO_A0 = 0x01,
CARRIZO_A1 = 0x02,
STONEY_A0 = 0x61,
CZ_UNKNOWN = 0xFF
};
#endif // _CZ_ID_H
#ifndef KV_ID_H
#define KV_ID_H
// SW revision section
enum
{
KV_SPECTRE_A0 = 0x01, // KV1 with Spectre GFX core, 8-8-1-2 (CU-Pix-Primitive-RB)
KV_SPOOKY_A0 = 0x41, // KV2 with Spooky GFX core, including downgraded from Spectre core, 3-4-1-1 (CU-Pix-Primitive-RB)
KB_KALINDI_A0 = 0x81, // KB with Kalindi GFX core, 2-4-1-1 (CU-Pix-Primitive-RB)
KB_KALINDI_A1 = 0x82, // KB with Kalindi GFX core, 2-4-1-1 (CU-Pix-Primitive-RB)
BV_KALINDI_A2 = 0x85, // BV with Kalindi GFX core, 2-4-1-1 (CU-Pix-Primitive-RB)
ML_GODAVARI_A0 = 0xa1, // ML with Godavari GFX core, 2-4-1-1 (CU-Pix-Primitive-RB)
ML_GODAVARI_A1 = 0xa2, // ML with Godavari GFX core, 2-4-1-1 (CU-Pix-Primitive-RB)
KV_UNKNOWN = 0xFF
};
#endif // KV_ID_H
#ifndef _SI_ID_H
#define _SI_ID_H
enum
{
SI_TAHITI_P_A11 = 1,
SI_TAHITI_P_A0 = SI_TAHITI_P_A11, //A0 is alias of A11
SI_TAHITI_P_A21 = 5,
SI_TAHITI_P_B0 = SI_TAHITI_P_A21, //B0 is alias of A21
SI_TAHITI_P_A22 = 6,
SI_TAHITI_P_B1 = SI_TAHITI_P_A22, //B1 is alias of A22
SI_PITCAIRN_PM_A11 = 20,
SI_PITCAIRN_PM_A0 = SI_PITCAIRN_PM_A11, //A0 is alias of A11
SI_PITCAIRN_PM_A12 = 21,
SI_PITCAIRN_PM_A1 = SI_PITCAIRN_PM_A12, //A1 is alias of A12
SI_CAPEVERDE_M_A11 = 40,
SI_CAPEVERDE_M_A0 = SI_CAPEVERDE_M_A11, //A0 is alias of A11
SI_CAPEVERDE_M_A12 = 41,
SI_CAPEVERDE_M_A1 = SI_CAPEVERDE_M_A12, //A1 is alias of A12
SI_OLAND_M_A0 = 60,
SI_HAINAN_V_A0 = 70,
SI_UNKNOWN = 0xFF
};
#endif // _SI_ID_H
#ifndef _VI_ID_H
#define _VI_ID_H
#endif
enum {
VI_ICELAND_M_A0 = 1,
VI_TONGA_P_A0 = 20,
VI_TONGA_P_A1 = 21,
VI_BERMUDA_P_A0 = 40,
VI_FIJI_P_A0 = 60,
VI_ELLESMERE_P_A0 = 80,
VI_ELLESMERE_P_A1 = 81,
VI_BAFFIN_M_A0 = 90,
VI_BAFFIN_M_A1 = 91,
VI_LEXA_V_A0 = 100,
VI_UNKNOWN = 0xFF
};
enum {
AI_GD_P0 = 1,
AI_GD_P1 = 2,
AI_UNKNOWN = 0xFF
};
#ifndef _ATIID_H
#define _ATIID_H
#define FAMILY_NI 100
#define FAMILY_NORTHERNISLAND FAMILY_NI
#define FAMILY_SI 110
#define FAMILY_TN 105
#define FAMILY_CI 120
#define FAMILY_KV 125
#define FAMILY_VI 130
#define FAMILY_CZ 135
#define FAMILY_PI 140
#define FAMILY_AI 141
#define ATI_VENDOR_ID 0x1002
#endif // _ATIID_H
@@ -0,0 +1,23 @@
* Copyright (c) 1996-1998 John D. Polstra.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
@@ -0,0 +1 @@
Taken from FreeBSD
@@ -0,0 +1,263 @@
/*-
* Copyright (c) 1996-1998 John D. Polstra.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _SYS_ELF32_H_
#define _SYS_ELF32_H_ 1
#include "elf_common.h"
/*
* ELF definitions common to all 32-bit architectures.
*/
typedef uint32_t Elf32_Addr;
typedef uint16_t Elf32_Half;
typedef uint32_t Elf32_Off;
typedef int32_t Elf32_Sword;
typedef uint32_t Elf32_Word;
typedef uint64_t Elf32_Lword;
typedef Elf32_Word Elf32_Hashelt;
/* Non-standard class-dependent datatype used for abstraction. */
typedef Elf32_Word Elf32_Size;
typedef Elf32_Sword Elf32_Ssize;
/*
* ELF header.
*/
typedef struct {
unsigned char e_ident[EI_NIDENT]; /* File identification. */
Elf32_Half e_type; /* File type. */
Elf32_Half e_machine; /* Machine architecture. */
Elf32_Word e_version; /* ELF format version. */
Elf32_Addr e_entry; /* Entry point. */
Elf32_Off e_phoff; /* Program header file offset. */
Elf32_Off e_shoff; /* Section header file offset. */
Elf32_Word e_flags; /* Architecture-specific flags. */
Elf32_Half e_ehsize; /* Size of ELF header in bytes. */
Elf32_Half e_phentsize; /* Size of program header entry. */
Elf32_Half e_phnum; /* Number of program header entries. */
Elf32_Half e_shentsize; /* Size of section header entry. */
Elf32_Half e_shnum; /* Number of section header entries. */
Elf32_Half e_shstrndx; /* Section name strings section. */
} Elf32_Ehdr;
/*
* Shared object information, found in SHT_MIPS_LIBLIST.
*/
typedef struct {
Elf32_Word l_name; /* The name of a shared object. */
Elf32_Word l_time_stamp; /* 32-bit timestamp. */
Elf32_Word l_checksum; /* Checksum of visible symbols, sizes. */
Elf32_Word l_version; /* Interface version string index. */
Elf32_Word l_flags; /* Flags (LL_*). */
} Elf32_Lib;
/*
* Section header.
*/
typedef struct {
Elf32_Word sh_name; /* Section name (index into the
section header string table). */
Elf32_Word sh_type; /* Section type. */
Elf32_Word sh_flags; /* Section flags. */
Elf32_Addr sh_addr; /* Address in memory image. */
Elf32_Off sh_offset; /* Offset in file. */
Elf32_Word sh_size; /* Size in bytes. */
Elf32_Word sh_link; /* Index of a related section. */
Elf32_Word sh_info; /* Depends on section type. */
Elf32_Word sh_addralign; /* Alignment in bytes. */
Elf32_Word sh_entsize; /* Size of each entry in section. */
} Elf32_Shdr;
/*
* Program header.
*/
typedef struct {
Elf32_Word p_type; /* Entry type. */
Elf32_Off p_offset; /* File offset of contents. */
Elf32_Addr p_vaddr; /* Virtual address in memory image. */
Elf32_Addr p_paddr; /* Physical address (not used). */
Elf32_Word p_filesz; /* Size of contents in file. */
Elf32_Word p_memsz; /* Size of contents in memory. */
Elf32_Word p_flags; /* Access permission flags. */
Elf32_Word p_align; /* Alignment in memory and file. */
} Elf32_Phdr;
/*
* Dynamic structure. The ".dynamic" section contains an array of them.
*/
typedef struct {
Elf32_Sword d_tag; /* Entry type. */
union {
Elf32_Word d_val; /* Integer value. */
Elf32_Addr d_ptr; /* Address value. */
} d_un;
} Elf32_Dyn;
/*
* Relocation entries.
*/
/* Relocations that don't need an addend field. */
typedef struct {
Elf32_Addr r_offset; /* Location to be relocated. */
Elf32_Word r_info; /* Relocation type and symbol index. */
} Elf32_Rel;
/* Relocations that need an addend field. */
typedef struct {
Elf32_Addr r_offset; /* Location to be relocated. */
Elf32_Word r_info; /* Relocation type and symbol index. */
Elf32_Sword r_addend; /* Addend. */
} Elf32_Rela;
/* Macros for accessing the fields of r_info. */
#define ELF32_R_SYM(info) ((info) >> 8)
#define ELF32_R_TYPE(info) ((unsigned char)(info))
/* Macro for constructing r_info from field values. */
#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type))
/*
* Note entry header
*/
typedef Elf_Note Elf32_Nhdr;
/*
* Move entry
*/
typedef struct {
Elf32_Lword m_value; /* symbol value */
Elf32_Word m_info; /* size + index */
Elf32_Word m_poffset; /* symbol offset */
Elf32_Half m_repeat; /* repeat count */
Elf32_Half m_stride; /* stride info */
} Elf32_Move;
/*
* The macros compose and decompose values for Move.r_info
*
* sym = ELF32_M_SYM(M.m_info)
* size = ELF32_M_SIZE(M.m_info)
* M.m_info = ELF32_M_INFO(sym, size)
*/
#define ELF32_M_SYM(info) ((info)>>8)
#define ELF32_M_SIZE(info) ((unsigned char)(info))
#define ELF32_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))
/*
* Hardware/Software capabilities entry
*/
typedef struct {
Elf32_Word c_tag; /* how to interpret value */
union {
Elf32_Word c_val;
Elf32_Addr c_ptr;
} c_un;
} Elf32_Cap;
/*
* Symbol table entries.
*/
typedef struct {
Elf32_Word st_name; /* String table index of name. */
Elf32_Addr st_value; /* Symbol value. */
Elf32_Word st_size; /* Size of associated object. */
unsigned char st_info; /* Type and binding information. */
unsigned char st_other; /* Reserved (not used). */
Elf32_Half st_shndx; /* Section index of symbol. */
} Elf32_Sym;
/* Macros for accessing the fields of st_info. */
#define ELF32_ST_BIND(info) ((info) >> 4)
#define ELF32_ST_TYPE(info) ((info) & 0xf)
/* Macro for constructing st_info from field values. */
#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
/* Macro for accessing the fields of st_other. */
#define ELF32_ST_VISIBILITY(oth) ((oth) & 0x3)
/* Structures used by Sun & GNU symbol versioning. */
typedef struct
{
Elf32_Half vd_version;
Elf32_Half vd_flags;
Elf32_Half vd_ndx;
Elf32_Half vd_cnt;
Elf32_Word vd_hash;
Elf32_Word vd_aux;
Elf32_Word vd_next;
} Elf32_Verdef;
typedef struct
{
Elf32_Word vda_name;
Elf32_Word vda_next;
} Elf32_Verdaux;
typedef struct
{
Elf32_Half vn_version;
Elf32_Half vn_cnt;
Elf32_Word vn_file;
Elf32_Word vn_aux;
Elf32_Word vn_next;
} Elf32_Verneed;
typedef struct
{
Elf32_Word vna_hash;
Elf32_Half vna_flags;
Elf32_Half vna_other;
Elf32_Word vna_name;
Elf32_Word vna_next;
} Elf32_Vernaux;
typedef Elf32_Half Elf32_Versym;
typedef struct {
Elf32_Half si_boundto; /* direct bindings - symbol bound to */
Elf32_Half si_flags; /* per symbol flags */
} Elf32_Syminfo;
typedef struct {
Elf32_Word ch_type;
Elf32_Word ch_size;
Elf32_Word ch_addralign;
} Elf32_Chdr;
#endif /* !_SYS_ELF32_H_ */
File diff suppressed because it is too large Load Diff
+15
View File
@@ -24,6 +24,7 @@
#include "vk_replay.h"
#include <float.h>
#include "driver/ihv/amd/amd_isa.h"
#include "maths/camera.h"
#include "maths/matrix.h"
#include "serialise/string_utils.h"
@@ -921,6 +922,17 @@ vector<string> VulkanReplay::GetDisassemblyTargets()
{
vector<string> ret;
std::string err;
if(GCNISA::IsSupported(GraphicsAPI::Vulkan, err))
{
GCNISA::GetTargets(GraphicsAPI::Vulkan, ret);
}
else
{
RDCLOG("AMD ISA Not available:\n%s", err.c_str());
}
// default is always first
ret.insert(ret.begin(), "SPIR-V (RenderDoc)");
// could add canonical disassembly here if spirv-dis is available
@@ -936,6 +948,7 @@ string VulkanReplay::DisassembleShader(const ShaderReflection *refl, const strin
if(it == m_pDriver->m_CreationInfo.m_ShaderModule.end())
return "Invalid Shader Specified";
if(target == "SPIR-V (RenderDoc)" || target.empty())
{
std::string &disasm = it->second.m_Reflections[refl->EntryPoint.c_str()].disassembly;
@@ -944,6 +957,8 @@ string VulkanReplay::DisassembleShader(const ShaderReflection *refl, const strin
return disasm;
}
return GCNISA::Disassemble(&it->second.spirv, refl->EntryPoint.c_str(), target);
}
void VulkanReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace,
Binary file not shown.