diff options
| author | 2018-10-12 22:24:40 -0400 | |
|---|---|---|
| committer | 2018-10-16 11:31:00 -0400 | |
| commit | 4e9683e9d5518a2e5dc69ddd12f20685a94646e2 (patch) | |
| tree | 41bb16430adb994f0dd5ff2742830a7132b4accc /src | |
| parent | memory_manager: Add a method for querying the end of a mapped GPU region. (diff) | |
| download | yuzu-4e9683e9d5518a2e5dc69ddd12f20685a94646e2.tar.gz yuzu-4e9683e9d5518a2e5dc69ddd12f20685a94646e2.tar.xz yuzu-4e9683e9d5518a2e5dc69ddd12f20685a94646e2.zip | |
gl_rasterizer_cache: Clamp cached surface size to mapped GPU region size.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 45 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 11 |
2 files changed, 37 insertions, 19 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 1bb842fe7..24781a3c1 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -34,16 +34,29 @@ struct FormatTuple { | |||
| 34 | bool compressed; | 34 | bool compressed; |
| 35 | }; | 35 | }; |
| 36 | 36 | ||
| 37 | static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | 37 | void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr) { |
| 38 | auto& gpu{Core::System::GetInstance().GPU()}; | 38 | auto& memory_manager{Core::System::GetInstance().GPU().MemoryManager()}; |
| 39 | const auto cpu_addr{gpu.MemoryManager().GpuToCpuAddress(gpu_addr)}; | 39 | const auto cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)}; |
| 40 | return cpu_addr ? *cpu_addr : 0; | 40 | const auto max_size{memory_manager.GetRegionEnd(gpu_addr) - gpu_addr}; |
| 41 | |||
| 42 | addr = cpu_addr ? *cpu_addr : 0; | ||
| 43 | size_in_bytes_total = SizeInBytesTotal(); | ||
| 44 | size_in_bytes_2d = SizeInBytes2D(); | ||
| 45 | |||
| 46 | // Clamp sizes to mapped GPU memory region | ||
| 47 | if (size_in_bytes_2d > max_size) { | ||
| 48 | LOG_ERROR(HW_GPU, "Surface size {} exceeds region size {}", size_in_bytes_2d, max_size); | ||
| 49 | size_in_bytes_total = max_size; | ||
| 50 | size_in_bytes_2d = max_size; | ||
| 51 | } else if (size_in_bytes_total > max_size) { | ||
| 52 | LOG_ERROR(HW_GPU, "Surface size {} exceeds region size {}", size_in_bytes_total, max_size); | ||
| 53 | size_in_bytes_total = max_size; | ||
| 54 | } | ||
| 41 | } | 55 | } |
| 42 | 56 | ||
| 43 | /*static*/ SurfaceParams SurfaceParams::CreateForTexture( | 57 | /*static*/ SurfaceParams SurfaceParams::CreateForTexture( |
| 44 | const Tegra::Texture::FullTextureInfo& config, const GLShader::SamplerEntry& entry) { | 58 | const Tegra::Texture::FullTextureInfo& config, const GLShader::SamplerEntry& entry) { |
| 45 | SurfaceParams params{}; | 59 | SurfaceParams params{}; |
| 46 | params.addr = TryGetCpuAddr(config.tic.Address()); | ||
| 47 | params.is_tiled = config.tic.IsTiled(); | 60 | params.is_tiled = config.tic.IsTiled(); |
| 48 | params.block_width = params.is_tiled ? config.tic.BlockWidth() : 0, | 61 | params.block_width = params.is_tiled ? config.tic.BlockWidth() : 0, |
| 49 | params.block_height = params.is_tiled ? config.tic.BlockHeight() : 0, | 62 | params.block_height = params.is_tiled ? config.tic.BlockHeight() : 0, |
| @@ -87,18 +100,18 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | |||
| 87 | break; | 100 | break; |
| 88 | } | 101 | } |
| 89 | 102 | ||
| 90 | params.size_in_bytes_total = params.SizeInBytesTotal(); | ||
| 91 | params.size_in_bytes_2d = params.SizeInBytes2D(); | ||
| 92 | params.max_mip_level = config.tic.max_mip_level + 1; | 103 | params.max_mip_level = config.tic.max_mip_level + 1; |
| 93 | params.rt = {}; | 104 | params.rt = {}; |
| 94 | 105 | ||
| 106 | params.InitCacheParameters(config.tic.Address()); | ||
| 107 | |||
| 95 | return params; | 108 | return params; |
| 96 | } | 109 | } |
| 97 | 110 | ||
| 98 | /*static*/ SurfaceParams SurfaceParams::CreateForFramebuffer(std::size_t index) { | 111 | /*static*/ SurfaceParams SurfaceParams::CreateForFramebuffer(std::size_t index) { |
| 99 | const auto& config{Core::System::GetInstance().GPU().Maxwell3D().regs.rt[index]}; | 112 | const auto& config{Core::System::GetInstance().GPU().Maxwell3D().regs.rt[index]}; |
| 100 | SurfaceParams params{}; | 113 | SurfaceParams params{}; |
| 101 | params.addr = TryGetCpuAddr(config.Address()); | 114 | |
| 102 | params.is_tiled = | 115 | params.is_tiled = |
| 103 | config.memory_layout.type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; | 116 | config.memory_layout.type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; |
| 104 | params.block_width = 1 << config.memory_layout.block_width; | 117 | params.block_width = 1 << config.memory_layout.block_width; |
| @@ -112,8 +125,6 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | |||
| 112 | params.unaligned_height = config.height; | 125 | params.unaligned_height = config.height; |
| 113 | params.target = SurfaceTarget::Texture2D; | 126 | params.target = SurfaceTarget::Texture2D; |
| 114 | params.depth = 1; | 127 | params.depth = 1; |
| 115 | params.size_in_bytes_total = params.SizeInBytesTotal(); | ||
| 116 | params.size_in_bytes_2d = params.SizeInBytes2D(); | ||
| 117 | params.max_mip_level = 0; | 128 | params.max_mip_level = 0; |
| 118 | 129 | ||
| 119 | // Render target specific parameters, not used for caching | 130 | // Render target specific parameters, not used for caching |
| @@ -122,6 +133,8 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | |||
| 122 | params.rt.layer_stride = config.layer_stride; | 133 | params.rt.layer_stride = config.layer_stride; |
| 123 | params.rt.base_layer = config.base_layer; | 134 | params.rt.base_layer = config.base_layer; |
| 124 | 135 | ||
| 136 | params.InitCacheParameters(config.Address()); | ||
| 137 | |||
| 125 | return params; | 138 | return params; |
| 126 | } | 139 | } |
| 127 | 140 | ||
| @@ -130,7 +143,7 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | |||
| 130 | u32 block_width, u32 block_height, u32 block_depth, | 143 | u32 block_width, u32 block_height, u32 block_depth, |
| 131 | Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout type) { | 144 | Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout type) { |
| 132 | SurfaceParams params{}; | 145 | SurfaceParams params{}; |
| 133 | params.addr = TryGetCpuAddr(zeta_address); | 146 | |
| 134 | params.is_tiled = type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; | 147 | params.is_tiled = type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; |
| 135 | params.block_width = 1 << std::min(block_width, 5U); | 148 | params.block_width = 1 << std::min(block_width, 5U); |
| 136 | params.block_height = 1 << std::min(block_height, 5U); | 149 | params.block_height = 1 << std::min(block_height, 5U); |
| @@ -143,18 +156,18 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | |||
| 143 | params.unaligned_height = zeta_height; | 156 | params.unaligned_height = zeta_height; |
| 144 | params.target = SurfaceTarget::Texture2D; | 157 | params.target = SurfaceTarget::Texture2D; |
| 145 | params.depth = 1; | 158 | params.depth = 1; |
| 146 | params.size_in_bytes_total = params.SizeInBytesTotal(); | ||
| 147 | params.size_in_bytes_2d = params.SizeInBytes2D(); | ||
| 148 | params.max_mip_level = 0; | 159 | params.max_mip_level = 0; |
| 149 | params.rt = {}; | 160 | params.rt = {}; |
| 150 | 161 | ||
| 162 | params.InitCacheParameters(zeta_address); | ||
| 163 | |||
| 151 | return params; | 164 | return params; |
| 152 | } | 165 | } |
| 153 | 166 | ||
| 154 | /*static*/ SurfaceParams SurfaceParams::CreateForFermiCopySurface( | 167 | /*static*/ SurfaceParams SurfaceParams::CreateForFermiCopySurface( |
| 155 | const Tegra::Engines::Fermi2D::Regs::Surface& config) { | 168 | const Tegra::Engines::Fermi2D::Regs::Surface& config) { |
| 156 | SurfaceParams params{}; | 169 | SurfaceParams params{}; |
| 157 | params.addr = TryGetCpuAddr(config.Address()); | 170 | |
| 158 | params.is_tiled = !config.linear; | 171 | params.is_tiled = !config.linear; |
| 159 | params.block_width = params.is_tiled ? std::min(config.BlockWidth(), 32U) : 0, | 172 | params.block_width = params.is_tiled ? std::min(config.BlockWidth(), 32U) : 0, |
| 160 | params.block_height = params.is_tiled ? std::min(config.BlockHeight(), 32U) : 0, | 173 | params.block_height = params.is_tiled ? std::min(config.BlockHeight(), 32U) : 0, |
| @@ -167,11 +180,11 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | |||
| 167 | params.unaligned_height = config.height; | 180 | params.unaligned_height = config.height; |
| 168 | params.target = SurfaceTarget::Texture2D; | 181 | params.target = SurfaceTarget::Texture2D; |
| 169 | params.depth = 1; | 182 | params.depth = 1; |
| 170 | params.size_in_bytes_total = params.SizeInBytesTotal(); | ||
| 171 | params.size_in_bytes_2d = params.SizeInBytes2D(); | ||
| 172 | params.max_mip_level = 0; | 183 | params.max_mip_level = 0; |
| 173 | params.rt = {}; | 184 | params.rt = {}; |
| 174 | 185 | ||
| 186 | params.InitCacheParameters(config.Address()); | ||
| 187 | |||
| 175 | return params; | 188 | return params; |
| 176 | } | 189 | } |
| 177 | 190 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index a15fb7b07..f6f7aad82 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -742,7 +742,9 @@ struct SurfaceParams { | |||
| 742 | other.depth); | 742 | other.depth); |
| 743 | } | 743 | } |
| 744 | 744 | ||
| 745 | VAddr addr; | 745 | /// Initializes parameters for caching, should be called after everything has been initialized |
| 746 | void InitCacheParameters(Tegra::GPUVAddr gpu_addr); | ||
| 747 | |||
| 746 | bool is_tiled; | 748 | bool is_tiled; |
| 747 | u32 block_width; | 749 | u32 block_width; |
| 748 | u32 block_height; | 750 | u32 block_height; |
| @@ -754,11 +756,14 @@ struct SurfaceParams { | |||
| 754 | u32 height; | 756 | u32 height; |
| 755 | u32 depth; | 757 | u32 depth; |
| 756 | u32 unaligned_height; | 758 | u32 unaligned_height; |
| 757 | std::size_t size_in_bytes_total; | ||
| 758 | std::size_t size_in_bytes_2d; | ||
| 759 | SurfaceTarget target; | 759 | SurfaceTarget target; |
| 760 | u32 max_mip_level; | 760 | u32 max_mip_level; |
| 761 | 761 | ||
| 762 | // Parameters used for caching | ||
| 763 | VAddr addr; | ||
| 764 | std::size_t size_in_bytes_total; | ||
| 765 | std::size_t size_in_bytes_2d; | ||
| 766 | |||
| 762 | // Render target specific parameters, not used in caching | 767 | // Render target specific parameters, not used in caching |
| 763 | struct { | 768 | struct { |
| 764 | u32 index; | 769 | u32 index; |