Rasterizer refactor hotfixes (#6465)
* texture_codec: Clamp buffer end to tiled buffer size * Fixes crash on Pokemon Super Mystery Dungeon * rasterizer_cache: Use rect for duplicate surface * Fixes broken bloom in fire emblem * surface_params: Check levels for exact match * It was removed previously to prevent copies when games used the base level of a multi level surface. FE on the other hand will first use the base level and then use it as a face of a cubemap with many levels. So instead check if the surface equal or more levels and consider it an exact match in that case * gl_texture_runtime: Bind old tex to 2D target * Fixes a small error opengl would print when creating texture cubes * gl_blit_helper: Fix nearest filter * Use texture unit 2 which has the nearest sampler bound
This commit is contained in:
@@ -725,8 +725,8 @@ void RasterizerCache::DuplicateSurface(const SurfaceRef& src_surface,
|
||||
const TextureCopy copy = {
|
||||
.src_level = 0,
|
||||
.dst_level = 0,
|
||||
.src_offset = {0, 0},
|
||||
.dst_offset = {0, 0},
|
||||
.src_offset = {src_rect.left, src_rect.bottom},
|
||||
.dst_offset = {dst_rect.left, dst_rect.bottom},
|
||||
.extent = {src_rect.GetWidth(), src_rect.GetHeight()},
|
||||
};
|
||||
runtime.CopyTextures(*src_surface, *dest_surface, copy);
|
||||
|
@@ -11,7 +11,7 @@ bool SurfaceParams::ExactMatch(const SurfaceParams& other_surface) const {
|
||||
return std::tie(other_surface.addr, other_surface.width, other_surface.height,
|
||||
other_surface.stride, other_surface.pixel_format, other_surface.is_tiled) ==
|
||||
std::tie(addr, width, height, stride, pixel_format, is_tiled) &&
|
||||
pixel_format != PixelFormat::Invalid;
|
||||
pixel_format != PixelFormat::Invalid && levels >= other_surface.levels;
|
||||
}
|
||||
|
||||
bool SurfaceParams::CanSubRect(const SurfaceParams& sub_surface) const {
|
||||
|
@@ -305,7 +305,9 @@ static constexpr void MortonCopy(u32 width, u32 height, u32 start_offset, u32 en
|
||||
|
||||
// If the copy spans multiple tiles, copy the fully aligned tiles in between.
|
||||
if (aligned_start_offset < aligned_end_offset) {
|
||||
const u32 buffer_end = tiled_offset + aligned_end_offset - aligned_start_offset;
|
||||
const u32 tile_buffer_size = static_cast<u32>(tiled_buffer.size());
|
||||
const u32 buffer_end =
|
||||
std::min(tiled_offset + aligned_end_offset - aligned_start_offset, tile_buffer_size);
|
||||
while (tiled_offset < buffer_end) {
|
||||
auto linear_data = linear_buffer.subspan(linear_offset, linear_tile_stride);
|
||||
auto tiled_data = tiled_buffer.subspan(tiled_offset, tile_size);
|
||||
|
Reference in New Issue
Block a user