mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-28 07:54:14 +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:
parent
8d4996bcda
commit
8cd13cc5bd
@ -204,19 +204,19 @@ namespace dxvk {
|
|||||||
void DxvkContext::bindShader(
|
void DxvkContext::bindShader(
|
||||||
VkShaderStageFlagBits stage,
|
VkShaderStageFlagBits stage,
|
||||||
const Rc<DxvkShader>& shader) {
|
const Rc<DxvkShader>& shader) {
|
||||||
DxvkShaderStage* shaderStage = nullptr;
|
Rc<DxvkShader>* shaderStage;
|
||||||
|
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case VK_SHADER_STAGE_VERTEX_BIT: shaderStage = &m_state.gp.vs; 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.tcs; 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.tes; 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.gs; break;
|
case VK_SHADER_STAGE_GEOMETRY_BIT: shaderStage = &m_state.gp.shaders.gs; break;
|
||||||
case VK_SHADER_STAGE_FRAGMENT_BIT: shaderStage = &m_state.gp.fs; break;
|
case VK_SHADER_STAGE_FRAGMENT_BIT: shaderStage = &m_state.gp.shaders.fs; break;
|
||||||
case VK_SHADER_STAGE_COMPUTE_BIT: shaderStage = &m_state.cp.cs; break;
|
case VK_SHADER_STAGE_COMPUTE_BIT: shaderStage = &m_state.cp.shaders.cs; break;
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
|
|
||||||
shaderStage->shader = shader;
|
*shaderStage = shader;
|
||||||
|
|
||||||
if (stage == VK_SHADER_STAGE_COMPUTE_BIT) {
|
if (stage == VK_SHADER_STAGE_COMPUTE_BIT) {
|
||||||
m_flags.set(
|
m_flags.set(
|
||||||
@ -3410,7 +3410,7 @@ namespace dxvk {
|
|||||||
m_flags.clr(DxvkContextFlag::CpDirtyPipeline);
|
m_flags.clr(DxvkContextFlag::CpDirtyPipeline);
|
||||||
|
|
||||||
m_state.cp.state.bsBindingMask.clear();
|
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
|
if (m_state.cp.pipeline != nullptr
|
||||||
&& m_state.cp.pipeline->layout()->pushConstRange().size)
|
&& m_state.cp.pipeline->layout()->pushConstRange().size)
|
||||||
@ -3460,11 +3460,8 @@ namespace dxvk {
|
|||||||
m_flags.clr(DxvkContextFlag::GpDirtyPipeline);
|
m_flags.clr(DxvkContextFlag::GpDirtyPipeline);
|
||||||
|
|
||||||
m_state.gp.state.bsBindingMask.clear();
|
m_state.gp.state.bsBindingMask.clear();
|
||||||
m_state.gp.pipeline = m_pipeMgr->createGraphicsPipeline(
|
m_state.gp.pipeline = m_pipeMgr->createGraphicsPipeline(m_state.gp.shaders);
|
||||||
m_state.gp.vs.shader,
|
m_state.gp.flags = DxvkGraphicsPipelineFlags();
|
||||||
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();
|
|
||||||
|
|
||||||
if (m_state.gp.pipeline != nullptr) {
|
if (m_state.gp.pipeline != nullptr) {
|
||||||
m_state.gp.flags = m_state.gp.pipeline->flags();
|
m_state.gp.flags = m_state.gp.pipeline->flags();
|
||||||
@ -3869,7 +3866,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void DxvkContext::updateTransformFeedbackBuffers() {
|
void DxvkContext::updateTransformFeedbackBuffers() {
|
||||||
auto gsOptions = m_state.gp.gs.shader->shaderOptions();
|
auto gsOptions = m_state.gp.shaders.gs->shaderOptions();
|
||||||
|
|
||||||
VkBuffer xfbBuffers[MaxNumXfbBuffers];
|
VkBuffer xfbBuffers[MaxNumXfbBuffers];
|
||||||
VkDeviceSize xfbOffsets[MaxNumXfbBuffers];
|
VkDeviceSize xfbOffsets[MaxNumXfbBuffers];
|
||||||
|
@ -113,18 +113,8 @@ namespace dxvk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct DxvkShaderStage {
|
|
||||||
Rc<DxvkShader> shader;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct DxvkGraphicsPipelineState {
|
struct DxvkGraphicsPipelineState {
|
||||||
DxvkShaderStage vs;
|
DxvkGraphicsPipelineShaders shaders;
|
||||||
DxvkShaderStage tcs;
|
|
||||||
DxvkShaderStage tes;
|
|
||||||
DxvkShaderStage gs;
|
|
||||||
DxvkShaderStage fs;
|
|
||||||
|
|
||||||
DxvkGraphicsPipelineStateInfo state;
|
DxvkGraphicsPipelineStateInfo state;
|
||||||
DxvkGraphicsPipelineFlags flags;
|
DxvkGraphicsPipelineFlags flags;
|
||||||
Rc<DxvkGraphicsPipeline> pipeline;
|
Rc<DxvkGraphicsPipeline> pipeline;
|
||||||
@ -132,8 +122,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
struct DxvkComputePipelineState {
|
struct DxvkComputePipelineState {
|
||||||
DxvkShaderStage cs;
|
DxvkComputePipelineShaders shaders;
|
||||||
|
|
||||||
DxvkComputePipelineStateInfo state;
|
DxvkComputePipelineStateInfo state;
|
||||||
Rc<DxvkComputePipeline> pipeline;
|
Rc<DxvkComputePipeline> pipeline;
|
||||||
};
|
};
|
||||||
|
@ -57,51 +57,37 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
Rc<DxvkComputePipeline> DxvkPipelineManager::createComputePipeline(
|
Rc<DxvkComputePipeline> DxvkPipelineManager::createComputePipeline(
|
||||||
const Rc<DxvkShader>& cs) {
|
const DxvkComputePipelineShaders& shaders) {
|
||||||
if (cs == nullptr)
|
if (shaders.cs == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(m_mutex);
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
DxvkComputePipelineShaders key;
|
auto pair = m_computePipelines.find(shaders);
|
||||||
key.cs = cs;
|
|
||||||
|
|
||||||
auto pair = m_computePipelines.find(key);
|
|
||||||
if (pair != m_computePipelines.end())
|
if (pair != m_computePipelines.end())
|
||||||
return pair->second;
|
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;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkGraphicsPipeline> DxvkPipelineManager::createGraphicsPipeline(
|
Rc<DxvkGraphicsPipeline> DxvkPipelineManager::createGraphicsPipeline(
|
||||||
const Rc<DxvkShader>& vs,
|
const DxvkGraphicsPipelineShaders& shaders) {
|
||||||
const Rc<DxvkShader>& tcs,
|
if (shaders.vs == nullptr)
|
||||||
const Rc<DxvkShader>& tes,
|
|
||||||
const Rc<DxvkShader>& gs,
|
|
||||||
const Rc<DxvkShader>& fs) {
|
|
||||||
if (vs == nullptr)
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(m_mutex);
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
DxvkGraphicsPipelineShaders key;
|
auto pair = m_graphicsPipelines.find(shaders);
|
||||||
key.vs = vs;
|
|
||||||
key.tcs = tcs;
|
|
||||||
key.tes = tes;
|
|
||||||
key.gs = gs;
|
|
||||||
key.fs = fs;
|
|
||||||
|
|
||||||
auto pair = m_graphicsPipelines.find(key);
|
|
||||||
if (pair != m_graphicsPipelines.end())
|
if (pair != m_graphicsPipelines.end())
|
||||||
return pair->second;
|
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;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,11 +60,11 @@ namespace dxvk {
|
|||||||
* If a pipeline for the given shader stage object
|
* If a pipeline for the given shader stage object
|
||||||
* already exists, it will be returned. Otherwise,
|
* already exists, it will be returned. Otherwise,
|
||||||
* a new pipeline will be created.
|
* a new pipeline will be created.
|
||||||
* \param [in] cs Compute shader
|
* \param [in] shaders Shaders for the pipeline
|
||||||
* \returns Compute pipeline object
|
* \returns Compute pipeline object
|
||||||
*/
|
*/
|
||||||
Rc<DxvkComputePipeline> createComputePipeline(
|
Rc<DxvkComputePipeline> createComputePipeline(
|
||||||
const Rc<DxvkShader>& cs);
|
const DxvkComputePipelineShaders& shaders);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Retrieves a graphics pipeline object
|
* \brief Retrieves a graphics pipeline object
|
||||||
@ -72,19 +72,11 @@ namespace dxvk {
|
|||||||
* If a pipeline for the given shader stage objects
|
* If a pipeline for the given shader stage objects
|
||||||
* already exists, it will be returned. Otherwise,
|
* already exists, it will be returned. Otherwise,
|
||||||
* a new pipeline will be created.
|
* a new pipeline will be created.
|
||||||
* \param [in] vs Vertex shader
|
* \param [in] shaders Shaders for the pipeline
|
||||||
* \param [in] tcs Tessellation control shader
|
|
||||||
* \param [in] tes Tessellation evaluation shader
|
|
||||||
* \param [in] gs Geometry shader
|
|
||||||
* \param [in] fs Fragment shader
|
|
||||||
* \returns Graphics pipeline object
|
* \returns Graphics pipeline object
|
||||||
*/
|
*/
|
||||||
Rc<DxvkGraphicsPipeline> createGraphicsPipeline(
|
Rc<DxvkGraphicsPipeline> createGraphicsPipeline(
|
||||||
const Rc<DxvkShader>& vs,
|
const DxvkGraphicsPipelineShaders& shaders);
|
||||||
const Rc<DxvkShader>& tcs,
|
|
||||||
const Rc<DxvkShader>& tes,
|
|
||||||
const Rc<DxvkShader>& gs,
|
|
||||||
const Rc<DxvkShader>& fs);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* \brief Registers a shader
|
* \brief Registers a shader
|
||||||
|
@ -191,12 +191,12 @@ namespace dxvk {
|
|||||||
for (auto p = pipelines.first; p != pipelines.second; p++) {
|
for (auto p = pipelines.first; p != pipelines.second; p++) {
|
||||||
WorkerItem item;
|
WorkerItem item;
|
||||||
|
|
||||||
if (!getShaderByKey(p->second.vs, item.vs)
|
if (!getShaderByKey(p->second.vs, item.gp.vs)
|
||||||
|| !getShaderByKey(p->second.tcs, item.tcs)
|
|| !getShaderByKey(p->second.tcs, item.gp.tcs)
|
||||||
|| !getShaderByKey(p->second.tes, item.tes)
|
|| !getShaderByKey(p->second.tes, item.gp.tes)
|
||||||
|| !getShaderByKey(p->second.gs, item.gs)
|
|| !getShaderByKey(p->second.gs, item.gp.gs)
|
||||||
|| !getShaderByKey(p->second.fs, item.fs)
|
|| !getShaderByKey(p->second.fs, item.gp.fs)
|
||||||
|| !getShaderByKey(p->second.cs, item.cs))
|
|| !getShaderByKey(p->second.cs, item.cp.cs))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!workerLock)
|
if (!workerLock)
|
||||||
@ -247,16 +247,15 @@ namespace dxvk {
|
|||||||
|
|
||||||
void DxvkStateCache::compilePipelines(const WorkerItem& item) {
|
void DxvkStateCache::compilePipelines(const WorkerItem& item) {
|
||||||
DxvkStateCacheKey key;
|
DxvkStateCacheKey key;
|
||||||
key.vs = getShaderKey(item.vs);
|
key.vs = getShaderKey(item.gp.vs);
|
||||||
key.tcs = getShaderKey(item.tcs);
|
key.tcs = getShaderKey(item.gp.tcs);
|
||||||
key.tes = getShaderKey(item.tes);
|
key.tes = getShaderKey(item.gp.tes);
|
||||||
key.gs = getShaderKey(item.gs);
|
key.gs = getShaderKey(item.gp.gs);
|
||||||
key.fs = getShaderKey(item.fs);
|
key.fs = getShaderKey(item.gp.fs);
|
||||||
key.cs = getShaderKey(item.cs);
|
key.cs = getShaderKey(item.cp.cs);
|
||||||
|
|
||||||
if (item.cs == nullptr) {
|
if (item.cp.cs == nullptr) {
|
||||||
auto pipeline = m_pipeManager->createGraphicsPipeline(
|
auto pipeline = m_pipeManager->createGraphicsPipeline(item.gp);
|
||||||
item.vs, item.tcs, item.tes, item.gs, item.fs);
|
|
||||||
auto entries = m_entryMap.equal_range(key);
|
auto entries = m_entryMap.equal_range(key);
|
||||||
|
|
||||||
for (auto e = entries.first; e != entries.second; e++) {
|
for (auto e = entries.first; e != entries.second; e++) {
|
||||||
@ -266,7 +265,7 @@ namespace dxvk {
|
|||||||
pipeline->getPipelineHandle(entry.gpState, *rp);
|
pipeline->getPipelineHandle(entry.gpState, *rp);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto pipeline = m_pipeManager->createComputePipeline(item.cs);
|
auto pipeline = m_pipeManager->createComputePipeline(item.cp);
|
||||||
auto entries = m_entryMap.equal_range(key);
|
auto entries = m_entryMap.equal_range(key);
|
||||||
|
|
||||||
for (auto e = entries.first; e != entries.second; e++) {
|
for (auto e = entries.first; e != entries.second; e++) {
|
||||||
|
@ -84,12 +84,8 @@ namespace dxvk {
|
|||||||
using WriterItem = DxvkStateCacheEntry;
|
using WriterItem = DxvkStateCacheEntry;
|
||||||
|
|
||||||
struct WorkerItem {
|
struct WorkerItem {
|
||||||
Rc<DxvkShader> vs;
|
DxvkGraphicsPipelineShaders gp;
|
||||||
Rc<DxvkShader> tcs;
|
DxvkComputePipelineShaders cp;
|
||||||
Rc<DxvkShader> tes;
|
|
||||||
Rc<DxvkShader> gs;
|
|
||||||
Rc<DxvkShader> fs;
|
|
||||||
Rc<DxvkShader> cs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DxvkPipelineManager* m_pipeManager;
|
DxvkPipelineManager* m_pipeManager;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user