yuzu-emu
/
yuzu-mainline
Archived
1
0
Fork 0

Corrections and redesign.

This commit is contained in:
Fernando Sahmkow 2019-02-16 18:32:26 -04:00 committed by FernandoS27
parent d6b9b51606
commit 5a9204dbd7
2 changed files with 51 additions and 51 deletions

View File

@ -3,6 +3,7 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <algorithm> #include <algorithm>
#include <optional>
#include <glad/glad.h> #include <glad/glad.h>
#include "common/alignment.h" #include "common/alignment.h"
@ -1000,7 +1001,7 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params, bool pres
Surface surface{TryGet(params.addr)}; Surface surface{TryGet(params.addr)};
if (surface) { if (surface) {
if (surface->GetSurfaceParams().IsCompatibleSurface(params)) { if (surface->GetSurfaceParams().IsCompatibleSurface(params)) {
// Use the cached surface as-is // Use the cached surface as-is unless it's not synced with memory
if (surface->MustReload()) if (surface->MustReload())
LoadSurface(surface); LoadSurface(surface);
return surface; return surface;
@ -1298,44 +1299,47 @@ Surface RasterizerCacheOpenGL::TryGetReservedSurface(const SurfaceParams& params
return {}; return {};
} }
bool FindBestMipMap(std::size_t memory, const SurfaceParams params, u32 height, u32& mipmap) { static std::optional<u32> TryFindBestMipMap(std::size_t memory, const SurfaceParams params,
for (u32 i = 0; i < params.max_mip_level; i++) u32 height) {
for (u32 i = 0; i < params.max_mip_level; i++) {
if (memory == params.GetMipmapSingleSize(i) && params.MipHeight(i) == height) { if (memory == params.GetMipmapSingleSize(i) && params.MipHeight(i) == height) {
mipmap = i; return {i};
return true;
} }
return false; }
return {};
} }
bool FindBestLayer(VAddr addr, const SurfaceParams params, u32 mipmap, u32& layer) { static std::optional<u32> TryFindBestLayer(VAddr addr, const SurfaceParams params, u32 mipmap) {
std::size_t size = params.LayerMemorySize(); const std::size_t size = params.LayerMemorySize();
VAddr start = params.addr + params.GetMipmapLevelOffset(mipmap); VAddr start = params.addr + params.GetMipmapLevelOffset(mipmap);
for (u32 i = 0; i < params.depth; i++) { for (u32 i = 0; i < params.depth; i++) {
if (start == addr) { if (start == addr) {
layer = i; return {i};
return true;
} }
start += size; start += size;
} }
return false; return {};
} }
bool LayerFitReinterpretSurface(RasterizerCacheOpenGL& cache, const Surface render_surface, static bool LayerFitReinterpretSurface(RasterizerCacheOpenGL& cache, const Surface render_surface,
const Surface blitted_surface) { const Surface blitted_surface) {
const auto dst_params = blitted_surface->GetSurfaceParams(); const auto& dst_params = blitted_surface->GetSurfaceParams();
const auto src_params = render_surface->GetSurfaceParams(); const auto& src_params = render_surface->GetSurfaceParams();
u32 level = 0; const std::size_t src_memory_size = src_params.size_in_bytes;
std::size_t src_memory_size = src_params.size_in_bytes; const std::optional<u32> level =
if (FindBestMipMap(src_memory_size, dst_params, src_params.height, level)) { TryFindBestMipMap(src_memory_size, dst_params, src_params.height);
if (src_params.width == dst_params.MipWidthGobAligned(level) && if (level.has_value()) {
src_params.height == dst_params.MipHeight(level) && if (src_params.width == dst_params.MipWidthGobAligned(*level) &&
src_params.block_height >= dst_params.MipBlockHeight(level)) { src_params.height == dst_params.MipHeight(*level) &&
u32 slot = 0; src_params.block_height >= dst_params.MipBlockHeight(*level)) {
if (FindBestLayer(render_surface->GetAddr(), dst_params, level, slot)) { const std::optional<u32> slot =
glCopyImageSubData( TryFindBestLayer(render_surface->GetAddr(), dst_params, *level);
render_surface->Texture().handle, SurfaceTargetToGL(src_params.target), 0, 0, 0, if (slot.has_value()) {
0, blitted_surface->Texture().handle, SurfaceTargetToGL(dst_params.target), glCopyImageSubData(render_surface->Texture().handle,
level, 0, 0, slot, dst_params.MipWidth(level), dst_params.MipHeight(level), 1); SurfaceTargetToGL(src_params.target), 0, 0, 0, 0,
blitted_surface->Texture().handle,
SurfaceTargetToGL(dst_params.target), *level, 0, 0, *slot,
dst_params.MipWidth(*level), dst_params.MipHeight(*level), 1);
blitted_surface->MarkAsModified(true, cache); blitted_surface->MarkAsModified(true, cache);
return true; return true;
} }
@ -1344,24 +1348,21 @@ bool LayerFitReinterpretSurface(RasterizerCacheOpenGL& cache, const Surface rend
return false; return false;
} }
bool IsReinterpretInvalid(const Surface render_surface, const Surface blitted_surface) { static bool IsReinterpretInvalid(const Surface render_surface, const Surface blitted_surface) {
VAddr bound1 = blitted_surface->GetAddr() + blitted_surface->GetMemorySize(); const VAddr bound1 = blitted_surface->GetAddr() + blitted_surface->GetMemorySize();
VAddr bound2 = render_surface->GetAddr() + render_surface->GetMemorySize(); const VAddr bound2 = render_surface->GetAddr() + render_surface->GetMemorySize();
if (bound2 > bound1) if (bound2 > bound1)
return true; return true;
const auto dst_params = blitted_surface->GetSurfaceParams(); const auto& dst_params = blitted_surface->GetSurfaceParams();
const auto src_params = render_surface->GetSurfaceParams(); const auto& src_params = render_surface->GetSurfaceParams();
if (dst_params.component_type != src_params.component_type) return (dst_params.component_type != src_params.component_type);
return true;
return false;
} }
bool IsReinterpretInvalidSecond(const Surface render_surface, const Surface blitted_surface) { static bool IsReinterpretInvalidSecond(const Surface render_surface,
const auto dst_params = blitted_surface->GetSurfaceParams(); const Surface blitted_surface) {
const auto src_params = render_surface->GetSurfaceParams(); const auto& dst_params = blitted_surface->GetSurfaceParams();
if (dst_params.height > src_params.height && dst_params.width > src_params.width) const auto& src_params = render_surface->GetSurfaceParams();
return false; return (dst_params.height > src_params.height && dst_params.width > src_params.width);
return true;
} }
bool RasterizerCacheOpenGL::PartialReinterpretSurface(Surface triggering_surface, bool RasterizerCacheOpenGL::PartialReinterpretSurface(Surface triggering_surface,
@ -1383,7 +1384,7 @@ bool RasterizerCacheOpenGL::PartialReinterpretSurface(Surface triggering_surface
} }
void RasterizerCacheOpenGL::SignalPreDrawCall() { void RasterizerCacheOpenGL::SignalPreDrawCall() {
if (texception) { if (texception && GLAD_GL_ARB_texture_barrier) {
glTextureBarrier(); glTextureBarrier();
} }
texception = false; texception = false;

View File

@ -412,7 +412,7 @@ public:
reinterpreted = true; reinterpreted = true;
} }
bool IsReinterpreted() { bool IsReinterpreted() const {
return reinterpreted; return reinterpreted;
} }
@ -420,11 +420,11 @@ public:
must_reload = reload; must_reload = reload;
} }
bool MustReload() { bool MustReload() const {
return must_reload; return must_reload;
} }
bool IsUploaded() { bool IsUploaded() const {
return params.identity == SurfaceParams::SurfaceClass::Uploaded; return params.identity == SurfaceParams::SurfaceClass::Uploaded;
} }
@ -489,6 +489,7 @@ private:
Surface TryGetReservedSurface(const SurfaceParams& params); Surface TryGetReservedSurface(const SurfaceParams& params);
// Partialy reinterpret a surface based on a triggering_surface that collides with it. // Partialy reinterpret a surface based on a triggering_surface that collides with it.
// returns true if the reinterpret was successful, false in case it was not.
bool PartialReinterpretSurface(Surface triggering_surface, Surface intersect); bool PartialReinterpretSurface(Surface triggering_surface, Surface intersect);
/// Performs a slow but accurate surface copy, flushing to RAM and reinterpreting the data /// Performs a slow but accurate surface copy, flushing to RAM and reinterpreting the data
@ -528,10 +529,10 @@ private:
// Reinterpreted surfaces are very fragil as the game may keep rendering into them. // Reinterpreted surfaces are very fragil as the game may keep rendering into them.
SurfaceIntervalCache reinterpreted_surfaces; SurfaceIntervalCache reinterpreted_surfaces;
void RegisterReinterpretSurface(Surface r_surface) { void RegisterReinterpretSurface(Surface reinterpret_surface) {
auto interval = GetReinterpretInterval(r_surface); auto interval = GetReinterpretInterval(reinterpret_surface);
reinterpreted_surfaces.insert({interval, r_surface}); reinterpreted_surfaces.insert({interval, reinterpret_surface});
r_surface->MarkReinterpreted(); reinterpret_surface->MarkReinterpreted();
} }
Surface CollideOnReinterpretedSurface(VAddr addr) const { Surface CollideOnReinterpretedSurface(VAddr addr) const {
@ -543,14 +544,12 @@ private:
return nullptr; return nullptr;
} }
protected:
void Register(const Surface& object) { void Register(const Surface& object) {
RasterizerCache<Surface>::Register(object); RasterizerCache<Surface>::Register(object);
} }
/// Unregisters an object from the cache /// Unregisters an object from the cache
void Unregister(const Surface& object) { void Unregister(const Surface& object) {
const auto& params = object->GetSurfaceParams();
if (object->IsReinterpreted()) { if (object->IsReinterpreted()) {
auto interval = GetReinterpretInterval(object); auto interval = GetReinterpretInterval(object);
reinterpreted_surfaces.erase(interval); reinterpreted_surfaces.erase(interval);