1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00

[dxvk] Add ability to hold two pipeline handles to pipeline instances

This commit is contained in:
Philip Rebohle 2018-05-10 14:15:47 +02:00
parent 010fc6ad49
commit 3b132196d3
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 62 additions and 20 deletions

View File

@ -37,16 +37,20 @@ namespace dxvk {
DxvkGraphicsPipelineInstance::DxvkGraphicsPipelineInstance( DxvkGraphicsPipelineInstance::DxvkGraphicsPipelineInstance(
const Rc<vk::DeviceFn>& vkd, const Rc<vk::DeviceFn>& vkd,
const DxvkGraphicsPipelineStateInfo& stateVector, const DxvkGraphicsPipelineStateInfo& stateVector,
VkRenderPass renderPass) VkRenderPass renderPass,
VkPipeline basePipeline)
: m_vkd (vkd), : m_vkd (vkd),
m_stateVector (stateVector), m_stateVector (stateVector),
m_renderPass (renderPass) { m_renderPass (renderPass),
m_basePipeline(basePipeline),
m_fastPipeline(VK_NULL_HANDLE) {
} }
DxvkGraphicsPipelineInstance::~DxvkGraphicsPipelineInstance() { DxvkGraphicsPipelineInstance::~DxvkGraphicsPipelineInstance() {
m_vkd->vkDestroyPipeline(m_vkd->device(), m_pipeline, nullptr); m_vkd->vkDestroyPipeline(m_vkd->device(), m_basePipeline, nullptr);
m_vkd->vkDestroyPipeline(m_vkd->device(), m_fastPipeline, nullptr);
} }
@ -113,11 +117,12 @@ 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.
Rc<DxvkGraphicsPipelineInstance> newPipeline = VkPipeline newPipelineHandle = this->compilePipeline(
new DxvkGraphicsPipelineInstance(m_device->vkd(), state, renderPassHandle); state, renderPassHandle, VK_NULL_HANDLE);
newPipeline->setPipeline(this->compilePipeline( Rc<DxvkGraphicsPipelineInstance> newPipeline =
state, renderPassHandle, VK_NULL_HANDLE)); new DxvkGraphicsPipelineInstance(m_device->vkd(), state,
renderPassHandle, newPipelineHandle);
{ std::lock_guard<sync::Spinlock> lock(m_mutex); { std::lock_guard<sync::Spinlock> lock(m_mutex);
@ -138,6 +143,19 @@ namespace dxvk {
} }
void DxvkGraphicsPipeline::compilePipelineInstance(
const Rc<DxvkGraphicsPipelineInstance>& instance) {
// Compile an optimized version of the pipeline
VkPipeline newPipelineHandle = this->compilePipeline(
instance->m_stateVector, instance->m_renderPass, VK_NULL_HANDLE);
// If an optimized version has been compiled
// in the meantime, discard the new pipeline
if (!instance->setFastPipeline(newPipelineHandle))
m_vkd->vkDestroyPipeline(m_vkd->device(), newPipelineHandle, nullptr);
}
DxvkGraphicsPipelineInstance* DxvkGraphicsPipeline::findInstance( DxvkGraphicsPipelineInstance* DxvkGraphicsPipeline::findInstance(
const DxvkGraphicsPipelineStateInfo& state, const DxvkGraphicsPipelineStateInfo& state,
VkRenderPass renderPass) const { VkRenderPass renderPass) const {

View File

@ -94,16 +94,17 @@ namespace dxvk {
* \brief Graphics pipeline instance * \brief Graphics pipeline instance
* *
* Stores a state vector and the corresponding * Stores a state vector and the corresponding
* pipeline handles. * unoptimized and optimized pipeline handles.
*/ */
class DxvkGraphicsPipelineInstance : public RcObject { class DxvkGraphicsPipelineInstance : public RcObject {
friend class DxvkGraphicsPipeline;
public: public:
DxvkGraphicsPipelineInstance( DxvkGraphicsPipelineInstance(
const Rc<vk::DeviceFn>& vkd, const Rc<vk::DeviceFn>& vkd,
const DxvkGraphicsPipelineStateInfo& stateVector, const DxvkGraphicsPipelineStateInfo& stateVector,
VkRenderPass renderPass); VkRenderPass renderPass,
VkPipeline basePipeline);
~DxvkGraphicsPipelineInstance(); ~DxvkGraphicsPipelineInstance();
@ -122,19 +123,31 @@ namespace dxvk {
} }
/** /**
* \brief Sets the pipeline handle * \brief Sets the optimized pipeline handle
* \param [in] pipeline The pipeline *
* If an optimized pipeline handle has already been
* set up, this method will fail and the new pipeline
* handle should be destroyed.
* \param [in] pipeline The optimized pipeline
*/ */
void setPipeline(VkPipeline pipeline) { bool setFastPipeline(VkPipeline pipeline) {
m_pipeline = pipeline; VkPipeline expected = VK_NULL_HANDLE;
return m_fastPipeline.compare_exchange_strong(expected, pipeline);
} }
/** /**
* \brief Retrieves pipeline * \brief Retrieves pipeline
* \returns The pipeline *
* Returns the optimized version of the pipeline if
* if has been set, or the base pipeline if not.
* \returns The pipeline handle
*/ */
VkPipeline getPipeline() const { VkPipeline getPipeline() const {
return m_pipeline; VkPipeline basePipeline = m_basePipeline.load();
VkPipeline fastPipeline = m_fastPipeline.load();
return fastPipeline != VK_NULL_HANDLE
? fastPipeline : basePipeline;
} }
private: private:
@ -144,7 +157,8 @@ namespace dxvk {
DxvkGraphicsPipelineStateInfo m_stateVector; DxvkGraphicsPipelineStateInfo m_stateVector;
VkRenderPass m_renderPass; VkRenderPass m_renderPass;
VkPipeline m_pipeline = VK_NULL_HANDLE; std::atomic<VkPipeline> m_basePipeline;
std::atomic<VkPipeline> m_fastPipeline;
}; };
@ -193,9 +207,19 @@ namespace dxvk {
* \returns Pipeline handle * \returns Pipeline handle
*/ */
VkPipeline getPipelineHandle( VkPipeline getPipelineHandle(
const DxvkGraphicsPipelineStateInfo& state, const DxvkGraphicsPipelineStateInfo& state,
const DxvkRenderPass& renderPass, const DxvkRenderPass& renderPass,
DxvkStatCounters& stats); DxvkStatCounters& stats);
/**
* \brief Compiles optimized pipeline
*
* Compiles an optimized version of a pipeline
* and makes it available to the system.
* \param [in] instance The pipeline instance
*/
void compilePipelineInstance(
const Rc<DxvkGraphicsPipelineInstance>& instance);
private: private: