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

[dxvk] Use shader key structs directly for pipeline lookups

Removes some overhead and unnecessary ref count changes on shaders.
This commit is contained in:
Philip Rebohle 2019-07-23 12:54:25 +02:00
parent 8d4996bcda
commit 8cd13cc5bd
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
6 changed files with 46 additions and 87 deletions

View File

@ -204,20 +204,20 @@ namespace dxvk {
void DxvkContext::bindShader(
VkShaderStageFlagBits stage,
const Rc<DxvkShader>& shader) {
DxvkShaderStage* shaderStage = nullptr;
Rc<DxvkShader>* shaderStage;
switch (stage) {
case VK_SHADER_STAGE_VERTEX_BIT: shaderStage = &m_state.gp.vs; break;
case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: shaderStage = &m_state.gp.tcs; break;
case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: shaderStage = &m_state.gp.tes; break;
case VK_SHADER_STAGE_GEOMETRY_BIT: shaderStage = &m_state.gp.gs; break;
case VK_SHADER_STAGE_FRAGMENT_BIT: shaderStage = &m_state.gp.fs; break;
case VK_SHADER_STAGE_COMPUTE_BIT: shaderStage = &m_state.cp.cs; break;
case VK_SHADER_STAGE_VERTEX_BIT: shaderStage = &m_state.gp.shaders.vs; break;
case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: shaderStage = &m_state.gp.shaders.tcs; break;
case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: shaderStage = &m_state.gp.shaders.tes; break;
case VK_SHADER_STAGE_GEOMETRY_BIT: shaderStage = &m_state.gp.shaders.gs; break;
case VK_SHADER_STAGE_FRAGMENT_BIT: shaderStage = &m_state.gp.shaders.fs; break;
case VK_SHADER_STAGE_COMPUTE_BIT: shaderStage = &m_state.cp.shaders.cs; break;
default: return;
}
shaderStage->shader = shader;
*shaderStage = shader;
if (stage == VK_SHADER_STAGE_COMPUTE_BIT) {
m_flags.set(
DxvkContextFlag::CpDirtyPipeline,
@ -3410,7 +3410,7 @@ namespace dxvk {
m_flags.clr(DxvkContextFlag::CpDirtyPipeline);
m_state.cp.state.bsBindingMask.clear();
m_state.cp.pipeline = m_pipeMgr->createComputePipeline(m_state.cp.cs.shader);
m_state.cp.pipeline = m_pipeMgr->createComputePipeline(m_state.cp.shaders);
if (m_state.cp.pipeline != nullptr
&& m_state.cp.pipeline->layout()->pushConstRange().size)
@ -3460,11 +3460,8 @@ namespace dxvk {
m_flags.clr(DxvkContextFlag::GpDirtyPipeline);
m_state.gp.state.bsBindingMask.clear();
m_state.gp.pipeline = m_pipeMgr->createGraphicsPipeline(
m_state.gp.vs.shader,
m_state.gp.tcs.shader, m_state.gp.tes.shader,
m_state.gp.gs.shader, m_state.gp.fs.shader);
m_state.gp.flags = DxvkGraphicsPipelineFlags();
m_state.gp.pipeline = m_pipeMgr->createGraphicsPipeline(m_state.gp.shaders);
m_state.gp.flags = DxvkGraphicsPipelineFlags();
if (m_state.gp.pipeline != nullptr) {
m_state.gp.flags = m_state.gp.pipeline->flags();
@ -3869,7 +3866,7 @@ namespace dxvk {
void DxvkContext::updateTransformFeedbackBuffers() {
auto gsOptions = m_state.gp.gs.shader->shaderOptions();
auto gsOptions = m_state.gp.shaders.gs->shaderOptions();
VkBuffer xfbBuffers[MaxNumXfbBuffers];
VkDeviceSize xfbOffsets[MaxNumXfbBuffers];

View File

@ -113,18 +113,8 @@ namespace dxvk {
};
struct DxvkShaderStage {
Rc<DxvkShader> shader;
};
struct DxvkGraphicsPipelineState {
DxvkShaderStage vs;
DxvkShaderStage tcs;
DxvkShaderStage tes;
DxvkShaderStage gs;
DxvkShaderStage fs;
DxvkGraphicsPipelineShaders shaders;
DxvkGraphicsPipelineStateInfo state;
DxvkGraphicsPipelineFlags flags;
Rc<DxvkGraphicsPipeline> pipeline;
@ -132,8 +122,7 @@ namespace dxvk {
struct DxvkComputePipelineState {
DxvkShaderStage cs;
DxvkComputePipelineShaders shaders;
DxvkComputePipelineStateInfo state;
Rc<DxvkComputePipeline> pipeline;
};

View File

@ -57,51 +57,37 @@ namespace dxvk {
Rc<DxvkComputePipeline> DxvkPipelineManager::createComputePipeline(
const Rc<DxvkShader>& cs) {
if (cs == nullptr)
const DxvkComputePipelineShaders& shaders) {
if (shaders.cs == nullptr)
return nullptr;
std::lock_guard<std::mutex> lock(m_mutex);
DxvkComputePipelineShaders key;
key.cs = cs;
auto pair = m_computePipelines.find(key);
auto pair = m_computePipelines.find(shaders);
if (pair != m_computePipelines.end())
return pair->second;
Rc<DxvkComputePipeline> pipeline = new DxvkComputePipeline(this, key);
Rc<DxvkComputePipeline> pipeline = new DxvkComputePipeline(this, shaders);
m_computePipelines.insert(std::make_pair(key, pipeline));
m_computePipelines.insert(std::make_pair(shaders, pipeline));
return pipeline;
}
Rc<DxvkGraphicsPipeline> DxvkPipelineManager::createGraphicsPipeline(
const Rc<DxvkShader>& vs,
const Rc<DxvkShader>& tcs,
const Rc<DxvkShader>& tes,
const Rc<DxvkShader>& gs,
const Rc<DxvkShader>& fs) {
if (vs == nullptr)
const DxvkGraphicsPipelineShaders& shaders) {
if (shaders.vs == nullptr)
return nullptr;
std::lock_guard<std::mutex> lock(m_mutex);
DxvkGraphicsPipelineShaders key;
key.vs = vs;
key.tcs = tcs;
key.tes = tes;
key.gs = gs;
key.fs = fs;
auto pair = m_graphicsPipelines.find(key);
auto pair = m_graphicsPipelines.find(shaders);
if (pair != m_graphicsPipelines.end())
return pair->second;
Rc<DxvkGraphicsPipeline> pipeline = new DxvkGraphicsPipeline(this, key);
Rc<DxvkGraphicsPipeline> pipeline = new DxvkGraphicsPipeline(this, shaders);
m_graphicsPipelines.insert(std::make_pair(key, pipeline));
m_graphicsPipelines.insert(std::make_pair(shaders, pipeline));
return pipeline;
}

View File

@ -60,11 +60,11 @@ namespace dxvk {
* If a pipeline for the given shader stage object
* already exists, it will be returned. Otherwise,
* a new pipeline will be created.
* \param [in] cs Compute shader
* \param [in] shaders Shaders for the pipeline
* \returns Compute pipeline object
*/
Rc<DxvkComputePipeline> createComputePipeline(
const Rc<DxvkShader>& cs);
const DxvkComputePipelineShaders& shaders);
/**
* \brief Retrieves a graphics pipeline object
@ -72,19 +72,11 @@ namespace dxvk {
* If a pipeline for the given shader stage objects
* already exists, it will be returned. Otherwise,
* a new pipeline will be created.
* \param [in] vs Vertex shader
* \param [in] tcs Tessellation control shader
* \param [in] tes Tessellation evaluation shader
* \param [in] gs Geometry shader
* \param [in] fs Fragment shader
* \param [in] shaders Shaders for the pipeline
* \returns Graphics pipeline object
*/
Rc<DxvkGraphicsPipeline> createGraphicsPipeline(
const Rc<DxvkShader>& vs,
const Rc<DxvkShader>& tcs,
const Rc<DxvkShader>& tes,
const Rc<DxvkShader>& gs,
const Rc<DxvkShader>& fs);
const DxvkGraphicsPipelineShaders& shaders);
/*
* \brief Registers a shader

View File

@ -191,12 +191,12 @@ namespace dxvk {
for (auto p = pipelines.first; p != pipelines.second; p++) {
WorkerItem item;
if (!getShaderByKey(p->second.vs, item.vs)
|| !getShaderByKey(p->second.tcs, item.tcs)
|| !getShaderByKey(p->second.tes, item.tes)
|| !getShaderByKey(p->second.gs, item.gs)
|| !getShaderByKey(p->second.fs, item.fs)
|| !getShaderByKey(p->second.cs, item.cs))
if (!getShaderByKey(p->second.vs, item.gp.vs)
|| !getShaderByKey(p->second.tcs, item.gp.tcs)
|| !getShaderByKey(p->second.tes, item.gp.tes)
|| !getShaderByKey(p->second.gs, item.gp.gs)
|| !getShaderByKey(p->second.fs, item.gp.fs)
|| !getShaderByKey(p->second.cs, item.cp.cs))
continue;
if (!workerLock)
@ -247,16 +247,15 @@ namespace dxvk {
void DxvkStateCache::compilePipelines(const WorkerItem& item) {
DxvkStateCacheKey key;
key.vs = getShaderKey(item.vs);
key.tcs = getShaderKey(item.tcs);
key.tes = getShaderKey(item.tes);
key.gs = getShaderKey(item.gs);
key.fs = getShaderKey(item.fs);
key.cs = getShaderKey(item.cs);
key.vs = getShaderKey(item.gp.vs);
key.tcs = getShaderKey(item.gp.tcs);
key.tes = getShaderKey(item.gp.tes);
key.gs = getShaderKey(item.gp.gs);
key.fs = getShaderKey(item.gp.fs);
key.cs = getShaderKey(item.cp.cs);
if (item.cs == nullptr) {
auto pipeline = m_pipeManager->createGraphicsPipeline(
item.vs, item.tcs, item.tes, item.gs, item.fs);
if (item.cp.cs == nullptr) {
auto pipeline = m_pipeManager->createGraphicsPipeline(item.gp);
auto entries = m_entryMap.equal_range(key);
for (auto e = entries.first; e != entries.second; e++) {
@ -266,7 +265,7 @@ namespace dxvk {
pipeline->getPipelineHandle(entry.gpState, *rp);
}
} else {
auto pipeline = m_pipeManager->createComputePipeline(item.cs);
auto pipeline = m_pipeManager->createComputePipeline(item.cp);
auto entries = m_entryMap.equal_range(key);
for (auto e = entries.first; e != entries.second; e++) {

View File

@ -84,12 +84,8 @@ namespace dxvk {
using WriterItem = DxvkStateCacheEntry;
struct WorkerItem {
Rc<DxvkShader> vs;
Rc<DxvkShader> tcs;
Rc<DxvkShader> tes;
Rc<DxvkShader> gs;
Rc<DxvkShader> fs;
Rc<DxvkShader> cs;
DxvkGraphicsPipelineShaders gp;
DxvkComputePipelineShaders cp;
};
DxvkPipelineManager* m_pipeManager;