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 New Issue
	
	Block a user