summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/gl_texture_cache.h
blob: 7787134fc6f1be6f46d23291d5530b5965ff48c9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Copyright 2019 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#pragma once

#include <array>
#include <functional>
#include <memory>
#include <unordered_map>
#include <utility>
#include <vector>

#include <glad/glad.h>

#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
#include "video_core/renderer_opengl/gl_device.h"
#include "video_core/renderer_opengl/gl_resource_manager.h"
#include "video_core/texture_cache/texture_cache.h"

namespace OpenGL {

using VideoCommon::SurfaceParams;
using VideoCommon::ViewParams;

class CachedSurfaceView;
class CachedSurface;
class TextureCacheOpenGL;
class StateTracker;

using Surface = std::shared_ptr<CachedSurface>;
using View = std::shared_ptr<CachedSurfaceView>;
using TextureCacheBase = VideoCommon::TextureCache<Surface, View>;

class CachedSurface final : public VideoCommon::SurfaceBase<View> {
    friend CachedSurfaceView;

public:
    explicit CachedSurface(GPUVAddr gpu_addr, const SurfaceParams& params, bool is_astc_supported);
    ~CachedSurface();

    void UploadTexture(const std::vector<u8>& staging_buffer) override;
    void DownloadTexture(std::vector<u8>& staging_buffer) override;

    GLenum GetTarget() const {
        return target;
    }

    GLuint GetTexture() const {
        return texture.handle;
    }

    bool IsCompressed() const {
        return is_compressed;
    }

protected:
    void DecorateSurfaceName() override;

    View CreateView(const ViewParams& view_key) override;
    View CreateViewInner(const ViewParams& view_key, bool is_proxy);

private:
    void UploadTextureMipmap(u32 level, const std::vector<u8>& staging_buffer);

    GLenum internal_format{};
    GLenum format{};
    GLenum type{};
    bool is_compressed{};
    GLenum target{};
    u32 view_count{};

    OGLTexture texture;
    OGLBuffer texture_buffer;
};

class CachedSurfaceView final : public VideoCommon::ViewBase {
public:
    explicit CachedSurfaceView(CachedSurface& surface, const ViewParams& params, bool is_proxy);
    ~CachedSurfaceView();

    /// @brief Attaches this texture view to the currently bound fb_target framebuffer
    /// @param attachment   Attachment to bind textures to
    /// @param fb_target    Framebuffer target to attach to (e.g. DRAW_FRAMEBUFFER)
    void Attach(GLenum attachment, GLenum fb_target) const;

    GLuint GetTexture(Tegra::Texture::SwizzleSource x_source,
                      Tegra::Texture::SwizzleSource y_source,
                      Tegra::Texture::SwizzleSource z_source,
                      Tegra::Texture::SwizzleSource w_source);

    void DecorateViewName(GPUVAddr gpu_addr, const std::string& prefix);

    void MarkAsModified(u64 tick) {
        surface.MarkAsModified(true, tick);
    }

    GLuint GetTexture() const {
        if (is_proxy) {
            return surface.GetTexture();
        }
        return main_view.handle;
    }

    GLenum GetFormat() const {
        return format;
    }

    const SurfaceParams& GetSurfaceParams() const {
        return surface.GetSurfaceParams();
    }

private:
    OGLTextureView CreateTextureView() const;

    CachedSurface& surface;
    const GLenum format;
    const GLenum target;
    const bool is_proxy;

    std::unordered_map<u32, OGLTextureView> view_cache;
    OGLTextureView main_view;

    // Use an invalid default so it always fails the comparison test
    u32 current_swizzle = 0xffffffff;
    GLuint current_view = 0;
};

class TextureCacheOpenGL final : public TextureCacheBase {
public:
    explicit TextureCacheOpenGL(VideoCore::RasterizerInterface& rasterizer,
                                Tegra::Engines::Maxwell3D& maxwell3d,
                                Tegra::MemoryManager& gpu_memory, const Device& device,
                                StateTracker& state_tracker);
    ~TextureCacheOpenGL();

protected:
    Surface CreateSurface(GPUVAddr gpu_addr, const SurfaceParams& params) override;

    void ImageCopy(Surface& src_surface, Surface& dst_surface,
                   const VideoCommon::CopyParams& copy_params) override;

    void ImageBlit(View& src_view, View& dst_view,
                   const Tegra::Engines::Fermi2D::Config& copy_config) override;

    void BufferCopy(Surface& src_surface, Surface& dst_surface) override;

private:
    GLuint FetchPBO(std::size_t buffer_size);

    StateTracker& state_tracker;

    OGLFramebuffer src_framebuffer;
    OGLFramebuffer dst_framebuffer;
    std::unordered_map<u32, OGLBuffer> copy_pbo_cache;
};

} // namespace OpenGL