gl_rasterizer_cache: Add a function for finding framebuffer GPU address.
This commit is contained in:
		@@ -560,6 +560,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& framebu
 | 
			
		||||
 | 
			
		||||
    SurfaceParams src_params;
 | 
			
		||||
    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.height = framebuffer.height;
 | 
			
		||||
    src_params.stride = pixel_stride;
 | 
			
		||||
 
 | 
			
		||||
@@ -954,6 +954,33 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params, ScaleMatc
 | 
			
		||||
    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,
 | 
			
		||||
                                                           ScaleMatch match_res_scale,
 | 
			
		||||
                                                           bool load_if_create) {
 | 
			
		||||
 
 | 
			
		||||
@@ -411,6 +411,9 @@ public:
 | 
			
		||||
    Surface GetSurface(const SurfaceParams& params, ScaleMatch match_res_scale,
 | 
			
		||||
                       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
 | 
			
		||||
    /// Switch memory to OpenGL and caches it (if not already cached)
 | 
			
		||||
    SurfaceRect_Tuple GetSurfaceSubRect(const SurfaceParams& params, ScaleMatch match_res_scale,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user