video_core: Use interval map for cached_pages
* Also eliminate g_memory in hardware renderers
This commit is contained in:
@@ -88,98 +88,6 @@ void RasterizerAccelerated::AddTriangle(const Pica::Shader::OutputVertex& v0,
|
|||||||
vertex_batch.emplace_back(v2, AreQuaternionsOpposite(v0.quat, v2.quat));
|
vertex_batch.emplace_back(v2, AreQuaternionsOpposite(v0.quat, v2.quat));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerAccelerated::UpdatePagesCachedCount(PAddr addr, u32 size, int delta) {
|
|
||||||
const u32 page_start = addr >> Memory::CITRA_PAGE_BITS;
|
|
||||||
const u32 page_end = ((addr + size - 1) >> Memory::CITRA_PAGE_BITS) + 1;
|
|
||||||
|
|
||||||
u32 uncache_start_addr = 0;
|
|
||||||
u32 cache_start_addr = 0;
|
|
||||||
u32 uncache_bytes = 0;
|
|
||||||
u32 cache_bytes = 0;
|
|
||||||
|
|
||||||
for (u32 page = page_start; page != page_end; page++) {
|
|
||||||
auto& count = cached_pages.at(page);
|
|
||||||
|
|
||||||
// Ensure no overflow happens
|
|
||||||
if (delta > 0) {
|
|
||||||
ASSERT_MSG(count < std::numeric_limits<u16>::max(), "Count will overflow!");
|
|
||||||
} else if (delta < 0) {
|
|
||||||
ASSERT_MSG(count > 0, "Count will underflow!");
|
|
||||||
} else {
|
|
||||||
ASSERT_MSG(false, "Delta must be non-zero!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds or subtracts 1, as count is a unsigned 8-bit value
|
|
||||||
count += delta;
|
|
||||||
|
|
||||||
// Assume delta is either -1 or 1
|
|
||||||
if (count == 0) {
|
|
||||||
if (uncache_bytes == 0) {
|
|
||||||
uncache_start_addr = page << Memory::CITRA_PAGE_BITS;
|
|
||||||
}
|
|
||||||
|
|
||||||
uncache_bytes += Memory::CITRA_PAGE_SIZE;
|
|
||||||
} else if (uncache_bytes > 0) {
|
|
||||||
VideoCore::g_memory->RasterizerMarkRegionCached(uncache_start_addr, uncache_bytes,
|
|
||||||
false);
|
|
||||||
uncache_bytes = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count == 1 && delta > 0) {
|
|
||||||
if (cache_bytes == 0) {
|
|
||||||
cache_start_addr = page << Memory::CITRA_PAGE_BITS;
|
|
||||||
}
|
|
||||||
|
|
||||||
cache_bytes += Memory::CITRA_PAGE_SIZE;
|
|
||||||
} else if (cache_bytes > 0) {
|
|
||||||
VideoCore::g_memory->RasterizerMarkRegionCached(cache_start_addr, cache_bytes, true);
|
|
||||||
|
|
||||||
cache_bytes = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uncache_bytes > 0) {
|
|
||||||
VideoCore::g_memory->RasterizerMarkRegionCached(uncache_start_addr, uncache_bytes, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cache_bytes > 0) {
|
|
||||||
VideoCore::g_memory->RasterizerMarkRegionCached(cache_start_addr, cache_bytes, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerAccelerated::ClearAll(bool flush) {
|
|
||||||
// Force flush all surfaces from the cache
|
|
||||||
if (flush) {
|
|
||||||
FlushRegion(0x0, 0xFFFFFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 uncache_start_addr = 0;
|
|
||||||
u32 uncache_bytes = 0;
|
|
||||||
|
|
||||||
for (u32 page = 0; page != cached_pages.size(); page++) {
|
|
||||||
auto& count = cached_pages.at(page);
|
|
||||||
|
|
||||||
// Assume delta is either -1 or 1
|
|
||||||
if (count != 0) {
|
|
||||||
if (uncache_bytes == 0) {
|
|
||||||
uncache_start_addr = page << Memory::CITRA_PAGE_BITS;
|
|
||||||
}
|
|
||||||
|
|
||||||
uncache_bytes += Memory::CITRA_PAGE_SIZE;
|
|
||||||
} else if (uncache_bytes > 0) {
|
|
||||||
VideoCore::g_memory->RasterizerMarkRegionCached(uncache_start_addr, uncache_bytes,
|
|
||||||
false);
|
|
||||||
uncache_bytes = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uncache_bytes > 0) {
|
|
||||||
VideoCore::g_memory->RasterizerMarkRegionCached(uncache_start_addr, uncache_bytes, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
cached_pages = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
RasterizerAccelerated::VertexArrayInfo RasterizerAccelerated::AnalyzeVertexArray(
|
RasterizerAccelerated::VertexArrayInfo RasterizerAccelerated::AnalyzeVertexArray(
|
||||||
bool is_indexed, u32 stride_alignment) {
|
bool is_indexed, u32 stride_alignment) {
|
||||||
const auto& regs = Pica::g_state.regs;
|
const auto& regs = Pica::g_state.regs;
|
||||||
|
@@ -18,18 +18,13 @@ public:
|
|||||||
|
|
||||||
void AddTriangle(const Pica::Shader::OutputVertex& v0, const Pica::Shader::OutputVertex& v1,
|
void AddTriangle(const Pica::Shader::OutputVertex& v0, const Pica::Shader::OutputVertex& v1,
|
||||||
const Pica::Shader::OutputVertex& v2) override;
|
const Pica::Shader::OutputVertex& v2) override;
|
||||||
|
|
||||||
void UpdatePagesCachedCount(PAddr addr, u32 size, int delta) override;
|
|
||||||
void NotifyPicaRegisterChanged(u32 id) override;
|
void NotifyPicaRegisterChanged(u32 id) override;
|
||||||
void ClearAll(bool flush) override;
|
|
||||||
|
|
||||||
/// Syncs entire status to match PICA registers
|
|
||||||
void SyncEntireState() override;
|
void SyncEntireState() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
/// Sync fixed-function pipeline state
|
/// Sync fixed-function pipeline state
|
||||||
virtual void SyncFixedState() = 0;
|
virtual void SyncFixedState() = 0;
|
||||||
|
|
||||||
protected:
|
|
||||||
/// Notifies that a fixed function PICA register changed to the video backend
|
/// Notifies that a fixed function PICA register changed to the video backend
|
||||||
virtual void NotifyFixedFunctionPicaRegisterChanged(u32 id) = 0;
|
virtual void NotifyFixedFunctionPicaRegisterChanged(u32 id) = 0;
|
||||||
|
|
||||||
@@ -137,7 +132,6 @@ protected:
|
|||||||
VertexArrayInfo AnalyzeVertexArray(bool is_indexed, u32 stride_alignment = 1);
|
VertexArrayInfo AnalyzeVertexArray(bool is_indexed, u32 stride_alignment = 1);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::array<u16, 0x30000> cached_pages{};
|
|
||||||
std::vector<HardwareVertex> vertex_batch;
|
std::vector<HardwareVertex> vertex_batch;
|
||||||
bool shader_dirty = true;
|
bool shader_dirty = true;
|
||||||
|
|
||||||
|
@@ -12,8 +12,8 @@
|
|||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
|
#include "core/memory.h"
|
||||||
#include "video_core/pica_state.h"
|
#include "video_core/pica_state.h"
|
||||||
#include "video_core/rasterizer_accelerated.h"
|
|
||||||
#include "video_core/rasterizer_cache/surface_base.h"
|
#include "video_core/rasterizer_cache/surface_base.h"
|
||||||
#include "video_core/rasterizer_cache/surface_params.h"
|
#include "video_core/rasterizer_cache/surface_params.h"
|
||||||
#include "video_core/rasterizer_cache/utils.h"
|
#include "video_core/rasterizer_cache/utils.h"
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
namespace VideoCore {
|
namespace VideoCore {
|
||||||
|
|
||||||
inline auto RangeFromInterval(auto& map, SurfaceInterval interval) {
|
inline auto RangeFromInterval(auto& map, const auto& interval) {
|
||||||
return boost::make_iterator_range(map.equal_range(interval));
|
return boost::make_iterator_range(map.equal_range(interval));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,9 +70,10 @@ private:
|
|||||||
|
|
||||||
using SurfaceRect_Tuple = std::tuple<Surface, Common::Rectangle<u32>>;
|
using SurfaceRect_Tuple = std::tuple<Surface, Common::Rectangle<u32>>;
|
||||||
using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, Common::Rectangle<u32>>;
|
using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, Common::Rectangle<u32>>;
|
||||||
|
using PageMap = boost::icl::interval_map<u32, int>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RasterizerCache(VideoCore::RasterizerAccelerated& rasterizer, TextureRuntime& runtime);
|
RasterizerCache(Memory::MemorySystem& memory, TextureRuntime& runtime);
|
||||||
~RasterizerCache() = default;
|
~RasterizerCache() = default;
|
||||||
|
|
||||||
/// Get the best surface match (and its match type) for the given flags
|
/// Get the best surface match (and its match type) for the given flags
|
||||||
@@ -124,6 +125,9 @@ public:
|
|||||||
/// Flush all cached resources tracked by this cache manager
|
/// Flush all cached resources tracked by this cache manager
|
||||||
void FlushAll();
|
void FlushAll();
|
||||||
|
|
||||||
|
/// Clear all cached resources tracked by this cache manager
|
||||||
|
void ClearAll(bool flush);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DuplicateSurface(const Surface& src_surface, const Surface& dest_surface);
|
void DuplicateSurface(const Surface& src_surface, const Surface& dest_surface);
|
||||||
|
|
||||||
@@ -159,23 +163,24 @@ private:
|
|||||||
/// Remove surface from the cache
|
/// Remove surface from the cache
|
||||||
void UnregisterSurface(const Surface& surface);
|
void UnregisterSurface(const Surface& surface);
|
||||||
|
|
||||||
|
/// Increase/decrease the number of surface in pages touching the specified region
|
||||||
|
void UpdatePagesCachedCount(PAddr addr, u32 size, int delta);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VideoCore::RasterizerAccelerated& rasterizer;
|
Memory::MemorySystem& memory;
|
||||||
TextureRuntime& runtime;
|
TextureRuntime& runtime;
|
||||||
SurfaceCache surface_cache;
|
SurfaceCache surface_cache;
|
||||||
|
PageMap cached_pages;
|
||||||
SurfaceMap dirty_regions;
|
SurfaceMap dirty_regions;
|
||||||
SurfaceSet remove_surfaces;
|
SurfaceSet remove_surfaces;
|
||||||
u16 resolution_scale_factor;
|
u16 resolution_scale_factor;
|
||||||
std::vector<std::function<void()>> download_queue;
|
std::vector<std::function<void()>> download_queue;
|
||||||
std::vector<u8> staging_buffer;
|
|
||||||
std::unordered_map<TextureCubeConfig, Surface> texture_cube_cache;
|
std::unordered_map<TextureCubeConfig, Surface> texture_cube_cache;
|
||||||
std::recursive_mutex mutex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
RasterizerCache<T>::RasterizerCache(VideoCore::RasterizerAccelerated& rasterizer,
|
RasterizerCache<T>::RasterizerCache(Memory::MemorySystem& memory_, TextureRuntime& runtime_)
|
||||||
TextureRuntime& runtime)
|
: memory{memory_}, runtime{runtime_} {
|
||||||
: rasterizer{rasterizer}, runtime{runtime} {
|
|
||||||
resolution_scale_factor = VideoCore::GetResolutionScaleFactor();
|
resolution_scale_factor = VideoCore::GetResolutionScaleFactor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -910,7 +915,7 @@ void RasterizerCache<T>::UploadSurface(const Surface& surface, SurfaceInterval i
|
|||||||
|
|
||||||
const auto staging = runtime.FindStaging(
|
const auto staging = runtime.FindStaging(
|
||||||
load_info.width * load_info.height * surface->GetInternalBytesPerPixel(), true);
|
load_info.width * load_info.height * surface->GetInternalBytesPerPixel(), true);
|
||||||
MemoryRef source_ptr = VideoCore::g_memory->GetPhysicalRef(load_info.addr);
|
MemoryRef source_ptr = memory.GetPhysicalRef(load_info.addr);
|
||||||
if (!source_ptr) [[unlikely]] {
|
if (!source_ptr) [[unlikely]] {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -944,7 +949,7 @@ void RasterizerCache<T>::DownloadSurface(const Surface& surface, SurfaceInterval
|
|||||||
|
|
||||||
surface->Download(download, staging);
|
surface->Download(download, staging);
|
||||||
|
|
||||||
MemoryRef dest_ptr = VideoCore::g_memory->GetPhysicalRef(flush_start);
|
MemoryRef dest_ptr = memory.GetPhysicalRef(flush_start);
|
||||||
if (!dest_ptr) [[unlikely]] {
|
if (!dest_ptr) [[unlikely]] {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -964,7 +969,7 @@ void RasterizerCache<T>::DownloadFillSurface(const Surface& surface, SurfaceInte
|
|||||||
const u32 flush_end = boost::icl::last_next(interval);
|
const u32 flush_end = boost::icl::last_next(interval);
|
||||||
ASSERT(flush_start >= surface->addr && flush_end <= surface->end);
|
ASSERT(flush_start >= surface->addr && flush_end <= surface->end);
|
||||||
|
|
||||||
MemoryRef dest_ptr = VideoCore::g_memory->GetPhysicalRef(flush_start);
|
MemoryRef dest_ptr = memory.GetPhysicalRef(flush_start);
|
||||||
if (!dest_ptr) [[unlikely]] {
|
if (!dest_ptr) [[unlikely]] {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1062,9 +1067,32 @@ bool RasterizerCache<T>::ValidateByReinterpretation(const Surface& surface, Surf
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void RasterizerCache<T>::FlushRegion(PAddr addr, u32 size, Surface flush_surface) {
|
void RasterizerCache<T>::ClearAll(bool flush) {
|
||||||
std::lock_guard lock{mutex};
|
const auto flush_interval = PageMap::interval_type::right_open(0x0, 0xFFFFFFFF);
|
||||||
|
// Force flush all surfaces from the cache
|
||||||
|
if (flush) {
|
||||||
|
FlushRegion(0x0, 0xFFFFFFFF);
|
||||||
|
}
|
||||||
|
// Unmark all of the marked pages
|
||||||
|
for (auto& pair : RangeFromInterval(cached_pages, flush_interval)) {
|
||||||
|
const auto interval = pair.first & flush_interval;
|
||||||
|
|
||||||
|
const PAddr interval_start_addr = boost::icl::first(interval) << Memory::CITRA_PAGE_BITS;
|
||||||
|
const PAddr interval_end_addr = boost::icl::last_next(interval) << Memory::CITRA_PAGE_BITS;
|
||||||
|
const u32 interval_size = interval_end_addr - interval_start_addr;
|
||||||
|
|
||||||
|
memory.RasterizerMarkRegionCached(interval_start_addr, interval_size, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the whole cache without really looking at it.
|
||||||
|
cached_pages -= flush_interval;
|
||||||
|
dirty_regions -= SurfaceInterval(0x0, 0xFFFFFFFF);
|
||||||
|
surface_cache -= SurfaceInterval(0x0, 0xFFFFFFFF);
|
||||||
|
remove_surfaces.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void RasterizerCache<T>::FlushRegion(PAddr addr, u32 size, Surface flush_surface) {
|
||||||
if (size == 0) [[unlikely]] {
|
if (size == 0) [[unlikely]] {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1116,8 +1144,6 @@ void RasterizerCache<T>::FlushAll() {
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void RasterizerCache<T>::InvalidateRegion(PAddr addr, u32 size, const Surface& region_owner) {
|
void RasterizerCache<T>::InvalidateRegion(PAddr addr, u32 size, const Surface& region_owner) {
|
||||||
std::lock_guard lock{mutex};
|
|
||||||
|
|
||||||
if (size == 0) [[unlikely]] {
|
if (size == 0) [[unlikely]] {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1189,28 +1215,60 @@ auto RasterizerCache<T>::CreateSurface(SurfaceParams& params) -> Surface {
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void RasterizerCache<T>::RegisterSurface(const Surface& surface) {
|
void RasterizerCache<T>::RegisterSurface(const Surface& surface) {
|
||||||
std::lock_guard lock{mutex};
|
|
||||||
|
|
||||||
if (surface->registered) {
|
if (surface->registered) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
surface->registered = true;
|
surface->registered = true;
|
||||||
surface_cache.add({surface->GetInterval(), SurfaceSet{surface}});
|
surface_cache.add({surface->GetInterval(), SurfaceSet{surface}});
|
||||||
rasterizer.UpdatePagesCachedCount(surface->addr, surface->size, 1);
|
UpdatePagesCachedCount(surface->addr, surface->size, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void RasterizerCache<T>::UnregisterSurface(const Surface& surface) {
|
void RasterizerCache<T>::UnregisterSurface(const Surface& surface) {
|
||||||
std::lock_guard lock{mutex};
|
|
||||||
|
|
||||||
if (!surface->registered) {
|
if (!surface->registered) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
surface->registered = false;
|
surface->registered = false;
|
||||||
rasterizer.UpdatePagesCachedCount(surface->addr, surface->size, -1);
|
UpdatePagesCachedCount(surface->addr, surface->size, -1);
|
||||||
surface_cache.subtract({surface->GetInterval(), SurfaceSet{surface}});
|
surface_cache.subtract({surface->GetInterval(), SurfaceSet{surface}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void RasterizerCache<T>::UpdatePagesCachedCount(PAddr addr, u32 size, int delta) {
|
||||||
|
const u32 num_pages =
|
||||||
|
((addr + size - 1) >> Memory::CITRA_PAGE_BITS) - (addr >> Memory::CITRA_PAGE_BITS) + 1;
|
||||||
|
const u32 page_start = addr >> Memory::CITRA_PAGE_BITS;
|
||||||
|
const u32 page_end = page_start + num_pages;
|
||||||
|
|
||||||
|
// Interval maps will erase segments if count reaches 0, so if delta is negative we have to
|
||||||
|
// subtract after iterating
|
||||||
|
const auto pages_interval = PageMap::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 PAddr interval_start_addr = boost::icl::first(interval) << Memory::CITRA_PAGE_BITS;
|
||||||
|
const PAddr interval_end_addr = boost::icl::last_next(interval) << Memory::CITRA_PAGE_BITS;
|
||||||
|
const u32 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
|
} // namespace VideoCore
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
#include "video_core/renderer_opengl/gl_driver.h"
|
#include "video_core/renderer_opengl/gl_driver.h"
|
||||||
#include "video_core/renderer_opengl/gl_rasterizer.h"
|
#include "video_core/renderer_opengl/gl_rasterizer.h"
|
||||||
#include "video_core/renderer_opengl/gl_shader_gen.h"
|
#include "video_core/renderer_opengl/gl_shader_gen.h"
|
||||||
#include "video_core/renderer_opengl/gl_vars.h"
|
|
||||||
#include "video_core/renderer_opengl/pica_to_gl.h"
|
#include "video_core/renderer_opengl/pica_to_gl.h"
|
||||||
#include "video_core/renderer_opengl/renderer_opengl.h"
|
#include "video_core/renderer_opengl/renderer_opengl.h"
|
||||||
#include "video_core/video_core.h"
|
#include "video_core/video_core.h"
|
||||||
@@ -25,8 +24,9 @@ constexpr std::size_t INDEX_BUFFER_SIZE = 1 * 1024 * 1024;
|
|||||||
constexpr std::size_t UNIFORM_BUFFER_SIZE = 2 * 1024 * 1024;
|
constexpr std::size_t UNIFORM_BUFFER_SIZE = 2 * 1024 * 1024;
|
||||||
constexpr std::size_t TEXTURE_BUFFER_SIZE = 1 * 1024 * 1024;
|
constexpr std::size_t TEXTURE_BUFFER_SIZE = 1 * 1024 * 1024;
|
||||||
|
|
||||||
RasterizerOpenGL::RasterizerOpenGL(Frontend::EmuWindow& emu_window, Driver& driver)
|
RasterizerOpenGL::RasterizerOpenGL(Memory::MemorySystem& memory_, Frontend::EmuWindow& emu_window,
|
||||||
: driver{driver}, runtime{driver}, res_cache{*this, runtime},
|
Driver& driver_)
|
||||||
|
: memory{memory_}, driver{driver_}, runtime{driver}, res_cache{memory, runtime},
|
||||||
shader_program_manager{emu_window, driver, !driver.IsOpenGLES()},
|
shader_program_manager{emu_window, driver, !driver.IsOpenGLES()},
|
||||||
vertex_buffer{GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE}, uniform_buffer{GL_UNIFORM_BUFFER,
|
vertex_buffer{GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE}, uniform_buffer{GL_UNIFORM_BUFFER,
|
||||||
UNIFORM_BUFFER_SIZE},
|
UNIFORM_BUFFER_SIZE},
|
||||||
@@ -210,7 +210,7 @@ void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset,
|
|||||||
u32 data_size = loader.byte_count * vertex_num;
|
u32 data_size = loader.byte_count * vertex_num;
|
||||||
|
|
||||||
res_cache.FlushRegion(data_addr, data_size, nullptr);
|
res_cache.FlushRegion(data_addr, data_size, nullptr);
|
||||||
std::memcpy(array_ptr, VideoCore::g_memory->GetPhysicalPointer(data_addr), data_size);
|
std::memcpy(array_ptr, memory.GetPhysicalPointer(data_addr), data_size);
|
||||||
|
|
||||||
array_ptr += data_size;
|
array_ptr += data_size;
|
||||||
buffer_offset += data_size;
|
buffer_offset += data_size;
|
||||||
@@ -326,9 +326,9 @@ bool RasterizerOpenGL::AccelerateDrawBatchInternal(bool is_indexed) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const u8* index_data = VideoCore::g_memory->GetPhysicalPointer(
|
const u8* index_data =
|
||||||
regs.pipeline.vertex_attributes.GetPhysicalBaseAddress() +
|
memory.GetPhysicalPointer(regs.pipeline.vertex_attributes.GetPhysicalBaseAddress() +
|
||||||
regs.pipeline.index_array.offset);
|
regs.pipeline.index_array.offset);
|
||||||
std::tie(buffer_ptr, buffer_offset, std::ignore) = index_buffer.Map(index_buffer_size, 4);
|
std::tie(buffer_ptr, buffer_offset, std::ignore) = index_buffer.Map(index_buffer_size, 4);
|
||||||
std::memcpy(buffer_ptr, index_data, index_buffer_size);
|
std::memcpy(buffer_ptr, index_data, index_buffer_size);
|
||||||
index_buffer.Unmap(index_buffer_size);
|
index_buffer.Unmap(index_buffer_size);
|
||||||
@@ -772,6 +772,10 @@ void RasterizerOpenGL::FlushAndInvalidateRegion(PAddr addr, u32 size) {
|
|||||||
res_cache.InvalidateRegion(addr, size, nullptr);
|
res_cache.InvalidateRegion(addr, size, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterizerOpenGL::ClearAll(bool flush) {
|
||||||
|
res_cache.ClearAll(flush);
|
||||||
|
}
|
||||||
|
|
||||||
MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255));
|
MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255));
|
||||||
bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) {
|
bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) {
|
||||||
MICROPROFILE_SCOPE(OpenGL_Blits);
|
MICROPROFILE_SCOPE(OpenGL_Blits);
|
||||||
|
@@ -11,6 +11,10 @@
|
|||||||
#include "video_core/renderer_opengl/gl_stream_buffer.h"
|
#include "video_core/renderer_opengl/gl_stream_buffer.h"
|
||||||
#include "video_core/renderer_opengl/gl_texture_runtime.h"
|
#include "video_core/renderer_opengl/gl_texture_runtime.h"
|
||||||
|
|
||||||
|
namespace Memory {
|
||||||
|
class MemorySystem;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Frontend {
|
namespace Frontend {
|
||||||
class EmuWindow;
|
class EmuWindow;
|
||||||
}
|
}
|
||||||
@@ -24,7 +28,8 @@ class ShaderProgramManager;
|
|||||||
|
|
||||||
class RasterizerOpenGL : public VideoCore::RasterizerAccelerated {
|
class RasterizerOpenGL : public VideoCore::RasterizerAccelerated {
|
||||||
public:
|
public:
|
||||||
explicit RasterizerOpenGL(Frontend::EmuWindow& emu_window, Driver& driver);
|
explicit RasterizerOpenGL(Memory::MemorySystem& memory, Frontend::EmuWindow& emu_window,
|
||||||
|
Driver& driver);
|
||||||
~RasterizerOpenGL() override;
|
~RasterizerOpenGL() override;
|
||||||
|
|
||||||
void LoadDiskResources(const std::atomic_bool& stop_loading,
|
void LoadDiskResources(const std::atomic_bool& stop_loading,
|
||||||
@@ -35,6 +40,7 @@ public:
|
|||||||
void FlushRegion(PAddr addr, u32 size) override;
|
void FlushRegion(PAddr addr, u32 size) override;
|
||||||
void InvalidateRegion(PAddr addr, u32 size) override;
|
void InvalidateRegion(PAddr addr, u32 size) override;
|
||||||
void FlushAndInvalidateRegion(PAddr addr, u32 size) override;
|
void FlushAndInvalidateRegion(PAddr addr, u32 size) override;
|
||||||
|
void ClearAll(bool flush) override;
|
||||||
bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) override;
|
bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) override;
|
||||||
bool AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config) override;
|
bool AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config) override;
|
||||||
bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) override;
|
bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) override;
|
||||||
@@ -132,6 +138,7 @@ private:
|
|||||||
bool SetupGeometryShader();
|
bool SetupGeometryShader();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Memory::MemorySystem& memory;
|
||||||
Driver& driver;
|
Driver& driver;
|
||||||
OpenGLState state;
|
OpenGLState state;
|
||||||
TextureRuntime runtime;
|
TextureRuntime runtime;
|
||||||
|
@@ -273,10 +273,11 @@ static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, cons
|
|||||||
return matrix;
|
return matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
RendererOpenGL::RendererOpenGL(Frontend::EmuWindow& window, Frontend::EmuWindow* secondary_window)
|
RendererOpenGL::RendererOpenGL(Memory::MemorySystem& memory_, Frontend::EmuWindow& window,
|
||||||
: RendererBase{window, secondary_window}, driver{Settings::values.graphics_api.GetValue() ==
|
Frontend::EmuWindow* secondary_window)
|
||||||
Settings::GraphicsAPI::OpenGLES,
|
: RendererBase{window, secondary_window}, memory{memory_},
|
||||||
Settings::values.renderer_debug.GetValue()},
|
driver{Settings::values.graphics_api.GetValue() == Settings::GraphicsAPI::OpenGLES,
|
||||||
|
Settings::values.renderer_debug.GetValue()},
|
||||||
frame_dumper(Core::System::GetInstance().VideoDumper(), window) {
|
frame_dumper(Core::System::GetInstance().VideoDumper(), window) {
|
||||||
window.mailbox = std::make_unique<OGLTextureMailbox>();
|
window.mailbox = std::make_unique<OGLTextureMailbox>();
|
||||||
if (secondary_window) {
|
if (secondary_window) {
|
||||||
@@ -294,7 +295,7 @@ VideoCore::ResultStatus RendererOpenGL::Init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
InitOpenGLObjects();
|
InitOpenGLObjects();
|
||||||
rasterizer = std::make_unique<RasterizerOpenGL>(render_window, driver);
|
rasterizer = std::make_unique<RasterizerOpenGL>(memory, render_window, driver);
|
||||||
|
|
||||||
return VideoCore::ResultStatus::Success;
|
return VideoCore::ResultStatus::Success;
|
||||||
}
|
}
|
||||||
@@ -495,8 +496,7 @@ void RendererOpenGL::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& fram
|
|||||||
screen_info.display_texcoords = Common::Rectangle<float>(0.f, 0.f, 1.f, 1.f);
|
screen_info.display_texcoords = Common::Rectangle<float>(0.f, 0.f, 1.f, 1.f);
|
||||||
|
|
||||||
Memory::RasterizerFlushRegion(framebuffer_addr, framebuffer.stride * framebuffer.height);
|
Memory::RasterizerFlushRegion(framebuffer_addr, framebuffer.stride * framebuffer.height);
|
||||||
|
const u8* framebuffer_data = memory.GetPhysicalPointer(framebuffer_addr);
|
||||||
const u8* framebuffer_data = VideoCore::g_memory->GetPhysicalPointer(framebuffer_addr);
|
|
||||||
|
|
||||||
state.texture_units[0].texture_2d = screen_info.texture.resource.handle;
|
state.texture_units[0].texture_2d = screen_info.texture.resource.handle;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
@@ -16,6 +16,10 @@ namespace Layout {
|
|||||||
struct FramebufferLayout;
|
struct FramebufferLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Memory {
|
||||||
|
class MemorySystem;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Frontend {
|
namespace Frontend {
|
||||||
|
|
||||||
struct Frame {
|
struct Frame {
|
||||||
@@ -57,7 +61,8 @@ class RasterizerOpenGL;
|
|||||||
|
|
||||||
class RendererOpenGL : public RendererBase {
|
class RendererOpenGL : public RendererBase {
|
||||||
public:
|
public:
|
||||||
explicit RendererOpenGL(Frontend::EmuWindow& window, Frontend::EmuWindow* secondary_window);
|
explicit RendererOpenGL(Memory::MemorySystem& memory, Frontend::EmuWindow& window,
|
||||||
|
Frontend::EmuWindow* secondary_window);
|
||||||
~RendererOpenGL() override;
|
~RendererOpenGL() override;
|
||||||
|
|
||||||
VideoCore::ResultStatus Init() override;
|
VideoCore::ResultStatus Init() override;
|
||||||
@@ -116,6 +121,7 @@ private:
|
|||||||
void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, const TextureInfo& texture);
|
void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, const TextureInfo& texture);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Memory::MemorySystem& memory;
|
||||||
Driver driver;
|
Driver driver;
|
||||||
OpenGLState state;
|
OpenGLState state;
|
||||||
std::unique_ptr<RasterizerOpenGL> rasterizer;
|
std::unique_ptr<RasterizerOpenGL> rasterizer;
|
||||||
|
@@ -100,8 +100,9 @@ std::string BuildCommaSeparatedExtensions(std::vector<std::string> available_ext
|
|||||||
|
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
RendererVulkan::RendererVulkan(Frontend::EmuWindow& window, Frontend::EmuWindow* secondary_window)
|
RendererVulkan::RendererVulkan(Memory::MemorySystem& memory_, Frontend::EmuWindow& window,
|
||||||
: RendererBase{window, secondary_window},
|
Frontend::EmuWindow* secondary_window)
|
||||||
|
: RendererBase{window, secondary_window}, memory{memory_},
|
||||||
telemetry_session{Core::System::GetInstance().TelemetrySession()},
|
telemetry_session{Core::System::GetInstance().TelemetrySession()},
|
||||||
instance{window, Settings::values.physical_device.GetValue()}, scheduler{instance,
|
instance{window, Settings::values.physical_device.GetValue()}, scheduler{instance,
|
||||||
renderpass_cache},
|
renderpass_cache},
|
||||||
@@ -110,7 +111,8 @@ RendererVulkan::RendererVulkan(Frontend::EmuWindow& window, Frontend::EmuWindow*
|
|||||||
renderpass_cache},
|
renderpass_cache},
|
||||||
vertex_buffer{instance, scheduler, vk::BufferUsageFlagBits::eVertexBuffer,
|
vertex_buffer{instance, scheduler, vk::BufferUsageFlagBits::eVertexBuffer,
|
||||||
VERTEX_BUFFER_SIZE},
|
VERTEX_BUFFER_SIZE},
|
||||||
rasterizer{render_window, instance, scheduler, desc_manager, runtime, renderpass_cache} {
|
rasterizer{memory, render_window, instance, scheduler,
|
||||||
|
desc_manager, runtime, renderpass_cache} {
|
||||||
Report();
|
Report();
|
||||||
window.mailbox = std::make_unique<TextureMailbox>(instance, swapchain, renderpass_cache);
|
window.mailbox = std::make_unique<TextureMailbox>(instance, swapchain, renderpass_cache);
|
||||||
}
|
}
|
||||||
|
@@ -23,12 +23,19 @@ namespace Core {
|
|||||||
class TelemetrySession;
|
class TelemetrySession;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Memory {
|
||||||
|
class MemorySystem;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
struct FramebufferLayout;
|
struct FramebufferLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structure used for storing information about the textures for each 3DS screen
|
||||||
|
**/
|
||||||
struct TextureInfo {
|
struct TextureInfo {
|
||||||
u32 width;
|
u32 width;
|
||||||
u32 height;
|
u32 height;
|
||||||
@@ -38,6 +45,9 @@ struct TextureInfo {
|
|||||||
VmaAllocation allocation;
|
VmaAllocation allocation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structure used for storing information about the display target for each 3DS screen
|
||||||
|
**/
|
||||||
struct ScreenInfo {
|
struct ScreenInfo {
|
||||||
TextureInfo texture;
|
TextureInfo texture;
|
||||||
Common::Rectangle<f32> texcoords;
|
Common::Rectangle<f32> texcoords;
|
||||||
@@ -50,7 +60,8 @@ class RendererVulkan : public RendererBase {
|
|||||||
static constexpr std::size_t PRESENT_PIPELINES = 3;
|
static constexpr std::size_t PRESENT_PIPELINES = 3;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit RendererVulkan(Frontend::EmuWindow& window, Frontend::EmuWindow* secondary_window);
|
explicit RendererVulkan(Memory::MemorySystem& memory, Frontend::EmuWindow& window,
|
||||||
|
Frontend::EmuWindow* secondary_window);
|
||||||
~RendererVulkan() override;
|
~RendererVulkan() override;
|
||||||
|
|
||||||
VideoCore::ResultStatus Init() override;
|
VideoCore::ResultStatus Init() override;
|
||||||
@@ -111,6 +122,7 @@ private:
|
|||||||
void LoadColorToActiveVkTexture(u8 color_r, u8 color_g, u8 color_b, const TextureInfo& texture);
|
void LoadColorToActiveVkTexture(u8 color_r, u8 color_g, u8 color_b, const TextureInfo& texture);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Memory::MemorySystem& memory;
|
||||||
Core::TelemetrySession& telemetry_session;
|
Core::TelemetrySession& telemetry_session;
|
||||||
|
|
||||||
Instance instance;
|
Instance instance;
|
||||||
|
@@ -57,11 +57,12 @@ struct DrawParams {
|
|||||||
return std::min(max_size, TEXTURE_BUFFER_SIZE);
|
return std::min(max_size, TEXTURE_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
RasterizerVulkan::RasterizerVulkan(Frontend::EmuWindow& emu_window, const Instance& instance,
|
RasterizerVulkan::RasterizerVulkan(Memory::MemorySystem& memory_, Frontend::EmuWindow& emu_window,
|
||||||
Scheduler& scheduler, DescriptorManager& desc_manager,
|
const Instance& instance, Scheduler& scheduler,
|
||||||
TextureRuntime& runtime, RenderpassCache& renderpass_cache)
|
DescriptorManager& desc_manager, TextureRuntime& runtime,
|
||||||
: instance{instance}, scheduler{scheduler}, runtime{runtime},
|
RenderpassCache& renderpass_cache)
|
||||||
renderpass_cache{renderpass_cache}, desc_manager{desc_manager}, res_cache{*this, runtime},
|
: memory{memory_}, instance{instance}, scheduler{scheduler}, runtime{runtime},
|
||||||
|
renderpass_cache{renderpass_cache}, desc_manager{desc_manager}, res_cache{memory, runtime},
|
||||||
pipeline_cache{instance, scheduler, renderpass_cache, desc_manager},
|
pipeline_cache{instance, scheduler, renderpass_cache, desc_manager},
|
||||||
null_surface{NULL_PARAMS, vk::Format::eR8G8B8A8Unorm, NULL_USAGE,
|
null_surface{NULL_PARAMS, vk::Format::eR8G8B8A8Unorm, NULL_USAGE,
|
||||||
vk::ImageAspectFlagBits::eColor, runtime},
|
vk::ImageAspectFlagBits::eColor, runtime},
|
||||||
@@ -235,7 +236,7 @@ void RasterizerVulkan::SetupVertexArray(u32 vs_input_size, u32 vs_input_index_mi
|
|||||||
const u32 data_size = loader.byte_count * vertex_num;
|
const u32 data_size = loader.byte_count * vertex_num;
|
||||||
res_cache.FlushRegion(data_addr, data_size);
|
res_cache.FlushRegion(data_addr, data_size);
|
||||||
|
|
||||||
const u8* src_ptr = VideoCore::g_memory->GetPhysicalPointer(data_addr);
|
const u8* src_ptr = memory.GetPhysicalPointer(data_addr);
|
||||||
u8* dst_ptr = array_ptr + buffer_offset;
|
u8* dst_ptr = array_ptr + buffer_offset;
|
||||||
|
|
||||||
// Align stride up if required by Vulkan implementation.
|
// Align stride up if required by Vulkan implementation.
|
||||||
@@ -270,6 +271,9 @@ void RasterizerVulkan::SetupVertexArray(u32 vs_input_size, u32 vs_input_index_mi
|
|||||||
// Bind the generated bindings
|
// Bind the generated bindings
|
||||||
scheduler.Record([this, binding_count = layout.binding_count,
|
scheduler.Record([this, binding_count = layout.binding_count,
|
||||||
vertex_offsets = binding_offsets](vk::CommandBuffer cmdbuf) {
|
vertex_offsets = binding_offsets](vk::CommandBuffer cmdbuf) {
|
||||||
|
for (auto& offset : vertex_offsets) {
|
||||||
|
ASSERT_MSG(offset != 0x8000000, "Bad offset");
|
||||||
|
}
|
||||||
cmdbuf.bindVertexBuffers(0, binding_count, vertex_buffers.data(), vertex_offsets.data());
|
cmdbuf.bindVertexBuffers(0, binding_count, vertex_buffers.data(), vertex_offsets.data());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -425,9 +429,9 @@ void RasterizerVulkan::SetupIndexArray() {
|
|||||||
const vk::IndexType index_type = native_u8 ? vk::IndexType::eUint8EXT : vk::IndexType::eUint16;
|
const vk::IndexType index_type = native_u8 ? vk::IndexType::eUint8EXT : vk::IndexType::eUint16;
|
||||||
const u32 index_buffer_size = regs.pipeline.num_vertices * (native_u8 ? 1 : 2);
|
const u32 index_buffer_size = regs.pipeline.num_vertices * (native_u8 ? 1 : 2);
|
||||||
|
|
||||||
const u8* index_data = VideoCore::g_memory->GetPhysicalPointer(
|
const u8* index_data =
|
||||||
regs.pipeline.vertex_attributes.GetPhysicalBaseAddress() +
|
memory.GetPhysicalPointer(regs.pipeline.vertex_attributes.GetPhysicalBaseAddress() +
|
||||||
regs.pipeline.index_array.offset);
|
regs.pipeline.index_array.offset);
|
||||||
|
|
||||||
auto [index_ptr, index_offset, _] = stream_buffer.Map(index_buffer_size, 2);
|
auto [index_ptr, index_offset, _] = stream_buffer.Map(index_buffer_size, 2);
|
||||||
if (index_u8 && !native_u8) {
|
if (index_u8 && !native_u8) {
|
||||||
@@ -852,6 +856,10 @@ void RasterizerVulkan::FlushAndInvalidateRegion(PAddr addr, u32 size) {
|
|||||||
res_cache.InvalidateRegion(addr, size, nullptr);
|
res_cache.InvalidateRegion(addr, size, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterizerVulkan::ClearAll(bool flush) {
|
||||||
|
res_cache.ClearAll(flush);
|
||||||
|
}
|
||||||
|
|
||||||
MICROPROFILE_DEFINE(Vulkan_Blits, "Vulkan", "Blits", MP_RGB(100, 100, 255));
|
MICROPROFILE_DEFINE(Vulkan_Blits, "Vulkan", "Blits", MP_RGB(100, 100, 255));
|
||||||
bool RasterizerVulkan::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) {
|
bool RasterizerVulkan::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) {
|
||||||
MICROPROFILE_SCOPE(Vulkan_Blits);
|
MICROPROFILE_SCOPE(Vulkan_Blits);
|
||||||
|
@@ -15,6 +15,10 @@ namespace Frontend {
|
|||||||
class EmuWindow;
|
class EmuWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Memory {
|
||||||
|
class MemorySystem;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
|
|
||||||
struct ScreenInfo;
|
struct ScreenInfo;
|
||||||
@@ -58,9 +62,10 @@ class RasterizerVulkan : public VideoCore::RasterizerAccelerated {
|
|||||||
friend class RendererVulkan;
|
friend class RendererVulkan;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit RasterizerVulkan(Frontend::EmuWindow& emu_window, const Instance& instance,
|
explicit RasterizerVulkan(Memory::MemorySystem& memory, Frontend::EmuWindow& emu_window,
|
||||||
Scheduler& scheduler, DescriptorManager& desc_manager,
|
const Instance& instance, Scheduler& scheduler,
|
||||||
TextureRuntime& runtime, RenderpassCache& renderpass_cache);
|
DescriptorManager& desc_manager, TextureRuntime& runtime,
|
||||||
|
RenderpassCache& renderpass_cache);
|
||||||
~RasterizerVulkan() override;
|
~RasterizerVulkan() override;
|
||||||
|
|
||||||
void LoadDiskResources(const std::atomic_bool& stop_loading,
|
void LoadDiskResources(const std::atomic_bool& stop_loading,
|
||||||
@@ -71,6 +76,7 @@ public:
|
|||||||
void FlushRegion(PAddr addr, u32 size) override;
|
void FlushRegion(PAddr addr, u32 size) override;
|
||||||
void InvalidateRegion(PAddr addr, u32 size) override;
|
void InvalidateRegion(PAddr addr, u32 size) override;
|
||||||
void FlushAndInvalidateRegion(PAddr addr, u32 size) override;
|
void FlushAndInvalidateRegion(PAddr addr, u32 size) override;
|
||||||
|
void ClearAll(bool flush) override;
|
||||||
bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) override;
|
bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) override;
|
||||||
bool AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config) override;
|
bool AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config) override;
|
||||||
bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) override;
|
bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) override;
|
||||||
@@ -151,6 +157,7 @@ private:
|
|||||||
vk::Sampler CreateSampler(const SamplerInfo& info);
|
vk::Sampler CreateSampler(const SamplerInfo& info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Memory::MemorySystem& memory;
|
||||||
const Instance& instance;
|
const Instance& instance;
|
||||||
Scheduler& scheduler;
|
Scheduler& scheduler;
|
||||||
TextureRuntime& runtime;
|
TextureRuntime& runtime;
|
||||||
|
@@ -40,10 +40,10 @@ ResultStatus Init(Frontend::EmuWindow& emu_window, Frontend::EmuWindow* secondar
|
|||||||
case Settings::GraphicsAPI::OpenGL:
|
case Settings::GraphicsAPI::OpenGL:
|
||||||
case Settings::GraphicsAPI::OpenGLES:
|
case Settings::GraphicsAPI::OpenGLES:
|
||||||
OpenGL::GLES = graphics_api == Settings::GraphicsAPI::OpenGLES;
|
OpenGL::GLES = graphics_api == Settings::GraphicsAPI::OpenGLES;
|
||||||
g_renderer = std::make_unique<OpenGL::RendererOpenGL>(emu_window, secondary_window);
|
g_renderer = std::make_unique<OpenGL::RendererOpenGL>(memory, emu_window, secondary_window);
|
||||||
break;
|
break;
|
||||||
case Settings::GraphicsAPI::Vulkan:
|
case Settings::GraphicsAPI::Vulkan:
|
||||||
g_renderer = std::make_unique<Vulkan::RendererVulkan>(emu_window, secondary_window);
|
g_renderer = std::make_unique<Vulkan::RendererVulkan>(memory, emu_window, secondary_window);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_CRITICAL(Render, "Invalid graphics API enum value {}", graphics_api);
|
LOG_CRITICAL(Render, "Invalid graphics API enum value {}", graphics_api);
|
||||||
|
Reference in New Issue
Block a user