1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-11-30 04:24:11 +01:00

[dxvk] Add compute shader support to pipeline state cache

This commit is contained in:
Philip Rebohle 2018-09-23 08:32:37 +02:00
parent 689602497f
commit 6c8ac9e5f4
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 77 additions and 16 deletions

View File

@ -11,7 +11,8 @@ namespace dxvk {
&& this->tcs.eq(key.tcs) && this->tcs.eq(key.tcs)
&& this->tes.eq(key.tes) && this->tes.eq(key.tes)
&& this->gs.eq(key.gs) && this->gs.eq(key.gs)
&& this->fs.eq(key.fs); && this->fs.eq(key.fs)
&& this->cs.eq(key.cs);
} }
@ -22,6 +23,7 @@ namespace dxvk {
hash.add(this->tes.hash()); hash.add(this->tes.hash());
hash.add(this->gs.hash()); hash.add(this->gs.hash());
hash.add(this->fs.hash()); hash.add(this->fs.hash());
hash.add(this->cs.hash());
return hash; return hash;
} }
@ -114,14 +116,40 @@ namespace dxvk {
for (auto e = entries.first; e != entries.second; e++) { for (auto e = entries.first; e != entries.second; e++) {
const DxvkStateCacheEntry& entry = m_entries[e->second]; const DxvkStateCacheEntry& entry = m_entries[e->second];
if (entry.format.matches(format) && entry.state == state) if (entry.format.matches(format) && entry.gpState == state)
return; return;
} }
// Queue a job to write this pipeline to the cache // Queue a job to write this pipeline to the cache
std::unique_lock<std::mutex> lock(m_writerLock); std::unique_lock<std::mutex> lock(m_writerLock);
m_writerQueue.push({ shaders, state, format, g_nullHash }); m_writerQueue.push({ shaders, state,
DxvkComputePipelineStateInfo(),
format, g_nullHash });
m_writerCond.notify_one();
}
void DxvkStateCache::addComputePipeline(
const DxvkStateCacheKey& shaders,
const DxvkComputePipelineStateInfo& state) {
if (shaders.cs.eq(g_nullShaderKey))
return;
// Do not add an entry that is already in the cache
auto entries = m_entryMap.equal_range(shaders);
for (auto e = entries.first; e != entries.second; e++) {
if (m_entries[e->second].cpState == state)
return;
}
// Queue a job to write this pipeline to the cache
std::unique_lock<std::mutex> lock(m_writerLock);
m_writerQueue.push({ shaders,
DxvkGraphicsPipelineStateInfo(), state,
DxvkRenderPassFormat(), g_nullHash });
m_writerCond.notify_one(); m_writerCond.notify_one();
} }
@ -148,7 +176,8 @@ namespace dxvk {
|| !getShaderByKey(p->second.tcs, item.tcs) || !getShaderByKey(p->second.tcs, item.tcs)
|| !getShaderByKey(p->second.tes, item.tes) || !getShaderByKey(p->second.tes, item.tes)
|| !getShaderByKey(p->second.gs, item.gs) || !getShaderByKey(p->second.gs, item.gs)
|| !getShaderByKey(p->second.fs, item.fs)) || !getShaderByKey(p->second.fs, item.fs)
|| !getShaderByKey(p->second.cs, item.cs))
continue; continue;
if (!workerLock) if (!workerLock)
@ -204,18 +233,27 @@ namespace dxvk {
key.tes = getShaderKey(item.tes); key.tes = getShaderKey(item.tes);
key.gs = getShaderKey(item.gs); key.gs = getShaderKey(item.gs);
key.fs = getShaderKey(item.fs); key.fs = getShaderKey(item.fs);
key.cs = getShaderKey(item.cs);
// Create the base pipeline object if (item.cs == nullptr) {
auto entries = m_entryMap.equal_range(key); auto pipeline = m_pipeManager->createGraphicsPipeline(
auto pipeline = m_pipeManager->createGraphicsPipeline( item.vs, item.tcs, item.tes, item.gs, item.fs);
item.vs, item.tcs, item.tes, item.gs, item.fs); auto entries = m_entryMap.equal_range(key);
// Compile all pipeline variations stored in the cache for (auto e = entries.first; e != entries.second; e++) {
for (auto e = entries.first; e != entries.second; e++) { const auto& entry = m_entries[e->second];
const auto& entry = m_entries[e->second];
auto rp = m_passManager->getRenderPass(entry.format); auto rp = m_passManager->getRenderPass(entry.format);
pipeline->getPipelineHandle(entry.state, *rp); pipeline->getPipelineHandle(entry.gpState, *rp);
}
} else {
auto pipeline = m_pipeManager->createComputePipeline(item.cs);
auto entries = m_entryMap.equal_range(key);
for (auto e = entries.first; e != entries.second; e++) {
const auto& entry = m_entries[e->second];
pipeline->getPipelineHandle(entry.cpState);
}
} }
} }
@ -255,6 +293,7 @@ namespace dxvk {
mapShaderToPipeline(entry.shaders.tes, entry.shaders); mapShaderToPipeline(entry.shaders.tes, entry.shaders);
mapShaderToPipeline(entry.shaders.gs, entry.shaders); mapShaderToPipeline(entry.shaders.gs, entry.shaders);
mapShaderToPipeline(entry.shaders.fs, entry.shaders); mapShaderToPipeline(entry.shaders.fs, entry.shaders);
mapShaderToPipeline(entry.shaders.cs, entry.shaders);
} else if (ifile) { } else if (ifile) {
numInvalidEntries += 1; numInvalidEntries += 1;
} }

View File

@ -26,6 +26,7 @@ namespace dxvk {
DxvkShaderKey tes; DxvkShaderKey tes;
DxvkShaderKey gs; DxvkShaderKey gs;
DxvkShaderKey fs; DxvkShaderKey fs;
DxvkShaderKey cs;
bool eq(const DxvkStateCacheKey& key) const; bool eq(const DxvkStateCacheKey& key) const;
@ -43,7 +44,8 @@ namespace dxvk {
*/ */
struct DxvkStateCacheEntry { struct DxvkStateCacheEntry {
DxvkStateCacheKey shaders; DxvkStateCacheKey shaders;
DxvkGraphicsPipelineStateInfo state; DxvkGraphicsPipelineStateInfo gpState;
DxvkComputePipelineStateInfo cpState;
DxvkRenderPassFormat format; DxvkRenderPassFormat format;
Sha1Hash hash; Sha1Hash hash;
}; };
@ -58,7 +60,7 @@ namespace dxvk {
*/ */
struct DxvkStateCacheHeader { struct DxvkStateCacheHeader {
char magic[4] = { 'D', 'X', 'V', 'K' }; char magic[4] = { 'D', 'X', 'V', 'K' };
uint32_t version = 1; uint32_t version = 2;
uint32_t entrySize = sizeof(DxvkStateCacheEntry); uint32_t entrySize = sizeof(DxvkStateCacheEntry);
}; };
@ -98,6 +100,18 @@ namespace dxvk {
const DxvkGraphicsPipelineStateInfo& state, const DxvkGraphicsPipelineStateInfo& state,
const DxvkRenderPassFormat& format); const DxvkRenderPassFormat& format);
/**
* Adds a compute pipeline to the cache
*
* If the pipeline is not already cached, this
* will write a new pipeline to the cache file.
* \param [in] shaders Shader keys
* \param [in] state Compute pipeline state
*/
void addComputePipeline(
const DxvkStateCacheKey& shaders,
const DxvkComputePipelineStateInfo& state);
/** /**
* \brief Registers a newly compiled shader * \brief Registers a newly compiled shader
* *
@ -111,9 +125,17 @@ namespace dxvk {
private: private:
using WorkerItem = DxvkGraphicsPipelineKey;
using WriterItem = DxvkStateCacheEntry; using WriterItem = DxvkStateCacheEntry;
struct WorkerItem {
Rc<DxvkShader> vs;
Rc<DxvkShader> tcs;
Rc<DxvkShader> tes;
Rc<DxvkShader> gs;
Rc<DxvkShader> fs;
Rc<DxvkShader> cs;
};
DxvkPipelineManager* m_pipeManager; DxvkPipelineManager* m_pipeManager;
DxvkRenderPassPool* m_passManager; DxvkRenderPassPool* m_passManager;