Add ShaderDepalMode enum, use in shader ID. Replaces smoothed bit.

This commit is contained in:
Henrik Rydgård
2022-09-11 14:14:18 +02:00
parent 9bd8b11bf8
commit 694dbe1271
11 changed files with 53 additions and 38 deletions
+22 -14
View File
@@ -92,8 +92,11 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
bool flatBug = bugs.Has(Draw::Bugs::BROKEN_FLAT_IN_SHADER) && g_Config.bVendorBugChecksEnabled;
bool doFlatShading = id.Bit(FS_BIT_FLATSHADE) && !flatBug;
bool shaderDepal = id.Bit(FS_BIT_SHADER_DEPAL) && !texture3D; // combination with texture3D not supported. Enforced elsewhere too.
bool smoothedDepal = id.Bit(FS_BIT_SHADER_SMOOTHED_DEPAL);
ShaderDepalMode shaderDepalMode = (ShaderDepalMode)id.Bits(FS_BIT_SHADER_DEPAL_MODE, 2);
if (texture3D) {
shaderDepalMode = ShaderDepalMode::OFF;
}
bool bgraTexture = id.Bit(FS_BIT_BGRA_TEXTURE);
bool colorWriteMask = id.Bit(FS_BIT_COLOR_WRITEMASK) && compat.bitwiseOps;
@@ -134,7 +137,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
bool needFragCoord = readFramebuffer || gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT);
bool writeDepth = gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT);
if (shaderDepal && !doTexture) {
if (shaderDepalMode != ShaderDepalMode::OFF && !doTexture) {
*errorString = "depal requires a texture";
return false;
}
@@ -153,7 +156,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
WRITE(p, "layout (binding = 1) uniform sampler2D fbotex;\n");
}
if (shaderDepal) {
if (shaderDepalMode != ShaderDepalMode::OFF) {
WRITE(p, "layout (binding = 2) uniform sampler2D pal;\n");
}
@@ -232,16 +235,13 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
WRITE(p, "Texture2D<vec4> fbotex : register(t1);\n");
}
if (shaderDepal) {
if (shaderDepalMode != ShaderDepalMode::OFF) {
WRITE(p, "SamplerState palSamp : register(s3);\n");
WRITE(p, "Texture2D<vec4> pal : register(t3);\n");
WRITE(p, "float2 textureSize(Texture2D<float4> tex, int mip) { float2 size; tex.GetDimensions(size.x, size.y); return size; }\n");
}
WRITE(p, "cbuffer base : register(b0) {\n%s};\n", ub_baseStr);
if (shaderDepal) {
WRITE(p, "float2 textureSize(Texture2D<float4> tex, int mip) { float2 size; tex.GetDimensions(size.x, size.y); return size; }\n");
}
}
if (enableAlphaTest) {
@@ -302,7 +302,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
WRITE(p, "};\n");
}
} else if (ShaderLanguageIsOpenGL(compat.shaderLanguage)) {
if ((shaderDepal || colorWriteMask) && gl_extensions.IsGLES) {
if ((shaderDepalMode != ShaderDepalMode::OFF || colorWriteMask) && gl_extensions.IsGLES) {
WRITE(p, "precision highp int;\n");
}
@@ -353,7 +353,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
}
}
if (shaderDepal) {
if (shaderDepalMode != ShaderDepalMode::OFF) {
WRITE(p, "uniform sampler2D pal;\n");
WRITE(p, "uniform uint u_depal_mask_shift_off_fmt;\n");
*uniformMask |= DIRTY_DEPAL;
@@ -563,7 +563,8 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
doTextureProjection = false;
}
if (!shaderDepal) {
switch (shaderDepalMode) {
case ShaderDepalMode::OFF:
if (compat.shaderLanguage == HLSL_D3D11) {
if (texture3D) {
if (doTextureProjection) {
@@ -609,7 +610,8 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
}
}
}
} else if (shaderDepal && smoothedDepal) {
break;
case ShaderDepalMode::SMOOTHED:
// Specific mode for Test Drive. Fixes the banding.
if (doTextureProjection) {
// We don't use textureProj because we need better control and it's probably not much of a savings anyway.
@@ -636,7 +638,8 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
p.C(" else if (depalShift == 10u) { index0 = t.b; }\n");
p.C(" }\n");
p.F(" t = ").SampleTexture2D("pal", "vec2(index0 * factor, 0.0)").C(";\n");
} else {
break;
case ShaderDepalMode::NORMAL:
if (doTextureProjection) {
// We don't use textureProj because we need better control and it's probably not much of a savings anyway.
// However it is good for precision on older hardware like PowerVR.
@@ -726,6 +729,11 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
WRITE(p, " t2 = mix(t2, t3, fraction.x);\n");
WRITE(p, " t = mix(t, t2, fraction.y);\n");
WRITE(p, " }\n");
break;
case ShaderDepalMode::CLUT8_8888:
// Not yet implemented.
WRITE(p, " t = vec4(0.0, 0.0, 0.0, 0.0);\n");
break;
}
if (texFunc != GE_TEXFUNC_REPLACE || !doTextureAlpha)
+10 -6
View File
@@ -180,8 +180,12 @@ std::string FragmentShaderDesc(const FShaderID &id) {
if (id.Bit(FS_BIT_COLOR_DOUBLE)) desc << "2x ";
if (id.Bit(FS_BIT_FLATSHADE)) desc << "Flat ";
if (id.Bit(FS_BIT_BGRA_TEXTURE)) desc << "BGRA ";
if (id.Bit(FS_BIT_SHADER_DEPAL)) desc << "Depal ";
if (id.Bit(FS_BIT_SHADER_SMOOTHED_DEPAL)) desc << "SmoothDepal ";
switch ((ShaderDepalMode)id.Bit(FS_BIT_SHADER_DEPAL_MODE)) {
case ShaderDepalMode::OFF: break;
case ShaderDepalMode::NORMAL: desc << "Depal "; break;
case ShaderDepalMode::SMOOTHED: desc << "SmoothDepal "; break;
case ShaderDepalMode::CLUT8_8888: desc << "CLUT8From8888Depal"; break;
}
if (id.Bit(FS_BIT_COLOR_WRITEMASK)) desc << "WriteMask ";
if (id.Bit(FS_BIT_SHADER_TEX_CLAMP)) {
desc << "TClamp";
@@ -261,8 +265,9 @@ void ComputeFragmentShaderID(FShaderID *id_out, const ComputedPipelineState &pip
bool doTextureProjection = (gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_MATRIX && MatrixNeedsProjection(gstate.tgenMatrix));
bool doTextureAlpha = gstate.isTextureAlphaUsed();
bool doFlatShading = gstate.getShadeMode() == GE_SHADE_FLAT;
bool useShaderDepal = gstate_c.useShaderDepal;
bool useSmoothedDepal = gstate_c.useSmoothedShaderDepal;
ShaderDepalMode shaderDepalMode = gstate_c.shaderDepalMode;
bool colorWriteMask = pipelineState.maskState.applyFramebufferRead;
ReplaceBlendType replaceBlend = pipelineState.blendState.replaceBlend;
@@ -289,8 +294,7 @@ void ComputeFragmentShaderID(FShaderID *id_out, const ComputedPipelineState &pip
id.SetBit(FS_BIT_TEXTURE_AT_OFFSET, textureAtOffset);
}
id.SetBit(FS_BIT_BGRA_TEXTURE, gstate_c.bgraTexture);
id.SetBit(FS_BIT_SHADER_DEPAL, useShaderDepal);
id.SetBit(FS_BIT_SHADER_SMOOTHED_DEPAL, useSmoothedDepal);
id.SetBits(FS_BIT_SHADER_DEPAL_MODE, 2, (int)shaderDepalMode);
id.SetBit(FS_BIT_3D_TEXTURE, gstate_c.curTextureIs3D);
}
+3 -4
View File
@@ -66,7 +66,7 @@ enum FShaderBit : uint8_t {
FS_BIT_DO_TEXTURE = 1,
FS_BIT_TEXFUNC = 2, // 3 bits
FS_BIT_TEXALPHA = 5,
FS_BIT_SHADER_DEPAL = 6,
FS_BIT_3D_TEXTURE = 6,
FS_BIT_SHADER_TEX_CLAMP = 7,
FS_BIT_CLAMP_S = 8,
FS_BIT_CLAMP_T = 9,
@@ -93,9 +93,8 @@ enum FShaderBit : uint8_t {
FS_BIT_TEST_DISCARD_TO_ZERO = 48,
FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL = 49,
FS_BIT_COLOR_WRITEMASK = 50,
FS_BIT_3D_TEXTURE = 51,
FS_BIT_SHADER_SMOOTHED_DEPAL = 52,
FS_BIT_REPLACE_LOGIC_OP = 53, // 4 bits. GE_LOGIC_COPY means no-op/off.
FS_BIT_REPLACE_LOGIC_OP = 51, // 4 bits. GE_LOGIC_COPY means no-op/off.
FS_BIT_SHADER_DEPAL_MODE = 55, // 2 bits (ShaderDepalMode)
};
static inline FShaderBit operator +(FShaderBit bit, int i) {
+3 -3
View File
@@ -1956,7 +1956,7 @@ void TextureCacheCommon::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer
// Since we started/ended render passes, might need these.
gstate_c.Dirty(DIRTY_DEPAL);
gstate_c.SetUseShaderDepal(true, smoothedDepal);
gstate_c.SetUseShaderDepal(smoothedDepal ? ShaderDepalMode::SMOOTHED : ShaderDepalMode::NORMAL);
gstate_c.depalFramebufferFormat = framebuffer->fb_format;
const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16);
@@ -1972,7 +1972,7 @@ void TextureCacheCommon::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer
depthUpperBits = (depth && framebuffer->fb_format == GE_FORMAT_8888) ? ((gstate.getTextureAddress(0) & 0x600000) >> 20) : 0;
textureShader = textureShaderCache_->GetDepalettizeShader(clutMode, texFormat, depth ? GE_FORMAT_DEPTH16 : framebuffer->fb_format, smoothedDepal, depthUpperBits);
gstate_c.SetUseShaderDepal(false, false);
gstate_c.SetUseShaderDepal(ShaderDepalMode::OFF);
}
if (textureShader) {
@@ -2045,7 +2045,7 @@ void TextureCacheCommon::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer
framebufferManager_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET);
BoundFramebufferTexture();
gstate_c.SetUseShaderDepal(false, false);
gstate_c.SetUseShaderDepal(ShaderDepalMode::OFF);
gstate_c.SetTextureFullAlpha(gstate.getTextureFormat() == GE_TFMT_5650);
}
+1 -1
View File
@@ -258,7 +258,7 @@ void TextureCacheD3D11::BindTexture(TexCacheEntry *entry) {
SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry);
ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, samplerKey);
context_->PSSetSamplers(0, 1, &state);
gstate_c.SetUseShaderDepal(false, false);
gstate_c.SetUseShaderDepal(ShaderDepalMode::OFF);
}
void TextureCacheD3D11::ApplySamplingParams(const SamplerCacheKey &key) {
+1 -1
View File
@@ -230,7 +230,7 @@ void TextureCacheGLES::BindTexture(TexCacheEntry *entry) {
int maxLevel = (entry->status & TexCacheEntry::STATUS_NO_MIPS) ? 0 : entry->maxLevel;
SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry);
ApplySamplingParams(samplerKey);
gstate_c.SetUseShaderDepal(false, false);
gstate_c.SetUseShaderDepal(ShaderDepalMode::OFF);
}
void TextureCacheGLES::Unbind() {
+7
View File
@@ -40,6 +40,13 @@ enum SkipDrawReasonFlags {
SKIPDRAW_WINDOW_MINIMIZED = 8, // Don't draw when the host window is minimized.
};
enum class ShaderDepalMode {
OFF = 0,
NORMAL = 1,
SMOOTHED = 2,
CLUT8_8888 = 3, // Read 8888 framebuffer as 8-bit CLUT.
};
// Global GPU-related utility functions.
// Nothing directly Ge-related in here.
+4 -6
View File
@@ -529,10 +529,9 @@ struct GPUStateCache {
bool IsDirty(u64 what) const {
return (dirty & what) != 0ULL;
}
void SetUseShaderDepal(bool depal, bool smoothed) {
if (depal != useShaderDepal) {
useShaderDepal = depal;
useSmoothedShaderDepal = smoothed;
void SetUseShaderDepal(ShaderDepalMode mode) {
if (mode != shaderDepalMode) {
shaderDepalMode = mode;
Dirty(DIRTY_FRAGMENTSHADER_STATE);
}
}
@@ -628,8 +627,7 @@ struct GPUStateCache {
SubmitType submitType;
int spline_num_points_u;
bool useShaderDepal;
bool useSmoothedShaderDepal;
ShaderDepalMode shaderDepalMode;
GEBufferFormat depalFramebufferFormat;
u32 getRelativeAddress(u32 data) const;
+1 -1
View File
@@ -371,7 +371,7 @@ VulkanFragmentShader *ShaderManagerVulkan::GetFragmentShaderFromModule(VkShaderM
// instantaneous.
#define CACHE_HEADER_MAGIC 0xff51f420
#define CACHE_VERSION 25
#define CACHE_VERSION 26
struct VulkanCacheHeader {
uint32_t magic;
uint32_t version;
+1 -1
View File
@@ -403,7 +403,7 @@ void TextureCacheVulkan::BindTexture(TexCacheEntry *entry) {
curSampler_ = samplerCache_.GetOrCreateSampler(samplerKey);
imageView_ = entry->vkTex->GetImageView();
drawEngine_->SetDepalTexture(VK_NULL_HANDLE, false);
gstate_c.SetUseShaderDepal(false, false);
gstate_c.SetUseShaderDepal(ShaderDepalMode::OFF);
}
void TextureCacheVulkan::ApplySamplingParams(const SamplerCacheKey &key) {
-1
View File
@@ -402,7 +402,6 @@ bool TestFragmentShaders() {
// bits we don't need to test because they are irrelevant on d3d11
id.SetBit(FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL, false);
id.SetBit(FS_BIT_SHADER_DEPAL, false);
// DX9 disabling:
if (static_cast<ReplaceAlphaType>(id.Bits(FS_BIT_STENCIL_TO_ALPHA, 2)) == ReplaceAlphaType::REPLACE_ALPHA_DUALSOURCE)