~ppsspp/ppsspp/ppsspp_1.3.0

« back to all changes in this revision

Viewing changes to GPU/Directx9/DepalettizeShaderDX9.cpp

  • 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) 2014- 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
#include <map>
 
19
 
 
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"
 
27
 
 
28
namespace DX9 {
 
29
 
 
30
static const int DEPAL_TEXTURE_OLD_AGE = 120;
 
31
 
 
32
#ifdef _WIN32
 
33
#define SHADERLOG
 
34
#endif
 
35
 
 
36
static const char *depalVShaderHLSL =
 
37
"struct VS_IN {\n"
 
38
"  float3 a_position : POSITION;\n"
 
39
"  float2 a_texcoord0 : TEXCOORD0;\n"
 
40
"};\n"
 
41
"struct VS_OUT {\n"
 
42
"  float4 Position : POSITION;\n"
 
43
"  float2 Texcoord : TEXCOORD0;\n"
 
44
"};\n"
 
45
"VS_OUT main(VS_IN input) {\n"
 
46
"  VS_OUT output;\n"
 
47
"  output.Texcoord = input.a_texcoord0;\n"
 
48
"  output.Position = float4(input.a_position, 1.0);\n"
 
49
"  return output;\n"
 
50
"}\n";
 
51
 
 
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());
 
56
        }
 
57
}
 
58
 
 
59
DepalShaderCacheDX9::~DepalShaderCacheDX9() {
 
60
        Clear();
 
61
        if (vertexShader_) {
 
62
                vertexShader_->Release();
 
63
        }
 
64
}
 
65
 
 
66
u32 DepalShaderCacheDX9::GenerateShaderID(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat) {
 
67
        return (clutFormat & 0xFFFFFF) | (pixelFormat << 24);
 
68
}
 
69
 
 
70
LPDIRECT3DTEXTURE9 DepalShaderCacheDX9::GetClutTexture(GEPaletteFormat clutFormat, const u32 clutID, u32 *rawClut) {
 
71
        const u32 realClutID = clutID ^ clutFormat;
 
72
 
 
73
        auto oldtex = texCache_.find(realClutID);
 
74
        if (oldtex != texCache_.end()) {
 
75
                oldtex->second->lastFrame = gpuStats.numFlips;
 
76
                return oldtex->second->texture;
 
77
        }
 
78
 
 
79
        D3DFORMAT dstFmt = DX9::getClutDestFormat(clutFormat);
 
80
        int texturePixels = clutFormat == GE_CMODE_32BIT_ABGR8888 ? 256 : 512;
 
81
 
 
82
        DepalTextureDX9 *tex = new DepalTextureDX9();
 
83
 
 
84
        // Create texture
 
85
        D3DPOOL pool = D3DPOOL_MANAGED;
 
86
        int usage = 0;
 
87
        if (pD3DdeviceEx) {
 
88
                pool = D3DPOOL_DEFAULT;
 
89
                usage = D3DUSAGE_DYNAMIC;  // TODO: Switch to using a staging texture?
 
90
        }
 
91
 
 
92
        HRESULT hr = pD3Ddevice->CreateTexture(texturePixels, 1, 1, usage, (D3DFORMAT)D3DFMT(dstFmt), pool, &tex->texture, NULL);
 
93
        if (FAILED(hr)) {
 
94
                ERROR_LOG(G3D, "Failed to create D3D texture for depal");
 
95
                delete tex;
 
96
                return nullptr;
 
97
        }
 
98
 
 
99
        D3DLOCKED_RECT rect;
 
100
        hr = tex->texture->LockRect(0, &rect, NULL, 0);
 
101
        if (FAILED(hr)) {
 
102
                ERROR_LOG(G3D, "Failed to lock D3D texture for depal");
 
103
                delete tex;
 
104
                return nullptr;
 
105
        }
 
106
        // Regardless of format, the CLUT should always be 1024 bytes.
 
107
        memcpy(rect.pBits, rawClut, 1024);
 
108
        tex->texture->UnlockRect(0);
 
109
 
 
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);
 
114
 
 
115
        tex->lastFrame = gpuStats.numFlips;
 
116
        texCache_[realClutID] = tex;
 
117
        return tex->texture;
 
118
}
 
119
 
 
120
void DepalShaderCacheDX9::Clear() {
 
121
        for (auto shader = cache_.begin(); shader != cache_.end(); ++shader) {
 
122
                shader->second->pixelShader->Release();
 
123
                delete shader->second;
 
124
        }
 
125
        cache_.clear();
 
126
        for (auto tex = texCache_.begin(); tex != texCache_.end(); ++tex) {
 
127
                tex->second->texture->Release();
 
128
                delete tex->second;
 
129
        }
 
130
        texCache_.clear();
 
131
}
 
132
 
 
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();
 
137
                        delete tex->second;
 
138
                        texCache_.erase(tex++);
 
139
                } else {
 
140
                        ++tex;
 
141
                }
 
142
        }
 
143
}
 
144
 
 
145
LPDIRECT3DPIXELSHADER9 DepalShaderCacheDX9::GetDepalettizePixelShader(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat) {
 
146
        u32 id = GenerateShaderID(clutFormat, pixelFormat);
 
147
 
 
148
        auto shader = cache_.find(id);
 
149
        if (shader != cache_.end()) {
 
150
                return shader->second->pixelShader;
 
151
        }
 
152
 
 
153
        char *buffer = new char[2048];
 
154
 
 
155
        GenerateDepalShader(buffer, pixelFormat, HLSL_DX9);
 
156
 
 
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());
 
161
                delete[] buffer;
 
162
                return nullptr;
 
163
        }
 
164
 
 
165
        DepalShaderDX9 *depal = new DepalShaderDX9();
 
166
        depal->pixelShader = pshader;
 
167
 
 
168
        cache_[id] = depal;
 
169
 
 
170
        delete[] buffer;
 
171
 
 
172
        return depal->pixelShader;
 
173
}
 
174
 
 
175
}  // namespace
 
 
b'\\ No newline at end of file'