rasterizer_cache: Reorder methods

This commit is contained in:
emufan4568
2022-09-11 13:15:40 +03:00
committed by GPUCode
parent 98eea4dcca
commit 2963682722

View File

@ -21,88 +21,7 @@ static constexpr auto RangeFromInterval(Map& map, const Interval& interval) {
return boost::make_iterator_range(map.equal_range(interval)); return boost::make_iterator_range(map.equal_range(interval));
} }
// Allocate an uninitialized texture of appropriate size and format for the surface enum class MatchFlags {
OGLTexture RasterizerCache::AllocateSurfaceTexture(PixelFormat format, u32 width, u32 height) {
const FormatTuple& tuple = GetFormatTuple(format);
auto recycled_tex = host_texture_recycler.find({format, width, height});
if (recycled_tex != host_texture_recycler.end()) {
OGLTexture texture = std::move(recycled_tex->second);
host_texture_recycler.erase(recycled_tex);
return texture;
}
const GLsizei levels = static_cast<GLsizei>(std::log2(std::max(width, height))) + 1;
OGLTexture texture;
texture.Create();
texture.Allocate(GL_TEXTURE_2D, levels, tuple.internal_format, width, height);
return texture;
}
MICROPROFILE_DEFINE(RasterizerCache_CopySurface, "RasterizerCache", "CopySurface", MP_RGB(128, 192, 64));
void RasterizerCache::CopySurface(const Surface& src_surface, const Surface& dst_surface,
SurfaceInterval copy_interval) {
MICROPROFILE_SCOPE(RasterizerCache_CopySurface);
SurfaceParams subrect_params = dst_surface->FromInterval(copy_interval);
ASSERT(subrect_params.GetInterval() == copy_interval && src_surface != dst_surface);
const auto dst_rect = dst_surface->GetScaledSubRect(subrect_params);
if (src_surface->type == SurfaceType::Fill) {
// FillSurface needs a 4 bytes buffer
const u32 fill_offset =
(boost::icl::first(copy_interval) - src_surface->addr) % src_surface->fill_size;
std::array<u8, 4> fill_buffer;
u32 fill_buff_pos = fill_offset;
for (std::size_t i = 0; i < fill_buffer.size(); i++) {
fill_buffer[i] = src_surface->fill_data[fill_buff_pos++ % src_surface->fill_size];
}
const ClearValue clear_value =
MakeClearValue(dst_surface->type, dst_surface->pixel_format, fill_buffer.data());
const TextureClear clear_rect = {
.surface_type = dst_surface->type,
.texture_format = dst_surface->pixel_format,
.texture_level = 0,
.rect = Rect2D{
.offset = {dst_rect.left, dst_rect.bottom},
.extent = {dst_rect.GetWidth(), dst_rect.GetHeight()}
}
};
runtime.ClearTexture(dst_surface->texture, clear_rect, clear_value);
return;
}
if (src_surface->CanSubRect(subrect_params)) {
const auto src_rect = src_surface->GetScaledSubRect(subrect_params);
const TextureBlit texture_blit = {
.surface_type = src_surface->type,
.src_level = 0,
.dst_level = 0,
.src_layer = 0,
.dst_layer = 0,
.src_region = Region2D{
.start = {src_rect.left, src_rect.bottom},
.end = {src_rect.right, src_rect.top}
},
.dst_region = Region2D{
.start = {dst_rect.left, dst_rect.bottom},
.end = {dst_rect.right, dst_rect.top}
}
};
runtime.BlitTextures(src_surface->texture, dst_surface->texture, texture_blit);
return;
}
UNREACHABLE();
}
enum MatchFlags {
Invalid = 1, ///< Surface is allowed to be only partially valid Invalid = 1, ///< Surface is allowed to be only partially valid
Exact = 1 << 1, ///< Surface perfectly matches params Exact = 1 << 1, ///< Surface perfectly matches params
SubRect = 1 << 2, ///< Surface encompasses params SubRect = 1 << 2, ///< Surface encompasses params
@ -111,9 +30,7 @@ enum MatchFlags {
TexCopy = 1 << 5 ///< Surface that will match a display transfer "texture copy" parameters TexCopy = 1 << 5 ///< Surface that will match a display transfer "texture copy" parameters
}; };
static constexpr MatchFlags operator|(MatchFlags lhs, MatchFlags rhs) { DECLARE_ENUM_FLAG_OPERATORS(MatchFlags);
return static_cast<MatchFlags>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
/// Get the best surface match (and its match type) for the given flags /// Get the best surface match (and its match type) for the given flags
template <MatchFlags find_flags> template <MatchFlags find_flags>
@ -132,15 +49,15 @@ static Surface FindMatch(const SurfaceCache& surface_cache, const SurfaceParams&
: (params.res_scale <= surface->res_scale); : (params.res_scale <= surface->res_scale);
// validity will be checked in GetCopyableInterval // validity will be checked in GetCopyableInterval
bool is_valid = bool is_valid =
find_flags & MatchFlags::Copy True(find_flags & MatchFlags::Copy)
? true ? true
: surface->IsRegionValid(validate_interval.value_or(params.GetInterval())); : surface->IsRegionValid(validate_interval.value_or(params.GetInterval()));
if (!(find_flags & MatchFlags::Invalid) && !is_valid) if (False(find_flags & MatchFlags::Invalid) && !is_valid)
continue; continue;
auto IsMatch_Helper = [&](auto check_type, auto match_fn) { auto IsMatch_Helper = [&](auto check_type, auto match_fn) {
if (!(find_flags & check_type)) if (False(find_flags & check_type))
return; return;
bool matched; bool matched;
@ -247,6 +164,69 @@ bool RasterizerCache::BlitSurfaces(const Surface& src_surface,
return false; return false;
} }
MICROPROFILE_DEFINE(RasterizerCache_CopySurface, "RasterizerCache", "CopySurface", MP_RGB(128, 192, 64));
void RasterizerCache::CopySurface(const Surface& src_surface, const Surface& dst_surface,
SurfaceInterval copy_interval) {
MICROPROFILE_SCOPE(RasterizerCache_CopySurface);
SurfaceParams subrect_params = dst_surface->FromInterval(copy_interval);
ASSERT(subrect_params.GetInterval() == copy_interval && src_surface != dst_surface);
const auto dst_rect = dst_surface->GetScaledSubRect(subrect_params);
if (src_surface->type == SurfaceType::Fill) {
// FillSurface needs a 4 bytes buffer
const u32 fill_offset =
(boost::icl::first(copy_interval) - src_surface->addr) % src_surface->fill_size;
std::array<u8, 4> fill_buffer;
u32 fill_buff_pos = fill_offset;
for (std::size_t i = 0; i < fill_buffer.size(); i++) {
fill_buffer[i] = src_surface->fill_data[fill_buff_pos++ % src_surface->fill_size];
}
const ClearValue clear_value =
MakeClearValue(dst_surface->type, dst_surface->pixel_format, fill_buffer.data());
const TextureClear clear_rect = {
.surface_type = dst_surface->type,
.texture_format = dst_surface->pixel_format,
.texture_level = 0,
.rect = Rect2D{
.offset = {dst_rect.left, dst_rect.bottom},
.extent = {dst_rect.GetWidth(), dst_rect.GetHeight()}
}
};
runtime.ClearTexture(dst_surface->texture, clear_rect, clear_value);
return;
}
if (src_surface->CanSubRect(subrect_params)) {
const auto src_rect = src_surface->GetScaledSubRect(subrect_params);
const TextureBlit texture_blit = {
.surface_type = src_surface->type,
.src_level = 0,
.dst_level = 0,
.src_layer = 0,
.dst_layer = 0,
.src_region = Region2D{
.start = {src_rect.left, src_rect.bottom},
.end = {src_rect.right, src_rect.top}
},
.dst_region = Region2D{
.start = {dst_rect.left, dst_rect.bottom},
.end = {dst_rect.right, dst_rect.top}
}
};
runtime.BlitTextures(src_surface->texture, dst_surface->texture, texture_blit);
return;
}
UNREACHABLE();
}
Surface RasterizerCache::GetSurface(const SurfaceParams& params, ScaleMatch match_res_scale, Surface RasterizerCache::GetSurface(const SurfaceParams& params, ScaleMatch match_res_scale,
bool load_if_create) { bool load_if_create) {
if (params.addr == 0 || params.height * params.width == 0) { if (params.addr == 0 || params.height * params.width == 0) {
@ -1055,4 +1035,23 @@ void RasterizerCache::UnregisterSurface(const Surface& surface) {
surface_cache.subtract({surface->GetInterval(), SurfaceSet{surface}}); surface_cache.subtract({surface->GetInterval(), SurfaceSet{surface}});
} }
// Allocate an uninitialized texture of appropriate size and format for the surface
OGLTexture RasterizerCache::AllocateSurfaceTexture(PixelFormat format, u32 width, u32 height) {
const FormatTuple& tuple = GetFormatTuple(format);
auto recycled_tex = host_texture_recycler.find({format, width, height});
if (recycled_tex != host_texture_recycler.end()) {
OGLTexture texture = std::move(recycled_tex->second);
host_texture_recycler.erase(recycled_tex);
return texture;
}
const GLsizei levels = static_cast<GLsizei>(std::log2(std::max(width, height))) + 1;
OGLTexture texture;
texture.Create();
texture.Allocate(GL_TEXTURE_2D, levels, tuple.internal_format, width, height);
return texture;
}
} // namespace OpenGL } // namespace OpenGL