rasterizer_accelerated: Add intermediary for GPU rasterizers
Add an intermediary class that implements common functions across GPU accelerated rasterizers. This avoids code repetition on different backends.
This commit is contained in:
parent
26f3e18c5c
commit
bd2aff3e26
5 changed files with 98 additions and 45 deletions
|
@ -36,6 +36,8 @@ add_library(video_core STATIC
|
||||||
memory_manager.h
|
memory_manager.h
|
||||||
morton.cpp
|
morton.cpp
|
||||||
morton.h
|
morton.h
|
||||||
|
rasterizer_accelerated.cpp
|
||||||
|
rasterizer_accelerated.h
|
||||||
rasterizer_cache.cpp
|
rasterizer_cache.cpp
|
||||||
rasterizer_cache.h
|
rasterizer_cache.h
|
||||||
rasterizer_interface.h
|
rasterizer_interface.h
|
||||||
|
|
63
src/video_core/rasterizer_accelerated.cpp
Normal file
63
src/video_core/rasterizer_accelerated.cpp
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
// Copyright 2019 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#include <boost/icl/interval_map.hpp>
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "core/memory.h"
|
||||||
|
#include "video_core/rasterizer_accelerated.h"
|
||||||
|
|
||||||
|
namespace VideoCore {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <typename Map, typename Interval>
|
||||||
|
constexpr auto RangeFromInterval(Map& map, const Interval& interval) {
|
||||||
|
return boost::make_iterator_range(map.equal_range(interval));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Anonymous namespace
|
||||||
|
|
||||||
|
RasterizerAccelerated::RasterizerAccelerated() = default;
|
||||||
|
|
||||||
|
RasterizerAccelerated::~RasterizerAccelerated() = default;
|
||||||
|
|
||||||
|
void RasterizerAccelerated::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {
|
||||||
|
std::lock_guard lock{pages_mutex};
|
||||||
|
const u64 page_start{addr >> Memory::PAGE_BITS};
|
||||||
|
const u64 page_end{(addr + size + Memory::PAGE_SIZE - 1) >> Memory::PAGE_BITS};
|
||||||
|
|
||||||
|
// Interval maps will erase segments if count reaches 0, so if delta is negative we have to
|
||||||
|
// subtract after iterating
|
||||||
|
const auto pages_interval = CachedPageMap::interval_type::right_open(page_start, page_end);
|
||||||
|
if (delta > 0) {
|
||||||
|
cached_pages.add({pages_interval, delta});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& pair : RangeFromInterval(cached_pages, pages_interval)) {
|
||||||
|
const auto interval = pair.first & pages_interval;
|
||||||
|
const int count = pair.second;
|
||||||
|
|
||||||
|
const VAddr interval_start_addr = boost::icl::first(interval) << Memory::PAGE_BITS;
|
||||||
|
const VAddr interval_end_addr = boost::icl::last_next(interval) << Memory::PAGE_BITS;
|
||||||
|
const u64 interval_size = interval_end_addr - interval_start_addr;
|
||||||
|
|
||||||
|
if (delta > 0 && count == delta) {
|
||||||
|
Memory::RasterizerMarkRegionCached(interval_start_addr, interval_size, true);
|
||||||
|
} else if (delta < 0 && count == -delta) {
|
||||||
|
Memory::RasterizerMarkRegionCached(interval_start_addr, interval_size, false);
|
||||||
|
} else {
|
||||||
|
ASSERT(count >= 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delta < 0) {
|
||||||
|
cached_pages.add({pages_interval, delta});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace VideoCore
|
31
src/video_core/rasterizer_accelerated.h
Normal file
31
src/video_core/rasterizer_accelerated.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright 2019 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#include <boost/icl/interval_map.hpp>
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "video_core/rasterizer_interface.h"
|
||||||
|
|
||||||
|
namespace VideoCore {
|
||||||
|
|
||||||
|
/// Implements the shared part in GPU accelerated rasterizers in RasterizerInterface.
|
||||||
|
class RasterizerAccelerated : public RasterizerInterface {
|
||||||
|
public:
|
||||||
|
explicit RasterizerAccelerated();
|
||||||
|
~RasterizerAccelerated() override;
|
||||||
|
|
||||||
|
void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
using CachedPageMap = boost::icl::interval_map<u64, int>;
|
||||||
|
CachedPageMap cached_pages;
|
||||||
|
|
||||||
|
std::mutex pages_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace VideoCore
|
|
@ -342,42 +342,6 @@ std::size_t RasterizerOpenGL::CalculateIndexBufferSize() const {
|
||||||
static_cast<std::size_t>(regs.index_array.FormatSizeInBytes());
|
static_cast<std::size_t>(regs.index_array.FormatSizeInBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Map, typename Interval>
|
|
||||||
static constexpr auto RangeFromInterval(Map& map, const Interval& interval) {
|
|
||||||
return boost::make_iterator_range(map.equal_range(interval));
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {
|
|
||||||
std::lock_guard lock{pages_mutex};
|
|
||||||
const u64 page_start{addr >> Memory::PAGE_BITS};
|
|
||||||
const u64 page_end{(addr + size + Memory::PAGE_SIZE - 1) >> Memory::PAGE_BITS};
|
|
||||||
|
|
||||||
// Interval maps will erase segments if count reaches 0, so if delta is negative we have to
|
|
||||||
// subtract after iterating
|
|
||||||
const auto pages_interval = CachedPageMap::interval_type::right_open(page_start, page_end);
|
|
||||||
if (delta > 0)
|
|
||||||
cached_pages.add({pages_interval, delta});
|
|
||||||
|
|
||||||
for (const auto& pair : RangeFromInterval(cached_pages, pages_interval)) {
|
|
||||||
const auto interval = pair.first & pages_interval;
|
|
||||||
const int count = pair.second;
|
|
||||||
|
|
||||||
const VAddr interval_start_addr = boost::icl::first(interval) << Memory::PAGE_BITS;
|
|
||||||
const VAddr interval_end_addr = boost::icl::last_next(interval) << Memory::PAGE_BITS;
|
|
||||||
const u64 interval_size = interval_end_addr - interval_start_addr;
|
|
||||||
|
|
||||||
if (delta > 0 && count == delta)
|
|
||||||
Memory::RasterizerMarkRegionCached(interval_start_addr, interval_size, true);
|
|
||||||
else if (delta < 0 && count == -delta)
|
|
||||||
Memory::RasterizerMarkRegionCached(interval_start_addr, interval_size, false);
|
|
||||||
else
|
|
||||||
ASSERT(count >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (delta < 0)
|
|
||||||
cached_pages.add({pages_interval, delta});
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading,
|
void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading,
|
||||||
const VideoCore::DiskResourceLoadCallback& callback) {
|
const VideoCore::DiskResourceLoadCallback& callback) {
|
||||||
shader_cache.LoadDiskCache(stop_loading, callback);
|
shader_cache.LoadDiskCache(stop_loading, callback);
|
||||||
|
|
|
@ -9,17 +9,16 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <boost/icl/interval_map.hpp>
|
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "video_core/engines/const_buffer_info.h"
|
#include "video_core/engines/const_buffer_info.h"
|
||||||
#include "video_core/engines/maxwell_3d.h"
|
#include "video_core/engines/maxwell_3d.h"
|
||||||
|
#include "video_core/rasterizer_accelerated.h"
|
||||||
#include "video_core/rasterizer_cache.h"
|
#include "video_core/rasterizer_cache.h"
|
||||||
#include "video_core/rasterizer_interface.h"
|
#include "video_core/rasterizer_interface.h"
|
||||||
#include "video_core/renderer_opengl/gl_buffer_cache.h"
|
#include "video_core/renderer_opengl/gl_buffer_cache.h"
|
||||||
|
@ -52,7 +51,7 @@ namespace OpenGL {
|
||||||
struct ScreenInfo;
|
struct ScreenInfo;
|
||||||
struct DrawParameters;
|
struct DrawParameters;
|
||||||
|
|
||||||
class RasterizerOpenGL : public VideoCore::RasterizerInterface {
|
class RasterizerOpenGL : public VideoCore::RasterizerAccelerated {
|
||||||
public:
|
public:
|
||||||
explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
|
explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
|
||||||
ScreenInfo& info);
|
ScreenInfo& info);
|
||||||
|
@ -73,7 +72,6 @@ public:
|
||||||
const Tegra::Engines::Fermi2D::Config& copy_config) override;
|
const Tegra::Engines::Fermi2D::Config& copy_config) override;
|
||||||
bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
|
bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
|
||||||
u32 pixel_stride) override;
|
u32 pixel_stride) override;
|
||||||
void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) override;
|
|
||||||
void LoadDiskResources(const std::atomic_bool& stop_loading,
|
void LoadDiskResources(const std::atomic_bool& stop_loading,
|
||||||
const VideoCore::DiskResourceLoadCallback& callback) override;
|
const VideoCore::DiskResourceLoadCallback& callback) override;
|
||||||
|
|
||||||
|
@ -228,11 +226,6 @@ private:
|
||||||
AccelDraw accelerate_draw = AccelDraw::Disabled;
|
AccelDraw accelerate_draw = AccelDraw::Disabled;
|
||||||
|
|
||||||
OGLFramebuffer clear_framebuffer;
|
OGLFramebuffer clear_framebuffer;
|
||||||
|
|
||||||
using CachedPageMap = boost::icl::interval_map<u64, int>;
|
|
||||||
CachedPageMap cached_pages;
|
|
||||||
|
|
||||||
std::mutex pages_mutex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace OpenGL
|
} // namespace OpenGL
|
||||||
|
|
Loading…
Reference in a new issue