summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
diff options
context:
space:
mode:
authorEmmanuel Gil Peyrot <linkmauve@linkmauve.fr>2016-09-18 02:38:01 +0200
committerEmmanuel Gil Peyrot <linkmauve@linkmauve.fr>2016-09-18 02:38:01 +0200
commitdc8479928c5aee4c6ad6fe4f59006fb604cee701 (patch)
tree569a7f13128450bbab973236615587ff00bced5f /src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
parentTravis: Import Dolphin’s clang-format hook. (diff)
downloadyuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.gz
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.bz2
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.lz
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.xz
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.zst
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.zip
Diffstat (limited to 'src/video_core/renderer_opengl/gl_rasterizer_cache.cpp')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp285
1 files changed, 187 insertions, 98 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 7efd0038a..8f1477bcd 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -35,18 +35,18 @@ struct FormatTuple {
};
static const std::array<FormatTuple, 5> fb_format_tuples = {{
- { GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8 }, // RGBA8
- { GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE }, // RGB8
- { GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 }, // RGB5A1
- { GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 }, // RGB565
- { GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 }, // RGBA4
+ {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}, // RGBA8
+ {GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE}, // RGB8
+ {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}, // RGB5A1
+ {GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, // RGB565
+ {GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}, // RGBA4
}};
static const std::array<FormatTuple, 4> depth_format_tuples = {{
- { GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT }, // D16
+ {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // D16
{},
- { GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT }, // D24
- { GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8 }, // D24S8
+ {GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT}, // D24
+ {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24S8
}};
RasterizerCacheOpenGL::RasterizerCacheOpenGL() {
@@ -58,7 +58,9 @@ RasterizerCacheOpenGL::~RasterizerCacheOpenGL() {
FlushAll();
}
-static void MortonCopyPixels(CachedSurface::PixelFormat pixel_format, u32 width, u32 height, u32 bytes_per_pixel, u32 gl_bytes_per_pixel, u8* morton_data, u8* gl_data, bool morton_to_gl) {
+static void MortonCopyPixels(CachedSurface::PixelFormat pixel_format, u32 width, u32 height,
+ u32 bytes_per_pixel, u32 gl_bytes_per_pixel, u8* morton_data,
+ u8* gl_data, bool morton_to_gl) {
using PixelFormat = CachedSurface::PixelFormat;
u8* data_ptrs[2];
@@ -72,7 +74,8 @@ static void MortonCopyPixels(CachedSurface::PixelFormat pixel_format, u32 width,
for (unsigned y = 0; y < height; ++y) {
for (unsigned x = 0; x < width; ++x) {
const u32 coarse_y = y & ~7;
- u32 morton_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * width * bytes_per_pixel;
+ u32 morton_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) +
+ coarse_y * width * bytes_per_pixel;
u32 gl_pixel_index = (x + (height - 1 - y) * width) * gl_bytes_per_pixel;
data_ptrs[morton_to_gl] = morton_data + morton_offset;
@@ -81,7 +84,8 @@ static void MortonCopyPixels(CachedSurface::PixelFormat pixel_format, u32 width,
// Swap depth and stencil value ordering since 3DS does not match OpenGL
u32 depth_stencil;
memcpy(&depth_stencil, data_ptrs[1], sizeof(u32));
- depth_stencil = (depth_stencil << depth_stencil_shifts[0]) | (depth_stencil >> depth_stencil_shifts[1]);
+ depth_stencil = (depth_stencil << depth_stencil_shifts[0]) |
+ (depth_stencil >> depth_stencil_shifts[1]);
memcpy(data_ptrs[0], &depth_stencil, sizeof(u32));
}
@@ -90,7 +94,8 @@ static void MortonCopyPixels(CachedSurface::PixelFormat pixel_format, u32 width,
for (unsigned y = 0; y < height; ++y) {
for (unsigned x = 0; x < width; ++x) {
const u32 coarse_y = y & ~7;
- u32 morton_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * width * bytes_per_pixel;
+ u32 morton_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) +
+ coarse_y * width * bytes_per_pixel;
u32 gl_pixel_index = (x + (height - 1 - y) * width) * gl_bytes_per_pixel;
data_ptrs[morton_to_gl] = morton_data + morton_offset;
@@ -102,17 +107,21 @@ static void MortonCopyPixels(CachedSurface::PixelFormat pixel_format, u32 width,
}
}
-bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, CachedSurface::SurfaceType type, const MathUtil::Rectangle<int>& src_rect, const MathUtil::Rectangle<int>& dst_rect) {
+bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex,
+ CachedSurface::SurfaceType type,
+ const MathUtil::Rectangle<int>& src_rect,
+ const MathUtil::Rectangle<int>& dst_rect) {
using SurfaceType = CachedSurface::SurfaceType;
OpenGLState cur_state = OpenGLState::GetCurState();
- // Make sure textures aren't bound to texture units, since going to bind them to framebuffer components
+ // Make sure textures aren't bound to texture units, since going to bind them to framebuffer
+ // components
OpenGLState::ResetTexture(src_tex);
OpenGLState::ResetTexture(dst_tex);
// Keep track of previous framebuffer bindings
- GLuint old_fbs[2] = { cur_state.draw.read_framebuffer, cur_state.draw.draw_framebuffer };
+ GLuint old_fbs[2] = {cur_state.draw.read_framebuffer, cur_state.draw.draw_framebuffer};
cur_state.draw.read_framebuffer = transfer_framebuffers[0].handle;
cur_state.draw.draw_framebuffer = transfer_framebuffers[1].handle;
cur_state.Apply();
@@ -120,11 +129,15 @@ bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, CachedS
u32 buffers = 0;
if (type == SurfaceType::Color || type == SurfaceType::Texture) {
- glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, src_tex, 0);
- glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
+ glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, src_tex,
+ 0);
+ glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
+ 0);
- glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex, 0);
- glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
+ glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex,
+ 0);
+ glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
+ 0);
buffers = GL_COLOR_BUFFER_BIT;
} else if (type == SurfaceType::Depth) {
@@ -139,10 +152,12 @@ bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, CachedS
buffers = GL_DEPTH_BUFFER_BIT;
} else if (type == SurfaceType::DepthStencil) {
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
- glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, src_tex, 0);
+ glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
+ src_tex, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
- glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, dst_tex, 0);
+ glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
+ dst_tex, 0);
buffers = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
}
@@ -155,9 +170,9 @@ bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, CachedS
return false;
}
- glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom,
- dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom,
- buffers, buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST);
+ glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom, dst_rect.left,
+ dst_rect.top, dst_rect.right, dst_rect.bottom, buffers,
+ buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST);
// Restore previous framebuffer bindings
cur_state.draw.read_framebuffer = old_fbs[0];
@@ -167,17 +182,24 @@ bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, CachedS
return true;
}
-bool RasterizerCacheOpenGL::TryBlitSurfaces(CachedSurface* src_surface, const MathUtil::Rectangle<int>& src_rect, CachedSurface* dst_surface, const MathUtil::Rectangle<int>& dst_rect) {
+bool RasterizerCacheOpenGL::TryBlitSurfaces(CachedSurface* src_surface,
+ const MathUtil::Rectangle<int>& src_rect,
+ CachedSurface* dst_surface,
+ const MathUtil::Rectangle<int>& dst_rect) {
using SurfaceType = CachedSurface::SurfaceType;
- if (!CachedSurface::CheckFormatsBlittable(src_surface->pixel_format, dst_surface->pixel_format)) {
+ if (!CachedSurface::CheckFormatsBlittable(src_surface->pixel_format,
+ dst_surface->pixel_format)) {
return false;
}
- return BlitTextures(src_surface->texture.handle, dst_surface->texture.handle, CachedSurface::GetFormatType(src_surface->pixel_format), src_rect, dst_rect);
+ return BlitTextures(src_surface->texture.handle, dst_surface->texture.handle,
+ CachedSurface::GetFormatType(src_surface->pixel_format), src_rect,
+ dst_rect);
}
-static void AllocateSurfaceTexture(GLuint texture, CachedSurface::PixelFormat pixel_format, u32 width, u32 height) {
+static void AllocateSurfaceTexture(GLuint texture, CachedSurface::PixelFormat pixel_format,
+ u32 width, u32 height) {
// Allocate an uninitialized texture of appropriate size and format for the surface
using SurfaceType = CachedSurface::SurfaceType;
@@ -200,11 +222,11 @@ static void AllocateSurfaceTexture(GLuint texture, CachedSurface::PixelFormat pi
ASSERT(tuple_idx < depth_format_tuples.size());
tuple = depth_format_tuples[tuple_idx];
} else {
- tuple = { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE };
+ tuple = {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE};
}
- glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, width, height, 0,
- tuple.format, tuple.type, nullptr);
+ glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, width, height, 0, tuple.format,
+ tuple.type, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -217,7 +239,8 @@ static void AllocateSurfaceTexture(GLuint texture, CachedSurface::PixelFormat pi
}
MICROPROFILE_DEFINE(OpenGL_SurfaceUpload, "OpenGL", "Surface Upload", MP_RGB(128, 64, 192));
-CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bool match_res_scale, bool load_if_create) {
+CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bool match_res_scale,
+ bool load_if_create) {
using PixelFormat = CachedSurface::PixelFormat;
using SurfaceType = CachedSurface::SurfaceType;
@@ -225,29 +248,31 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo
return nullptr;
}
- u32 params_size = params.width * params.height * CachedSurface::GetFormatBpp(params.pixel_format) / 8;
+ u32 params_size =
+ params.width * params.height * CachedSurface::GetFormatBpp(params.pixel_format) / 8;
// Check for an exact match in existing surfaces
CachedSurface* best_exact_surface = nullptr;
float exact_surface_goodness = -1.f;
- auto surface_interval = boost::icl::interval<PAddr>::right_open(params.addr, params.addr + params_size);
+ auto surface_interval =
+ boost::icl::interval<PAddr>::right_open(params.addr, params.addr + params_size);
auto range = surface_cache.equal_range(surface_interval);
for (auto it = range.first; it != range.second; ++it) {
for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2) {
CachedSurface* surface = it2->get();
// Check if the request matches the surface exactly
- if (params.addr == surface->addr &&
- params.width == surface->width && params.height == surface->height &&
- params.pixel_format == surface->pixel_format)
- {
+ if (params.addr == surface->addr && params.width == surface->width &&
+ params.height == surface->height && params.pixel_format == surface->pixel_format) {
// Make sure optional param-matching criteria are fulfilled
bool tiling_match = (params.is_tiled == surface->is_tiled);
- bool res_scale_match = (params.res_scale_width == surface->res_scale_width && params.res_scale_height == surface->res_scale_height);
+ bool res_scale_match = (params.res_scale_width == surface->res_scale_width &&
+ params.res_scale_height == surface->res_scale_height);
if (!match_res_scale || res_scale_match) {
// Prioritize same-tiling and highest resolution surfaces
- float match_goodness = (float)tiling_match + surface->res_scale_width * surface->res_scale_height;
+ float match_goodness =
+ (float)tiling_match + surface->res_scale_width * surface->res_scale_height;
if (match_goodness > exact_surface_goodness || surface->dirty) {
exact_surface_goodness = match_goodness;
best_exact_surface = surface;
@@ -288,9 +313,11 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo
if (!load_if_create) {
// Don't load any data; just allocate the surface's texture
- AllocateSurfaceTexture(new_surface->texture.handle, new_surface->pixel_format, new_surface->GetScaledWidth(), new_surface->GetScaledHeight());
+ AllocateSurfaceTexture(new_surface->texture.handle, new_surface->pixel_format,
+ new_surface->GetScaledWidth(), new_surface->GetScaledHeight());
} else {
- // TODO: Consider attempting subrect match in existing surfaces and direct blit here instead of memory upload below if that's a common scenario in some game
+ // TODO: Consider attempting subrect match in existing surfaces and direct blit here instead
+ // of memory upload below if that's a common scenario in some game
Memory::RasterizerFlushRegion(params.addr, params_size);
@@ -318,7 +345,7 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo
tuple = fb_format_tuples[(unsigned int)params.pixel_format];
} else {
// Texture
- tuple = { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE };
+ tuple = {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE};
}
std::vector<Math::Vec4<u8>> tex_buffer(params.width * params.height);
@@ -326,19 +353,23 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo
Pica::DebugUtils::TextureInfo tex_info;
tex_info.width = params.width;
tex_info.height = params.height;
- tex_info.stride = params.width * CachedSurface::GetFormatBpp(params.pixel_format) / 8;
+ tex_info.stride =
+ params.width * CachedSurface::GetFormatBpp(params.pixel_format) / 8;
tex_info.format = (Pica::Regs::TextureFormat)params.pixel_format;
tex_info.physical_address = params.addr;
for (unsigned y = 0; y < params.height; ++y) {
for (unsigned x = 0; x < params.width; ++x) {
- tex_buffer[x + params.width * y] = Pica::DebugUtils::LookupTexture(texture_src_data, x, params.height - 1 - y, tex_info);
+ tex_buffer[x + params.width * y] = Pica::DebugUtils::LookupTexture(
+ texture_src_data, x, params.height - 1 - y, tex_info);
}
}
- glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, params.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_buffer.data());
+ glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, params.height,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_buffer.data());
} else {
- // Depth/Stencil formats need special treatment since they aren't sampleable using LookupTexture and can't use RGBA format
+ // Depth/Stencil formats need special treatment since they aren't sampleable using
+ // LookupTexture and can't use RGBA format
size_t tuple_idx = (size_t)params.pixel_format - 14;
ASSERT(tuple_idx < depth_format_tuples.size());
const FormatTuple& tuple = depth_format_tuples[tuple_idx];
@@ -350,14 +381,18 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo
u32 gl_bytes_per_pixel = use_4bpp ? 4 : bytes_per_pixel;
- std::vector<u8> temp_fb_depth_buffer(params.width * params.height * gl_bytes_per_pixel);
+ std::vector<u8> temp_fb_depth_buffer(params.width * params.height *
+ gl_bytes_per_pixel);
- u8* temp_fb_depth_buffer_ptr = use_4bpp ? temp_fb_depth_buffer.data() + 1 : temp_fb_depth_buffer.data();
+ u8* temp_fb_depth_buffer_ptr =
+ use_4bpp ? temp_fb_depth_buffer.data() + 1 : temp_fb_depth_buffer.data();
- MortonCopyPixels(params.pixel_format, params.width, params.height, bytes_per_pixel, gl_bytes_per_pixel, texture_src_data, temp_fb_depth_buffer_ptr, true);
+ MortonCopyPixels(params.pixel_format, params.width, params.height, bytes_per_pixel,
+ gl_bytes_per_pixel, texture_src_data, temp_fb_depth_buffer_ptr,
+ true);
- glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, params.height, 0,
- tuple.format, tuple.type, temp_fb_depth_buffer.data());
+ glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, params.height,
+ 0, tuple.format, tuple.type, temp_fb_depth_buffer.data());
}
}
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
@@ -367,10 +402,13 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo
OGLTexture scaled_texture;
scaled_texture.Create();
- AllocateSurfaceTexture(scaled_texture.handle, new_surface->pixel_format, new_surface->GetScaledWidth(), new_surface->GetScaledHeight());
- BlitTextures(new_surface->texture.handle, scaled_texture.handle, CachedSurface::GetFormatType(new_surface->pixel_format),
- MathUtil::Rectangle<int>(0, 0, new_surface->width, new_surface->height),
- MathUtil::Rectangle<int>(0, 0, new_surface->GetScaledWidth(), new_surface->GetScaledHeight()));
+ AllocateSurfaceTexture(scaled_texture.handle, new_surface->pixel_format,
+ new_surface->GetScaledWidth(), new_surface->GetScaledHeight());
+ BlitTextures(new_surface->texture.handle, scaled_texture.handle,
+ CachedSurface::GetFormatType(new_surface->pixel_format),
+ MathUtil::Rectangle<int>(0, 0, new_surface->width, new_surface->height),
+ MathUtil::Rectangle<int>(0, 0, new_surface->GetScaledWidth(),
+ new_surface->GetScaledHeight()));
new_surface->texture.Release();
new_surface->texture.handle = scaled_texture.handle;
@@ -389,11 +427,15 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo
}
Memory::RasterizerMarkRegionCached(new_surface->addr, new_surface->size, 1);
- surface_cache.add(std::make_pair(boost::icl::interval<PAddr>::right_open(new_surface->addr, new_surface->addr + new_surface->size), std::set<std::shared_ptr<CachedSurface>>({ new_surface })));
+ surface_cache.add(std::make_pair(boost::icl::interval<PAddr>::right_open(
+ new_surface->addr, new_surface->addr + new_surface->size),
+ std::set<std::shared_ptr<CachedSurface>>({new_surface})));
return new_surface.get();
}
-CachedSurface* RasterizerCacheOpenGL::GetSurfaceRect(const CachedSurface& params, bool match_res_scale, bool load_if_create, MathUtil::Rectangle<int>& out_rect) {
+CachedSurface* RasterizerCacheOpenGL::GetSurfaceRect(const CachedSurface& params,
+ bool match_res_scale, bool load_if_create,
+ MathUtil::Rectangle<int>& out_rect) {
if (params.addr == 0) {
return nullptr;
}
@@ -405,7 +447,8 @@ CachedSurface* RasterizerCacheOpenGL::GetSurfaceRect(const CachedSurface& params
CachedSurface* best_subrect_surface = nullptr;
float subrect_surface_goodness = -1.f;
- auto surface_interval = boost::icl::interval<PAddr>::right_open(params.addr, params.addr + params_size);
+ auto surface_interval =
+ boost::icl::interval<PAddr>::right_open(params.addr, params.addr + params_size);
auto cache_upper_bound = surface_cache.upper_bound(surface_interval);
for (auto it = surface_cache.lower_bound(surface_interval); it != cache_upper_bound; ++it) {
for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2) {
@@ -414,14 +457,15 @@ CachedSurface* RasterizerCacheOpenGL::GetSurfaceRect(const CachedSurface& params
// Check if the request is contained in the surface
if (params.addr >= surface->addr &&
params.addr + params_size - 1 <= surface->addr + surface->size - 1 &&
- params.pixel_format == surface->pixel_format)
- {
+ params.pixel_format == surface->pixel_format) {
// Make sure optional param-matching criteria are fulfilled
bool tiling_match = (params.is_tiled == surface->is_tiled);
- bool res_scale_match = (params.res_scale_width == surface->res_scale_width && params.res_scale_height == surface->res_scale_height);
+ bool res_scale_match = (params.res_scale_width == surface->res_scale_width &&
+ params.res_scale_height == surface->res_scale_height);
if (!match_res_scale || res_scale_match) {
// Prioritize same-tiling and highest resolution surfaces
- float match_goodness = (float)tiling_match + surface->res_scale_width * surface->res_scale_height;
+ float match_goodness =
+ (float)tiling_match + surface->res_scale_width * surface->res_scale_height;
if (match_goodness > subrect_surface_goodness || surface->dirty) {
subrect_surface_goodness = match_goodness;
best_subrect_surface = surface;
@@ -433,7 +477,8 @@ CachedSurface* RasterizerCacheOpenGL::GetSurfaceRect(const CachedSurface& params
// Return the best subrect surface if found
if (best_subrect_surface != nullptr) {
- unsigned int bytes_per_pixel = (CachedSurface::GetFormatBpp(best_subrect_surface->pixel_format) / 8);
+ unsigned int bytes_per_pixel =
+ (CachedSurface::GetFormatBpp(best_subrect_surface->pixel_format) / 8);
int x0, y0;
@@ -452,7 +497,9 @@ CachedSurface* RasterizerCacheOpenGL::GetSurfaceRect(const CachedSurface& params
y0 = begin_tile_index / tiles_per_row * 8;
// Tiled surfaces are flipped vertically in the rasterizer vs. 3DS memory.
- out_rect = MathUtil::Rectangle<int>(x0, best_subrect_surface->height - y0, x0 + params.width, best_subrect_surface->height - (y0 + params.height));
+ out_rect =
+ MathUtil::Rectangle<int>(x0, best_subrect_surface->height - y0, x0 + params.width,
+ best_subrect_surface->height - (y0 + params.height));
}
out_rect.left = (int)(out_rect.left * best_subrect_surface->res_scale_width);
@@ -465,16 +512,20 @@ CachedSurface* RasterizerCacheOpenGL::GetSurfaceRect(const CachedSurface& params
// No subrect found - create and return a new surface
if (!params.is_tiled) {
- out_rect = MathUtil::Rectangle<int>(0, 0, (int)(params.width * params.res_scale_width), (int)(params.height * params.res_scale_height));
+ out_rect = MathUtil::Rectangle<int>(0, 0, (int)(params.width * params.res_scale_width),
+ (int)(params.height * params.res_scale_height));
} else {
- out_rect = MathUtil::Rectangle<int>(0, (int)(params.height * params.res_scale_height), (int)(params.width * params.res_scale_width), 0);
+ out_rect = MathUtil::Rectangle<int>(0, (int)(params.height * params.res_scale_height),
+ (int)(params.width * params.res_scale_width), 0);
}
return GetSurface(params, match_res_scale, load_if_create);
}
-CachedSurface* RasterizerCacheOpenGL::GetTextureSurface(const Pica::Regs::FullTextureConfig& config) {
- Pica::DebugUtils::TextureInfo info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format);
+CachedSurface*
+RasterizerCacheOpenGL::GetTextureSurface(const Pica::Regs::FullTextureConfig& config) {
+ Pica::DebugUtils::TextureInfo info =
+ Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format);
CachedSurface params;
params.addr = info.physical_address;
@@ -485,20 +536,28 @@ CachedSurface* RasterizerCacheOpenGL::GetTextureSurface(const Pica::Regs::FullTe
return GetSurface(params, false, true);
}
-std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>> RasterizerCacheOpenGL::GetFramebufferSurfaces(const Pica::Regs::FramebufferConfig& config) {
+std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>>
+RasterizerCacheOpenGL::GetFramebufferSurfaces(const Pica::Regs::FramebufferConfig& config) {
const auto& regs = Pica::g_state.regs;
// Make sur that framebuffers don't overlap if both color and depth are being used
u32 fb_area = config.GetWidth() * config.GetHeight();
- bool framebuffers_overlap = config.GetColorBufferPhysicalAddress() != 0 &&
- config.GetDepthBufferPhysicalAddress() != 0 &&
- MathUtil::IntervalsIntersect(config.GetColorBufferPhysicalAddress(), fb_area * GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(config.color_format.Value())),
- config.GetDepthBufferPhysicalAddress(), fb_area * Pica::Regs::BytesPerDepthPixel(config.depth_format));
+ bool framebuffers_overlap =
+ config.GetColorBufferPhysicalAddress() != 0 &&
+ config.GetDepthBufferPhysicalAddress() != 0 &&
+ MathUtil::IntervalsIntersect(
+ config.GetColorBufferPhysicalAddress(),
+ fb_area * GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(config.color_format.Value())),
+ config.GetDepthBufferPhysicalAddress(),
+ fb_area * Pica::Regs::BytesPerDepthPixel(config.depth_format));
bool using_color_fb = config.GetColorBufferPhysicalAddress() != 0;
- bool using_depth_fb = config.GetDepthBufferPhysicalAddress() != 0 && (regs.output_merger.depth_test_enable || regs.output_merger.depth_write_enable || !framebuffers_overlap);
+ bool using_depth_fb = config.GetDepthBufferPhysicalAddress() != 0 &&
+ (regs.output_merger.depth_test_enable ||
+ regs.output_merger.depth_write_enable || !framebuffers_overlap);
if (framebuffers_overlap && using_color_fb && using_depth_fb) {
- LOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer memory regions overlap; overlapping framebuffers not supported!");
+ LOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer memory regions overlap; "
+ "overlapping framebuffers not supported!");
using_depth_fb = false;
}
@@ -512,8 +571,10 @@ std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>> RasterizerC
auto layout = VideoCore::g_emu_window->GetFramebufferLayout();
// Assume same scaling factor for top and bottom screens
- color_params.res_scale_width = depth_params.res_scale_width = (float)layout.top_screen.GetWidth() / VideoCore::kScreenTopWidth;
- color_params.res_scale_height = depth_params.res_scale_height = (float)layout.top_screen.GetHeight() / VideoCore::kScreenTopHeight;
+ color_params.res_scale_width = depth_params.res_scale_width =
+ (float)layout.top_screen.GetWidth() / VideoCore::kScreenTopWidth;
+ color_params.res_scale_height = depth_params.res_scale_height =
+ (float)layout.top_screen.GetHeight() / VideoCore::kScreenTopHeight;
}
color_params.addr = config.GetColorBufferPhysicalAddress();
@@ -523,22 +584,28 @@ std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>> RasterizerC
depth_params.pixel_format = CachedSurface::PixelFormatFromDepthFormat(config.depth_format);
MathUtil::Rectangle<int> color_rect;
- CachedSurface* color_surface = using_color_fb ? GetSurfaceRect(color_params, true, true, color_rect) : nullptr;
+ CachedSurface* color_surface =
+ using_color_fb ? GetSurfaceRect(color_params, true, true, color_rect) : nullptr;
MathUtil::Rectangle<int> depth_rect;
- CachedSurface* depth_surface = using_depth_fb ? GetSurfaceRect(depth_params, true, true, depth_rect) : nullptr;
+ CachedSurface* depth_surface =
+ using_depth_fb ? GetSurfaceRect(depth_params, true, true, depth_rect) : nullptr;
// Sanity check to make sure found surfaces aren't the same
if (using_depth_fb && using_color_fb && color_surface == depth_surface) {
- LOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer surfaces overlap; overlapping surfaces not supported!");
+ LOG_CRITICAL(
+ Render_OpenGL,
+ "Color and depth framebuffer surfaces overlap; overlapping surfaces not supported!");
using_depth_fb = false;
depth_surface = nullptr;
}
MathUtil::Rectangle<int> rect;
- if (color_surface != nullptr && depth_surface != nullptr && (depth_rect.left != color_rect.left || depth_rect.top != color_rect.top)) {
- // Can't specify separate color and depth viewport offsets in OpenGL, so re-zero both if they don't match
+ if (color_surface != nullptr && depth_surface != nullptr &&
+ (depth_rect.left != color_rect.left || depth_rect.top != color_rect.top)) {
+ // Can't specify separate color and depth viewport offsets in OpenGL, so re-zero both if
+ // they don't match
if (color_rect.left != 0 || color_rect.top != 0) {
color_surface = GetSurface(color_params, true, true);
}
@@ -548,9 +615,13 @@ std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>> RasterizerC
}
if (!color_surface->is_tiled) {
- rect = MathUtil::Rectangle<int>(0, 0, (int)(color_params.width * color_params.res_scale_width), (int)(color_params.height * color_params.res_scale_height));
+ rect = MathUtil::Rectangle<int>(
+ 0, 0, (int)(color_params.width * color_params.res_scale_width),
+ (int)(color_params.height * color_params.res_scale_height));
} else {
- rect = MathUtil::Rectangle<int>(0, (int)(color_params.height * color_params.res_scale_height), (int)(color_params.width * color_params.res_scale_width), 0);
+ rect = MathUtil::Rectangle<int>(
+ 0, (int)(color_params.height * color_params.res_scale_height),
+ (int)(color_params.width * color_params.res_scale_width), 0);
}
} else if (color_surface != nullptr) {
rect = color_rect;
@@ -564,7 +635,8 @@ std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>> RasterizerC
}
CachedSurface* RasterizerCacheOpenGL::TryGetFillSurface(const GPU::Regs::MemoryFillConfig& config) {
- auto surface_interval = boost::icl::interval<PAddr>::right_open(config.GetStartAddress(), config.GetEndAddress());
+ auto surface_interval =
+ boost::icl::interval<PAddr>::right_open(config.GetStartAddress(), config.GetEndAddress());
auto range = surface_cache.equal_range(surface_interval);
for (auto it = range.first; it != range.second; ++it) {
for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2) {
@@ -581,8 +653,9 @@ CachedSurface* RasterizerCacheOpenGL::TryGetFillSurface(const GPU::Regs::MemoryF
if (surface->addr == config.GetStartAddress() &&
CachedSurface::GetFormatBpp(surface->pixel_format) == bits_per_value &&
- (surface->width * surface->height * CachedSurface::GetFormatBpp(surface->pixel_format) / 8) == (config.GetEndAddress() - config.GetStartAddress()))
- {
+ (surface->width * surface->height *
+ CachedSurface::GetFormatBpp(surface->pixel_format) / 8) ==
+ (config.GetEndAddress() - config.GetStartAddress())) {
return surface;
}
}
@@ -617,8 +690,11 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) {
if (surface->res_scale_width != 1.f || surface->res_scale_height != 1.f) {
unscaled_tex.Create();
- AllocateSurfaceTexture(unscaled_tex.handle, surface->pixel_format, surface->width, surface->height);
- BlitTextures(surface->texture.handle, unscaled_tex.handle, CachedSurface::GetFormatType(surface->pixel_format),
+ AllocateSurfaceTexture(unscaled_tex.handle, surface->pixel_format, surface->width,
+ surface->height);
+ BlitTextures(
+ surface->texture.handle, unscaled_tex.handle,
+ CachedSurface::GetFormatType(surface->pixel_format),
MathUtil::Rectangle<int>(0, 0, surface->GetScaledWidth(), surface->GetScaledHeight()),
MathUtil::Rectangle<int>(0, 0, surface->width, surface->height));
@@ -648,10 +724,14 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) {
glGetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, temp_gl_buffer.data());
- // Directly copy pixels. Internal OpenGL color formats are consistent so no conversion is necessary.
- MortonCopyPixels(surface->pixel_format, surface->width, surface->height, bytes_per_pixel, bytes_per_pixel, dst_buffer, temp_gl_buffer.data(), false);
+ // Directly copy pixels. Internal OpenGL color formats are consistent so no conversion
+ // is necessary.
+ MortonCopyPixels(surface->pixel_format, surface->width, surface->height,
+ bytes_per_pixel, bytes_per_pixel, dst_buffer, temp_gl_buffer.data(),
+ false);
} else {
- // Depth/Stencil formats need special treatment since they aren't sampleable using LookupTexture and can't use RGBA format
+ // Depth/Stencil formats need special treatment since they aren't sampleable using
+ // LookupTexture and can't use RGBA format
size_t tuple_idx = (size_t)surface->pixel_format - 14;
ASSERT(tuple_idx < depth_format_tuples.size());
const FormatTuple& tuple = depth_format_tuples[tuple_idx];
@@ -669,7 +749,9 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) {
u8* temp_gl_buffer_ptr = use_4bpp ? temp_gl_buffer.data() + 1 : temp_gl_buffer.data();
- MortonCopyPixels(surface->pixel_format, surface->width, surface->height, bytes_per_pixel, gl_bytes_per_pixel, dst_buffer, temp_gl_buffer_ptr, false);
+ MortonCopyPixels(surface->pixel_format, surface->width, surface->height,
+ bytes_per_pixel, gl_bytes_per_pixel, dst_buffer, temp_gl_buffer_ptr,
+ false);
}
}
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
@@ -680,7 +762,8 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) {
cur_state.Apply();
}
-void RasterizerCacheOpenGL::FlushRegion(PAddr addr, u32 size, const CachedSurface* skip_surface, bool invalidate) {
+void RasterizerCacheOpenGL::FlushRegion(PAddr addr, u32 size, const CachedSurface* skip_surface,
+ bool invalidate) {
if (size == 0) {
return;
}
@@ -691,8 +774,11 @@ void RasterizerCacheOpenGL::FlushRegion(PAddr addr, u32 size, const CachedSurfac
auto surface_interval = boost::icl::interval<PAddr>::right_open(addr, addr + size);
auto cache_upper_bound = surface_cache.upper_bound(surface_interval);
for (auto it = surface_cache.lower_bound(surface_interval); it != cache_upper_bound; ++it) {
- std::copy_if(it->second.begin(), it->second.end(), std::inserter(touching_surfaces, touching_surfaces.end()),
- [skip_surface](std::shared_ptr<CachedSurface> surface) { return (surface.get() != skip_surface); });
+ std::copy_if(it->second.begin(), it->second.end(),
+ std::inserter(touching_surfaces, touching_surfaces.end()),
+ [skip_surface](std::shared_ptr<CachedSurface> surface) {
+ return (surface.get() != skip_surface);
+ });
}
// Flush and invalidate surfaces
@@ -700,7 +786,10 @@ void RasterizerCacheOpenGL::FlushRegion(PAddr addr, u32 size, const CachedSurfac
FlushSurface(surface.get());
if (invalidate) {
Memory::RasterizerMarkRegionCached(surface->addr, surface->size, -1);
- surface_cache.subtract(std::make_pair(boost::icl::interval<PAddr>::right_open(surface->addr, surface->addr + surface->size), std::set<std::shared_ptr<CachedSurface>>({ surface })));
+ surface_cache.subtract(
+ std::make_pair(boost::icl::interval<PAddr>::right_open(
+ surface->addr, surface->addr + surface->size),
+ std::set<std::shared_ptr<CachedSurface>>({surface})));
}
}
}