This commit is contained in:
Henrik Rydgård 2022-08-26 15:15:20 +02:00
parent 3c5ec25f61
commit 1ccfd7986a
5 changed files with 24 additions and 6 deletions

View File

@ -47,10 +47,18 @@ void GenerateDepalShader300(ShaderWriter &writer, const DepalConfig &config) {
const int shift = config.shift;
const int mask = config.mask;
writer.C(" vec2 texcoord = v_texcoord;\n");
if (config.bufferFormat == GE_FORMAT_DEPTH16) {
DepthScaleFactors factors = GetDepthScaleFactors();
writer.ConstFloat("z_scale", factors.scale);
writer.ConstFloat("z_offset", factors.offset);
if (config.depthUpperBits == 0x2) {
writer.C(" int x = int(texcoord.x * texSize.x);\n");
writer.C(" int bit1 = x & 0x10; int bit2 = x & 0x100;\n");
writer.C(" x = (x & 0xFFFFFEEF) | (bit1 << 4) | (bit2 >> 4);\n");
writer.C(" texcoord.x = float(x) / texSize.x;\n");
}
}
// Sampling turns our texture into floating point. To avoid this, might be able
@ -66,7 +74,7 @@ void GenerateDepalShader300(ShaderWriter &writer, const DepalConfig &config) {
// An alternative would be to have a special mode where we keep some extra precision here and sample the CLUT linearly - works for ramps such
// as those that Test Drive uses for its color remapping. But would need game specific flagging.
writer.C(" vec4 color = ").SampleTexture2D("tex", "v_texcoord").C(";\n");
writer.C(" vec4 color = ").SampleTexture2D("tex", "texcoord").C(";\n");
int shiftedMask = mask << shift;
switch (config.bufferFormat) {
@ -98,6 +106,11 @@ void GenerateDepalShader300(ShaderWriter &writer, const DepalConfig &config) {
writer.C(" int index = (a << 15) | (b << 10) | (g << 5) | (r);\n");
break;
case GE_FORMAT_DEPTH16:
// Byteswap experiment, seems to be wrong.
// writer.C(" int d = int(color.x * 65535.0);\n");
// writer.C(" d = ((d >> 8) & 0xFF) | ((d << 8) & 0xFF00);\n");
// float(d) / 65535.0
// Remap depth buffer.
writer.C(" float depth = (color.x - z_offset) * z_scale;\n");

View File

@ -27,13 +27,14 @@ class ShaderWriter;
static const int DEPAL_TEXTURE_OLD_AGE = 120;
struct DepalConfig {
int mask;
int shift;
u32 startPos;
u8 mask;
u8 shift;
bool smoothedDepal;
u8 depthUpperBits;
GEPaletteFormat clutFormat;
GETextureFormat textureFormat;
GEBufferFormat bufferFormat;
bool smoothedDepal;
};
void GenerateDepalFs(ShaderWriter &writer, const DepalConfig &config);

View File

@ -191,7 +191,9 @@ Draw2DPipeline *TextureShaderCache::GetDepalettizeShader(uint32_t clutMode, GETe
using namespace Draw;
// Generate an ID for depal shaders.
u32 id = (clutMode & 0xFFFFFF) | (textureFormat << 24) | (bufferFormat << 28);
u64 depthUpperBits = bufferFormat == GE_FORMAT_DEPTH16 ? ((gstate.getTextureAddress(0) & 0x600000) >> 20) : 0;
u64 id = (depthUpperBits << 32) | (clutMode & 0xFFFFFF) | (textureFormat << 24) | (bufferFormat << 28);
auto shader = depalCache_.find(id);
if (shader != depalCache_.end()) {
@ -207,6 +209,7 @@ Draw2DPipeline *TextureShaderCache::GetDepalettizeShader(uint32_t clutMode, GETe
config.bufferFormat = bufferFormat;
config.textureFormat = textureFormat;
config.smoothedDepal = smoothedDepal;
config.depthUpperBits = depthUpperBits;
char *buffer = new char[4096];
Draw2DPipeline *ts = draw2D_->Create2DPipeline([=](ShaderWriter &writer) -> Draw2DPipelineInfo {

View File

@ -62,6 +62,6 @@ private:
Draw::SamplerState *linearSampler_ = nullptr;
Draw2D *draw2D_;
std::map<u32, Draw2DPipeline *> depalCache_;
std::map<u64, Draw2DPipeline *> depalCache_;
std::map<u32, ClutTexture *> texCache_;
};

View File

@ -286,6 +286,7 @@ bool TestDepalShaders() {
config.mask = 0xFF;
config.bufferFormat = GE_FORMAT_8888;
config.textureFormat = GE_TFMT_CLUT32;
config.depthUpperBits = 0;
ShaderWriter writer(buffer, desc, ShaderStage::Fragment);
GenerateDepalFs(writer, config);