~ppsspp/ppsspp/ppsspp_1.3.0

« back to all changes in this revision

Viewing changes to GPU/Common/TextureCacheCommon.h

  • Committer: Sérgio Benjamim
  • Date: 2017-01-02 00:12:05 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20170102001205-cxbta9za203nmjwm
1.3.0 source (from ppsspp_1.3.0-r160.p5.l1762.a165.t83~56~ubuntu16.04.1.tar.xz).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2013- PPSSPP Project.
 
2
 
 
3
// This program is free software: you can redistribute it and/or modify
 
4
// it under the terms of the GNU General Public License as published by
 
5
// the Free Software Foundation, version 2.0 or later versions.
 
6
 
 
7
// This program is distributed in the hope that it will be useful,
 
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
// GNU General Public License 2.0 for more details.
 
11
 
 
12
// A copy of the GPL 2.0 should have been included with the program.
 
13
// If not, see http://www.gnu.org/licenses/
 
14
 
 
15
// Official git repository and contact information can be found at
 
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
 
17
 
 
18
#pragma once
 
19
 
 
20
#include <map>
 
21
#include <vector>
 
22
 
 
23
#include "Common/CommonTypes.h"
 
24
#include "Common/MemoryUtil.h"
 
25
#include "Core/TextureReplacer.h"
 
26
#include "GPU/Common/GPUDebugInterface.h"
 
27
 
 
28
enum TextureFiltering {
 
29
        TEX_FILTER_AUTO = 1,
 
30
        TEX_FILTER_NEAREST = 2,
 
31
        TEX_FILTER_LINEAR = 3,
 
32
        TEX_FILTER_LINEAR_VIDEO = 4,
 
33
};
 
34
 
 
35
enum FramebufferNotification {
 
36
        NOTIFY_FB_CREATED,
 
37
        NOTIFY_FB_UPDATED,
 
38
        NOTIFY_FB_DESTROYED,
 
39
};
 
40
 
 
41
struct VirtualFramebuffer;
 
42
 
 
43
class CachedTextureVulkan;
 
44
 
 
45
class TextureCacheCommon {
 
46
public:
 
47
        TextureCacheCommon();
 
48
        virtual ~TextureCacheCommon();
 
49
 
 
50
        void LoadClut(u32 clutAddr, u32 loadBytes);
 
51
        bool GetCurrentClutBuffer(GPUDebugBuffer &buffer);
 
52
 
 
53
        virtual bool SetOffsetTexture(u32 offset);
 
54
 
 
55
        // FramebufferManager keeps TextureCache updated about what regions of memory are being rendered to.
 
56
        void NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer, FramebufferNotification msg);
 
57
        void NotifyConfigChanged();
 
58
        void NotifyVideoUpload(u32 addr, int size, int width, GEBufferFormat fmt);
 
59
 
 
60
        int AttachedDrawingHeight();
 
61
 
 
62
        // Wow this is starting to grow big. Soon need to start looking at resizing it.
 
63
        // Must stay a POD.
 
64
        struct TexCacheEntry {
 
65
                // After marking STATUS_UNRELIABLE, if it stays the same this many frames we'll trust it again.
 
66
                const static int FRAMES_REGAIN_TRUST = 1000;
 
67
 
 
68
                enum Status {
 
69
                        STATUS_HASHING = 0x00,
 
70
                        STATUS_RELIABLE = 0x01,        // Don't bother rehashing.
 
71
                        STATUS_UNRELIABLE = 0x02,      // Always recheck hash.
 
72
                        STATUS_MASK = 0x03,
 
73
 
 
74
                        STATUS_ALPHA_UNKNOWN = 0x04,
 
75
                        STATUS_ALPHA_FULL = 0x00,      // Has no alpha channel, or always full alpha.
 
76
                        STATUS_ALPHA_SIMPLE = 0x08,    // Like above, but also has 0 alpha (e.g. 5551.)
 
77
                        STATUS_ALPHA_MASK = 0x0c,
 
78
 
 
79
                        STATUS_CHANGE_FREQUENT = 0x10, // Changes often (less than 6 frames in between.)
 
80
                        STATUS_CLUT_RECHECK = 0x20,    // Another texture with same addr had a hashfail.
 
81
                        STATUS_DEPALETTIZE = 0x40,     // Needs to go through a depalettize pass.
 
82
                        STATUS_TO_SCALE = 0x80,        // Pending texture scaling in a later frame.
 
83
                        STATUS_IS_SCALED = 0x100,      // Has been scaled (can't be replaceImages'd.)
 
84
                        STATUS_FREE_CHANGE = 0x200,    // Allow one change before marking "frequent".
 
85
                };
 
86
 
 
87
                // Status, but int so we can zero initialize.
 
88
                int status;
 
89
                u32 addr;
 
90
                u32 hash;
 
91
                VirtualFramebuffer *framebuffer;  // if null, not sourced from an FBO.
 
92
                u32 sizeInRAM;
 
93
                int lastFrame;
 
94
                int numFrames;
 
95
                int numInvalidated;
 
96
                u32 framesUntilNextFullHash;
 
97
                u8 format;
 
98
                u8 maxLevel;
 
99
                u16 dim;
 
100
                u16 bufw;
 
101
                union {
 
102
                        u32 textureName;
 
103
                        void *texturePtr;
 
104
                        CachedTextureVulkan *vkTex;
 
105
                };
 
106
                int invalidHint;
 
107
                u32 fullhash;
 
108
                u32 cluthash;
 
109
                float lodBias;
 
110
                u16 maxSeenV;
 
111
 
 
112
                // Cache the current filter settings so we can avoid setting it again.
 
113
                // (OpenGL madness where filter settings are attached to each texture. Unused in Vulkan).
 
114
                u8 magFilt;
 
115
                u8 minFilt;
 
116
                bool sClamp;
 
117
                bool tClamp;
 
118
 
 
119
                Status GetHashStatus() {
 
120
                        return Status(status & STATUS_MASK);
 
121
                }
 
122
                void SetHashStatus(Status newStatus) {
 
123
                        status = (status & ~STATUS_MASK) | newStatus;
 
124
                }
 
125
                Status GetAlphaStatus() {
 
126
                        return Status(status & STATUS_ALPHA_MASK);
 
127
                }
 
128
                void SetAlphaStatus(Status newStatus) {
 
129
                        status = (status & ~STATUS_ALPHA_MASK) | newStatus;
 
130
                }
 
131
                void SetAlphaStatus(Status newStatus, int level) {
 
132
                        // For non-level zero, only set more restrictive.
 
133
                        if (newStatus == STATUS_ALPHA_UNKNOWN || level == 0) {
 
134
                                SetAlphaStatus(newStatus);
 
135
                        } else if (newStatus == STATUS_ALPHA_SIMPLE && GetAlphaStatus() == STATUS_ALPHA_FULL) {
 
136
                                SetAlphaStatus(STATUS_ALPHA_SIMPLE);
 
137
                        }
 
138
                }
 
139
 
 
140
                bool Matches(u16 dim2, u8 format2, u8 maxLevel2) const;
 
141
                u64 CacheKey() const;
 
142
                static u64 CacheKey(u32 addr, u8 format, u16 dim, u32 cluthash);
 
143
        };
 
144
 
 
145
protected:
 
146
        // Can't be unordered_map, we use lower_bound ... although for some reason that compiles on MSVC.
 
147
        typedef std::map<u64, TexCacheEntry> TexCache;
 
148
 
 
149
        // Separate to keep main texture cache size down.
 
150
        struct AttachedFramebufferInfo {
 
151
                u32 xOffset;
 
152
                u32 yOffset;
 
153
        };
 
154
 
 
155
        bool DecodeTextureLevel(u8 *out, int outPitch, GETextureFormat format, GEPaletteFormat clutformat, uint32_t texaddr, int level, int bufw, bool reverseColors, bool useBGRA = false);
 
156
        void UnswizzleFromMem(u32 *dest, u32 destPitch, const u8 *texptr, u32 bufw, u32 height, u32 bytesPerPixel);
 
157
        bool ReadIndexedTex(u8 *out, int outPitch, int level, const u8 *texptr, int bytesPerIndex, int bufw);
 
158
 
 
159
        template <typename T>
 
160
        inline const T *GetCurrentClut() {
 
161
                return (const T *)clutBuf_;
 
162
        }
 
163
 
 
164
        u32 EstimateTexMemoryUsage(const TexCacheEntry *entry);
 
165
        void GetSamplingParams(int &minFilt, int &magFilt, bool &sClamp, bool &tClamp, float &lodBias, u8 maxLevel, u32 addr);
 
166
        void UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode);
 
167
 
 
168
        virtual bool AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset = 0) = 0;
 
169
        void AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo);
 
170
        void AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo);
 
171
        void DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer);
 
172
 
 
173
        virtual void DownloadFramebufferForClut(u32 clutAddr, u32 bytes) = 0;
 
174
 
 
175
        void DecimateVideos();
 
176
 
 
177
        TextureReplacer replacer;
 
178
 
 
179
        TexCache cache;
 
180
        u32 cacheSizeEstimate_;
 
181
 
 
182
        std::vector<VirtualFramebuffer *> fbCache_;
 
183
        std::map<u64, AttachedFramebufferInfo> fbTexInfo_;
 
184
 
 
185
        std::map<u32, int> videos_;
 
186
 
 
187
        SimpleBuf<u32> tmpTexBuf32;
 
188
        SimpleBuf<u16> tmpTexBuf16;
 
189
        SimpleBuf<u32> tmpTexBufRearrange;
 
190
 
 
191
        TexCacheEntry *nextTexture_;
 
192
 
 
193
        // Raw is where we keep the original bytes.  Converted is where we swap colors if necessary.
 
194
        u32 *clutBufRaw_;
 
195
        u32 *clutBufConverted_;
 
196
        // This is the active one.
 
197
        u32 *clutBuf_;
 
198
        u32 clutLastFormat_;
 
199
        u32 clutTotalBytes_;
 
200
        u32 clutMaxBytes_;
 
201
        u32 clutRenderAddress_;
 
202
        u32 clutRenderOffset_;
 
203
        // True if the clut is just alpha values in the same order (RGBA4444-bit only.)
 
204
        bool clutAlphaLinear_;
 
205
        u16 clutAlphaLinearColor_;
 
206
 
 
207
        int standardScaleFactor_;
 
208
};
 
209
 
 
210
inline bool TextureCacheCommon::TexCacheEntry::Matches(u16 dim2, u8 format2, u8 maxLevel2) const {
 
211
        return dim == dim2 && format == format2 && maxLevel == maxLevel2;
 
212
}
 
213
 
 
214
inline u64 TextureCacheCommon::TexCacheEntry::CacheKey() const {
 
215
        return CacheKey(addr, format, dim, cluthash);
 
216
}
 
217
 
 
218
inline u64 TextureCacheCommon::TexCacheEntry::CacheKey(u32 addr, u8 format, u16 dim, u32 cluthash) {
 
219
        u64 cachekey = ((u64)(addr & 0x3FFFFFFF) << 32) | dim;
 
220
        bool hasClut = (format & 4) != 0;
 
221
        if (hasClut) {
 
222
                cachekey ^= cluthash;
 
223
        }
 
224
        return cachekey;
 
225
}