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:
GPUCode 2023-04-23 22:46:08 +03:00 committed by GitHub
parent 9ba6a90193
commit 2c74ed1a6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 9 additions and 6 deletions

View File

@ -8,7 +8,7 @@ precision mediump float;
layout(location = 0) in vec2 tex_coord; layout(location = 0) in vec2 tex_coord;
layout(location = 0) out vec4 frag_color; layout(location = 0) out vec4 frag_color;
layout(binding = 0) uniform sampler2D input_texture; layout(binding = 2) uniform sampler2D input_texture;
void main() { void main() {
frag_color = texture(input_texture, tex_coord); frag_color = texture(input_texture, tex_coord);

View File

@ -725,8 +725,8 @@ void RasterizerCache::DuplicateSurface(const SurfaceRef& src_surface,
const TextureCopy copy = { const TextureCopy copy = {
.src_level = 0, .src_level = 0,
.dst_level = 0, .dst_level = 0,
.src_offset = {0, 0}, .src_offset = {src_rect.left, src_rect.bottom},
.dst_offset = {0, 0}, .dst_offset = {dst_rect.left, dst_rect.bottom},
.extent = {src_rect.GetWidth(), src_rect.GetHeight()}, .extent = {src_rect.GetWidth(), src_rect.GetHeight()},
}; };
runtime.CopyTextures(*src_surface, *dest_surface, copy); runtime.CopyTextures(*src_surface, *dest_surface, copy);

View File

@ -11,7 +11,7 @@ bool SurfaceParams::ExactMatch(const SurfaceParams& other_surface) const {
return std::tie(other_surface.addr, other_surface.width, other_surface.height, return std::tie(other_surface.addr, other_surface.width, other_surface.height,
other_surface.stride, other_surface.pixel_format, other_surface.is_tiled) == other_surface.stride, other_surface.pixel_format, other_surface.is_tiled) ==
std::tie(addr, width, height, stride, pixel_format, 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 { bool SurfaceParams::CanSubRect(const SurfaceParams& sub_surface) const {

View File

@ -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 the copy spans multiple tiles, copy the fully aligned tiles in between.
if (aligned_start_offset < aligned_end_offset) { 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) { while (tiled_offset < buffer_end) {
auto linear_data = linear_buffer.subspan(linear_offset, linear_tile_stride); auto linear_data = linear_buffer.subspan(linear_offset, linear_tile_stride);
auto tiled_data = tiled_buffer.subspan(tiled_offset, tile_size); auto tiled_data = tiled_buffer.subspan(tiled_offset, tile_size);

View File

@ -166,6 +166,7 @@ void BlitHelper::FilterBicubic(Surface& surface, const VideoCore::TextureBlit& b
} }
void BlitHelper::FilterNearest(Surface& surface, const VideoCore::TextureBlit& blit) { void BlitHelper::FilterNearest(Surface& surface, const VideoCore::TextureBlit& blit) {
state.texture_units[2].texture_2d = surface.Handle(false);
SetParams(nearest_program, surface.width, surface.height, blit.src_rect); SetParams(nearest_program, surface.width, surface.height, blit.src_rect);
Draw(nearest_program, surface.Handle(), filter_fbo.handle, blit.dst_level, blit.dst_rect); Draw(nearest_program, surface.Handle(), filter_fbo.handle, blit.dst_level, blit.dst_rect);
} }

View File

@ -199,7 +199,7 @@ Allocation TextureRuntime::Allocate(const VideoCore::SurfaceParams& params) {
handles[1] = textures[1].handle; handles[1] = textures[1].handle;
} }
glBindTexture(target, old_tex); glBindTexture(GL_TEXTURE_2D, old_tex);
return Allocation{ return Allocation{
.textures = std::move(textures), .textures = std::move(textures),