mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-24 20:36:24 -05:00
gl_rasterizer_cache: Add a function for finding framebuffer GPU address.
This commit is contained in:
parent
bc0f1896fc
commit
fbb3cd110c
3 changed files with 31 additions and 0 deletions
|
@ -560,6 +560,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& framebu
|
||||||
|
|
||||||
SurfaceParams src_params;
|
SurfaceParams src_params;
|
||||||
src_params.cpu_addr = framebuffer_addr;
|
src_params.cpu_addr = framebuffer_addr;
|
||||||
|
src_params.addr = res_cache.TryFindFramebufferGpuAddress(framebuffer_addr).get_value_or(0);
|
||||||
src_params.width = std::min(framebuffer.width, pixel_stride);
|
src_params.width = std::min(framebuffer.width, pixel_stride);
|
||||||
src_params.height = framebuffer.height;
|
src_params.height = framebuffer.height;
|
||||||
src_params.stride = pixel_stride;
|
src_params.stride = pixel_stride;
|
||||||
|
|
|
@ -954,6 +954,33 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params, ScaleMatc
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<Tegra::GPUVAddr> RasterizerCacheOpenGL::TryFindFramebufferGpuAddress(
|
||||||
|
VAddr cpu_addr) const {
|
||||||
|
// Tries to find the GPU address of a framebuffer based on the CPU address. This is because
|
||||||
|
// final output framebuffers are specified by CPU address, but internally our GPU cache uses GPU
|
||||||
|
// addresses. We iterate through all cached framebuffers, and compare their starting CPU address
|
||||||
|
// to the one provided. This is obviously not great, and won't work if the framebuffer overlaps
|
||||||
|
// surfaces.
|
||||||
|
|
||||||
|
std::vector<Tegra::GPUVAddr> gpu_addresses;
|
||||||
|
for (const auto& pair : surface_cache) {
|
||||||
|
for (const auto& surface : pair.second) {
|
||||||
|
const VAddr surface_cpu_addr = surface->GetCpuAddr();
|
||||||
|
if (cpu_addr >= surface_cpu_addr && cpu_addr < (surface_cpu_addr + surface->size)) {
|
||||||
|
ASSERT_MSG(cpu_addr == surface_cpu_addr, "overlapping surfaces are unsupported");
|
||||||
|
gpu_addresses.push_back(surface->addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gpu_addresses.empty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_MSG(gpu_addresses.size() == 1, ">1 surface is unsupported");
|
||||||
|
return gpu_addresses[0];
|
||||||
|
}
|
||||||
|
|
||||||
SurfaceRect_Tuple RasterizerCacheOpenGL::GetSurfaceSubRect(const SurfaceParams& params,
|
SurfaceRect_Tuple RasterizerCacheOpenGL::GetSurfaceSubRect(const SurfaceParams& params,
|
||||||
ScaleMatch match_res_scale,
|
ScaleMatch match_res_scale,
|
||||||
bool load_if_create) {
|
bool load_if_create) {
|
||||||
|
|
|
@ -411,6 +411,9 @@ public:
|
||||||
Surface GetSurface(const SurfaceParams& params, ScaleMatch match_res_scale,
|
Surface GetSurface(const SurfaceParams& params, ScaleMatch match_res_scale,
|
||||||
bool load_if_create);
|
bool load_if_create);
|
||||||
|
|
||||||
|
/// Tries to find a framebuffer GPU address based on the provided CPU address
|
||||||
|
boost::optional<Tegra::GPUVAddr> TryFindFramebufferGpuAddress(VAddr cpu_addr) const;
|
||||||
|
|
||||||
/// Attempt to find a subrect (resolution scaled) of a surface, otherwise loads a texture from
|
/// Attempt to find a subrect (resolution scaled) of a surface, otherwise loads a texture from
|
||||||
/// Switch memory to OpenGL and caches it (if not already cached)
|
/// Switch memory to OpenGL and caches it (if not already cached)
|
||||||
SurfaceRect_Tuple GetSurfaceSubRect(const SurfaceParams& params, ScaleMatch match_res_scale,
|
SurfaceRect_Tuple GetSurfaceSubRect(const SurfaceParams& params, ScaleMatch match_res_scale,
|
||||||
|
|
Loading…
Reference in a new issue