1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-19 05:52:11 +01:00

[dxvk] Bump state cache version to v5

This commit is contained in:
Philip Rebohle 2019-05-06 02:54:39 +02:00
parent 37f1087783
commit 584fd870b2
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 216 additions and 73 deletions

View File

@ -7,6 +7,20 @@ namespace dxvk {
static const Sha1Hash g_nullHash = Sha1Hash::compute(nullptr, 0); static const Sha1Hash g_nullHash = Sha1Hash::compute(nullptr, 0);
static const DxvkShaderKey g_nullShaderKey = DxvkShaderKey(); static const DxvkShaderKey g_nullShaderKey = DxvkShaderKey();
template<typename T>
bool readCacheEntryTyped(std::istream& stream, T& entry) {
auto data = reinterpret_cast<char*>(&entry);
auto size = sizeof(entry);
if (!stream.read(data, size))
return false;
Sha1Hash expectedHash = std::exchange(entry.hash, g_nullHash);
Sha1Hash computedHash = Sha1Hash::compute(entry);
return expectedHash == computedHash;
}
bool DxvkStateCacheKey::eq(const DxvkStateCacheKey& key) const { bool DxvkStateCacheKey::eq(const DxvkStateCacheKey& key) const {
return this->vs.eq(key.vs) return this->vs.eq(key.vs)
&& this->tcs.eq(key.tcs) && this->tcs.eq(key.tcs)
@ -282,8 +296,13 @@ namespace dxvk {
return false; return false;
} }
// Struct size hasn't changed between v2/v3 // Struct size hasn't changed between v2 and v4
if (curHeader.entrySize != newHeader.entrySize) { size_t expectedSize = newHeader.entrySize;
if (curHeader.version <= 4)
expectedSize = sizeof(DxvkStateCacheEntryV4);
if (curHeader.entrySize != expectedSize) {
Logger::warn("DXVK: State cache entry size changed"); Logger::warn("DXVK: State cache entry size changed");
return false; return false;
} }
@ -306,11 +325,7 @@ namespace dxvk {
while (ifile) { while (ifile) {
DxvkStateCacheEntry entry; DxvkStateCacheEntry entry;
if (readCacheEntry(ifile, entry)) { if (readCacheEntry(curHeader.version, ifile, entry)) {
switch (curHeader.version) {
case 2: convertEntryV2(entry); /* fall through */
}
size_t entryId = m_entries.size(); size_t entryId = m_entries.size();
m_entries.push_back(entry); m_entries.push_back(entry);
@ -364,17 +379,22 @@ namespace dxvk {
bool DxvkStateCache::readCacheEntry( bool DxvkStateCache::readCacheEntry(
uint32_t version,
std::istream& stream, std::istream& stream,
DxvkStateCacheEntry& entry) const { DxvkStateCacheEntry& entry) const {
auto data = reinterpret_cast<char*>(&entry); if (version <= 4) {
auto size = sizeof(DxvkStateCacheEntry); DxvkStateCacheEntryV4 v4;
if (!stream.read(data, size)) if (!readCacheEntryTyped(stream, v4))
return false; return false;
Sha1Hash expectedHash = std::exchange(entry.hash, g_nullHash); if (version == 2)
Sha1Hash computedHash = Sha1Hash::compute(entry); convertEntryV2(v4);
return expectedHash == computedHash;
return convertEntryV4(v4, entry);
} else {
return readCacheEntryTyped(stream, entry);
}
} }
@ -392,7 +412,7 @@ namespace dxvk {
bool DxvkStateCache::convertEntryV2( bool DxvkStateCache::convertEntryV2(
DxvkStateCacheEntry& entry) const { DxvkStateCacheEntryV4& entry) const {
// Semantics changed: // Semantics changed:
// v2: rsDepthClampEnable // v2: rsDepthClampEnable
// v3: rsDepthClipEnable // v3: rsDepthClipEnable
@ -405,6 +425,62 @@ namespace dxvk {
} }
bool DxvkStateCache::convertEntryV4(
const DxvkStateCacheEntryV4& in,
DxvkStateCacheEntry& out) const {
out.shaders = in.shaders;
out.cpState = in.cpState;
out.format = in.format;
out.hash = in.hash;
out.gpState.bsBindingMask = in.gpState.bsBindingMask;
out.gpState.iaPrimitiveTopology = in.gpState.iaPrimitiveTopology;
out.gpState.iaPrimitiveRestart = in.gpState.iaPrimitiveRestart;
out.gpState.iaPatchVertexCount = in.gpState.iaPatchVertexCount;
out.gpState.ilAttributeCount = in.gpState.ilAttributeCount;
out.gpState.ilBindingCount = in.gpState.ilBindingCount;
for (uint32_t i = 0; i < in.gpState.ilAttributeCount; i++)
out.gpState.ilAttributes[i] = in.gpState.ilAttributes[i];
for (uint32_t i = 0; i < in.gpState.ilBindingCount; i++) {
out.gpState.ilBindings[i] = in.gpState.ilBindings[i];
out.gpState.ilDivisors[i] = in.gpState.ilDivisors[i];
}
out.gpState.rsDepthClipEnable = in.gpState.rsDepthClipEnable;
out.gpState.rsDepthBiasEnable = in.gpState.rsDepthBiasEnable;
out.gpState.rsPolygonMode = in.gpState.rsPolygonMode;
out.gpState.rsCullMode = in.gpState.rsCullMode;
out.gpState.rsFrontFace = in.gpState.rsFrontFace;
out.gpState.rsViewportCount = in.gpState.rsViewportCount;
out.gpState.rsSampleCount = in.gpState.rsSampleCount;
out.gpState.msSampleCount = in.gpState.msSampleCount;
out.gpState.msSampleMask = in.gpState.msSampleMask;
out.gpState.msEnableAlphaToCoverage = in.gpState.msEnableAlphaToCoverage;
out.gpState.dsEnableDepthTest = in.gpState.dsEnableDepthTest;
out.gpState.dsEnableDepthWrite = in.gpState.dsEnableDepthWrite;
out.gpState.dsEnableStencilTest = in.gpState.dsEnableStencilTest;
out.gpState.dsDepthCompareOp = in.gpState.dsDepthCompareOp;
out.gpState.dsStencilOpFront = in.gpState.dsStencilOpFront;
out.gpState.dsStencilOpBack = in.gpState.dsStencilOpBack;
out.gpState.omEnableLogicOp = in.gpState.omEnableLogicOp;
out.gpState.omLogicOp = in.gpState.omLogicOp;
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
out.gpState.omBlendAttachments[i] = in.gpState.omBlendAttachments[i];
out.gpState.omComponentMapping[i] = in.gpState.omComponentMapping[i];
}
return true;
}
void DxvkStateCache::workerFunc() { void DxvkStateCache::workerFunc() {
env::setThreadName("dxvk-shader"); env::setThreadName("dxvk-shader");

View File

@ -8,67 +8,12 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "dxvk_pipemanager.h" #include "dxvk_state_cache_types.h"
#include "dxvk_renderpass.h"
namespace dxvk { namespace dxvk {
class DxvkDevice; class DxvkDevice;
/**
* \brief State cache entry key
*
* Stores the shader keys for all
* graphics shader stages. Used to
* look up cached state entries.
*/
struct DxvkStateCacheKey {
DxvkShaderKey vs;
DxvkShaderKey tcs;
DxvkShaderKey tes;
DxvkShaderKey gs;
DxvkShaderKey fs;
DxvkShaderKey cs;
bool eq(const DxvkStateCacheKey& key) const;
size_t hash() const;
};
/**
* \brief State entry
*
* Stores the shaders used in a pipeline, as well
* as the full state vector, including its render
* pass format. This also includes a SHA-1 hash
* that is used as a check sum to verify integrity.
*/
struct DxvkStateCacheEntry {
DxvkStateCacheKey shaders;
DxvkGraphicsPipelineStateInfo gpState;
DxvkComputePipelineStateInfo cpState;
DxvkRenderPassFormat format;
Sha1Hash hash;
};
/**
* \brief State cache header
*
* Stores the state cache format version. If an
* existing cache file is incompatible to the
* current version, it will be discarded.
*/
struct DxvkStateCacheHeader {
char magic[4] = { 'D', 'X', 'V', 'K' };
uint32_t version = 4;
uint32_t entrySize = sizeof(DxvkStateCacheEntry);
};
static_assert(sizeof(DxvkStateCacheHeader) == 12);
/** /**
* \brief State cache * \brief State cache
* *
@ -203,6 +148,7 @@ namespace dxvk {
DxvkStateCacheHeader& header) const; DxvkStateCacheHeader& header) const;
bool readCacheEntry( bool readCacheEntry(
uint32_t version,
std::istream& stream, std::istream& stream,
DxvkStateCacheEntry& entry) const; DxvkStateCacheEntry& entry) const;
@ -211,7 +157,11 @@ namespace dxvk {
DxvkStateCacheEntry& entry) const; DxvkStateCacheEntry& entry) const;
bool convertEntryV2( bool convertEntryV2(
DxvkStateCacheEntry& entry) const; DxvkStateCacheEntryV4& entry) const;
bool convertEntryV4(
const DxvkStateCacheEntryV4& in,
DxvkStateCacheEntry& out) const;
void workerFunc(); void workerFunc();

View File

@ -0,0 +1,117 @@
#pragma once
#include "dxvk_pipemanager.h"
#include "dxvk_renderpass.h"
namespace dxvk {
/**
* \brief State cache entry key
*
* Stores the shader keys for all
* graphics shader stages. Used to
* look up cached state entries.
*/
struct DxvkStateCacheKey {
DxvkShaderKey vs;
DxvkShaderKey tcs;
DxvkShaderKey tes;
DxvkShaderKey gs;
DxvkShaderKey fs;
DxvkShaderKey cs;
bool eq(const DxvkStateCacheKey& key) const;
size_t hash() const;
};
/**
* \brief State entry
*
* Stores the shaders used in a pipeline, as well
* as the full state vector, including its render
* pass format. This also includes a SHA-1 hash
* that is used as a check sum to verify integrity.
*/
struct DxvkStateCacheEntry {
DxvkStateCacheKey shaders;
DxvkGraphicsPipelineStateInfo gpState;
DxvkComputePipelineStateInfo cpState;
DxvkRenderPassFormat format;
Sha1Hash hash;
};
/**
* \brief State cache header
*
* Stores the state cache format version. If an
* existing cache file is incompatible to the
* current version, it will be discarded.
*/
struct DxvkStateCacheHeader {
char magic[4] = { 'D', 'X', 'V', 'K' };
uint32_t version = 5;
uint32_t entrySize = sizeof(DxvkStateCacheEntry);
};
static_assert(sizeof(DxvkStateCacheHeader) == 12);
/**
* \brief Version 4 graphics pipeline state
*/
struct DxvkGraphicsPipelineStateInfoV4 {
DxvkBindingMask bsBindingMask;
VkPrimitiveTopology iaPrimitiveTopology;
VkBool32 iaPrimitiveRestart;
uint32_t iaPatchVertexCount;
uint32_t ilAttributeCount;
uint32_t ilBindingCount;
VkVertexInputAttributeDescription ilAttributes[DxvkLimits::MaxNumVertexAttributes];
VkVertexInputBindingDescription ilBindings[DxvkLimits::MaxNumVertexBindings];
uint32_t ilDivisors[DxvkLimits::MaxNumVertexBindings];
VkBool32 rsDepthClipEnable;
VkBool32 rsDepthBiasEnable;
VkPolygonMode rsPolygonMode;
VkCullModeFlags rsCullMode;
VkFrontFace rsFrontFace;
uint32_t rsViewportCount;
VkSampleCountFlags rsSampleCount;
VkSampleCountFlags msSampleCount;
uint32_t msSampleMask;
VkBool32 msEnableAlphaToCoverage;
VkCompareOp xsAlphaCompareOp;
VkBool32 dsEnableDepthTest;
VkBool32 dsEnableDepthWrite;
VkBool32 dsEnableStencilTest;
VkCompareOp dsDepthCompareOp;
VkStencilOpState dsStencilOpFront;
VkStencilOpState dsStencilOpBack;
VkBool32 omEnableLogicOp;
VkLogicOp omLogicOp;
VkPipelineColorBlendAttachmentState omBlendAttachments[MaxNumRenderTargets];
VkComponentMapping omComponentMapping[MaxNumRenderTargets];
};
/**
* \brief Version 4 state cache entry
*/
struct DxvkStateCacheEntryV4 {
DxvkStateCacheKey shaders;
DxvkGraphicsPipelineStateInfoV4 gpState;
DxvkComputePipelineStateInfo cpState;
DxvkRenderPassFormat format;
Sha1Hash hash;
};
}