1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-20 19:54:19 +01:00

[dxvk] Refactor render pass objects to not use reference counting

Like pipeline objects, we keep these around anyway so there's no
reason to add ref count overhead. Also use a hash map to perform
the lookup.
This commit is contained in:
Philip Rebohle 2019-07-30 13:04:13 +02:00
parent d01b6baf38
commit 13bc3df92f
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
5 changed files with 39 additions and 19 deletions

View File

@ -4,7 +4,7 @@ namespace dxvk {
DxvkFramebuffer::DxvkFramebuffer(
const Rc<vk::DeviceFn>& vkd,
const Rc<DxvkRenderPass>& renderPass,
DxvkRenderPass* renderPass,
const DxvkRenderTargets& renderTargets,
const DxvkFramebufferSize& defaultSize)
: m_vkd (vkd),

View File

@ -56,7 +56,7 @@ namespace dxvk {
DxvkFramebuffer(
const Rc<vk::DeviceFn>& vkd,
const Rc<DxvkRenderPass>& renderPass,
DxvkRenderPass* renderPass,
const DxvkRenderTargets& renderTargets,
const DxvkFramebufferSize& defaultSize);
@ -204,7 +204,7 @@ namespace dxvk {
private:
const Rc<vk::DeviceFn> m_vkd;
const Rc<DxvkRenderPass> m_renderPass;
DxvkRenderPass* m_renderPass;
const DxvkRenderTargets m_renderTargets;
const DxvkFramebufferSize m_renderSize;

View File

@ -4,7 +4,7 @@
namespace dxvk {
bool DxvkRenderPassFormat::matches(const DxvkRenderPassFormat& fmt) const {
bool DxvkRenderPassFormat::eq(const DxvkRenderPassFormat& fmt) const {
bool eq = sampleCount == fmt.sampleCount;
for (uint32_t i = 0; i < MaxNumRenderTargets && eq; i++) {
@ -17,6 +17,21 @@ namespace dxvk {
return eq;
}
size_t DxvkRenderPassFormat::hash() const {
DxvkHashState state;
state.add(uint32_t(sampleCount));
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
state.add(uint32_t(color[i].format));
state.add(uint32_t(color[i].layout));
}
state.add(uint32_t(depth.format));
state.add(uint32_t(depth.layout));
return state;
}
DxvkRenderPass::DxvkRenderPass(
@ -39,7 +54,7 @@ namespace dxvk {
bool DxvkRenderPass::hasCompatibleFormat(const DxvkRenderPassFormat& fmt) const {
return m_format.matches(fmt);
return m_format.eq(fmt);
}
@ -216,17 +231,17 @@ namespace dxvk {
}
Rc<DxvkRenderPass> DxvkRenderPassPool::getRenderPass(const DxvkRenderPassFormat& fmt) {
DxvkRenderPass* DxvkRenderPassPool::getRenderPass(const DxvkRenderPassFormat& fmt) {
std::lock_guard<std::mutex> lock(m_mutex);
auto entry = m_renderPasses.find(fmt);
if (entry != m_renderPasses.end())
return &entry->second;
for (const auto& r : m_renderPasses) {
if (r->hasCompatibleFormat(fmt))
return r;
}
Rc<DxvkRenderPass> rp = new DxvkRenderPass(m_vkd, fmt);
m_renderPasses.push_back(rp);
return rp;
auto result = m_renderPasses.emplace(std::piecewise_construct,
std::tuple(fmt),
std::tuple(m_vkd, fmt));
return &result.first->second;
}
}

View File

@ -32,7 +32,9 @@ namespace dxvk {
DxvkAttachmentFormat depth;
DxvkAttachmentFormat color[MaxNumRenderTargets];
bool matches(const DxvkRenderPassFormat& fmt) const;
bool eq(const DxvkRenderPassFormat& fmt) const;
size_t hash() const;
};
@ -101,7 +103,7 @@ namespace dxvk {
* render passes which share the same format but
* may differ in their attachment operations.
*/
class DxvkRenderPass : public RcObject {
class DxvkRenderPass {
public:
@ -211,7 +213,7 @@ namespace dxvk {
* \param [in] fmt The render pass format
* \returns Matching render pass object
*/
Rc<DxvkRenderPass> getRenderPass(
DxvkRenderPass* getRenderPass(
const DxvkRenderPassFormat& fmt);
private:
@ -219,7 +221,10 @@ namespace dxvk {
const Rc<vk::DeviceFn> m_vkd;
std::mutex m_mutex;
std::vector<Rc<DxvkRenderPass>> m_renderPasses;
std::unordered_map<
DxvkRenderPassFormat,
DxvkRenderPass,
DxvkHash, DxvkEq> m_renderPasses;
};

View File

@ -135,7 +135,7 @@ namespace dxvk {
for (auto e = entries.first; e != entries.second; e++) {
const DxvkStateCacheEntry& entry = m_entries[e->second];
if (entry.format.matches(format) && entry.gpState == state)
if (entry.format.eq(format) && entry.gpState == state)
return;
}