mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-18 20:52:10 +01:00
[dxvk] Bump state cache version to v5
This commit is contained in:
parent
37f1087783
commit
584fd870b2
@ -7,6 +7,20 @@ namespace dxvk {
|
||||
static const Sha1Hash g_nullHash = Sha1Hash::compute(nullptr, 0);
|
||||
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 {
|
||||
return this->vs.eq(key.vs)
|
||||
&& this->tcs.eq(key.tcs)
|
||||
@ -282,8 +296,13 @@ namespace dxvk {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Struct size hasn't changed between v2/v3
|
||||
if (curHeader.entrySize != newHeader.entrySize) {
|
||||
// Struct size hasn't changed between v2 and v4
|
||||
size_t expectedSize = newHeader.entrySize;
|
||||
|
||||
if (curHeader.version <= 4)
|
||||
expectedSize = sizeof(DxvkStateCacheEntryV4);
|
||||
|
||||
if (curHeader.entrySize != expectedSize) {
|
||||
Logger::warn("DXVK: State cache entry size changed");
|
||||
return false;
|
||||
}
|
||||
@ -306,11 +325,7 @@ namespace dxvk {
|
||||
while (ifile) {
|
||||
DxvkStateCacheEntry entry;
|
||||
|
||||
if (readCacheEntry(ifile, entry)) {
|
||||
switch (curHeader.version) {
|
||||
case 2: convertEntryV2(entry); /* fall through */
|
||||
}
|
||||
|
||||
if (readCacheEntry(curHeader.version, ifile, entry)) {
|
||||
size_t entryId = m_entries.size();
|
||||
m_entries.push_back(entry);
|
||||
|
||||
@ -364,17 +379,22 @@ namespace dxvk {
|
||||
|
||||
|
||||
bool DxvkStateCache::readCacheEntry(
|
||||
uint32_t version,
|
||||
std::istream& stream,
|
||||
DxvkStateCacheEntry& entry) const {
|
||||
auto data = reinterpret_cast<char*>(&entry);
|
||||
auto size = sizeof(DxvkStateCacheEntry);
|
||||
if (version <= 4) {
|
||||
DxvkStateCacheEntryV4 v4;
|
||||
|
||||
if (!stream.read(data, size))
|
||||
return false;
|
||||
|
||||
Sha1Hash expectedHash = std::exchange(entry.hash, g_nullHash);
|
||||
Sha1Hash computedHash = Sha1Hash::compute(entry);
|
||||
return expectedHash == computedHash;
|
||||
if (!readCacheEntryTyped(stream, v4))
|
||||
return false;
|
||||
|
||||
if (version == 2)
|
||||
convertEntryV2(v4);
|
||||
|
||||
return convertEntryV4(v4, entry);
|
||||
} else {
|
||||
return readCacheEntryTyped(stream, entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -392,7 +412,7 @@ namespace dxvk {
|
||||
|
||||
|
||||
bool DxvkStateCache::convertEntryV2(
|
||||
DxvkStateCacheEntry& entry) const {
|
||||
DxvkStateCacheEntryV4& entry) const {
|
||||
// Semantics changed:
|
||||
// v2: rsDepthClampEnable
|
||||
// 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() {
|
||||
env::setThreadName("dxvk-shader");
|
||||
|
||||
|
@ -8,67 +8,12 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "dxvk_pipemanager.h"
|
||||
#include "dxvk_renderpass.h"
|
||||
#include "dxvk_state_cache_types.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
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
|
||||
*
|
||||
@ -203,6 +148,7 @@ namespace dxvk {
|
||||
DxvkStateCacheHeader& header) const;
|
||||
|
||||
bool readCacheEntry(
|
||||
uint32_t version,
|
||||
std::istream& stream,
|
||||
DxvkStateCacheEntry& entry) const;
|
||||
|
||||
@ -211,7 +157,11 @@ namespace dxvk {
|
||||
DxvkStateCacheEntry& entry) const;
|
||||
|
||||
bool convertEntryV2(
|
||||
DxvkStateCacheEntry& entry) const;
|
||||
DxvkStateCacheEntryV4& entry) const;
|
||||
|
||||
bool convertEntryV4(
|
||||
const DxvkStateCacheEntryV4& in,
|
||||
DxvkStateCacheEntry& out) const;
|
||||
|
||||
void workerFunc();
|
||||
|
||||
|
117
src/dxvk/dxvk_state_cache_types.h
Normal file
117
src/dxvk/dxvk_state_cache_types.h
Normal 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;
|
||||
};
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user