mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[dxvk] Repurpose asynchronous pipeline compiler
Removes support for DISABLE_OPTIMIZATION_BIT. Instead, pipelines will not be made available until compiled by one of the worker threads.
This commit is contained in:
parent
012a5c2f74
commit
c3b542878c
@ -39,19 +39,17 @@ namespace dxvk {
|
|||||||
const Rc<vk::DeviceFn>& vkd,
|
const Rc<vk::DeviceFn>& vkd,
|
||||||
const DxvkGraphicsPipelineStateInfo& stateVector,
|
const DxvkGraphicsPipelineStateInfo& stateVector,
|
||||||
VkRenderPass renderPass,
|
VkRenderPass renderPass,
|
||||||
VkPipeline basePipeline)
|
VkPipeline pipeline)
|
||||||
: m_vkd (vkd),
|
: m_vkd (vkd),
|
||||||
m_stateVector (stateVector),
|
m_stateVector (stateVector),
|
||||||
m_renderPass (renderPass),
|
m_renderPass (renderPass),
|
||||||
m_basePipeline(basePipeline),
|
m_pipeline (pipeline) {
|
||||||
m_fastPipeline(VK_NULL_HANDLE) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkGraphicsPipelineInstance::~DxvkGraphicsPipelineInstance() {
|
DxvkGraphicsPipelineInstance::~DxvkGraphicsPipelineInstance() {
|
||||||
m_vkd->vkDestroyPipeline(m_vkd->device(), m_basePipeline, nullptr);
|
m_vkd->vkDestroyPipeline(m_vkd->device(), m_pipeline, nullptr);
|
||||||
m_vkd->vkDestroyPipeline(m_vkd->device(), m_fastPipeline, nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -123,14 +121,17 @@ namespace dxvk {
|
|||||||
|
|
||||||
// If no pipeline instance exists with the given state
|
// If no pipeline instance exists with the given state
|
||||||
// vector, create a new one and add it to the list.
|
// vector, create a new one and add it to the list.
|
||||||
VkPipeline newPipelineBase = m_basePipelineBase.load();
|
VkPipeline newPipelineBase = m_basePipeline.load();
|
||||||
VkPipeline newPipelineHandle = this->compilePipeline(state, renderPassHandle,
|
VkPipeline newPipelineHandle = VK_NULL_HANDLE;
|
||||||
m_compiler != nullptr ? VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT : 0,
|
|
||||||
newPipelineBase);
|
if (m_compiler == nullptr) {
|
||||||
|
newPipelineHandle = this->compilePipeline(
|
||||||
|
state, renderPassHandle, newPipelineBase);
|
||||||
|
}
|
||||||
|
|
||||||
Rc<DxvkGraphicsPipelineInstance> newPipeline =
|
Rc<DxvkGraphicsPipelineInstance> newPipeline =
|
||||||
new DxvkGraphicsPipelineInstance(m_device->vkd(), state,
|
new DxvkGraphicsPipelineInstance(m_device->vkd(),
|
||||||
renderPassHandle, newPipelineHandle);
|
state, renderPassHandle, newPipelineHandle);
|
||||||
|
|
||||||
{ std::lock_guard<sync::Spinlock> lock(m_mutex);
|
{ std::lock_guard<sync::Spinlock> lock(m_mutex);
|
||||||
|
|
||||||
@ -144,15 +145,15 @@ namespace dxvk {
|
|||||||
|
|
||||||
// Add new pipeline to the set
|
// Add new pipeline to the set
|
||||||
m_pipelines.push_back(newPipeline);
|
m_pipelines.push_back(newPipeline);
|
||||||
|
|
||||||
stats.addCtr(DxvkStatCounter::PipeCountGraphics, 1);
|
stats.addCtr(DxvkStatCounter::PipeCountGraphics, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the new pipeline as the base pipeline for derivative pipelines
|
// Use the new pipeline as the base pipeline for derivative pipelines
|
||||||
if (newPipelineBase == VK_NULL_HANDLE && newPipelineHandle != VK_NULL_HANDLE)
|
if (newPipelineBase == VK_NULL_HANDLE && newPipelineHandle != VK_NULL_HANDLE)
|
||||||
m_basePipelineBase.compare_exchange_strong(newPipelineBase, newPipelineHandle);
|
m_basePipeline.compare_exchange_strong(newPipelineBase, newPipelineHandle);
|
||||||
|
|
||||||
// Compile optimized pipeline asynchronously
|
// Compile pipeline asynchronously if requested
|
||||||
if (m_compiler != nullptr)
|
if (m_compiler != nullptr)
|
||||||
m_compiler->queueCompilation(this, newPipeline);
|
m_compiler->queueCompilation(this, newPipeline);
|
||||||
|
|
||||||
@ -163,18 +164,18 @@ namespace dxvk {
|
|||||||
void DxvkGraphicsPipeline::compileInstance(
|
void DxvkGraphicsPipeline::compileInstance(
|
||||||
const Rc<DxvkGraphicsPipelineInstance>& instance) {
|
const Rc<DxvkGraphicsPipelineInstance>& instance) {
|
||||||
// Compile an optimized version of the pipeline
|
// Compile an optimized version of the pipeline
|
||||||
VkPipeline newPipelineBase = m_fastPipelineBase.load();
|
VkPipeline newPipelineBase = m_basePipeline.load();
|
||||||
VkPipeline newPipelineHandle = this->compilePipeline(
|
VkPipeline newPipelineHandle = this->compilePipeline(
|
||||||
instance->m_stateVector, instance->m_renderPass,
|
instance->m_stateVector, instance->m_renderPass,
|
||||||
0, m_fastPipelineBase);
|
newPipelineBase);
|
||||||
|
|
||||||
if (!instance->setFastPipeline(newPipelineHandle)) {
|
if (!instance->setPipeline(newPipelineHandle)) {
|
||||||
// If another thread finished compiling an optimized version of this
|
// If another thread finished compiling an optimized version of this
|
||||||
// pipeline before this one finished, discard the new pipeline object.
|
// pipeline before this one finished, discard the new pipeline object.
|
||||||
m_vkd->vkDestroyPipeline(m_vkd->device(), newPipelineHandle, nullptr);
|
m_vkd->vkDestroyPipeline(m_vkd->device(), newPipelineHandle, nullptr);
|
||||||
} else if (newPipelineBase == VK_NULL_HANDLE && newPipelineHandle != VK_NULL_HANDLE) {
|
} else if (newPipelineBase == VK_NULL_HANDLE && newPipelineHandle != VK_NULL_HANDLE) {
|
||||||
// Use the new pipeline as the base pipeline for derivative pipelines.
|
// Use the new pipeline as the base pipeline for derivative pipelines.
|
||||||
m_fastPipelineBase.compare_exchange_strong(newPipelineBase, newPipelineHandle);
|
m_basePipeline.compare_exchange_strong(newPipelineBase, newPipelineHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +195,6 @@ namespace dxvk {
|
|||||||
VkPipeline DxvkGraphicsPipeline::compilePipeline(
|
VkPipeline DxvkGraphicsPipeline::compilePipeline(
|
||||||
const DxvkGraphicsPipelineStateInfo& state,
|
const DxvkGraphicsPipelineStateInfo& state,
|
||||||
VkRenderPass renderPass,
|
VkRenderPass renderPass,
|
||||||
VkPipelineCreateFlags createFlags,
|
|
||||||
VkPipeline baseHandle) const {
|
VkPipeline baseHandle) const {
|
||||||
if (Logger::logLevel() <= LogLevel::Debug) {
|
if (Logger::logLevel() <= LogLevel::Debug) {
|
||||||
Logger::debug("Compiling graphics pipeline...");
|
Logger::debug("Compiling graphics pipeline...");
|
||||||
@ -363,7 +363,7 @@ namespace dxvk {
|
|||||||
VkGraphicsPipelineCreateInfo info;
|
VkGraphicsPipelineCreateInfo info;
|
||||||
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||||
info.pNext = nullptr;
|
info.pNext = nullptr;
|
||||||
info.flags = createFlags;
|
info.flags = 0;
|
||||||
info.stageCount = stages.size();
|
info.stageCount = stages.size();
|
||||||
info.pStages = stages.data();
|
info.pStages = stages.data();
|
||||||
info.pVertexInputState = &viInfo;
|
info.pVertexInputState = &viInfo;
|
||||||
|
@ -88,8 +88,8 @@ namespace dxvk {
|
|||||||
/**
|
/**
|
||||||
* \brief Graphics pipeline instance
|
* \brief Graphics pipeline instance
|
||||||
*
|
*
|
||||||
* Stores a state vector and the corresponding
|
* Stores a state vector and the
|
||||||
* unoptimized and optimized pipeline handles.
|
* corresponding pipeline handle.
|
||||||
*/
|
*/
|
||||||
class DxvkGraphicsPipelineInstance : public RcObject {
|
class DxvkGraphicsPipelineInstance : public RcObject {
|
||||||
friend class DxvkGraphicsPipeline;
|
friend class DxvkGraphicsPipeline;
|
||||||
@ -99,7 +99,7 @@ namespace dxvk {
|
|||||||
const Rc<vk::DeviceFn>& vkd,
|
const Rc<vk::DeviceFn>& vkd,
|
||||||
const DxvkGraphicsPipelineStateInfo& stateVector,
|
const DxvkGraphicsPipelineStateInfo& stateVector,
|
||||||
VkRenderPass renderPass,
|
VkRenderPass renderPass,
|
||||||
VkPipeline basePipeline);
|
VkPipeline pipeline);
|
||||||
|
|
||||||
~DxvkGraphicsPipelineInstance();
|
~DxvkGraphicsPipelineInstance();
|
||||||
|
|
||||||
@ -125,9 +125,9 @@ namespace dxvk {
|
|||||||
* handle should be destroyed.
|
* handle should be destroyed.
|
||||||
* \param [in] pipeline The optimized pipeline
|
* \param [in] pipeline The optimized pipeline
|
||||||
*/
|
*/
|
||||||
bool setFastPipeline(VkPipeline pipeline) {
|
bool setPipeline(VkPipeline pipeline) {
|
||||||
VkPipeline expected = VK_NULL_HANDLE;
|
VkPipeline expected = VK_NULL_HANDLE;
|
||||||
return m_fastPipeline.compare_exchange_strong(expected, pipeline);
|
return m_pipeline.compare_exchange_strong(expected, pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,11 +138,7 @@ namespace dxvk {
|
|||||||
* \returns The pipeline handle
|
* \returns The pipeline handle
|
||||||
*/
|
*/
|
||||||
VkPipeline getPipeline() const {
|
VkPipeline getPipeline() const {
|
||||||
VkPipeline basePipeline = m_basePipeline.load();
|
return m_pipeline.load();
|
||||||
VkPipeline fastPipeline = m_fastPipeline.load();
|
|
||||||
|
|
||||||
return fastPipeline != VK_NULL_HANDLE
|
|
||||||
? fastPipeline : basePipeline;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -151,9 +147,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkGraphicsPipelineStateInfo m_stateVector;
|
DxvkGraphicsPipelineStateInfo m_stateVector;
|
||||||
VkRenderPass m_renderPass;
|
VkRenderPass m_renderPass;
|
||||||
|
|
||||||
std::atomic<VkPipeline> m_basePipeline;
|
std::atomic<VkPipeline> m_pipeline;
|
||||||
std::atomic<VkPipeline> m_fastPipeline;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -248,8 +243,7 @@ namespace dxvk {
|
|||||||
std::vector<Rc<DxvkGraphicsPipelineInstance>> m_pipelines;
|
std::vector<Rc<DxvkGraphicsPipelineInstance>> m_pipelines;
|
||||||
|
|
||||||
// Pipeline handles used for derivative pipelines
|
// Pipeline handles used for derivative pipelines
|
||||||
std::atomic<VkPipeline> m_basePipelineBase = { VK_NULL_HANDLE };
|
std::atomic<VkPipeline> m_basePipeline = { VK_NULL_HANDLE };
|
||||||
std::atomic<VkPipeline> m_fastPipelineBase = { VK_NULL_HANDLE };
|
|
||||||
|
|
||||||
DxvkGraphicsPipelineInstance* findInstance(
|
DxvkGraphicsPipelineInstance* findInstance(
|
||||||
const DxvkGraphicsPipelineStateInfo& state,
|
const DxvkGraphicsPipelineStateInfo& state,
|
||||||
@ -258,7 +252,6 @@ namespace dxvk {
|
|||||||
VkPipeline compilePipeline(
|
VkPipeline compilePipeline(
|
||||||
const DxvkGraphicsPipelineStateInfo& state,
|
const DxvkGraphicsPipelineStateInfo& state,
|
||||||
VkRenderPass renderPass,
|
VkRenderPass renderPass,
|
||||||
VkPipelineCreateFlags createFlags,
|
|
||||||
VkPipeline baseHandle) const;
|
VkPipeline baseHandle) const;
|
||||||
|
|
||||||
bool validatePipelineState(
|
bool validatePipelineState(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user