mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-11-04 12:34:39 +08:00 
			
		
		
		
	gl_rasterizer_cache: Implement GetFramebufferSurfaces.
This commit is contained in:
		
							parent
							
								
									94c70693f9
								
							
						
					
					
						commit
						170ac3f9ee
					
				@ -21,10 +21,13 @@
 | 
			
		||||
#include "common/microprofile.h"
 | 
			
		||||
#include "common/scope_exit.h"
 | 
			
		||||
#include "common/vector_math.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/frontend/emu_window.h"
 | 
			
		||||
#include "core/hle/kernel/process.h"
 | 
			
		||||
#include "core/hle/kernel/vm_manager.h"
 | 
			
		||||
#include "core/memory.h"
 | 
			
		||||
#include "core/settings.h"
 | 
			
		||||
#include "video_core/engines/maxwell_3d.h"
 | 
			
		||||
#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
 | 
			
		||||
#include "video_core/renderer_opengl/gl_state.h"
 | 
			
		||||
#include "video_core/utils.h"
 | 
			
		||||
@ -1098,9 +1101,97 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const void* config) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(
 | 
			
		||||
    bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle<s32>& viewport_rect) {
 | 
			
		||||
    UNIMPLEMENTED();
 | 
			
		||||
    return {};
 | 
			
		||||
    bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle<s32>& viewport) {
 | 
			
		||||
    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
 | 
			
		||||
    const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager;
 | 
			
		||||
    const auto& config = regs.rt[0];
 | 
			
		||||
 | 
			
		||||
    // TODO(bunnei): This is hard corded to use just the first render buffer
 | 
			
		||||
    LOG_WARNING(Render_OpenGL, "hard-coded for render target 0!");
 | 
			
		||||
 | 
			
		||||
    // update resolution_scale_factor and reset cache if changed
 | 
			
		||||
    // TODO (bunnei): This code was ported as-is from Citra, and is technically not thread-safe. We
 | 
			
		||||
    // need to fix this before making the renderer multi-threaded.
 | 
			
		||||
    static u16 resolution_scale_factor = GetResolutionScaleFactor();
 | 
			
		||||
    if (resolution_scale_factor != GetResolutionScaleFactor()) {
 | 
			
		||||
        resolution_scale_factor = GetResolutionScaleFactor();
 | 
			
		||||
        FlushAll();
 | 
			
		||||
        while (!surface_cache.empty())
 | 
			
		||||
            UnregisterSurface(*surface_cache.begin()->second.begin());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MathUtil::Rectangle<u32> viewport_clamped{
 | 
			
		||||
        static_cast<u32>(MathUtil::Clamp(viewport.left, 0, static_cast<s32>(config.width))),
 | 
			
		||||
        static_cast<u32>(MathUtil::Clamp(viewport.top, 0, static_cast<s32>(config.height))),
 | 
			
		||||
        static_cast<u32>(MathUtil::Clamp(viewport.right, 0, static_cast<s32>(config.width))),
 | 
			
		||||
        static_cast<u32>(MathUtil::Clamp(viewport.bottom, 0, static_cast<s32>(config.height)))};
 | 
			
		||||
 | 
			
		||||
    // get color and depth surfaces
 | 
			
		||||
    SurfaceParams color_params;
 | 
			
		||||
    color_params.is_tiled = true;
 | 
			
		||||
    color_params.res_scale = resolution_scale_factor;
 | 
			
		||||
    color_params.width = config.width;
 | 
			
		||||
    color_params.height = config.height;
 | 
			
		||||
    SurfaceParams depth_params = color_params;
 | 
			
		||||
 | 
			
		||||
    color_params.addr = memory_manager->PhysicalToVirtualAddress(config.Address());
 | 
			
		||||
    color_params.pixel_format = SurfaceParams::PixelFormatFromRenderTargetFormat(config.format);
 | 
			
		||||
    color_params.UpdateParams();
 | 
			
		||||
 | 
			
		||||
    ASSERT(!using_depth_fb, "depth buffer is unimplemented");
 | 
			
		||||
    // depth_params.addr = config.GetDepthBufferPhysicalAddress();
 | 
			
		||||
    // depth_params.pixel_format = SurfaceParams::PixelFormatFromDepthFormat(config.depth_format);
 | 
			
		||||
    // depth_params.UpdateParams();
 | 
			
		||||
 | 
			
		||||
    auto color_vp_interval = color_params.GetSubRectInterval(viewport_clamped);
 | 
			
		||||
    auto depth_vp_interval = depth_params.GetSubRectInterval(viewport_clamped);
 | 
			
		||||
 | 
			
		||||
    // Make sure that framebuffers don't overlap if both color and depth are being used
 | 
			
		||||
    if (using_color_fb && using_depth_fb &&
 | 
			
		||||
        boost::icl::length(color_vp_interval & depth_vp_interval)) {
 | 
			
		||||
        LOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer memory regions overlap; "
 | 
			
		||||
                                    "overlapping framebuffers not supported!");
 | 
			
		||||
        using_depth_fb = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MathUtil::Rectangle<u32> color_rect{};
 | 
			
		||||
    Surface color_surface = nullptr;
 | 
			
		||||
    if (using_color_fb)
 | 
			
		||||
        std::tie(color_surface, color_rect) =
 | 
			
		||||
            GetSurfaceSubRect(color_params, ScaleMatch::Exact, false);
 | 
			
		||||
 | 
			
		||||
    MathUtil::Rectangle<u32> depth_rect{};
 | 
			
		||||
    Surface depth_surface = nullptr;
 | 
			
		||||
    if (using_depth_fb)
 | 
			
		||||
        std::tie(depth_surface, depth_rect) =
 | 
			
		||||
            GetSurfaceSubRect(depth_params, ScaleMatch::Exact, false);
 | 
			
		||||
 | 
			
		||||
    MathUtil::Rectangle<u32> fb_rect{};
 | 
			
		||||
    if (color_surface != nullptr && depth_surface != nullptr) {
 | 
			
		||||
        fb_rect = color_rect;
 | 
			
		||||
        // Color and Depth surfaces must have the same dimensions and offsets
 | 
			
		||||
        if (color_rect.bottom != depth_rect.bottom || color_rect.top != depth_rect.top ||
 | 
			
		||||
            color_rect.left != depth_rect.left || color_rect.right != depth_rect.right) {
 | 
			
		||||
            color_surface = GetSurface(color_params, ScaleMatch::Exact, false);
 | 
			
		||||
            depth_surface = GetSurface(depth_params, ScaleMatch::Exact, false);
 | 
			
		||||
            fb_rect = color_surface->GetScaledRect();
 | 
			
		||||
        }
 | 
			
		||||
    } else if (color_surface != nullptr) {
 | 
			
		||||
        fb_rect = color_rect;
 | 
			
		||||
    } else if (depth_surface != nullptr) {
 | 
			
		||||
        fb_rect = depth_rect;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (color_surface != nullptr) {
 | 
			
		||||
        ValidateSurface(color_surface, boost::icl::first(color_vp_interval),
 | 
			
		||||
                        boost::icl::length(color_vp_interval));
 | 
			
		||||
    }
 | 
			
		||||
    if (depth_surface != nullptr) {
 | 
			
		||||
        ValidateSurface(depth_surface, boost::icl::first(depth_vp_interval),
 | 
			
		||||
                        boost::icl::length(depth_vp_interval));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return std::make_tuple(color_surface, depth_surface, fb_rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Surface RasterizerCacheOpenGL::GetFillSurface(const void* config) {
 | 
			
		||||
 | 
			
		||||
@ -116,6 +116,15 @@ struct SurfaceParams {
 | 
			
		||||
        return GetFormatBpp(pixel_format);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) {
 | 
			
		||||
        switch (format) {
 | 
			
		||||
        case Tegra::RenderTargetFormat::RGBA8_UNORM:
 | 
			
		||||
            return PixelFormat::RGBA8;
 | 
			
		||||
        default:
 | 
			
		||||
            UNREACHABLE();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) {
 | 
			
		||||
        switch (format) {
 | 
			
		||||
        case Tegra::FramebufferConfig::PixelFormat::ABGR8:
 | 
			
		||||
@ -308,7 +317,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    /// Get the color and depth surfaces based on the framebuffer configuration
 | 
			
		||||
    SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb,
 | 
			
		||||
                                                    const MathUtil::Rectangle<s32>& viewport_rect);
 | 
			
		||||
                                                    const MathUtil::Rectangle<s32>& viewport);
 | 
			
		||||
 | 
			
		||||
    /// Get a surface that matches the fill config
 | 
			
		||||
    Surface GetFillSurface(const void* config);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user