mirror of
https://gitlab.com/suyu-emu/suyu.git
synced 2024-03-15 23:15:44 +00:00
gl_rasterizer_cache: Clamp cached surface size to mapped GPU region size.
This commit is contained in:
parent
37575eae65
commit
4e9683e9d5
|
@ -34,16 +34,29 @@ struct FormatTuple {
|
|||
bool compressed;
|
||||
};
|
||||
|
||||
static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
|
||||
auto& gpu{Core::System::GetInstance().GPU()};
|
||||
const auto cpu_addr{gpu.MemoryManager().GpuToCpuAddress(gpu_addr)};
|
||||
return cpu_addr ? *cpu_addr : 0;
|
||||
void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr) {
|
||||
auto& memory_manager{Core::System::GetInstance().GPU().MemoryManager()};
|
||||
const auto cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)};
|
||||
const auto max_size{memory_manager.GetRegionEnd(gpu_addr) - gpu_addr};
|
||||
|
||||
addr = cpu_addr ? *cpu_addr : 0;
|
||||
size_in_bytes_total = SizeInBytesTotal();
|
||||
size_in_bytes_2d = SizeInBytes2D();
|
||||
|
||||
// Clamp sizes to mapped GPU memory region
|
||||
if (size_in_bytes_2d > max_size) {
|
||||
LOG_ERROR(HW_GPU, "Surface size {} exceeds region size {}", size_in_bytes_2d, max_size);
|
||||
size_in_bytes_total = max_size;
|
||||
size_in_bytes_2d = max_size;
|
||||
} else if (size_in_bytes_total > max_size) {
|
||||
LOG_ERROR(HW_GPU, "Surface size {} exceeds region size {}", size_in_bytes_total, max_size);
|
||||
size_in_bytes_total = max_size;
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/ SurfaceParams SurfaceParams::CreateForTexture(
|
||||
const Tegra::Texture::FullTextureInfo& config, const GLShader::SamplerEntry& entry) {
|
||||
SurfaceParams params{};
|
||||
params.addr = TryGetCpuAddr(config.tic.Address());
|
||||
params.is_tiled = config.tic.IsTiled();
|
||||
params.block_width = params.is_tiled ? config.tic.BlockWidth() : 0,
|
||||
params.block_height = params.is_tiled ? config.tic.BlockHeight() : 0,
|
||||
|
@ -87,18 +100,18 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
|
|||
break;
|
||||
}
|
||||
|
||||
params.size_in_bytes_total = params.SizeInBytesTotal();
|
||||
params.size_in_bytes_2d = params.SizeInBytes2D();
|
||||
params.max_mip_level = config.tic.max_mip_level + 1;
|
||||
params.rt = {};
|
||||
|
||||
params.InitCacheParameters(config.tic.Address());
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/*static*/ SurfaceParams SurfaceParams::CreateForFramebuffer(std::size_t index) {
|
||||
const auto& config{Core::System::GetInstance().GPU().Maxwell3D().regs.rt[index]};
|
||||
SurfaceParams params{};
|
||||
params.addr = TryGetCpuAddr(config.Address());
|
||||
|
||||
params.is_tiled =
|
||||
config.memory_layout.type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear;
|
||||
params.block_width = 1 << config.memory_layout.block_width;
|
||||
|
@ -112,8 +125,6 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
|
|||
params.unaligned_height = config.height;
|
||||
params.target = SurfaceTarget::Texture2D;
|
||||
params.depth = 1;
|
||||
params.size_in_bytes_total = params.SizeInBytesTotal();
|
||||
params.size_in_bytes_2d = params.SizeInBytes2D();
|
||||
params.max_mip_level = 0;
|
||||
|
||||
// Render target specific parameters, not used for caching
|
||||
|
@ -122,6 +133,8 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
|
|||
params.rt.layer_stride = config.layer_stride;
|
||||
params.rt.base_layer = config.base_layer;
|
||||
|
||||
params.InitCacheParameters(config.Address());
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
@ -130,7 +143,7 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
|
|||
u32 block_width, u32 block_height, u32 block_depth,
|
||||
Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout type) {
|
||||
SurfaceParams params{};
|
||||
params.addr = TryGetCpuAddr(zeta_address);
|
||||
|
||||
params.is_tiled = type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear;
|
||||
params.block_width = 1 << std::min(block_width, 5U);
|
||||
params.block_height = 1 << std::min(block_height, 5U);
|
||||
|
@ -143,18 +156,18 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
|
|||
params.unaligned_height = zeta_height;
|
||||
params.target = SurfaceTarget::Texture2D;
|
||||
params.depth = 1;
|
||||
params.size_in_bytes_total = params.SizeInBytesTotal();
|
||||
params.size_in_bytes_2d = params.SizeInBytes2D();
|
||||
params.max_mip_level = 0;
|
||||
params.rt = {};
|
||||
|
||||
params.InitCacheParameters(zeta_address);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/*static*/ SurfaceParams SurfaceParams::CreateForFermiCopySurface(
|
||||
const Tegra::Engines::Fermi2D::Regs::Surface& config) {
|
||||
SurfaceParams params{};
|
||||
params.addr = TryGetCpuAddr(config.Address());
|
||||
|
||||
params.is_tiled = !config.linear;
|
||||
params.block_width = params.is_tiled ? std::min(config.BlockWidth(), 32U) : 0,
|
||||
params.block_height = params.is_tiled ? std::min(config.BlockHeight(), 32U) : 0,
|
||||
|
@ -167,11 +180,11 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
|
|||
params.unaligned_height = config.height;
|
||||
params.target = SurfaceTarget::Texture2D;
|
||||
params.depth = 1;
|
||||
params.size_in_bytes_total = params.SizeInBytesTotal();
|
||||
params.size_in_bytes_2d = params.SizeInBytes2D();
|
||||
params.max_mip_level = 0;
|
||||
params.rt = {};
|
||||
|
||||
params.InitCacheParameters(config.Address());
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
|
|
@ -742,7 +742,9 @@ struct SurfaceParams {
|
|||
other.depth);
|
||||
}
|
||||
|
||||
VAddr addr;
|
||||
/// Initializes parameters for caching, should be called after everything has been initialized
|
||||
void InitCacheParameters(Tegra::GPUVAddr gpu_addr);
|
||||
|
||||
bool is_tiled;
|
||||
u32 block_width;
|
||||
u32 block_height;
|
||||
|
@ -754,11 +756,14 @@ struct SurfaceParams {
|
|||
u32 height;
|
||||
u32 depth;
|
||||
u32 unaligned_height;
|
||||
std::size_t size_in_bytes_total;
|
||||
std::size_t size_in_bytes_2d;
|
||||
SurfaceTarget target;
|
||||
u32 max_mip_level;
|
||||
|
||||
// Parameters used for caching
|
||||
VAddr addr;
|
||||
std::size_t size_in_bytes_total;
|
||||
std::size_t size_in_bytes_2d;
|
||||
|
||||
// Render target specific parameters, not used in caching
|
||||
struct {
|
||||
u32 index;
|
||||
|
|
Loading…
Reference in a new issue