CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/GPU/Common/ReplacedTexture.h
Views: 1401
// Copyright (c) 2016- PPSSPP Project.12// This program is free software: you can redistribute it and/or modify3// it under the terms of the GNU General Public License as published by4// the Free Software Foundation, version 2.0 or later versions.56// This program is distributed in the hope that it will be useful,7// but WITHOUT ANY WARRANTY; without even the implied warranty of8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9// GNU General Public License 2.0 for more details.1011// A copy of the GPL 2.0 should have been included with the program.12// If not, see http://www.gnu.org/licenses/1314// Official git repository and contact information can be found at15// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.1617#pragma once1819#include <mutex>20#include <string>2122#include "Common/File/VFS/VFS.h"23#include "Common/GPU/thin3d.h"24#include "Common/Log.h"25#include "Core/ConfigValues.h"2627class TextureReplacer;28class LimitedWaitable;2930// These must match the constants in TextureCacheCommon.31enum class ReplacedTextureAlpha {32UNKNOWN = 0x04,33FULL = 0x00,34};3536// For forward compatibility, we specify the hash.37enum class ReplacedTextureHash {38QUICK,39XXH32,40XXH64,41};4243enum class ReplacedImageType {44PNG,45ZIM,46DDS,47BASIS, // TODO: Might not even do this, KTX2 is a better container.48KTX2,49INVALID,50};5152static const int MAX_REPLACEMENT_MIP_LEVELS = 12; // 12 should be plenty, 8 is the max mip levels supported by the PSP.5354enum class ReplacementState : uint32_t {55UNLOADED,56PENDING,57NOT_FOUND, // Also used on error loading the images.58ACTIVE,59CANCEL_INIT,60};6162const char *StateString(ReplacementState state);6364struct GPUFormatSupport {65bool bc123;66bool astc;67bool bc7;68bool etc2;69};7071struct ReplacementDesc {72int newW;73int newH;74uint64_t cachekey;75uint32_t hash;76int w;77int h;78TextureFiltering forceFiltering;79std::string hashfiles;80Path basePath;81std::vector<std::string> filenames;82std::string logId;83GPUFormatSupport formatSupport;84};8586class ReplacedTexture;8788// These aren't actually all replaced, they can also represent a placeholder for a not-found89// replacement (texture == nullptr).90struct ReplacedTextureRef {91ReplacedTexture *texture; // shortcut92std::string hashfiles; // key into the cache93};9495// Metadata about a given texture level.96struct ReplacedTextureLevel {97// Data dimensions98int w = 0;99int h = 0;100// PSP texture dimensions101int fullW = 0;102int fullH = 0;103104int fullDataSize = 0;105106// To be able to reload, we need to be able to reopen, unfortunate we can't use zip_file_t.107// TODO: This really belongs on the level in the cache, not in the individual ReplacedTextureLevel objects.108VFSFileReference *fileRef = nullptr;109};110111class ReplacedTexture {112public:113ReplacedTexture(VFSBackend *vfs, const ReplacementDesc &desc);114~ReplacedTexture();115116inline ReplacementState State() const {117return state_;118}119120void SetState(ReplacementState state) {121_dbg_assert_(state != state_);122#ifdef _DEBUG123// WARN_LOG(Log::G3D, "Texture %s changed state from %s to %s", logId_.c_str(), StateString(state_), StateString(state));124#endif125state_ = state;126}127128void GetSize(int level, int *w, int *h) const {129_dbg_assert_(State() == ReplacementState::ACTIVE);130_dbg_assert_((size_t)level < levels_.size());131*w = levels_[level].fullW;132*h = levels_[level].fullH;133}134135int GetLevelDataSizeAfterCopy(int level) const {136// Includes padding etc.137return levels_[level].fullDataSize;138}139140size_t GetTotalDataSize() const {141if (State() != ReplacementState::ACTIVE) {142return 0;143}144size_t sz = 0;145for (auto &data : data_) {146sz += data.size();147}148return sz;149}150151bool ForceFiltering(TextureFiltering *forceFiltering) const {152if (desc_.forceFiltering != (TextureFiltering)0) {153*forceFiltering = desc_.forceFiltering;154return true;155} else {156return false;157}158}159160int NumLevels() const {161_dbg_assert_(State() == ReplacementState::ACTIVE);162return (int)levels_.size();163}164165Draw::DataFormat Format() const {166_dbg_assert_(State() == ReplacementState::ACTIVE);167return fmt;168}169170u8 AlphaStatus() const {171return (u8)alphaStatus_;172}173174bool Poll(double budget);175bool CopyLevelTo(int level, uint8_t *out, size_t outDataSize, int rowPitch);176177std::string logId_;178179private:180enum class LoadLevelResult {181LOAD_ERROR = 0,182CONTINUE = 1,183DONE = 2,184};185186void Prepare(VFSBackend *vfs);187LoadLevelResult LoadLevelData(VFSFileReference *fileRef, const std::string &filename, int level, Draw::DataFormat *pixelFormat);188void PurgeIfNotUsedSinceTime(double t);189190std::vector<std::vector<uint8_t>> data_;191std::vector<ReplacedTextureLevel> levels_;192193double lastUsed_ = 0.0;194LimitedWaitable *threadWaitable_ = nullptr;195std::mutex lock_;196Draw::DataFormat fmt = Draw::DataFormat::UNDEFINED; // NOTE: Right now, the only supported format is Draw::DataFormat::R8G8B8A8_UNORM.197ReplacedTextureAlpha alphaStatus_ = ReplacedTextureAlpha::UNKNOWN;198double lastUsed = 0.0;199200std::atomic<ReplacementState> state_ = ReplacementState::UNLOADED;201202VFSBackend *vfs_ = nullptr;203ReplacementDesc desc_;204205friend class TextureReplacer;206friend class ReplacedTextureTask;207};208209210