1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-31 14:52:11 +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(
const Rc<vk::DeviceFn>& vkd,
const DxvkGraphicsPipelineStateInfo& stateVector,
VkRenderPass renderPass)
VkRenderPass renderPass,
VkPipeline basePipeline)
: m_vkd (vkd),
m_stateVector (stateVector),
m_renderPass (renderPass) {
m_renderPass (renderPass),
m_basePipeline(basePipeline),
m_fastPipeline(VK_NULL_HANDLE) {
}
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
// vector, create a new one and add it to the list.
Rc<DxvkGraphicsPipelineInstance> newPipeline =
new DxvkGraphicsPipelineInstance(m_device->vkd(), state, renderPassHandle);
VkPipeline newPipelineHandle = this->compilePipeline(
state, renderPassHandle, VK_NULL_HANDLE);
newPipeline->setPipeline(this->compilePipeline(
state, renderPassHandle, VK_NULL_HANDLE));
Rc<DxvkGraphicsPipelineInstance> newPipeline =
new DxvkGraphicsPipelineInstance(m_device->vkd(), state,
renderPassHandle, newPipelineHandle);
{ 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(
const DxvkGraphicsPipelineStateInfo& state,
VkRenderPass renderPass) const {

View File

@ -94,16 +94,17 @@ namespace dxvk {
* \brief Graphics pipeline instance
*
* Stores a state vector and the corresponding
* pipeline handles.
* unoptimized and optimized pipeline handles.
*/
class DxvkGraphicsPipelineInstance : public RcObject {
friend class DxvkGraphicsPipeline;
public:
DxvkGraphicsPipelineInstance(
const Rc<vk::DeviceFn>& vkd,
const DxvkGraphicsPipelineStateInfo& stateVector,
VkRenderPass renderPass);
VkRenderPass renderPass,
VkPipeline basePipeline);
~DxvkGraphicsPipelineInstance();
@ -122,19 +123,31 @@ namespace dxvk {
}
/**
* \brief Sets the pipeline handle
* \param [in] pipeline The pipeline
* \brief Sets the optimized pipeline handle
*
* 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) {
m_pipeline = pipeline;
bool setFastPipeline(VkPipeline pipeline) {
VkPipeline expected = VK_NULL_HANDLE;
return m_fastPipeline.compare_exchange_strong(expected, 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 {
return m_pipeline;
VkPipeline basePipeline = m_basePipeline.load();
VkPipeline fastPipeline = m_fastPipeline.load();
return fastPipeline != VK_NULL_HANDLE
? fastPipeline : basePipeline;
}
private:
@ -144,7 +157,8 @@ namespace dxvk {
DxvkGraphicsPipelineStateInfo m_stateVector;
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
*/
VkPipeline getPipelineHandle(
const DxvkGraphicsPipelineStateInfo& state,
const DxvkRenderPass& renderPass,
DxvkStatCounters& stats);
const DxvkGraphicsPipelineStateInfo& state,
const DxvkRenderPass& renderPass,
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: