Skip to content

Commit

Permalink
Merge pull request #15859 from hrydgard/depal-depth-565
Browse files Browse the repository at this point in the history
Allow binding depth as 565 by going through depal
  • Loading branch information
hrydgard authored Aug 21, 2022
2 parents 5f30c88 + a11e7e1 commit 58adf3e
Show file tree
Hide file tree
Showing 17 changed files with 198 additions and 35 deletions.
16 changes: 16 additions & 0 deletions Common/GPU/ShaderWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,3 +423,19 @@ ShaderWriter &ShaderWriter::SampleTexture2D(const char *sampName, const char *uv
}
return *this;
}

ShaderWriter &ShaderWriter::GetTextureSize(const char *szVariable, const char *texName) {
switch (lang_.shaderLanguage) {
case HLSL_D3D11:
F(" float2 %s; %s.GetDimensions(%s.x, %s.y);", szVariable, texName, szVariable, szVariable);
break;
case HLSL_D3D9:
F(" float2 %s; %s.GetDimensions(%s.x, %s.y);", szVariable, texName, szVariable, szVariable);
break;
default:
// Note: we ignore the sampler. make sure you bound samplers to the textures correctly.
F("vec2 %s = textureSize(%s, 0);", szVariable, texName);
break;
}
return *this;
}
3 changes: 2 additions & 1 deletion Common/GPU/ShaderWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ class ShaderWriter {

void ConstFloat(const char *name, float value);

ShaderWriter &SampleTexture2D(const char *sampName, const char *uv);
ShaderWriter &SampleTexture2D(const char *texName, const char *uv);
ShaderWriter &GetTextureSize(const char *szVariable, const char *texName);

// Simple shaders with no special tricks.
void BeginVSMain(Slice<InputDef> inputs, Slice<UniformDef> uniforms, Slice<VaryingDef> varyings);
Expand Down
1 change: 1 addition & 0 deletions Core/Compatibility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) {
CheckSetting(iniFile, gameID, "ZZT3SelectHack", &flags_.ZZT3SelectHack);
CheckSetting(iniFile, gameID, "AllowLargeFBTextureOffsets", &flags_.AllowLargeFBTextureOffsets);
CheckSetting(iniFile, gameID, "AtracLoopHack", &flags_.AtracLoopHack);
CheckSetting(iniFile, gameID, "DeswizzleDepth", &flags_.DeswizzleDepth);
}

void Compatibility::CheckSetting(IniFile &iniFile, const std::string &gameID, const char *option, bool *flag) {
Expand Down
1 change: 1 addition & 0 deletions Core/Compatibility.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ struct CompatFlags {
bool ZZT3SelectHack;
bool AllowLargeFBTextureOffsets;
bool AtracLoopHack;
bool DeswizzleDepth;
};

class IniFile;
Expand Down
2 changes: 1 addition & 1 deletion Core/CoreParameter.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ struct CoreParameter {
bool headLess; // Try to avoid messageboxes etc

// Internal PSP rendering resolution and scale factor.
int renderScaleFactor;
int renderScaleFactor = 1;
int renderWidth;
int renderHeight;

Expand Down
7 changes: 4 additions & 3 deletions GPU/Common/DepalettizeCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,10 @@ Draw::SamplerState *DepalShaderCache::GetSampler() {
return nearestSampler_;
}

DepalShader *DepalShaderCache::GetDepalettizeShader(uint32_t clutMode, GEBufferFormat pixelFormat) {
DepalShader *DepalShaderCache::GetDepalettizeShader(uint32_t clutMode, GETextureFormat textureFormat, GEBufferFormat bufferFormat) {
using namespace Draw;

u32 id = GenerateShaderID(clutMode, pixelFormat);
u32 id = GenerateShaderID(clutMode, textureFormat, bufferFormat);

auto shader = cache_.find(id);
if (shader != cache_.end()) {
Expand All @@ -171,7 +171,8 @@ DepalShader *DepalShaderCache::GetDepalettizeShader(uint32_t clutMode, GEBufferF
config.startPos = gstate.getClutIndexStartPos();
config.shift = gstate.getClutIndexShift();
config.mask = gstate.getClutIndexMask();
config.pixelFormat = pixelFormat;
config.bufferFormat = bufferFormat;
config.textureFormat = textureFormat;

GenerateDepalFs(buffer, config, draw_->GetShaderLanguageDesc());

Expand Down
6 changes: 3 additions & 3 deletions GPU/Common/DepalettizeCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class DepalShaderCache {
~DepalShaderCache();

// This also uploads the palette and binds the correct texture.
DepalShader *GetDepalettizeShader(uint32_t clutMode, GEBufferFormat pixelFormat);
DepalShader *GetDepalettizeShader(uint32_t clutMode, GETextureFormat texFormat, GEBufferFormat pixelFormat);
Draw::Texture *GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut);

Draw::SamplerState *GetSampler();
Expand All @@ -63,8 +63,8 @@ class DepalShaderCache {
void DeviceRestore(Draw::DrawContext *draw);

private:
static uint32_t GenerateShaderID(uint32_t clutMode, GEBufferFormat pixelFormat) {
return (clutMode & 0xFFFFFF) | (pixelFormat << 24);
static uint32_t GenerateShaderID(uint32_t clutMode, GETextureFormat texFormat, GEBufferFormat pixelFormat) {
return (clutMode & 0xFFFFFF) | (pixelFormat << 24) | (texFormat << 28);
}

static uint32_t GetClutID(GEPaletteFormat clutFormat, uint32_t clutHash) {
Expand Down
37 changes: 31 additions & 6 deletions GPU/Common/DepalettizeShaderCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void GenerateDepalShader300(ShaderWriter &writer, const DepalConfig &config, con
const int shift = config.shift;
const int mask = config.mask;

if (config.pixelFormat == GE_FORMAT_DEPTH16) {
if (config.bufferFormat == GE_FORMAT_DEPTH16) {
DepthScaleFactors factors = GetDepthScaleFactors();
writer.ConstFloat("z_scale", factors.scale);
writer.ConstFloat("z_offset", factors.offset);
Expand All @@ -71,7 +71,7 @@ void GenerateDepalShader300(ShaderWriter &writer, const DepalConfig &config, con
writer.C(" vec4 color = ").SampleTexture2D("tex", "v_texcoord").C(";\n");

int shiftedMask = mask << shift;
switch (config.pixelFormat) {
switch (config.bufferFormat) {
case GE_FORMAT_8888:
if (shiftedMask & 0xFF) writer.C(" int r = int(color.r * 255.99);\n"); else writer.C(" int r = 0;\n");
if (shiftedMask & 0xFF00) writer.C(" int g = int(color.g * 255.99);\n"); else writer.C(" int g = 0;\n");
Expand Down Expand Up @@ -102,6 +102,17 @@ void GenerateDepalShader300(ShaderWriter &writer, const DepalConfig &config, con
case GE_FORMAT_DEPTH16:
// Remap depth buffer.
writer.C(" float depth = (color.x - z_offset) * z_scale;\n");

if (config.bufferFormat == GE_FORMAT_DEPTH16 && config.textureFormat == GE_TFMT_5650) {
// Convert depth to 565, without going through a CLUT.
writer.C(" int idepth = int(clamp(depth, 0.0, 65535.0));\n");
writer.C(" float r = (idepth & 31) / 31.0f;\n");
writer.C(" float g = ((idepth >> 5) & 63) / 63.0f;\n");
writer.C(" float b = ((idepth >> 11) & 31) / 31.0f;\n");
writer.C(" vec4 outColor = vec4(r, g, b, 1.0);\n");
return;
}

writer.C(" int index = int(clamp(depth, 0.0, 65535.0));\n");
break;
default:
Expand Down Expand Up @@ -135,16 +146,18 @@ void GenerateDepalShaderFloat(ShaderWriter &writer, const DepalConfig &config, c
const int shift = config.shift;
const int mask = config.mask;

if (config.pixelFormat == GE_FORMAT_DEPTH16) {
if (config.bufferFormat == GE_FORMAT_DEPTH16) {
DepthScaleFactors factors = GetDepthScaleFactors();
writer.ConstFloat("z_scale", factors.scale);
writer.ConstFloat("z_offset", factors.offset);
}

writer.C(" vec4 index = ").SampleTexture2D("tex", "v_texcoord").C(";\n");

float index_multiplier = 1.0f;
// pixelformat is the format of the texture we are sampling.
bool formatOK = true;
switch (config.pixelFormat) {
switch (config.bufferFormat) {
case GE_FORMAT_8888:
if ((mask & (mask + 1)) == 0) {
// If the value has all bits contiguous (bitmask check above), we can mod by it + 1.
Expand Down Expand Up @@ -222,6 +235,19 @@ void GenerateDepalShaderFloat(ShaderWriter &writer, const DepalConfig &config, c
case GE_FORMAT_DEPTH16:
{
// TODO: I think we can handle most scenarios here, but texturing from depth buffers requires an extension on ES 2.0 anyway.
// Not on D3D9 though, so this path is still relevant.

if (config.bufferFormat == GE_FORMAT_DEPTH16 && config.textureFormat == GE_TFMT_5650) {
// Convert depth to 565, without going through a CLUT.
writer.C(" float depth = (index.x - z_offset) * z_scale;\n");
writer.C(" float idepth = floor(clamp(depth, 0.0, 65535.0));\n");
writer.C(" float r = mod(idepth, 32.0) / 31.0f;\n");
writer.C(" float g = mod(floor(idepth / 32.0), 64.0) / 63.0f;\n");
writer.C(" float b = mod(floor(idepth / 2048.0), 32.0) / 31.0f;\n");
writer.C(" vec4 outColor = vec4(r, g, b, 1.0);\n");
return;
}

if (shift < 16) {
index_multiplier = 1.0f / (float)(1 << shift);
truncate_cpy(lookupMethod, "((index.x - z_offset) * z_scale)");
Expand Down Expand Up @@ -249,7 +275,7 @@ void GenerateDepalShaderFloat(ShaderWriter &writer, const DepalConfig &config, c
// index_multiplier -= 0.01f / texturePixels;

if (!formatOK) {
ERROR_LOG_REPORT_ONCE(depal, G3D, "%s depal unsupported: shift=%d mask=%02x offset=%d", GeBufferFormatToString(config.pixelFormat), shift, mask, config.startPos);
ERROR_LOG_REPORT_ONCE(depal, G3D, "%s depal unsupported: shift=%d mask=%02x offset=%d", GeBufferFormatToString(config.bufferFormat), shift, mask, config.startPos);
}

// Offset by half a texel (plus clutBase) to turn NEAREST filtering into FLOOR.
Expand All @@ -258,7 +284,6 @@ void GenerateDepalShaderFloat(ShaderWriter &writer, const DepalConfig &config, c
char offset[128] = "";
sprintf(offset, " + %f", texel_offset);

writer.C(" vec4 index = ").SampleTexture2D("tex", "v_texcoord").C(";\n");
writer.F(" float coord = (%s * %f)%s;\n", lookupMethod, index_multiplier, offset);
writer.C(" vec4 outColor = ").SampleTexture2D("pal", "vec2(coord, 0.0)").C(";\n");
}
Expand Down
3 changes: 2 additions & 1 deletion GPU/Common/DepalettizeShaderCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ struct DepalConfig {
int shift;
u32 startPos;
GEPaletteFormat clutFormat;
GEBufferFormat pixelFormat;
GETextureFormat textureFormat;
GEBufferFormat bufferFormat;
};

void GenerateDepalFs(char *buffer, const DepalConfig &config, const ShaderLanguageDesc &lang);
Expand Down
68 changes: 64 additions & 4 deletions GPU/Common/Draw2D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,23 @@ static const SamplerDef samplers[1] = {
{ "tex" },
};

static const UniformDef uniforms[2] = {
{ "vec2", "texSize", 0 },
{ "float", "scaleFactor", 1},
};

struct Draw2DUB {
float texSizeX;
float texSizeY;
float scaleFactor;
};

const UniformBufferDesc draw2DUBDesc{ sizeof(Draw2DUB), {
{ "texSize", -1, 0, UniformType::FLOAT2, 0 },
{ "scaleFactor", -1, 1, UniformType::FLOAT1, 0 },
} };


RasterChannel GenerateDraw2DFs(ShaderWriter &writer) {
writer.DeclareSamplers(samplers);
writer.BeginFSMain(Slice<UniformDef>::empty(), varyings, FSFLAG_NONE);
Expand Down Expand Up @@ -70,6 +87,27 @@ RasterChannel GenerateDraw2D565ToDepthFs(ShaderWriter &writer) {
writer.F(" highp float depthValue = (floor(rgb.x * 31.99) + floor(rgb.y * 63.99) * 32.0 + floor(rgb.z * 31.99) * 2048.0); \n");
writer.F(" gl_FragDepth = (depthValue / %f) + %f;\n", factors.scale, factors.offset);
writer.EndFSMain("outColor", FSFLAG_WRITEDEPTH);

return RASTER_DEPTH;
}

RasterChannel GenerateDraw2D565ToDepthDeswizzleFs(ShaderWriter &writer) {
writer.DeclareSamplers(samplers);
writer.BeginFSMain(uniforms, varyings, FSFLAG_WRITEDEPTH);
writer.C(" vec4 outColor = vec4(0.0, 0.0, 0.0, 0.0);\n");
// Unlike when just copying a depth buffer, here we're generating new depth values so we'll
// have to apply the scaling.
DepthScaleFactors factors = GetDepthScaleFactors();
writer.C(" vec2 tsize = texSize;\n");
writer.C(" vec2 coord = v_texcoord * tsize;\n");
writer.F(" float strip = 4.0 * scaleFactor;\n");
writer.C(" float in_strip = mod(coord.y, strip);\n");
writer.C(" coord.y = coord.y - in_strip + strip - in_strip;\n");
writer.C(" coord /= tsize;\n");
writer.C(" vec3 rgb = ").SampleTexture2D("tex", "coord").C(".xyz;\n");
writer.F(" highp float depthValue = (floor(rgb.x * 31.99) + floor(rgb.y * 63.99) * 32.0 + floor(rgb.z * 31.99) * 2048.0); \n");
writer.F(" gl_FragDepth = (depthValue / %f) + %f;\n", factors.scale, factors.offset);
writer.EndFSMain("outColor", FSFLAG_WRITEDEPTH);
return RASTER_DEPTH;
}

Expand Down Expand Up @@ -159,7 +197,7 @@ Draw::Pipeline *FramebufferManagerCommon::Create2DPipeline(RasterChannel (*gener
{ draw2DVs_, fs },
inputLayout,
depthStencil,
blend, rasterNoCull, nullptr,
blend, rasterNoCull, &draw2DUBDesc,
};

Draw::Pipeline *pipeline = draw_->CreateGraphicsPipeline(pipelineDesc);
Expand All @@ -174,7 +212,7 @@ Draw::Pipeline *FramebufferManagerCommon::Create2DPipeline(RasterChannel (*gener
return pipeline;
}

void FramebufferManagerCommon::DrawStrip2D(Draw::Texture *tex, Draw2DVertex *verts, int vertexCount, bool linearFilter, Draw2DShader shader) {
void FramebufferManagerCommon::DrawStrip2D(Draw::Texture *tex, Draw2DVertex *verts, int vertexCount, bool linearFilter, Draw2DShader shader, float texW, float texH) {
using namespace Draw;

Ensure2DResources();
Expand All @@ -196,8 +234,8 @@ void FramebufferManagerCommon::DrawStrip2D(Draw::Texture *tex, Draw2DVertex *ver
}
if (!draw2DPipelineDepth_) {
draw2DPipelineDepth_ = Create2DPipeline(&GenerateDraw2DDepthFs);
linearFilter = false;
}
linearFilter = false;
draw_->BindPipeline(draw2DPipelineDepth_);
break;

Expand All @@ -208,15 +246,37 @@ void FramebufferManagerCommon::DrawStrip2D(Draw::Texture *tex, Draw2DVertex *ver
}
if (!draw2DPipeline565ToDepth_) {
draw2DPipeline565ToDepth_ = Create2DPipeline(&GenerateDraw2D565ToDepthFs);
linearFilter = false;
}
linearFilter = false;
draw_->BindPipeline(draw2DPipeline565ToDepth_);
break;

case DRAW2D_565_TO_DEPTH_DESWIZZLE:
if (!draw_->GetDeviceCaps().fragmentShaderDepthWriteSupported) {
// Can't do it
return;
}
if (!draw2DPipeline565ToDepthDeswizzle_) {
draw2DPipeline565ToDepthDeswizzle_ = Create2DPipeline(&GenerateDraw2D565ToDepthDeswizzleFs);
}
linearFilter = false;
draw_->BindPipeline(draw2DPipeline565ToDepthDeswizzle_);
break;
}

Draw2DUB ub;
ub.texSizeX = tex ? tex->Width() : texW;
ub.texSizeY = tex ? tex->Height() : texH;
ub.scaleFactor = (float)renderScaleFactor_;
draw_->UpdateDynamicUniformBuffer(&ub, sizeof(ub));

if (tex) {
draw_->BindTextures(TEX_SLOT_PSP_TEXTURE, 1, &tex);
}
draw_->BindSamplerStates(TEX_SLOT_PSP_TEXTURE, 1, linearFilter ? &draw2DSamplerLinear_ : &draw2DSamplerNearest_);
draw_->DrawUP(verts, vertexCount);

draw_->InvalidateCachedState();

gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE | DIRTY_VERTEXSHADER_STATE);
}
2 changes: 2 additions & 0 deletions GPU/Common/Draw2D.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ enum Draw2DShader {
DRAW2D_COPY_COLOR,
DRAW2D_COPY_DEPTH,
DRAW2D_565_TO_DEPTH,
DRAW2D_565_TO_DEPTH_DESWIZZLE,
};

inline RasterChannel Draw2DSourceChannel(Draw2DShader shader) {
Expand All @@ -22,6 +23,7 @@ inline RasterChannel Draw2DSourceChannel(Draw2DShader shader) {
return RASTER_DEPTH;
case DRAW2D_COPY_COLOR:
case DRAW2D_565_TO_DEPTH:
case DRAW2D_565_TO_DEPTH_DESWIZZLE:
default:
return RASTER_COLOR;
}
Expand Down
Loading

0 comments on commit 58adf3e

Please sign in to comment.