DX9: Add DepalettizeShader manager (not hooked up, so untested)

This commit is contained in:
Henrik Rydgard 2014-09-17 22:52:27 +02:00 committed by Unknown W. Brackets
parent 0c9f541a43
commit 13bf0acd28
4 changed files with 226 additions and 0 deletions

View File

@ -0,0 +1,159 @@
// Copyright (c) 2014- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <map>
#include "base/logging.h"
#include "Common/Log.h"
#include "Core/Reporting.h"
#include "GPU/GPUState.h"
#include "GPU/Directx9/TextureCacheDX9.h"
#include "GPU/Directx9/DepalettizeShaderDX9.h"
#include "GPU/Common/DepalettizeShaderCommon.h"
#include "GPU/Directx9/helper/global.h"
namespace DX9 {
static const int DEPAL_TEXTURE_OLD_AGE = 120;
#ifdef _WIN32
#define SHADERLOG
#endif
static const char *depalVShaderHLSL =
"struct VS_IN {\n"
" float3 a_position : POSITION;\n"
" float2 a_texcoord0 : TEXCOORD0;\n"
"};\n"
"struct VS_OUT {\n"
" float3 Position : POSITION;\n"
" float2 Texcoord : TEXCOORD0;\n"
"}\n"
"VS_OUT main(VS_IN in) {\n"
" VS_OUT out;\n"
" out.Texcoord = in.a_texcoord0;\n"
" out.Position = in.a_position;\n"
"}\n";
DepalShaderCacheDX9::DepalShaderCacheDX9() : vertexShader_(nullptr) {
std::string errorMessage;
if (!DX9::CompileVertexShader(depalVShaderHLSL, &vertexShader_, nullptr, errorMessage)) {
ERROR_LOG(G3D, "error compling depal vshader: %s", errorMessage.c_str());
}
}
DepalShaderCacheDX9::~DepalShaderCacheDX9() {
Clear();
if (vertexShader_) {
vertexShader_->Release();
}
}
u32 DepalShaderCacheDX9::GenerateShaderID(GEBufferFormat pixelFormat) {
return (gstate.clutformat & 0xFFFFFF) | (pixelFormat << 24);
}
LPDIRECT3DTEXTURE9 DepalShaderCacheDX9::GetClutTexture(const u32 clutID, u32 *rawClut) {
GEPaletteFormat palFormat = gstate.getClutPaletteFormat();
const u32 realClutID = clutID ^ palFormat;
auto oldtex = texCache_.find(realClutID);
if (oldtex != texCache_.end()) {
oldtex->second->lastFrame = gpuStats.numFlips;
return oldtex->second->texture;
}
D3DFORMAT dstFmt = DX9::getClutDestFormat(palFormat);
int texturePixels = palFormat == GE_CMODE_32BIT_ABGR8888 ? 256 : 512;
DepalTextureDX9 *tex = new DepalTextureDX9();
// Create texture
D3DPOOL pool = D3DPOOL_MANAGED;
int usage = 0;
if (pD3DdeviceEx) {
pool = D3DPOOL_DEFAULT;
usage = D3DUSAGE_DYNAMIC; // TODO: Switch to using a staging texture?
}
HRESULT hr = pD3Ddevice->CreateTexture(texturePixels, 1, 1, usage, (D3DFORMAT)D3DFMT(dstFmt), pool, &tex->texture, NULL);
if (FAILED(hr)) {
INFO_LOG(G3D, "Failed to create D3D texture for depal");
return nullptr;
}
tex->lastFrame = gpuStats.numFlips;
texCache_[realClutID] = tex;
return tex->texture;
}
void DepalShaderCacheDX9::Clear() {
for (auto shader = cache_.begin(); shader != cache_.end(); ++shader) {
shader->second->pixelShader->Release();
delete shader->second;
}
cache_.clear();
for (auto tex = texCache_.begin(); tex != texCache_.end(); ++tex) {
tex->second->texture->Release();
delete tex->second;
}
texCache_.clear();
}
void DepalShaderCacheDX9::Decimate() {
for (auto tex = texCache_.begin(); tex != texCache_.end();) {
if (tex->second->lastFrame + DEPAL_TEXTURE_OLD_AGE < gpuStats.numFlips) {
tex->second->texture->Release();
delete tex->second;
texCache_.erase(tex++);
} else {
++tex;
}
}
}
LPDIRECT3DPIXELSHADER9 DepalShaderCacheDX9::GetDepalettizePixelShader(GEBufferFormat pixelFormat) {
u32 id = GenerateShaderID(pixelFormat);
auto shader = cache_.find(id);
if (shader != cache_.end()) {
return shader->second->pixelShader;
}
char *buffer = new char[2048];
GenerateDepalShader(buffer, pixelFormat, HLSL_DX9);
LPDIRECT3DPIXELSHADER9 pshader;
std::string errorMessage;
if (!CompilePixelShader(buffer, &pshader, NULL, errorMessage)) {
ERROR_LOG(G3D, "Failed to compile depal pixel shader: %s\n\n%s", buffer, errorMessage.c_str());
delete[] buffer;
return nullptr;
}
DepalShaderDX9 *depal = new DepalShaderDX9();
depal->pixelShader = pshader;
cache_[id] = depal;
delete[] buffer;
return depal->pixelShader;
}
} // namespace

View File

@ -0,0 +1,59 @@
// Copyright (c) 2014- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <map>
#include "Common/CommonTypes.h"
#include "GPU/ge_constants.h"
#include "GPU/Directx9/helper/global.h"
namespace DX9 {
class DepalShaderDX9 {
public:
LPDIRECT3DPIXELSHADER9 pixelShader;
};
class DepalTextureDX9 {
public:
LPDIRECT3DTEXTURE9 texture;
int lastFrame;
};
// Caches both shaders and palette textures.
class DepalShaderCacheDX9 {
public:
DepalShaderCacheDX9();
~DepalShaderCacheDX9();
// This also uploads the palette and binds the correct texture.
LPDIRECT3DPIXELSHADER9 GetDepalettizePixelShader(GEBufferFormat pixelFormat);
LPDIRECT3DVERTEXSHADER9 GetDepalettizeVertexShader();
LPDIRECT3DTEXTURE9 GetClutTexture(const u32 clutHash, u32 *rawClut);
void Clear();
void Decimate();
private:
u32 GenerateShaderID(GEBufferFormat pixelFormat);
LPDIRECT3DVERTEXSHADER9 vertexShader_;
std::map<u32, DepalShaderDX9 *> cache_;
std::map<u32, DepalTextureDX9 *> texCache_;
};
} // namespace

View File

@ -200,6 +200,7 @@
<ClInclude Include="Common\VertexDecoderCommon.h" />
<ClInclude Include="Debugger\Breakpoints.h" />
<ClInclude Include="Debugger\Stepping.h" />
<ClInclude Include="Directx9\DepalettizeShaderDX9.h" />
<ClInclude Include="Directx9\GPU_DX9.h" />
<ClInclude Include="Directx9\helper\dx_state.h" />
<ClInclude Include="Directx9\helper\fbo.h" />
@ -265,6 +266,7 @@
<ClCompile Include="Common\VertexDecoderX86.cpp" />
<ClCompile Include="Debugger\Breakpoints.cpp" />
<ClCompile Include="Debugger\Stepping.cpp" />
<ClCompile Include="Directx9\DepalettizeShaderDX9.cpp" />
<ClCompile Include="Directx9\GPU_DX9.cpp" />
<ClCompile Include="Directx9\helper\dx_state.cpp" />
<ClCompile Include="Directx9\helper\fbo.cpp" />

View File

@ -180,6 +180,9 @@
<ClInclude Include="Common\DepalettizeShaderCommon.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Directx9\DepalettizeShaderDX9.h">
<Filter>DirectX9</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Math3D.cpp">
@ -344,6 +347,9 @@
<ClCompile Include="Common\DepalettizeShaderCommon.cpp">
<Filter>Common</Filter>
</ClCompile>
<ClCompile Include="Directx9\DepalettizeShaderDX9.cpp">
<Filter>DirectX9</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />