1
// Copyright (c) 2014- PPSSPP Project.
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.
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.
12
// A copy of the GPL 2.0 should have been included with the program.
13
// If not, see http://www.gnu.org/licenses/
15
// Official git repository and contact information can be found at
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
20
#include "base/logging.h"
21
#include "Common/Log.h"
22
#include "Core/Reporting.h"
23
#include "GPU/Directx9/TextureCacheDX9.h"
24
#include "GPU/Directx9/DepalettizeShaderDX9.h"
25
#include "GPU/Common/DepalettizeShaderCommon.h"
26
#include "GPU/Directx9/helper/global.h"
30
static const int DEPAL_TEXTURE_OLD_AGE = 120;
36
static const char *depalVShaderHLSL =
38
" float3 a_position : POSITION;\n"
39
" float2 a_texcoord0 : TEXCOORD0;\n"
42
" float4 Position : POSITION;\n"
43
" float2 Texcoord : TEXCOORD0;\n"
45
"VS_OUT main(VS_IN input) {\n"
47
" output.Texcoord = input.a_texcoord0;\n"
48
" output.Position = float4(input.a_position, 1.0);\n"
52
DepalShaderCacheDX9::DepalShaderCacheDX9() : vertexShader_(nullptr) {
53
std::string errorMessage;
54
if (!DX9::CompileVertexShader(depalVShaderHLSL, &vertexShader_, nullptr, errorMessage)) {
55
ERROR_LOG(G3D, "error compling depal vshader: %s", errorMessage.c_str());
59
DepalShaderCacheDX9::~DepalShaderCacheDX9() {
62
vertexShader_->Release();
66
u32 DepalShaderCacheDX9::GenerateShaderID(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat) {
67
return (clutFormat & 0xFFFFFF) | (pixelFormat << 24);
70
LPDIRECT3DTEXTURE9 DepalShaderCacheDX9::GetClutTexture(GEPaletteFormat clutFormat, const u32 clutID, u32 *rawClut) {
71
const u32 realClutID = clutID ^ clutFormat;
73
auto oldtex = texCache_.find(realClutID);
74
if (oldtex != texCache_.end()) {
75
oldtex->second->lastFrame = gpuStats.numFlips;
76
return oldtex->second->texture;
79
D3DFORMAT dstFmt = DX9::getClutDestFormat(clutFormat);
80
int texturePixels = clutFormat == GE_CMODE_32BIT_ABGR8888 ? 256 : 512;
82
DepalTextureDX9 *tex = new DepalTextureDX9();
85
D3DPOOL pool = D3DPOOL_MANAGED;
88
pool = D3DPOOL_DEFAULT;
89
usage = D3DUSAGE_DYNAMIC; // TODO: Switch to using a staging texture?
92
HRESULT hr = pD3Ddevice->CreateTexture(texturePixels, 1, 1, usage, (D3DFORMAT)D3DFMT(dstFmt), pool, &tex->texture, NULL);
94
ERROR_LOG(G3D, "Failed to create D3D texture for depal");
100
hr = tex->texture->LockRect(0, &rect, NULL, 0);
102
ERROR_LOG(G3D, "Failed to lock D3D texture for depal");
106
// Regardless of format, the CLUT should always be 1024 bytes.
107
memcpy(rect.pBits, rawClut, 1024);
108
tex->texture->UnlockRect(0);
110
pD3Ddevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
111
pD3Ddevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
112
pD3Ddevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_POINT);
113
pD3Ddevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
115
tex->lastFrame = gpuStats.numFlips;
116
texCache_[realClutID] = tex;
120
void DepalShaderCacheDX9::Clear() {
121
for (auto shader = cache_.begin(); shader != cache_.end(); ++shader) {
122
shader->second->pixelShader->Release();
123
delete shader->second;
126
for (auto tex = texCache_.begin(); tex != texCache_.end(); ++tex) {
127
tex->second->texture->Release();
133
void DepalShaderCacheDX9::Decimate() {
134
for (auto tex = texCache_.begin(); tex != texCache_.end();) {
135
if (tex->second->lastFrame + DEPAL_TEXTURE_OLD_AGE < gpuStats.numFlips) {
136
tex->second->texture->Release();
138
texCache_.erase(tex++);
145
LPDIRECT3DPIXELSHADER9 DepalShaderCacheDX9::GetDepalettizePixelShader(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat) {
146
u32 id = GenerateShaderID(clutFormat, pixelFormat);
148
auto shader = cache_.find(id);
149
if (shader != cache_.end()) {
150
return shader->second->pixelShader;
153
char *buffer = new char[2048];
155
GenerateDepalShader(buffer, pixelFormat, HLSL_DX9);
157
LPDIRECT3DPIXELSHADER9 pshader;
158
std::string errorMessage;
159
if (!CompilePixelShader(buffer, &pshader, NULL, errorMessage)) {
160
ERROR_LOG(G3D, "Failed to compile depal pixel shader: %s\n\n%s", buffer, errorMessage.c_str());
165
DepalShaderDX9 *depal = new DepalShaderDX9();
166
depal->pixelShader = pshader;
172
return depal->pixelShader;
b'\\ No newline at end of file'