Engine is now installable

This commit is contained in:
Dynamitos
2022-11-22 22:11:37 +01:00
parent d401027caf
commit 3d3e264867
47 changed files with 323 additions and 1031 deletions
+14
View File
@@ -19,6 +19,20 @@ target_sources(Engine
VertexShaderInput.cpp
StaticMeshVertexInput.h
StaticMeshVertexInput.cpp)
target_sources(Engine
PUBLIC FILE_SET HEADERS
FILES
GraphicsResources.h
GraphicsInitializer.h
GraphicsEnums.h
Graphics.h
Mesh.h
MeshBatch.h
RenderMaterial.h
ShaderCompiler.h
VertexShaderInput.h
StaticMeshVertexInput.h)
add_subdirectory(RenderPass/)
add_subdirectory(Vulkan/)
+1 -3
View File
@@ -401,9 +401,7 @@ static Map<uint32, PVertexDeclaration> vertexDeclarationCache;
PVertexDeclaration VertexDeclaration::createDeclaration(PGraphics graphics, const Array<VertexElement>& elementList)
{
std::scoped_lock lock(vertexDeclarationLock);
boost::crc_32_type result;
result.process_bytes(&elementList, sizeof(VertexElement) * elementList.size());
uint32 key = result.checksum();
uint32 key = CRC::Calculate(&elementList, sizeof(VertexElement) * elementList.size(), CRC::CRC_32());
auto found = vertexDeclarationCache[key];
if(found == nullptr)
+2 -7
View File
@@ -3,10 +3,7 @@
#include "Containers/Array.h"
#include "Containers/List.h"
#include "GraphicsInitializer.h"
#pragma warning(push)
#pragma warning(disable: 4701)
#include <boost/crc.hpp>
#pragma warning(pop)
#include "CRC.h"
#include <functional>
@@ -103,9 +100,7 @@ struct PermutationId
{}
PermutationId(ShaderPermutation permutation)
{
boost::crc_32_type result;
result.process_bytes(&permutation, sizeof(ShaderPermutation));
hash = result.checksum();
hash = CRC::Calculate(&permutation, sizeof(ShaderPermutation), CRC::CRC_32());
}
friend inline bool operator==(const PermutationId& lhs, const PermutationId& rhs)
{
+3 -3
View File
@@ -9,9 +9,9 @@
using namespace Seele;
BasePassMeshProcessor::BasePassMeshProcessor(Gfx::PGraphics graphics, uint8 translucentBasePass)
BasePassMeshProcessor::BasePassMeshProcessor(Gfx::PGraphics graphics)
: MeshProcessor(graphics)
, translucentBasePass(translucentBasePass)
// , translucentBasePass(translucentBasePass)
//, cachedPrimitiveIndex(0)
{
}
@@ -71,7 +71,7 @@ void BasePassMeshProcessor::processMeshBatch(
BasePass::BasePass(Gfx::PGraphics graphics)
: RenderPass(graphics)
, processor(new BasePassMeshProcessor(graphics, false))
, processor(new BasePassMeshProcessor(graphics))
, descriptorSets(4)
{
UniformBufferCreateInfo uniformInitializer;
+2 -3
View File
@@ -8,7 +8,7 @@ namespace Seele
class BasePassMeshProcessor : public MeshProcessor
{
public:
BasePassMeshProcessor(Gfx::PGraphics graphics, uint8 translucentBasePass);
BasePassMeshProcessor(Gfx::PGraphics graphics);
virtual ~BasePassMeshProcessor();
virtual void processMeshBatch(
@@ -21,8 +21,7 @@ public:
int32 staticMeshId = -1) override;
private:
//Array<Gfx::PDescriptorSet> cachedPrimitiveSets;
Gfx::PViewport target;
uint8 translucentBasePass;
//uint8 translucentBasePass;
//uint32 cachedPrimitiveIndex;
};
DEFINE_REF(BasePassMeshProcessor)
+14 -1
View File
@@ -15,4 +15,17 @@ target_sources(Engine
TextPass.h
TextPass.cpp
UIPass.h
UIPass.cpp)
UIPass.cpp)
target_sources(Engine
PUBLIC FILE_SET HEADERS
FILES
BasePass.h
DepthPrepass.h
LightCullingPass.h
MeshProcessor.h
RenderGraph.h
RenderGraphResources.h
RenderPass.h
TextPass.h
UIPass.h)
+19 -5
View File
@@ -1,10 +1,5 @@
target_sources(Engine
PRIVATE
NsightAftermathGpuCrashTracker.h
NsightAftermathGpuCrashTracker.cpp
NsightAftermathHelpers.h
NsightAftermathShaderDatabase.h
NsightAftermathShaderDatabase.cpp
VulkanAllocator.h
VulkanAllocator.cpp
VulkanBuffer.cpp
@@ -34,3 +29,22 @@ target_sources(Engine
VulkanQueue.h
VulkanQueue.cpp
VulkanViewport.cpp)
target_sources(Engine
PUBLIC FILE_SET HEADERS
FILES
VulkanAllocator.h
VulkanBuffer.cpp
VulkanCommandBuffer.h
VulkanFramebuffer.h
VulkanGraphics.h
VulkanGraphicsResources.h
VulkanDescriptorSets.h
VulkanGraphicsEnums.h
VulkanInitializer.h
VulkanRenderPass.h
VulkanPipeline.h
VulkanPipelineCache.h
VulkanShader.h
VulkanQueue.h)
@@ -1,346 +0,0 @@
//*********************************************************
//
// Copyright (c) 2019-2020, NVIDIA CORPORATION. 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.
//
//*********************************************************
#include <fstream>
#include <iomanip>
#include <string>
#include "NsightAftermathGpuCrashTracker.h"
//*********************************************************
// GpuCrashTracker implementation
//*********************************************************
GpuCrashTracker::GpuCrashTracker()
: m_initialized(false)
, m_mutex()
, m_shaderDebugInfo()
, m_shaderDatabase()
{
}
GpuCrashTracker::~GpuCrashTracker()
{
// If initialized, disable GPU crash dumps
if (m_initialized)
{
AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_DisableGpuCrashDumps());
}
}
// Initialize the GPU Crash Dump Tracker
void GpuCrashTracker::Initialize()
{
// Enable GPU crash dumps and set up the callbacks for crash dump notifications,
// shader debug information notifications, and providing additional crash
// dump description data.Only the crash dump callback is mandatory. The other two
// callbacks are optional and can be omitted, by passing nullptr, if the corresponding
// functionality is not used.
// The DeferDebugInfoCallbacks flag enables caching of shader debug information data
// in memory. If the flag is set, ShaderDebugInfoCallback will be called only
// in the event of a crash, right before GpuCrashDumpCallback. If the flag is not set,
// ShaderDebugInfoCallback will be called for every shader that is compiled.
AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_EnableGpuCrashDumps(
GFSDK_Aftermath_Version_API,
GFSDK_Aftermath_GpuCrashDumpWatchedApiFlags_Vulkan,
GFSDK_Aftermath_GpuCrashDumpFeatureFlags_DeferDebugInfoCallbacks, // Let the Nsight Aftermath library cache shader debug information.
GpuCrashDumpCallback, // Register callback for GPU crash dumps.
ShaderDebugInfoCallback, // Register callback for shader debug information.
CrashDumpDescriptionCallback, // Register callback for GPU crash dump description.
this)); // Set the GpuCrashTracker object as user data for the above callbacks.
m_initialized = true;
}
// Handler for GPU crash dump callbacks from Nsight Aftermath
void GpuCrashTracker::OnCrashDump(const void* pGpuCrashDump, const uint32_t gpuCrashDumpSize)
{
// Make sure only one thread at a time...
std::scoped_lock<std::mutex> lock(m_mutex);
// Write to file for later in-depth analysis with Nsight Graphics.
WriteGpuCrashDumpToFile(pGpuCrashDump, gpuCrashDumpSize);
}
// Handler for shader debug information callbacks
void GpuCrashTracker::OnShaderDebugInfo(const void* pShaderDebugInfo, const uint32_t shaderDebugInfoSize)
{
// Make sure only one thread at a time...
std::scoped_lock<std::mutex> lock(m_mutex);
// Get shader debug information identifier
GFSDK_Aftermath_ShaderDebugInfoIdentifier identifier = {};
AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GetShaderDebugInfoIdentifier(
GFSDK_Aftermath_Version_API,
pShaderDebugInfo,
shaderDebugInfoSize,
&identifier));
// Store information for decoding of GPU crash dumps with shader address mapping
// from within the application.
std::vector<uint8_t> data((uint8_t*)pShaderDebugInfo, (uint8_t*)pShaderDebugInfo + shaderDebugInfoSize);
m_shaderDebugInfo[identifier].swap(data);
// Write to file for later in-depth analysis of crash dumps with Nsight Graphics
WriteShaderDebugInformationToFile(identifier, pShaderDebugInfo, shaderDebugInfoSize);
}
// Handler for GPU crash dump description callbacks
void GpuCrashTracker::OnDescription(PFN_GFSDK_Aftermath_AddGpuCrashDumpDescription addDescription)
{
// Add some basic description about the crash. This is called after the GPU crash happens, but before
// the actual GPU crash dump callback. The provided data is included in the crash dump and can be
// retrieved using GFSDK_Aftermath_GpuCrashDump_GetDescription().
addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_ApplicationName, "VkHelloNsightAftermath");
addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_ApplicationVersion, "v1.0");
addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_UserDefined, "This is a GPU crash dump example.");
addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_UserDefined + 1, "Engine State: Rendering.");
addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_UserDefined + 2, "More user-defined information...");
}
// Helper for writing a GPU crash dump to a file
void GpuCrashTracker::WriteGpuCrashDumpToFile(const void* pGpuCrashDump, const uint32_t gpuCrashDumpSize)
{
// Create a GPU crash dump decoder object for the GPU crash dump.
GFSDK_Aftermath_GpuCrashDump_Decoder decoder = {};
AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_CreateDecoder(
GFSDK_Aftermath_Version_API,
pGpuCrashDump,
gpuCrashDumpSize,
&decoder));
// Use the decoder object to read basic information, like application
// name, PID, etc. from the GPU crash dump.
GFSDK_Aftermath_GpuCrashDump_BaseInfo baseInfo = {};
AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_GetBaseInfo(decoder, &baseInfo));
// Use the decoder object to query the application name that was set
// in the GPU crash dump description.
uint32_t applicationNameLength = 0;
AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_GetDescriptionSize(
decoder,
GFSDK_Aftermath_GpuCrashDumpDescriptionKey_ApplicationName,
&applicationNameLength));
std::vector<char> applicationName(applicationNameLength, '\0');
AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_GetDescription(
decoder,
GFSDK_Aftermath_GpuCrashDumpDescriptionKey_ApplicationName,
uint32_t(applicationName.size()),
applicationName.data()));
// Create a unique file name for writing the crash dump data to a file.
// Note: due to an Nsight Aftermath bug (will be fixed in an upcoming
// driver release) we may see redundant crash dumps. As a workaround,
// attach a unique count to each generated file name.
static int count = 0;
const std::string baseFileName =
std::string(applicationName.data())
+ "-"
+ std::to_string(baseInfo.pid)
+ "-"
+ std::to_string(++count);
// Write the the crash dump data to a file using the .nv-gpudmp extension
// registered with Nsight Graphics.
const std::string crashDumpFileName = baseFileName + ".nv-gpudmp";
std::ofstream dumpFile(crashDumpFileName, std::ios::out | std::ios::binary);
if (dumpFile)
{
dumpFile.write((const char*)pGpuCrashDump, gpuCrashDumpSize);
dumpFile.close();
}
// Decode the crash dump to a JSON string.
// Step 1: Generate the JSON and get the size.
uint32_t jsonSize = 0;
AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_GenerateJSON(
decoder,
GFSDK_Aftermath_GpuCrashDumpDecoderFlags_ALL_INFO,
GFSDK_Aftermath_GpuCrashDumpFormatterFlags_NONE,
ShaderDebugInfoLookupCallback,
ShaderLookupCallback,
nullptr,
ShaderSourceDebugInfoLookupCallback,
this,
&jsonSize));
// Step 2: Allocate a buffer and fetch the generated JSON.
std::vector<char> json(jsonSize);
AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_GetJSON(
decoder,
uint32_t(json.size()),
json.data()));
// Write the the crash dump data as JSON to a file.
const std::string jsonFileName = crashDumpFileName + ".json";
std::ofstream jsonFile(jsonFileName, std::ios::out | std::ios::binary);
if (jsonFile)
{
jsonFile.write(json.data(), json.size());
jsonFile.close();
}
// Destroy the GPU crash dump decoder object.
AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_DestroyDecoder(decoder));
}
// Helper for writing shader debug information to a file
void GpuCrashTracker::WriteShaderDebugInformationToFile(
GFSDK_Aftermath_ShaderDebugInfoIdentifier identifier,
const void* pShaderDebugInfo,
const uint32_t shaderDebugInfoSize)
{
// Create a unique file name.
const std::string filePath = "shader-" + std::to_string(identifier) + ".nvdbg";
std::ofstream f(filePath, std::ios::out | std::ios::binary);
if (f)
{
f.write((const char*)pShaderDebugInfo, shaderDebugInfoSize);
}
}
// Handler for shader debug information lookup callbacks.
// This is used by the JSON decoder for mapping shader instruction
// addresses to DXIL lines or HLSl source lines.
void GpuCrashTracker::OnShaderDebugInfoLookup(
const GFSDK_Aftermath_ShaderDebugInfoIdentifier& identifier,
PFN_GFSDK_Aftermath_SetData setShaderDebugInfo) const
{
// Search the list of shader debug information blobs received earlier.
auto i_debugInfo = m_shaderDebugInfo.find(identifier);
if (i_debugInfo == m_shaderDebugInfo.end())
{
// Early exit, nothing found. No need to call setShaderDebugInfo.
return;
}
// Let the GPU crash dump decoder know about the shader debug information
// that was found.
setShaderDebugInfo(i_debugInfo->second.data(), uint32_t(i_debugInfo->second.size()));
}
// Handler for shader lookup callbacks.
// This is used by the JSON decoder for mapping shader instruction
// addresses to DXIL lines or HLSL source lines.
// NOTE: If the application loads stripped shader binaries (-Qstrip_debug),
// Aftermath will require access to both the stripped and the not stripped
// shader binaries.
void GpuCrashTracker::OnShaderLookup(
const GFSDK_Aftermath_ShaderHash& shaderHash,
PFN_GFSDK_Aftermath_SetData setShaderBinary) const
{
// Find shader binary data for the shader hash in the shader database.
std::vector<uint8_t> shaderBinary;
if (!m_shaderDatabase.FindShaderBinary(shaderHash, shaderBinary))
{
// Early exit, nothing found. No need to call setShaderBinary.
return;
}
// Let the GPU crash dump decoder know about the shader data
// that was found.
setShaderBinary(shaderBinary.data(), uint32_t(shaderBinary.size()));
}
// Handler for shader source debug info lookup callbacks.
// This is used by the JSON decoder for mapping shader instruction addresses to
// HLSL source lines, if the shaders used by the application were compiled with
// separate debug info data files.
void GpuCrashTracker::OnShaderSourceDebugInfoLookup(
const GFSDK_Aftermath_ShaderDebugName& shaderDebugName,
PFN_GFSDK_Aftermath_SetData setShaderBinary) const
{
// Find source debug info for the shader DebugName in the shader database.
std::vector<uint8_t> shaderBinary;
if (!m_shaderDatabase.FindShaderBinaryWithDebugData(shaderDebugName, shaderBinary))
{
// Early exit, nothing found. No need to call setShaderBinary.
return;
}
// Let the GPU crash dump decoder know about the shader debug data that was
// found.
setShaderBinary(shaderBinary.data(), uint32_t(shaderBinary.size()));
}
// Static callback wrapper for OnCrashDump
void GpuCrashTracker::GpuCrashDumpCallback(
const void* pGpuCrashDump,
const uint32_t gpuCrashDumpSize,
void* pUserData)
{
GpuCrashTracker* pGpuCrashTracker = reinterpret_cast<GpuCrashTracker*>(pUserData);
pGpuCrashTracker->OnCrashDump(pGpuCrashDump, gpuCrashDumpSize);
}
// Static callback wrapper for OnShaderDebugInfo
void GpuCrashTracker::ShaderDebugInfoCallback(
const void* pShaderDebugInfo,
const uint32_t shaderDebugInfoSize,
void* pUserData)
{
GpuCrashTracker* pGpuCrashTracker = reinterpret_cast<GpuCrashTracker*>(pUserData);
pGpuCrashTracker->OnShaderDebugInfo(pShaderDebugInfo, shaderDebugInfoSize);
}
// Static callback wrapper for OnDescription
void GpuCrashTracker::CrashDumpDescriptionCallback(
PFN_GFSDK_Aftermath_AddGpuCrashDumpDescription addDescription,
void* pUserData)
{
GpuCrashTracker* pGpuCrashTracker = reinterpret_cast<GpuCrashTracker*>(pUserData);
pGpuCrashTracker->OnDescription(addDescription);
}
// Static callback wrapper for OnShaderDebugInfoLookup
void GpuCrashTracker::ShaderDebugInfoLookupCallback(
const GFSDK_Aftermath_ShaderDebugInfoIdentifier* pIdentifier,
PFN_GFSDK_Aftermath_SetData setShaderDebugInfo,
void* pUserData)
{
GpuCrashTracker* pGpuCrashTracker = reinterpret_cast<GpuCrashTracker*>(pUserData);
pGpuCrashTracker->OnShaderDebugInfoLookup(*pIdentifier, setShaderDebugInfo);
}
// Static callback wrapper for OnShaderLookup
void GpuCrashTracker::ShaderLookupCallback(
const GFSDK_Aftermath_ShaderHash* pShaderHash,
PFN_GFSDK_Aftermath_SetData setShaderBinary,
void* pUserData)
{
GpuCrashTracker* pGpuCrashTracker = reinterpret_cast<GpuCrashTracker*>(pUserData);
pGpuCrashTracker->OnShaderLookup(*pShaderHash, setShaderBinary);
}
// Static callback wrapper for OnShaderSourceDebugInfoLookup
void GpuCrashTracker::ShaderSourceDebugInfoLookupCallback(
const GFSDK_Aftermath_ShaderDebugName* pShaderDebugName,
PFN_GFSDK_Aftermath_SetData setShaderBinary,
void* pUserData)
{
GpuCrashTracker* pGpuCrashTracker = reinterpret_cast<GpuCrashTracker*>(pUserData);
pGpuCrashTracker->OnShaderSourceDebugInfoLookup(*pShaderDebugName, setShaderBinary);
}
@@ -1,159 +0,0 @@
//*********************************************************
//
// Copyright (c) 2019-2020, NVIDIA CORPORATION. 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.
//
//*********************************************************
#pragma once
#include <map>
#include <mutex>
#include "NsightAftermathHelpers.h"
#include "NsightAftermathShaderDatabase.h"
//*********************************************************
// Implements GPU crash dump tracking using the Nsight
// Aftermath API.
//
class GpuCrashTracker
{
public:
GpuCrashTracker();
~GpuCrashTracker();
// Initialize the GPU crash dump tracker.
void Initialize();
private:
//*********************************************************
// Callback handlers for GPU crash dumps and related data.
//
// Handler for GPU crash dump callbacks.
void OnCrashDump(const void* pGpuCrashDump, const uint32_t gpuCrashDumpSize);
// Handler for shader debug information callbacks.
void OnShaderDebugInfo(const void* pShaderDebugInfo, const uint32_t shaderDebugInfoSize);
// Handler for GPU crash dump description callbacks.
void OnDescription(PFN_GFSDK_Aftermath_AddGpuCrashDumpDescription addDescription);
//*********************************************************
// Helpers for writing a GPU crash dump and debug information
// data to files.
//
// Helper for writing a GPU crash dump to a file.
void WriteGpuCrashDumpToFile(const void* pGpuCrashDump, const uint32_t gpuCrashDumpSize);
// Helper for writing shader debug information to a file
void WriteShaderDebugInformationToFile(
GFSDK_Aftermath_ShaderDebugInfoIdentifier identifier,
const void* pShaderDebugInfo,
const uint32_t shaderDebugInfoSize);
//*********************************************************
// Helpers for decoding GPU crash dump to JSON.
//
// Handler for shader debug info lookup callbacks.
void OnShaderDebugInfoLookup(
const GFSDK_Aftermath_ShaderDebugInfoIdentifier& identifier,
PFN_GFSDK_Aftermath_SetData setShaderDebugInfo) const;
// Handler for shader lookup callbacks.
void OnShaderLookup(
const GFSDK_Aftermath_ShaderHash& shaderHash,
PFN_GFSDK_Aftermath_SetData setShaderBinary) const;
// Handler for shader instructions lookup callbacks.
void OnShaderInstructionsLookup(
const GFSDK_Aftermath_ShaderInstructionsHash& shaderInstructionsHash,
PFN_GFSDK_Aftermath_SetData setShaderBinary) const;
// Handler for shader source debug info lookup callbacks.
void OnShaderSourceDebugInfoLookup(
const GFSDK_Aftermath_ShaderDebugName& shaderDebugName,
PFN_GFSDK_Aftermath_SetData setShaderBinary) const;
//*********************************************************
// Static callback wrappers.
//
// GPU crash dump callback.
static void GpuCrashDumpCallback(
const void* pGpuCrashDump,
const uint32_t gpuCrashDumpSize,
void* pUserData);
// Shader debug information callback.
static void ShaderDebugInfoCallback(
const void* pShaderDebugInfo,
const uint32_t shaderDebugInfoSize,
void* pUserData);
// GPU crash dump description callback.
static void CrashDumpDescriptionCallback(
PFN_GFSDK_Aftermath_AddGpuCrashDumpDescription addDescription,
void* pUserData);
// Shader debug information lookup callback.
static void ShaderDebugInfoLookupCallback(
const GFSDK_Aftermath_ShaderDebugInfoIdentifier* pIdentifier,
PFN_GFSDK_Aftermath_SetData setShaderDebugInfo,
void* pUserData);
// Shader lookup callback.
static void ShaderLookupCallback(
const GFSDK_Aftermath_ShaderHash* pShaderHash,
PFN_GFSDK_Aftermath_SetData setShaderBinary,
void* pUserData);
// Shader instructions lookup callback.
static void ShaderInstructionsLookupCallback(
const GFSDK_Aftermath_ShaderInstructionsHash* pShaderInstructionsHash,
PFN_GFSDK_Aftermath_SetData setShaderBinary,
void* pUserData);
// Shader source debug info lookup callback.
static void ShaderSourceDebugInfoLookupCallback(
const GFSDK_Aftermath_ShaderDebugName* pShaderDebugName,
PFN_GFSDK_Aftermath_SetData setShaderBinary,
void* pUserData);
//*********************************************************
// GPU crash tracker state.
//
// Is the GPU crash dump tracker initialized?
bool m_initialized;
// For thread-safe access of GPU crash tracker state.
mutable std::mutex m_mutex;
// List of Shader Debug Information by ShaderDebugInfoIdentifier.
std::map<GFSDK_Aftermath_ShaderDebugInfoIdentifier, std::vector<uint8_t>> m_shaderDebugInfo;
// The mock shader database.
ShaderDatabase m_shaderDatabase;
};
@@ -1,142 +0,0 @@
//*********************************************************
//
// Copyright (c) 2019, NVIDIA CORPORATION. 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.
//
//*********************************************************
#pragma once
#include <iomanip>
#include <string>
#include <sstream>
#include <vulkan/vulkan.hpp>
#include "GFSDK_Aftermath.h"
#include "GFSDK_Aftermath_GpuCrashDump.h"
#include "GFSDK_Aftermath_GpuCrashDumpDecoding.h"
//*********************************************************
// Some std::to_string overloads for some Nsight Aftermath
// API types.
//
namespace std
{
template<typename T>
inline std::string to_hex_string(T n)
{
std::stringstream stream;
stream << std::setfill('0') << std::setw(2 * sizeof(T)) << std::hex << n;
return stream.str();
}
inline std::string to_string(GFSDK_Aftermath_Result result)
{
return std::string("0x") + to_hex_string(static_cast<uint32_t>(result));
}
inline std::string to_string(const GFSDK_Aftermath_ShaderDebugInfoIdentifier& identifier)
{
return to_hex_string(identifier.id[0]) + "-" + to_hex_string(identifier.id[1]);
}
inline std::string to_string(const GFSDK_Aftermath_ShaderHash& hash)
{
return to_hex_string(hash.hash);
}
inline std::string to_string(const GFSDK_Aftermath_ShaderInstructionsHash& hash)
{
return to_hex_string(hash.hash) + "-" + to_hex_string(hash.hash);
}
} // namespace std
//*********************************************************
// Helper for comparing shader hashes and debug info identifier.
//
// Helper for comparing GFSDK_Aftermath_ShaderDebugInfoIdentifier.
inline bool operator<(const GFSDK_Aftermath_ShaderDebugInfoIdentifier& lhs, const GFSDK_Aftermath_ShaderDebugInfoIdentifier& rhs)
{
if (lhs.id[0] == rhs.id[0])
{
return lhs.id[1] < rhs.id[1];
}
return lhs.id[0] < rhs.id[0];
}
// Helper for comparing GFSDK_Aftermath_ShaderHash.
inline bool operator<(const GFSDK_Aftermath_ShaderHash& lhs, const GFSDK_Aftermath_ShaderHash& rhs)
{
return lhs.hash < rhs.hash;
}
// Helper for comparing GFSDK_Aftermath_ShaderInstructionsHash.
inline bool operator<(const GFSDK_Aftermath_ShaderInstructionsHash& lhs, const GFSDK_Aftermath_ShaderInstructionsHash& rhs)
{
return lhs.hash < rhs.hash;
}
// Helper for comparing GFSDK_Aftermath_ShaderDebugName.
inline bool operator<(const GFSDK_Aftermath_ShaderDebugName& lhs, const GFSDK_Aftermath_ShaderDebugName& rhs)
{
return strncmp(lhs.name, rhs.name, sizeof(lhs.name)) < 0;
}
//*********************************************************
// Helper for checking Nsight Aftermath failures.
//
inline std::string AftermathErrorMessage(GFSDK_Aftermath_Result result)
{
switch (result)
{
case GFSDK_Aftermath_Result_FAIL_DriverVersionNotSupported:
return "Unsupported driver version - requires a recent NVIDIA R445 display driver or newer.";
default:
return "Aftermath Error 0x" + std::to_hex_string(result);
}
}
// Helper macro for checking Nsight Aftermath results and throwing exception
// in case of a failure.
#ifdef _WIN32
#define AFTERMATH_CHECK_ERROR(FC) \
[&]() { \
GFSDK_Aftermath_Result _result = FC; \
if (!GFSDK_Aftermath_SUCCEED(_result)) \
{ \
std::cout << AftermathErrorMessage(_result).c_str() << std::endl; \
exit(1); \
} \
}()
#else
#define AFTERMATH_CHECK_ERROR(FC) \
[&]() { \
GFSDK_Aftermath_Result _result = FC; \
if (!GFSDK_Aftermath_SUCCEED(_result)) \
{ \
printf("%s\n", AftermathErrorMessage(_result).c_str()); \
fflush(stdout); \
exit(1); \
} \
}()
#endif
@@ -1,147 +0,0 @@
//*********************************************************
//
// Copyright (c) 2019-2020, NVIDIA CORPORATION. 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.
//
//*********************************************************
#include <fstream>
#include <iomanip>
#include "NsightAftermathShaderDatabase.h"
//*********************************************************
// ShaderDatabase implementation
//*********************************************************
ShaderDatabase::ShaderDatabase()
: m_shaderBinaries()
, m_shaderBinariesWithDebugInfo()
{
// Add shader binaries to database
AddShaderBinary("cube.vert.spirv");
AddShaderBinary("cube.frag.spirv");
// Add the not stripped shader binaries to the database, too.
AddShaderBinaryWithDebugInfo("cube.vert.spirv", "cube.vert.full.spirv");
AddShaderBinaryWithDebugInfo("cube.frag.spirv", "cube.frag.full.spirv");
}
ShaderDatabase::~ShaderDatabase()
{
}
bool ShaderDatabase::ReadFile(const char* filename, std::vector<uint8_t>& data)
{
std::ifstream fs(filename, std::ios::in | std::ios::binary);
if (!fs)
{
return false;
}
fs.seekg(0, std::ios::end);
data.resize(fs.tellg());
fs.seekg(0, std::ios::beg);
fs.read(reinterpret_cast<char*>(data.data()), data.size());
fs.close();
return true;
}
void ShaderDatabase::AddShaderBinary(const char* shaderFilePath)
{
// Read the shader binary code from the file
std::vector<uint8_t> data;
if (!ReadFile(shaderFilePath, data))
{
return;
}
// Create shader hash for the shader
const GFSDK_Aftermath_SpirvCode shader{ data.data(), uint32_t(data.size()) };
GFSDK_Aftermath_ShaderHash shaderHash;
AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GetShaderHashSpirv(
GFSDK_Aftermath_Version_API,
&shader,
&shaderHash));
// Store the data for shader mapping when decoding GPU crash dumps.
// cf. FindShaderBinary()
m_shaderBinaries[shaderHash].swap(data);
}
void ShaderDatabase::AddShaderBinaryWithDebugInfo(const char* strippedShaderFilePath, const char* shaderFilePath)
{
// Read the shader debug data from the file
std::vector<uint8_t> data;
if (!ReadFile(shaderFilePath, data))
{
return;
}
std::vector<uint8_t> strippedData;
if (!ReadFile(strippedShaderFilePath, strippedData))
{
return;
}
// Generate shader debug name.
GFSDK_Aftermath_ShaderDebugName debugName;
const GFSDK_Aftermath_SpirvCode shader{ data.data(), uint32_t(data.size()) };
const GFSDK_Aftermath_SpirvCode strippedShader{ strippedData.data(), uint32_t(strippedData.size()) };
AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GetShaderDebugNameSpirv(
GFSDK_Aftermath_Version_API,
&shader,
&strippedShader,
&debugName));
// Store the data for shader instruction address mapping when decoding GPU crash dumps.
// cf. FindShaderBinaryWithDebugData()
m_shaderBinariesWithDebugInfo[debugName].swap(data);
}
// Find a shader binary by shader hash.
bool ShaderDatabase::FindShaderBinary(const GFSDK_Aftermath_ShaderHash& shaderHash, std::vector<uint8_t>& shader) const
{
// Find shader binary data for the shader hash
auto i_shader = m_shaderBinaries.find(shaderHash);
if (i_shader == m_shaderBinaries.end())
{
// Nothing found.
return false;
}
shader = i_shader->second;
return true;
}
// Find a shader binary with debug information by shader debug name.
bool ShaderDatabase::FindShaderBinaryWithDebugData(const GFSDK_Aftermath_ShaderDebugName& shaderDebugName, std::vector<uint8_t>& shader) const
{
// Find shader binary for the shader debug name.
auto i_shader = m_shaderBinariesWithDebugInfo.find(shaderDebugName);
if (i_shader == m_shaderBinariesWithDebugInfo.end())
{
// Nothing found.
return false;
}
shader = i_shader->second;
return true;
}
@@ -1,64 +0,0 @@
//*********************************************************
//
// Copyright (c) 2019, NVIDIA CORPORATION. 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.
//
//*********************************************************
#pragma once
#include <vector>
#include <map>
#include <mutex>
#include "NsightAftermathHelpers.h"
//*********************************************************
// Implements a very simple shader database to help demonstrate
// how to use the Nsight Aftermath GPU crash dump decoder API.
//
// In a real world scenario this would be part of an offline
// analysis tool. This is for demonstration purposes only!
//
class ShaderDatabase
{
public:
ShaderDatabase();
~ShaderDatabase();
// Find a shader bytecode binary by shader hash.
bool FindShaderBinary(const GFSDK_Aftermath_ShaderHash& shaderHash, std::vector<uint8_t>& shader) const;
// Find a source shader debug info by shader debug name generated by the DXC compiler.
bool FindShaderBinaryWithDebugData(const GFSDK_Aftermath_ShaderDebugName& shaderDebugName, std::vector<uint8_t>& shader) const;
private:
void AddShaderBinary(const char* shaderFilePath);
void AddShaderBinaryWithDebugInfo(const char* strippedShaderFilePath, const char* shaderFilePath);
static bool ReadFile(const char* filename, std::vector<uint8_t>& data);
// List of shader binaries by ShaderHash.
std::map<GFSDK_Aftermath_ShaderHash, std::vector<uint8_t>> m_shaderBinaries;
// List of available shader binaries with source debug information by ShaderDebugName.
std::map<GFSDK_Aftermath_ShaderDebugName, std::vector<uint8_t>> m_shaderBinariesWithDebugInfo;
};
@@ -53,9 +53,7 @@ void DescriptorLayout::create()
allocator = new DescriptorAllocator(graphics, *this);
boost::crc_32_type result;
result.process_bytes(bindings.data(), sizeof(VkDescriptorSetLayoutBinding) * bindings.size());
hash = result.checksum();
hash = CRC::Calculate(bindings.data(), sizeof(VkDescriptorSetLayoutBinding) * bindings.size(), CRC::CRC_32());
}
PipelineLayout::~PipelineLayout()
@@ -96,10 +94,8 @@ void PipelineLayout::create()
createInfo.pushConstantRangeCount = (uint32)vkPushConstants.size();
createInfo.pPushConstantRanges = vkPushConstants.data();
boost::crc_32_type result;
result.process_bytes(createInfo.pPushConstantRanges, sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount);
result.process_bytes(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount);
layoutHash = result.checksum();
layoutHash = CRC::Calculate(createInfo.pPushConstantRanges, sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount, CRC::CRC_32());
layoutHash = CRC::Calculate(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount, CRC::CRC_32(), layoutHash);
if(layoutCache[layoutHash] != VK_NULL_HANDLE)
{
@@ -52,9 +52,7 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::PRende
VK_CHECK(vkCreateFramebuffer(graphics->getDevice(), &createInfo, nullptr, &handle));
boost::crc_32_type result;
result.process_bytes(&description, sizeof(FramebufferDescription));
hash = result.checksum();
hash = CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32());
}
Framebuffer::~Framebuffer()
@@ -417,8 +417,6 @@ void Graphics::setupDebugCallback()
VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT);
VK_CHECK(CreateDebugReportCallbackEXT(instance, &createInfo, nullptr, &callback));
crashTracker.Initialize();
}
void Graphics::pickPhysicalDevice()
@@ -1,7 +1,6 @@
#pragma once
#include "VulkanGraphicsResources.h"
#include "Graphics/Graphics.h"
#include "NsightAftermathGpuCrashTracker.h"
namespace Seele
{
@@ -100,7 +99,6 @@ protected:
Map<uint32, PFramebuffer> allocatedFramebuffers;
PAllocator allocator;
PStagingManager stagingManager;
GpuCrashTracker crashTracker;
friend class Window;
};
@@ -318,9 +318,7 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
PPipelineLayout layout = gfxInfo.pipelineLayout.cast<PipelineLayout>();
hashStruct.pipelineLayoutHash = layout->getHash();
boost::crc_32_type crc;
crc.process_bytes(&hashStruct, sizeof(PipelineCreateHashStruct));
uint32 hash = crc.checksum();
uint32 hash = CRC::Calculate(&hashStruct, sizeof(PipelineCreateHashStruct), CRC::CRC_32());
VkPipeline pipelineHandle;
std::scoped_lock lock(createdPipelinesLock);
@@ -142,7 +142,5 @@ uint32 RenderPass::getFramebufferHash()
PTexture2D tex = layout->depthAttachment->getTexture().cast<Texture2D>();
description.depthAttachment = tex->getView();
}
boost::crc_32_type result;
result.process_bytes(&description, sizeof(FramebufferDescription));
return result.checksum();
return CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32());
}
+2 -4
View File
@@ -155,8 +155,6 @@ void Shader::create(const ShaderCreateInfo& createInfo)
moduleInfo.pCode = (uint32_t*)kernelBlob->getBufferPointer();
VK_CHECK(vkCreateShaderModule(graphics->getDevice(), &moduleInfo, nullptr, &module));
boost::crc_32_type result;
result.process_bytes(entryPointName.data(), entryPointName.size());
result.process_bytes(kernelBlob->getBufferPointer(), kernelBlob->getBufferSize());
hash = result.checksum();
hash = CRC::Calculate(entryPointName.data(), entryPointName.size(), CRC::CRC_32());
hash = CRC::Calculate(kernelBlob->getBufferPointer(), kernelBlob->getBufferSize(), CRC::CRC_32(), hash);
}