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:
parent
8d4996bcda
commit
8cd13cc5bd
@ -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];
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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++) {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user