diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 03b92abda..d05f9e759 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -5,6 +5,7 @@ #include "dxvk_include.h" #include "dxvk_limits.h" #include "dxvk_pipelayout.h" +#include "dxvk_shader_key.h" #include "../spirv/spirv_code_buffer.h" diff --git a/src/dxvk/dxvk_shader_key.cpp b/src/dxvk/dxvk_shader_key.cpp new file mode 100644 index 000000000..013cf7fb8 --- /dev/null +++ b/src/dxvk/dxvk_shader_key.cpp @@ -0,0 +1,51 @@ +#include "dxvk_shader_key.h" + +namespace dxvk { + + DxvkShaderKey::DxvkShaderKey() + : m_type(0), + m_sha1(Sha1Hash::compute(nullptr, 0)) { } + + + DxvkShaderKey::DxvkShaderKey( + VkShaderStageFlagBits shaderStage, + const void* sourceCode, + size_t sourceSize) + : m_type(shaderStage), + m_sha1(Sha1Hash::compute(reinterpret_cast(sourceCode), sourceSize)) { } + + + std::string DxvkShaderKey::toString() const { + const char* prefix = nullptr; + + switch (m_type) { + case VK_SHADER_STAGE_VERTEX_BIT: prefix = "VS_"; break; + case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: prefix = "TCS_"; break; + case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: prefix = "TES_"; break; + case VK_SHADER_STAGE_GEOMETRY_BIT: prefix = "GS_"; break; + case VK_SHADER_STAGE_FRAGMENT_BIT: prefix = "FS_"; break; + case VK_SHADER_STAGE_COMPUTE_BIT: prefix = "CS_"; break; + default: prefix = ""; + } + + return str::format(prefix, m_sha1.toString()); + } + + + size_t DxvkShaderKey::hash() const { + DxvkHashState result; + result.add(uint32_t(m_type)); + + for (uint32_t i = 0; i < 5; i++) + result.add(m_sha1.dword(i)); + + return result; + } + + + bool DxvkShaderKey::eq(const DxvkShaderKey& key) const { + return m_type == key.m_type + && m_sha1 == key.m_sha1; + } + +} \ No newline at end of file diff --git a/src/dxvk/dxvk_shader_key.h b/src/dxvk/dxvk_shader_key.h new file mode 100644 index 000000000..657438f4c --- /dev/null +++ b/src/dxvk/dxvk_shader_key.h @@ -0,0 +1,65 @@ +#pragma once + +#include "dxvk_hash.h" +#include "dxvk_include.h" + +namespace dxvk { + + /** + * \brief Shader key + * + * Provides a unique key that can be used + * to look up a specific shader within a + * structure. This consists of the shader + * stage and the source hash, which should + * be generated from the original code. + */ + class DxvkShaderKey { + + public: + + /** + * \brief Creates default shader key + */ + DxvkShaderKey(); + + /** + * \brief Creates shader key + * + * \param [in] shaderStage Shader stage + * \param [in] sourceCode Shader source + * \param [in] sourceSize Source length + */ + DxvkShaderKey( + VkShaderStageFlagBits shaderStage, + const void* sourceCode, + size_t sourceSize); + + /** + * \brief Generates string from shader key + * \returns String representation of the key + */ + std::string toString() const; + + /** + * \brief Computes lookup hash + * \returns Lookup hash + */ + size_t hash() const; + + /** + * \brief Checks whether two keys are equal + * + * \param [in] key The shader key to compare to + * \returns \c true if the two keys are equal + */ + bool eq(const DxvkShaderKey& key) const; + + private: + + VkShaderStageFlags m_type; + Sha1Hash m_sha1; + + }; + +} \ No newline at end of file diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 5be8beaab..e64fe748b 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -70,6 +70,7 @@ dxvk_src = files([ 'dxvk_resource.cpp', 'dxvk_sampler.cpp', 'dxvk_shader.cpp', + 'dxvk_shader_key.cpp', 'dxvk_spec_const.cpp', 'dxvk_staging.cpp', 'dxvk_stats.cpp',