From 694dbe1271085155433ef2ddf52d7305dc8a8bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 11 Sep 2022 14:14:18 +0200 Subject: [PATCH] Add ShaderDepalMode enum, use in shader ID. Replaces smoothed bit. --- GPU/Common/FragmentShaderGenerator.cpp | 36 ++++++++++++++++---------- GPU/Common/ShaderId.cpp | 16 +++++++----- GPU/Common/ShaderId.h | 7 +++-- GPU/Common/TextureCacheCommon.cpp | 6 ++--- GPU/D3D11/TextureCacheD3D11.cpp | 2 +- GPU/GLES/TextureCacheGLES.cpp | 2 +- GPU/GPU.h | 7 +++++ GPU/GPUState.h | 10 +++---- GPU/Vulkan/ShaderManagerVulkan.cpp | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 2 +- unittest/TestShaderGenerators.cpp | 1 - 11 files changed, 53 insertions(+), 38 deletions(-) diff --git a/GPU/Common/FragmentShaderGenerator.cpp b/GPU/Common/FragmentShaderGenerator.cpp index feec43ff75..d1aabac698 100644 --- a/GPU/Common/FragmentShaderGenerator.cpp +++ b/GPU/Common/FragmentShaderGenerator.cpp @@ -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 fbotex : register(t1);\n"); } - if (shaderDepal) { + if (shaderDepalMode != ShaderDepalMode::OFF) { WRITE(p, "SamplerState palSamp : register(s3);\n"); WRITE(p, "Texture2D pal : register(t3);\n"); + WRITE(p, "float2 textureSize(Texture2D 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 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) diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index d05cc3a986..f873024c39 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -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); } diff --git a/GPU/Common/ShaderId.h b/GPU/Common/ShaderId.h index bd54e2bd82..999faf2e44 100644 --- a/GPU/Common/ShaderId.h +++ b/GPU/Common/ShaderId.h @@ -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) { diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index cefc86f4c5..1be81f8abc 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -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); } diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index c656f3d7dd..799f905514 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -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) { diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 928854f1e2..14ebad20be 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -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() { diff --git a/GPU/GPU.h b/GPU/GPU.h index 5410fb43d5..1fd455c662 100644 --- a/GPU/GPU.h +++ b/GPU/GPU.h @@ -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. diff --git a/GPU/GPUState.h b/GPU/GPUState.h index f31d31e176..cbfb58395d 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -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; diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index b3e5ff339f..9cb91e00c6 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -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; diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index d11e92ba05..bbb0f611bb 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -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) { diff --git a/unittest/TestShaderGenerators.cpp b/unittest/TestShaderGenerators.cpp index 7bdb0b3e8c..8cf73cd8b4 100644 --- a/unittest/TestShaderGenerators.cpp +++ b/unittest/TestShaderGenerators.cpp @@ -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(id.Bits(FS_BIT_STENCIL_TO_ALPHA, 2)) == ReplaceAlphaType::REPLACE_ALPHA_DUALSOURCE)