Depal: Use the full CLUT mode setting as the depal shader key. Fixes #9550 for both D3D11 and D3D9.

This commit is contained in:
Henrik Rydgard 2017-04-04 11:09:29 +02:00
parent 0ca16c29ae
commit 22d5acb40e
17 changed files with 160 additions and 42 deletions

View File

@ -34,6 +34,7 @@ enum DebugShaderType {
SHADER_TYPE_GEOMETRY = 2,
SHADER_TYPE_VERTEXLOADER = 3, // Not really a shader, but might as well re-use this mechanism
SHADER_TYPE_PIPELINE = 4, // Vulkan and DX12 combines a bunch of state into pipeline objects. Might as well make them inspectable.
SHADER_TYPE_DEPAL = 5,
};
enum DebugShaderStringType {

View File

@ -22,6 +22,7 @@
#include "base/logging.h"
#include "Common/Log.h"
#include "Common/ColorConv.h"
#include "Common/StringUtils.h"
#include "Core/Reporting.h"
#include "GPU/D3D11/TextureCacheD3D11.h"
#include "GPU/D3D11/DepalettizeShaderD3D11.h"
@ -71,8 +72,8 @@ DepalShaderCacheD3D11::~DepalShaderCacheD3D11() {
inputLayout_->Release();
}
u32 DepalShaderCacheD3D11::GenerateShaderID(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat) {
return (clutFormat & 0xFFFFFF) | (pixelFormat << 24);
u32 DepalShaderCacheD3D11::GenerateShaderID(uint32_t clutMode, GEBufferFormat pixelFormat) {
return (clutMode & 0xFFFFFF) | (pixelFormat << 24);
}
ID3D11ShaderResourceView *DepalShaderCacheD3D11::GetClutTexture(GEPaletteFormat clutFormat, const u32 clutID, u32 *rawClut, bool expandTo32bit) {
@ -161,8 +162,8 @@ void DepalShaderCacheD3D11::Decimate() {
}
}
ID3D11PixelShader *DepalShaderCacheD3D11::GetDepalettizePixelShader(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat) {
u32 id = GenerateShaderID(clutFormat, pixelFormat);
ID3D11PixelShader *DepalShaderCacheD3D11::GetDepalettizePixelShader(uint32_t clutMode, GEBufferFormat pixelFormat) {
u32 id = GenerateShaderID(clutMode, pixelFormat);
auto shader = cache_.find(id);
if (shader != cache_.end()) {
@ -183,10 +184,36 @@ ID3D11PixelShader *DepalShaderCacheD3D11::GetDepalettizePixelShader(GEPaletteFor
DepalShaderD3D11 *depal = new DepalShaderD3D11();
depal->pixelShader = pshader;
depal->code = buffer;
cache_[id] = depal;
delete[] buffer;
return depal->pixelShader;
}
}
std::vector<std::string> DepalShaderCacheD3D11::DebugGetShaderIDs(DebugShaderType type) {
std::vector<std::string> ids;
for (auto &iter : cache_) {
ids.push_back(StringFromFormat("%08x", iter.first));
}
return ids;
}
std::string DepalShaderCacheD3D11::DebugGetShaderString(std::string idstr, DebugShaderType type, DebugShaderStringType stringType) {
uint32_t id;
sscanf(idstr.c_str(), "%08x", &id);
auto iter = cache_.find(id);
if (iter == cache_.end())
return "";
switch (stringType) {
case SHADER_STRING_SHORT_DESC:
return idstr;
case SHADER_STRING_SOURCE_CODE:
return iter->second->code;
default:
return "";
}
}

View File

@ -27,6 +27,7 @@
class DepalShaderD3D11 {
public:
ID3D11PixelShader *pixelShader;
std::string code;
};
class DepalTextureD3D11 {
@ -49,15 +50,17 @@ public:
~DepalShaderCacheD3D11();
// This also uploads the palette and binds the correct texture.
ID3D11PixelShader *GetDepalettizePixelShader(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat);
ID3D11PixelShader *GetDepalettizePixelShader(uint32_t clutMode, GEBufferFormat pixelFormat);
ID3D11VertexShader *GetDepalettizeVertexShader() { return vertexShader_; }
ID3D11InputLayout *GetInputLayout() { return inputLayout_; }
ID3D11ShaderResourceView *GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut, bool expandTo32bit);
void Clear();
void Decimate();
std::vector<std::string> DebugGetShaderIDs(DebugShaderType type);
std::string DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType);
private:
u32 GenerateShaderID(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat);
u32 GenerateShaderID(uint32_t clutMode, GEBufferFormat pixelFormat);
ID3D11Device *device_;
ID3D11DeviceContext *context_;

View File

@ -204,7 +204,7 @@ static void VertexAttribSetup(D3D11_INPUT_ELEMENT_DESC * VertexElement, u8 fmt,
ID3D11InputLayout *DrawEngineD3D11::SetupDecFmtForDraw(D3D11VertexShader *vshader, const DecVtxFormat &decFmt, u32 pspFmt) {
// TODO: Instead of one for each vshader, we can reduce it to one for each type of shader
// that reads TEXCOORD or not, etc. Not sure if worth it.
InputLayoutKey key{ pspFmt, vshader };
InputLayoutKey key{ vshader, pspFmt };
auto vertexDeclCached = inputLayoutMap_.find(key);
if (vertexDeclCached == inputLayoutMap_.end()) {
D3D11_INPUT_ELEMENT_DESC VertexElements[8];
@ -878,7 +878,7 @@ rotateVBO:
// We really do need a vertex layout for each vertex shader (or at least check its ID bits for what inputs it uses)!
// Some vertex shaders ignore one of the inputs, and then the layout created from it will lack it, which will be a problem for others.
InputLayoutKey key{ 0xFFFFFFFF, vshader }; // Let's use 0xFFFFFFFF to signify TransformedVertex
InputLayoutKey key{ vshader, 0xFFFFFFFF }; // Let's use 0xFFFFFFFF to signify TransformedVertex
auto iter = inputLayoutMap_.find(key);
ID3D11InputLayout *layout;
if (iter == inputLayoutMap_.end()) {

View File

@ -204,8 +204,8 @@ private:
std::unordered_map<u32, VertexArrayInfoD3D11 *> vai_;
struct InputLayoutKey {
u32 vertType;
D3D11VertexShader *vshader;
u32 vertType;
bool operator <(const InputLayoutKey &other) const {
if (vertType < other.vertType)
return true;

View File

@ -771,17 +771,23 @@ bool GPU_D3D11::GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex>
}
std::vector<std::string> GPU_D3D11::DebugGetShaderIDs(DebugShaderType type) {
if (type == SHADER_TYPE_VERTEXLOADER) {
switch (type) {
case SHADER_TYPE_VERTEXLOADER:
return drawEngine_.DebugGetVertexLoaderIDs();
} else {
case SHADER_TYPE_DEPAL:
return depalShaderCache_->DebugGetShaderIDs(type);
default:
return shaderManagerD3D11_->DebugGetShaderIDs(type);
}
}
std::string GPU_D3D11::DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType) {
if (type == SHADER_TYPE_VERTEXLOADER) {
switch (type) {
case SHADER_TYPE_VERTEXLOADER:
return drawEngine_.DebugGetVertexLoaderString(id, stringType);
} else {
case SHADER_TYPE_DEPAL:
return depalShaderCache_->DebugGetShaderString(id, type, stringType);
default:
return shaderManagerD3D11_->DebugGetShaderString(id, type, stringType);
}
}

View File

@ -391,13 +391,14 @@ protected:
void TextureCacheD3D11::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) {
ID3D11PixelShader *pshader = nullptr;
const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat();
uint32_t clutMode = gstate.clutformat & 0xFFFFFF;
if ((entry->status & TexCacheEntry::STATUS_DEPALETTIZE) && !g_Config.bDisableSlowFramebufEffects) {
pshader = depalShaderCache_->GetDepalettizePixelShader(clutFormat, framebuffer->drawnFormat);
pshader = depalShaderCache_->GetDepalettizePixelShader(clutMode, framebuffer->drawnFormat);
}
if (pshader) {
bool expand32 = !gstate_c.Supports(GPU_SUPPORTS_16BIT_FORMATS);
const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat();
ID3D11ShaderResourceView *clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_, expand32);
Draw::Framebuffer *depalFBO = framebufferManagerD3D11_->GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, Draw::FBO_8888);

View File

@ -21,6 +21,7 @@
#include "base/logging.h"
#include "thin3d/thin3d.h"
#include "Common/Log.h"
#include "Common/StringUtils.h"
#include "Core/Reporting.h"
#include "GPU/Directx9/TextureCacheDX9.h"
#include "GPU/Directx9/DepalettizeShaderDX9.h"
@ -66,8 +67,8 @@ DepalShaderCacheDX9::~DepalShaderCacheDX9() {
}
}
u32 DepalShaderCacheDX9::GenerateShaderID(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat) {
return (clutFormat & 0xFFFFFF) | (pixelFormat << 24);
u32 DepalShaderCacheDX9::GenerateShaderID(uint32_t clutMode, GEBufferFormat pixelFormat) {
return (clutMode & 0xFFFFFF) | (pixelFormat << 24);
}
LPDIRECT3DTEXTURE9 DepalShaderCacheDX9::GetClutTexture(GEPaletteFormat clutFormat, const u32 clutID, u32 *rawClut) {
@ -145,8 +146,8 @@ void DepalShaderCacheDX9::Decimate() {
}
}
LPDIRECT3DPIXELSHADER9 DepalShaderCacheDX9::GetDepalettizePixelShader(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat) {
u32 id = GenerateShaderID(clutFormat, pixelFormat);
LPDIRECT3DPIXELSHADER9 DepalShaderCacheDX9::GetDepalettizePixelShader(uint32_t clutMode, GEBufferFormat pixelFormat) {
u32 id = GenerateShaderID(clutMode, pixelFormat);
auto shader = cache_.find(id);
if (shader != cache_.end()) {
@ -167,6 +168,7 @@ LPDIRECT3DPIXELSHADER9 DepalShaderCacheDX9::GetDepalettizePixelShader(GEPaletteF
DepalShaderDX9 *depal = new DepalShaderDX9();
depal->pixelShader = pshader;
depal->code = buffer;
cache_[id] = depal;
@ -175,4 +177,28 @@ LPDIRECT3DPIXELSHADER9 DepalShaderCacheDX9::GetDepalettizePixelShader(GEPaletteF
return depal->pixelShader;
}
} // namespace
std::vector<std::string> DepalShaderCacheDX9::DebugGetShaderIDs(DebugShaderType type) {
std::vector<std::string> ids;
for (auto &iter : cache_) {
ids.push_back(StringFromFormat("%08x", iter.first));
}
return ids;
}
std::string DepalShaderCacheDX9::DebugGetShaderString(std::string idstr, DebugShaderType type, DebugShaderStringType stringType) {
uint32_t id;
sscanf(idstr.c_str(), "%08x", &id);
auto iter = cache_.find(id);
if (iter == cache_.end())
return "";
switch (stringType) {
case SHADER_STRING_SHORT_DESC:
return idstr;
case SHADER_STRING_SOURCE_CODE:
return iter->second->code;
default:
return "";
}
}
} // namespace

View File

@ -20,12 +20,14 @@
#include <d3d9.h>
#include "Common/CommonTypes.h"
#include "GPU/ge_constants.h"
#include "GPU/Common/ShaderCommon.h"
namespace DX9 {
class DepalShaderDX9 {
public:
LPDIRECT3DPIXELSHADER9 pixelShader;
std::string code;
};
class DepalTextureDX9 {
@ -41,14 +43,16 @@ public:
~DepalShaderCacheDX9();
// This also uploads the palette and binds the correct texture.
LPDIRECT3DPIXELSHADER9 GetDepalettizePixelShader(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat);
LPDIRECT3DPIXELSHADER9 GetDepalettizePixelShader(uint32_t clutMode, GEBufferFormat pixelFormat);
LPDIRECT3DVERTEXSHADER9 GetDepalettizeVertexShader() { return vertexShader_; }
LPDIRECT3DTEXTURE9 GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut);
void Clear();
void Decimate();
std::vector<std::string> DebugGetShaderIDs(DebugShaderType type);
std::string DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType);
private:
u32 GenerateShaderID(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat);
u32 GenerateShaderID(uint32_t clutMode, GEBufferFormat pixelFormat);
LPDIRECT3DDEVICE9 device_;
LPDIRECT3DVERTEXSHADER9 vertexShader_;

View File

@ -793,17 +793,23 @@ bool GPU_DX9::GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &v
}
std::vector<std::string> GPU_DX9::DebugGetShaderIDs(DebugShaderType type) {
if (type == SHADER_TYPE_VERTEXLOADER) {
switch (type) {
case SHADER_TYPE_VERTEXLOADER:
return drawEngine_.DebugGetVertexLoaderIDs();
} else {
case SHADER_TYPE_DEPAL:
return depalShaderCache_.DebugGetShaderIDs(type);
default:
return shaderManagerDX9_->DebugGetShaderIDs(type);
}
}
std::string GPU_DX9::DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType) {
if (type == SHADER_TYPE_VERTEXLOADER) {
switch (type) {
case SHADER_TYPE_VERTEXLOADER:
return drawEngine_.DebugGetVertexLoaderString(id, stringType);
} else {
case SHADER_TYPE_DEPAL:
return depalShaderCache_.DebugGetShaderString(id, type, stringType);
default:
return shaderManagerDX9_->DebugGetShaderString(id, type, stringType);
}
}

View File

@ -408,12 +408,13 @@ protected:
void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) {
LPDIRECT3DPIXELSHADER9 pshader = nullptr;
const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat();
uint32_t clutMode = gstate.clutformat & 0xFFFFFF;
if ((entry->status & TexCacheEntry::STATUS_DEPALETTIZE) && !g_Config.bDisableSlowFramebufEffects) {
pshader = depalShaderCache_->GetDepalettizePixelShader(clutFormat, framebuffer->drawnFormat);
pshader = depalShaderCache_->GetDepalettizePixelShader(clutMode, framebuffer->drawnFormat);
}
if (pshader) {
const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat();
LPDIRECT3DTEXTURE9 clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_);
Draw::Framebuffer *depalFBO = framebufferManagerDX9_->GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, Draw::FBO_8888);

View File

@ -19,6 +19,7 @@
#include "base/logging.h"
#include "Common/Log.h"
#include "Common/StringUtils.h"
#include "Core/Reporting.h"
#include "DepalettizeShaderGLES.h"
#include "GPU/GLES/TextureCacheGLES.h"
@ -121,8 +122,8 @@ bool DepalShaderCacheGLES::CreateVertexShader() {
return !vertexShaderFailed_;
}
u32 DepalShaderCacheGLES::GenerateShaderID(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat) {
return (gstate.clutformat & 0xFFFFFF) | (pixelFormat << 24);
u32 DepalShaderCacheGLES::GenerateShaderID(uint32_t clutMode, GEBufferFormat pixelFormat) {
return (clutMode & 0xFFFFFF) | (pixelFormat << 24);
}
GLuint DepalShaderCacheGLES::GetClutTexture(GEPaletteFormat clutFormat, const u32 clutID, u32 *rawClut) {
@ -188,8 +189,8 @@ void DepalShaderCacheGLES::Decimate() {
}
}
DepalShader *DepalShaderCacheGLES::GetDepalettizeShader(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat) {
u32 id = GenerateShaderID(clutFormat, pixelFormat);
DepalShader *DepalShaderCacheGLES::GetDepalettizeShader(uint32_t clutMode, GEBufferFormat pixelFormat) {
u32 id = GenerateShaderID(clutMode, pixelFormat);
auto shader = cache_.find(id);
if (shader != cache_.end()) {
@ -234,6 +235,7 @@ DepalShader *DepalShaderCacheGLES::GetDepalettizeShader(GEPaletteFormat clutForm
DepalShader *depal = new DepalShader();
depal->program = program;
depal->fragShader = fragShader;
depal->code = buffer;
cache_[id] = depal;
GLint linkStatus = GL_FALSE;
@ -266,3 +268,27 @@ DepalShader *DepalShaderCacheGLES::GetDepalettizeShader(GEPaletteFormat clutForm
delete[] buffer;
return depal->program ? depal : nullptr;
}
std::vector<std::string> DepalShaderCacheGLES::DebugGetShaderIDs(DebugShaderType type) {
std::vector<std::string> ids;
for (auto &iter : cache_) {
ids.push_back(StringFromFormat("%08x", iter.first));
}
return ids;
}
std::string DepalShaderCacheGLES::DebugGetShaderString(std::string idstr, DebugShaderType type, DebugShaderStringType stringType) {
uint32_t id;
sscanf(idstr.c_str(), "%08x", &id);
auto iter = cache_.find(id);
if (iter == cache_.end())
return "";
switch (stringType) {
case SHADER_STRING_SHORT_DESC:
return idstr;
case SHADER_STRING_SOURCE_CODE:
return iter->second->code;
default:
return "";
}
}

View File

@ -20,6 +20,7 @@
#include "Common/CommonTypes.h"
#include "gfx/gl_common.h"
#include "GPU/ge_constants.h"
#include "GPU/Common/ShaderCommon.h"
class DepalShader {
public:
@ -27,6 +28,7 @@ public:
GLuint fragShader;
GLint a_position;
GLint a_texcoord0;
std::string code;
};
class DepalTexture {
@ -42,13 +44,15 @@ public:
~DepalShaderCacheGLES();
// This also uploads the palette and binds the correct texture.
DepalShader *GetDepalettizeShader(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat);
DepalShader *GetDepalettizeShader(uint32_t clutMode, GEBufferFormat pixelFormat);
GLuint GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut);
void Clear();
void Decimate();
std::vector<std::string> DebugGetShaderIDs(DebugShaderType type);
std::string DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType);
private:
u32 GenerateShaderID(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat);
u32 GenerateShaderID(uint32_t clutMode, GEBufferFormat pixelFormat);
bool CreateVertexShader();
bool useGL3_;

View File

@ -991,17 +991,23 @@ bool GPU_GLES::DescribeCodePtr(const u8 *ptr, std::string &name) {
}
std::vector<std::string> GPU_GLES::DebugGetShaderIDs(DebugShaderType type) {
if (type == SHADER_TYPE_VERTEXLOADER) {
switch (type) {
case SHADER_TYPE_VERTEXLOADER:
return drawEngine_.DebugGetVertexLoaderIDs();
} else {
case SHADER_TYPE_DEPAL:
return depalShaderCache_.DebugGetShaderIDs(type);
default:
return shaderManagerGL_->DebugGetShaderIDs(type);
}
}
std::string GPU_GLES::DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType) {
if (type == SHADER_TYPE_VERTEXLOADER) {
switch (type) {
case SHADER_TYPE_VERTEXLOADER:
return drawEngine_.DebugGetVertexLoaderString(id, stringType);
} else {
case SHADER_TYPE_DEPAL:
return depalShaderCache_.DebugGetShaderString(id, type, stringType);
default:
return shaderManagerGL_->DebugGetShaderString(id, type, stringType);
}
}

View File

@ -473,11 +473,12 @@ protected:
void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) {
DepalShader *depal = nullptr;
const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat();
uint32_t clutMode = gstate.clutformat & 0xFFFFFF;
if ((entry->status & TexCacheEntry::STATUS_DEPALETTIZE) && !g_Config.bDisableSlowFramebufEffects) {
depal = depalShaderCache_->GetDepalettizeShader(clutFormat, framebuffer->drawnFormat);
depal = depalShaderCache_->GetDepalettizeShader(clutMode, framebuffer->drawnFormat);
}
if (depal) {
const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat();
GLuint clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_);
Draw::Framebuffer *depalFBO = framebufferManagerGL_->GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, Draw::FBO_8888);
draw_->BindFramebufferAsRenderTarget(depalFBO);

View File

@ -846,6 +846,9 @@ std::vector<std::string> GPU_Vulkan::DebugGetShaderIDs(DebugShaderType type) {
return drawEngine_.DebugGetVertexLoaderIDs();
} else if (type == SHADER_TYPE_PIPELINE) {
return pipelineManager_->DebugGetObjectIDs(type);
} else if (type == SHADER_TYPE_DEPAL) {
///...
return std::vector<std::string>();
} else {
return shaderManagerVulkan_->DebugGetShaderIDs(type);
}
@ -856,6 +859,8 @@ std::string GPU_Vulkan::DebugGetShaderString(std::string id, DebugShaderType typ
return drawEngine_.DebugGetVertexLoaderString(id, stringType);
} else if (type == SHADER_TYPE_PIPELINE) {
return pipelineManager_->DebugGetObjectString(id, type, stringType);
} else if (type == SHADER_TYPE_DEPAL) {
return "";
} else {
return shaderManagerVulkan_->DebugGetShaderString(id, type, stringType);
}

View File

@ -899,6 +899,8 @@ struct { DebugShaderType type; const char *name; } shaderTypes[] = {
{ SHADER_TYPE_FRAGMENT, "Fragment" },
// { SHADER_TYPE_GEOMETRY, "Geometry" },
{ SHADER_TYPE_VERTEXLOADER, "VertexLoader" },
{ SHADER_TYPE_PIPELINE, "Pipeline" },
{ SHADER_TYPE_DEPAL, "Depal" },
};
void ShaderListScreen::CreateViews() {
@ -913,7 +915,6 @@ void ShaderListScreen::CreateViews() {
tabs_->SetTag("DevShaderList");
layout->Add(tabs_);
layout->Add(new Button(di->T("Back")))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
for (size_t i = 0; i < ARRAY_SIZE(shaderTypes); i++) {
ScrollView *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0));
LinearLayout *shaderList = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT));