mirror of
https://github.com/yuzu-emu/yuzu-android.git
synced 2024-11-23 15:15:43 +01:00
Corrections and redesign.
This commit is contained in:
parent
d6b9b51606
commit
5a9204dbd7
@ -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;
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user