mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	gl_rasterizer_cache: Keep track of texture type per surface.
This commit is contained in:
		
							parent
							
								
									a439f7b6e1
								
							
						
					
					
						commit
						030676b95d
					
				@ -700,6 +700,7 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader,
 | 
			
		||||
        Surface surface = res_cache.GetTextureSurface(texture);
 | 
			
		||||
        if (surface != nullptr) {
 | 
			
		||||
            state.texture_units[current_bindpoint].texture = surface->Texture().handle;
 | 
			
		||||
            state.texture_units[current_bindpoint].target = surface->Target();
 | 
			
		||||
            state.texture_units[current_bindpoint].swizzle.r =
 | 
			
		||||
                MaxwellToGL::SwizzleSource(texture.tic.x_source);
 | 
			
		||||
            state.texture_units[current_bindpoint].swizzle.g =
 | 
			
		||||
 | 
			
		||||
@ -55,6 +55,7 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
 | 
			
		||||
    params.size_in_bytes = params.SizeInBytes();
 | 
			
		||||
    params.cache_width = Common::AlignUp(params.width, 16);
 | 
			
		||||
    params.cache_height = Common::AlignUp(params.height, 16);
 | 
			
		||||
    params.target = SurfaceTargetFromTextureType(config.tic.texture_type);
 | 
			
		||||
    return params;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -73,6 +74,7 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
 | 
			
		||||
    params.size_in_bytes = params.SizeInBytes();
 | 
			
		||||
    params.cache_width = Common::AlignUp(params.width, 16);
 | 
			
		||||
    params.cache_height = Common::AlignUp(params.height, 16);
 | 
			
		||||
    params.target = SurfaceTarget::Texture2D;
 | 
			
		||||
    return params;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -93,6 +95,7 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
 | 
			
		||||
    params.size_in_bytes = params.SizeInBytes();
 | 
			
		||||
    params.cache_width = Common::AlignUp(params.width, 16);
 | 
			
		||||
    params.cache_height = Common::AlignUp(params.height, 16);
 | 
			
		||||
    params.target = SurfaceTarget::Texture2D;
 | 
			
		||||
    return params;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -166,6 +169,26 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form
 | 
			
		||||
     ComponentType::Float, false}, // Z32FS8
 | 
			
		||||
}};
 | 
			
		||||
 | 
			
		||||
static GLenum SurfaceTargetToGL(SurfaceParams::SurfaceTarget target) {
 | 
			
		||||
    switch (target) {
 | 
			
		||||
    case SurfaceParams::SurfaceTarget::Texture1D:
 | 
			
		||||
        return GL_TEXTURE_1D;
 | 
			
		||||
    case SurfaceParams::SurfaceTarget::Texture2D:
 | 
			
		||||
        return GL_TEXTURE_2D;
 | 
			
		||||
    case SurfaceParams::SurfaceTarget::Texture3D:
 | 
			
		||||
        return GL_TEXTURE_3D;
 | 
			
		||||
    case SurfaceParams::SurfaceTarget::Texture1DArray:
 | 
			
		||||
        return GL_TEXTURE_1D_ARRAY;
 | 
			
		||||
    case SurfaceParams::SurfaceTarget::Texture2DArray:
 | 
			
		||||
        return GL_TEXTURE_2D_ARRAY;
 | 
			
		||||
    case SurfaceParams::SurfaceTarget::TextureCubemap:
 | 
			
		||||
        return GL_TEXTURE_CUBE_MAP;
 | 
			
		||||
    }
 | 
			
		||||
    LOG_CRITICAL(Render_OpenGL, "Unimplemented texture target={}", static_cast<u32>(target));
 | 
			
		||||
    UNREACHABLE();
 | 
			
		||||
    return {};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) {
 | 
			
		||||
    ASSERT(static_cast<size_t>(pixel_format) < tex_format_tuples.size());
 | 
			
		||||
    auto& format = tex_format_tuples[static_cast<unsigned int>(pixel_format)];
 | 
			
		||||
@ -357,33 +380,6 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, VAddr),
 | 
			
		||||
        // clang-format on
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Allocate an uninitialized texture of appropriate size and format for the surface
 | 
			
		||||
static void AllocateSurfaceTexture(GLuint texture, const FormatTuple& format_tuple, u32 width,
 | 
			
		||||
                                   u32 height) {
 | 
			
		||||
    OpenGLState cur_state = OpenGLState::GetCurState();
 | 
			
		||||
 | 
			
		||||
    // Keep track of previous texture bindings
 | 
			
		||||
    GLuint old_tex = cur_state.texture_units[0].texture;
 | 
			
		||||
    cur_state.texture_units[0].texture = texture;
 | 
			
		||||
    cur_state.Apply();
 | 
			
		||||
    glActiveTexture(GL_TEXTURE0);
 | 
			
		||||
 | 
			
		||||
    if (!format_tuple.compressed) {
 | 
			
		||||
        // Only pre-create the texture for non-compressed textures.
 | 
			
		||||
        glTexImage2D(GL_TEXTURE_2D, 0, format_tuple.internal_format, width, height, 0,
 | 
			
		||||
                     format_tuple.format, format_tuple.type, nullptr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
 | 
			
		||||
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 | 
			
		||||
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 | 
			
		||||
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 | 
			
		||||
 | 
			
		||||
    // Restore previous texture bindings
 | 
			
		||||
    cur_state.texture_units[0].texture = old_tex;
 | 
			
		||||
    cur_state.Apply();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool BlitTextures(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rect, GLuint dst_tex,
 | 
			
		||||
                         const MathUtil::Rectangle<u32>& dst_rect, SurfaceType type,
 | 
			
		||||
                         GLuint read_fb_handle, GLuint draw_fb_handle) {
 | 
			
		||||
@ -438,12 +434,34 @@ static bool BlitTextures(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rec
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CachedSurface::CachedSurface(const SurfaceParams& params) : params(params) {
 | 
			
		||||
CachedSurface::CachedSurface(const SurfaceParams& params)
 | 
			
		||||
    : params(params), gl_target(SurfaceTargetToGL(params.target)) {
 | 
			
		||||
    texture.Create();
 | 
			
		||||
    const auto& rect{params.GetRect()};
 | 
			
		||||
    AllocateSurfaceTexture(texture.handle,
 | 
			
		||||
                           GetFormatTuple(params.pixel_format, params.component_type),
 | 
			
		||||
                           rect.GetWidth(), rect.GetHeight());
 | 
			
		||||
 | 
			
		||||
    OpenGLState cur_state = OpenGLState::GetCurState();
 | 
			
		||||
 | 
			
		||||
    // Keep track of previous texture bindings
 | 
			
		||||
    GLuint old_tex = cur_state.texture_units[0].texture;
 | 
			
		||||
    cur_state.texture_units[0].texture = texture.handle;
 | 
			
		||||
    cur_state.Apply();
 | 
			
		||||
    glActiveTexture(GL_TEXTURE0);
 | 
			
		||||
 | 
			
		||||
    const auto& format_tuple = GetFormatTuple(params.pixel_format, params.component_type);
 | 
			
		||||
    if (!format_tuple.compressed) {
 | 
			
		||||
        // Only pre-create the texture for non-compressed textures.
 | 
			
		||||
        glTexImage2D(GL_TEXTURE_2D, 0, format_tuple.internal_format, rect.GetWidth(),
 | 
			
		||||
                     rect.GetHeight(), 0, format_tuple.format, format_tuple.type, nullptr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MAX_LEVEL, 0);
 | 
			
		||||
    glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 | 
			
		||||
    glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 | 
			
		||||
    glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 | 
			
		||||
 | 
			
		||||
    // Restore previous texture bindings
 | 
			
		||||
    cur_state.texture_units[0].texture = old_tex;
 | 
			
		||||
    cur_state.Apply();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height) {
 | 
			
		||||
 | 
			
		||||
@ -109,6 +109,33 @@ struct SurfaceParams {
 | 
			
		||||
        Invalid = 4,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum class SurfaceTarget {
 | 
			
		||||
        Texture1D,
 | 
			
		||||
        Texture2D,
 | 
			
		||||
        Texture3D,
 | 
			
		||||
        Texture1DArray,
 | 
			
		||||
        Texture2DArray,
 | 
			
		||||
        TextureCubemap,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_type) {
 | 
			
		||||
        switch (texture_type) {
 | 
			
		||||
        case Tegra::Texture::TextureType::Texture1D:
 | 
			
		||||
            return SurfaceTarget::Texture1D;
 | 
			
		||||
        case Tegra::Texture::TextureType::Texture2D:
 | 
			
		||||
        case Tegra::Texture::TextureType::Texture2DNoMipmap:
 | 
			
		||||
            return SurfaceTarget::Texture2D;
 | 
			
		||||
        case Tegra::Texture::TextureType::Texture1DArray:
 | 
			
		||||
            return SurfaceTarget::Texture1DArray;
 | 
			
		||||
        case Tegra::Texture::TextureType::Texture2DArray:
 | 
			
		||||
            return SurfaceTarget::Texture2DArray;
 | 
			
		||||
        default:
 | 
			
		||||
            LOG_CRITICAL(HW_GPU, "Unimplemented texture_type={}", static_cast<u32>(texture_type));
 | 
			
		||||
            UNREACHABLE();
 | 
			
		||||
            return SurfaceTarget::Texture2D;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the compression factor for the specified PixelFormat. This applies to just the
 | 
			
		||||
     * "compressed width" and "compressed height", not the overall compression factor of a
 | 
			
		||||
@ -666,6 +693,7 @@ struct SurfaceParams {
 | 
			
		||||
    u32 height;
 | 
			
		||||
    u32 unaligned_height;
 | 
			
		||||
    size_t size_in_bytes;
 | 
			
		||||
    SurfaceTarget target;
 | 
			
		||||
 | 
			
		||||
    // Parameters used for caching only
 | 
			
		||||
    u32 cache_width;
 | 
			
		||||
@ -709,6 +737,10 @@ public:
 | 
			
		||||
        return texture;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    GLenum Target() const {
 | 
			
		||||
        return gl_target;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static constexpr unsigned int GetGLBytesPerPixel(SurfaceParams::PixelFormat format) {
 | 
			
		||||
        if (format == SurfaceParams::PixelFormat::Invalid)
 | 
			
		||||
            return 0;
 | 
			
		||||
@ -724,13 +756,14 @@ public:
 | 
			
		||||
    void LoadGLBuffer();
 | 
			
		||||
    void FlushGLBuffer();
 | 
			
		||||
 | 
			
		||||
    // Upload/Download data in gl_buffer in/to this surface's texture
 | 
			
		||||
    // Upload data in gl_buffer to this surface's texture
 | 
			
		||||
    void UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    OGLTexture texture;
 | 
			
		||||
    std::vector<u8> gl_buffer;
 | 
			
		||||
    SurfaceParams params;
 | 
			
		||||
    GLenum gl_target;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class RasterizerCacheOpenGL final : public RasterizerCache<Surface> {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user