summaryrefslogtreecommitdiffstats
path: root/src/video_core
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2018-10-13 04:24:40 +0200
committerbunnei <bunneidev@gmail.com>2018-10-16 17:31:00 +0200
commit4e9683e9d5518a2e5dc69ddd12f20685a94646e2 (patch)
tree41bb16430adb994f0dd5ff2742830a7132b4accc /src/video_core
parentmemory_manager: Add a method for querying the end of a mapped GPU region. (diff)
downloadyuzu-4e9683e9d5518a2e5dc69ddd12f20685a94646e2.tar
yuzu-4e9683e9d5518a2e5dc69ddd12f20685a94646e2.tar.gz
yuzu-4e9683e9d5518a2e5dc69ddd12f20685a94646e2.tar.bz2
yuzu-4e9683e9d5518a2e5dc69ddd12f20685a94646e2.tar.lz
yuzu-4e9683e9d5518a2e5dc69ddd12f20685a94646e2.tar.xz
yuzu-4e9683e9d5518a2e5dc69ddd12f20685a94646e2.tar.zst
yuzu-4e9683e9d5518a2e5dc69ddd12f20685a94646e2.zip
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp45
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h11
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 {
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;
}
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 {
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;