mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Implement smoothed depal for the "old" depal path as well.
This commit is contained in:
parent
2a6015c1e3
commit
e3943f6d0d
5 changed files with 98 additions and 31 deletions
|
@ -45,7 +45,7 @@ static const VaryingDef varyings[1] = {
|
|||
};
|
||||
|
||||
// Uses integer instructions available since OpenGL 3.0, ES 3.0 (and 2.0 with extensions), and of course Vulkan and D3D11.
|
||||
void GenerateDepalShader300(ShaderWriter &writer, const DepalConfig &config, const ShaderLanguageDesc &lang) {
|
||||
void GenerateDepalShader300(ShaderWriter &writer, const DepalConfig &config) {
|
||||
const int shift = config.shift;
|
||||
const int mask = config.mask;
|
||||
|
||||
|
@ -140,7 +140,7 @@ void GenerateDepalShader300(ShaderWriter &writer, const DepalConfig &config, con
|
|||
}
|
||||
|
||||
// FP only, to suit GL(ES) 2.0 and DX9
|
||||
void GenerateDepalShaderFloat(ShaderWriter &writer, const DepalConfig &config, const ShaderLanguageDesc &lang) {
|
||||
void GenerateDepalShaderFloat(ShaderWriter &writer, const DepalConfig &config) {
|
||||
char lookupMethod[128] = "index.r";
|
||||
|
||||
const int shift = config.shift;
|
||||
|
@ -288,23 +288,64 @@ void GenerateDepalShaderFloat(ShaderWriter &writer, const DepalConfig &config, c
|
|||
writer.C(" vec4 outColor = ").SampleTexture2D("pal", "vec2(coord, 0.0)").C(";\n");
|
||||
}
|
||||
|
||||
void GenerateDepalSmoothed(ShaderWriter &writer, const DepalConfig &config) {
|
||||
const char *sourceChannel = "error";
|
||||
float indexMultiplier = 32.0f;
|
||||
|
||||
if (config.bufferFormat == GE_FORMAT_5551) {
|
||||
_dbg_assert_(config.mask == 0x1F);
|
||||
switch (config.shift) {
|
||||
case 0: sourceChannel = "r"; break;
|
||||
case 5: sourceChannel = "g"; break;
|
||||
case 10: sourceChannel = "b"; break;
|
||||
default: _dbg_assert_(false);
|
||||
}
|
||||
} else if (config.bufferFormat == GE_FORMAT_565) {
|
||||
_dbg_assert_(config.mask == 0x1F || config.mask == 0x3F);
|
||||
switch (config.shift) {
|
||||
case 0: sourceChannel = "r"; break;
|
||||
case 5: sourceChannel = "g"; indexMultiplier = 64.0f; break;
|
||||
case 11: sourceChannel = "b"; break;
|
||||
default: _dbg_assert_(false);
|
||||
}
|
||||
} else {
|
||||
_dbg_assert_(false);
|
||||
}
|
||||
|
||||
writer.C(" float index = ").SampleTexture2D("tex", "v_texcoord").F(".%s * %0.1f;\n", sourceChannel, indexMultiplier);
|
||||
|
||||
float texturePixels = 256.f;
|
||||
if (config.clutFormat != GE_CMODE_32BIT_ABGR8888) {
|
||||
texturePixels = 512.f;
|
||||
}
|
||||
|
||||
writer.F(" float coord = (index + 0.5) * %f;\n", 1.0 / texturePixels);
|
||||
writer.C(" vec4 outColor = ").SampleTexture2D("pal", "vec2(coord, 0.0)").C(";\n");
|
||||
}
|
||||
|
||||
void GenerateDepalFs(char *buffer, const DepalConfig &config, const ShaderLanguageDesc &lang) {
|
||||
ShaderWriter writer(buffer, lang, ShaderStage::Fragment);
|
||||
writer.DeclareSamplers(samplers);
|
||||
writer.HighPrecisionFloat();
|
||||
writer.BeginFSMain(Slice<UniformDef>::empty(), varyings, FSFLAG_NONE);
|
||||
switch (lang.shaderLanguage) {
|
||||
case HLSL_D3D9:
|
||||
case GLSL_1xx:
|
||||
GenerateDepalShaderFloat(writer, config, lang);
|
||||
break;
|
||||
case GLSL_VULKAN:
|
||||
case GLSL_3xx:
|
||||
case HLSL_D3D11:
|
||||
GenerateDepalShader300(writer, config, lang);
|
||||
break;
|
||||
default:
|
||||
_assert_msg_(false, "Depal shader language not supported: %d", (int)lang.shaderLanguage);
|
||||
if (config.smoothedDepal) {
|
||||
// Handles a limited set of cases, but doesn't need any integer math so we don't
|
||||
// need two variants.
|
||||
GenerateDepalSmoothed(writer, config);
|
||||
} else {
|
||||
switch (lang.shaderLanguage) {
|
||||
case HLSL_D3D9:
|
||||
case GLSL_1xx:
|
||||
GenerateDepalShaderFloat(writer, config);
|
||||
break;
|
||||
case GLSL_VULKAN:
|
||||
case GLSL_3xx:
|
||||
case HLSL_D3D11:
|
||||
GenerateDepalShader300(writer, config);
|
||||
break;
|
||||
default:
|
||||
_assert_msg_(false, "Depal shader language not supported: %d", (int)lang.shaderLanguage);
|
||||
}
|
||||
}
|
||||
writer.EndFSMain("outColor", FSFLAG_NONE);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ struct DepalConfig {
|
|||
GEPaletteFormat clutFormat;
|
||||
GETextureFormat textureFormat;
|
||||
GEBufferFormat bufferFormat;
|
||||
bool smoothedDepal;
|
||||
};
|
||||
|
||||
void GenerateDepalFs(char *buffer, const DepalConfig &config, const ShaderLanguageDesc &lang);
|
||||
|
|
|
@ -1906,12 +1906,17 @@ void TextureCacheCommon::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer
|
|||
break;
|
||||
}
|
||||
|
||||
const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat();
|
||||
ClutTexture clutTexture{};
|
||||
bool smoothedDepal = false;
|
||||
|
||||
if (need_depalettize && !g_Config.bDisableSlowFramebufEffects) {
|
||||
clutTexture = textureShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBufRaw_);
|
||||
smoothedDepal = CanUseSmoothDepal(gstate, framebuffer->drawnFormat, clutTexture.rampLength);
|
||||
|
||||
if (useShaderDepal) {
|
||||
const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat();
|
||||
|
||||
// Very icky conflation here of native and thin3d rendering. This will need careful work per backend in BindAsClutTexture.
|
||||
ClutTexture clutTexture = textureShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBufRaw_);
|
||||
BindAsClutTexture(clutTexture.texture);
|
||||
|
||||
framebufferManager_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET);
|
||||
|
@ -1927,7 +1932,7 @@ void TextureCacheCommon::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer
|
|||
// Since we started/ended render passes, might need these.
|
||||
gstate_c.Dirty(DIRTY_DEPAL);
|
||||
|
||||
gstate_c.SetUseShaderDepal(true, CanUseSmoothDepal(gstate, framebuffer->drawnFormat, clutTexture.rampLength));
|
||||
gstate_c.SetUseShaderDepal(true, smoothedDepal);
|
||||
gstate_c.depalFramebufferFormat = framebuffer->drawnFormat;
|
||||
const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16);
|
||||
const u32 clutTotalColors = clutMaxBytes_ / bytesPerColor;
|
||||
|
@ -1939,7 +1944,7 @@ void TextureCacheCommon::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer
|
|||
return;
|
||||
}
|
||||
|
||||
textureShader = textureShaderCache_->GetDepalettizeShader(clutMode, texFormat, depth ? GE_FORMAT_DEPTH16 : framebuffer->drawnFormat);
|
||||
textureShader = textureShaderCache_->GetDepalettizeShader(clutMode, texFormat, depth ? GE_FORMAT_DEPTH16 : framebuffer->drawnFormat, smoothedDepal);
|
||||
gstate_c.SetUseShaderDepal(false, false);
|
||||
}
|
||||
|
||||
|
@ -1957,9 +1962,10 @@ void TextureCacheCommon::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer
|
|||
|
||||
draw_->BindFramebufferAsTexture(framebuffer->fbo, 0, depth ? Draw::FB_DEPTH_BIT : Draw::FB_COLOR_BIT, 0);
|
||||
draw_->BindTexture(1, clutTexture.texture);
|
||||
Draw::SamplerState *nearest = textureShaderCache_->GetSampler();
|
||||
Draw::SamplerState *nearest = textureShaderCache_->GetSampler(false);
|
||||
Draw::SamplerState *clutSampler = textureShaderCache_->GetSampler(smoothedDepal);
|
||||
draw_->BindSamplerStates(0, 1, &nearest);
|
||||
draw_->BindSamplerStates(1, 1, &nearest);
|
||||
draw_->BindSamplerStates(1, 1, &clutSampler);
|
||||
|
||||
textureShaderCache_->ApplyShader(textureShader,
|
||||
framebuffer->bufferWidth, framebuffer->bufferHeight, framebuffer->renderWidth, framebuffer->renderHeight,
|
||||
|
|
|
@ -147,6 +147,10 @@ void TextureShaderCache::Clear() {
|
|||
nearestSampler_->Release();
|
||||
nearestSampler_ = nullptr;
|
||||
}
|
||||
if (linearSampler_) {
|
||||
linearSampler_->Release();
|
||||
linearSampler_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void TextureShaderCache::Decimate() {
|
||||
|
@ -161,15 +165,28 @@ void TextureShaderCache::Decimate() {
|
|||
}
|
||||
}
|
||||
|
||||
Draw::SamplerState *TextureShaderCache::GetSampler() {
|
||||
if (!nearestSampler_) {
|
||||
Draw::SamplerStateDesc desc{};
|
||||
desc.wrapU = Draw::TextureAddressMode::CLAMP_TO_EDGE;
|
||||
desc.wrapV = Draw::TextureAddressMode::CLAMP_TO_EDGE;
|
||||
desc.wrapW = Draw::TextureAddressMode::CLAMP_TO_EDGE;
|
||||
nearestSampler_ = draw_->CreateSamplerState(desc);
|
||||
Draw::SamplerState *TextureShaderCache::GetSampler(bool linearFilter) {
|
||||
if (linearFilter) {
|
||||
if (!linearSampler_) {
|
||||
Draw::SamplerStateDesc desc{};
|
||||
desc.magFilter = Draw::TextureFilter::LINEAR;
|
||||
desc.minFilter = Draw::TextureFilter::LINEAR;
|
||||
desc.wrapU = Draw::TextureAddressMode::CLAMP_TO_EDGE;
|
||||
desc.wrapV = Draw::TextureAddressMode::CLAMP_TO_EDGE;
|
||||
desc.wrapW = Draw::TextureAddressMode::CLAMP_TO_EDGE;
|
||||
linearSampler_ = draw_->CreateSamplerState(desc);
|
||||
}
|
||||
return linearSampler_;
|
||||
} else {
|
||||
if (!nearestSampler_) {
|
||||
Draw::SamplerStateDesc desc{};
|
||||
desc.wrapU = Draw::TextureAddressMode::CLAMP_TO_EDGE;
|
||||
desc.wrapV = Draw::TextureAddressMode::CLAMP_TO_EDGE;
|
||||
desc.wrapW = Draw::TextureAddressMode::CLAMP_TO_EDGE;
|
||||
nearestSampler_ = draw_->CreateSamplerState(desc);
|
||||
}
|
||||
return nearestSampler_;
|
||||
}
|
||||
return nearestSampler_;
|
||||
}
|
||||
|
||||
TextureShader *TextureShaderCache::CreateShader(const char *fs) {
|
||||
|
@ -220,7 +237,7 @@ TextureShader *TextureShaderCache::CreateShader(const char *fs) {
|
|||
return depal;
|
||||
}
|
||||
|
||||
TextureShader *TextureShaderCache::GetDepalettizeShader(uint32_t clutMode, GETextureFormat textureFormat, GEBufferFormat bufferFormat) {
|
||||
TextureShader *TextureShaderCache::GetDepalettizeShader(uint32_t clutMode, GETextureFormat textureFormat, GEBufferFormat bufferFormat, bool smoothedDepal) {
|
||||
using namespace Draw;
|
||||
|
||||
// Generate an ID for depal shaders.
|
||||
|
@ -240,6 +257,7 @@ TextureShader *TextureShaderCache::GetDepalettizeShader(uint32_t clutMode, GETex
|
|||
config.mask = gstate.getClutIndexMask();
|
||||
config.bufferFormat = bufferFormat;
|
||||
config.textureFormat = textureFormat;
|
||||
config.smoothedDepal = smoothedDepal;
|
||||
|
||||
char *buffer = new char[4096];
|
||||
GenerateDepalFs(buffer, config, draw_->GetShaderLanguageDesc());
|
||||
|
|
|
@ -49,10 +49,10 @@ public:
|
|||
TextureShaderCache(Draw::DrawContext *draw);
|
||||
~TextureShaderCache();
|
||||
|
||||
TextureShader *GetDepalettizeShader(uint32_t clutMode, GETextureFormat texFormat, GEBufferFormat pixelFormat);
|
||||
TextureShader *GetDepalettizeShader(uint32_t clutMode, GETextureFormat texFormat, GEBufferFormat pixelFormat, bool smoothedDepal);
|
||||
ClutTexture GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut);
|
||||
|
||||
Draw::SamplerState *GetSampler();
|
||||
Draw::SamplerState *GetSampler(bool linearFilter);
|
||||
|
||||
void ApplyShader(TextureShader *shader, float bufferW, float bufferH, int renderW, int renderH, const KnownVertexBounds &bounds, u32 uoff, u32 voff);
|
||||
|
||||
|
@ -70,6 +70,7 @@ private:
|
|||
Draw::DrawContext *draw_;
|
||||
Draw::ShaderModule *vertexShader_ = nullptr;
|
||||
Draw::SamplerState *nearestSampler_ = nullptr;
|
||||
Draw::SamplerState *linearSampler_ = nullptr;
|
||||
|
||||
std::map<u32, TextureShader *> depalCache_;
|
||||
std::map<u32, ClutTexture *> texCache_;
|
||||
|
|
Loading…
Add table
Reference in a new issue