mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-10-12 02:08:45 +00:00
GS/HW: Treat depth input as R32 color input in convert shaders.
Co-authored-by: TellowKrinkle
This commit is contained in:
committed by
lightningterror
co-authored by
TellowKrinkle
parent
a44fe80caa
commit
bf892e9ece
@@ -1824,27 +1824,23 @@ void GSHWDrawConfig::DumpConfig(const std::string& path, const GSHWDrawConfig& c
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr u32 NUM_REMAP_INPUTS = static_cast<u32>(ShaderConvert::Count) * 8;
|
||||
static constexpr u32 NUM_REMAP_INPUTS = static_cast<u32>(ShaderConvert::Count) * 4;
|
||||
|
||||
static constexpr ShaderConvertSelector GetRemappedShader(u32 idx)
|
||||
{
|
||||
ShaderConvert convert = static_cast<ShaderConvert>(idx >> 3);
|
||||
bool depth_in = (idx >> 0) & 1;
|
||||
bool depth_out = (idx >> 1) & 1;
|
||||
bool biln = (idx >> 2) & 1;
|
||||
return ShaderConvertSelector(convert, 0xf, depth_in, depth_out, biln);
|
||||
ShaderConvert convert = static_cast<ShaderConvert>(idx >> 2);
|
||||
bool depth_out = (idx >> 0) & 1;
|
||||
bool biln = (idx >> 1) & 1;
|
||||
return ShaderConvertSelector(convert, 0xf, depth_out, biln);
|
||||
}
|
||||
|
||||
static constexpr bool RemapIndexIsValid(u32 idx)
|
||||
{
|
||||
ShaderConvert convert = static_cast<ShaderConvert>(idx >> 3);
|
||||
bool depth_in = (idx >> 0) & 1;
|
||||
bool depth_out = (idx >> 1) & 1;
|
||||
bool biln = (idx >> 2) & 1;
|
||||
if (HasVariableWriteMask(convert) && !depth_in && !depth_out && !biln)
|
||||
ShaderConvert convert = static_cast<ShaderConvert>(idx >> 2);
|
||||
bool depth_out = (idx >> 0) & 1;
|
||||
bool biln = (idx >> 1) & 1;
|
||||
if (HasVariableWriteMask(convert) && !depth_out && !biln)
|
||||
return false; // Handled as variable write mask
|
||||
if (depth_in && !HasFloat32Input(convert))
|
||||
return false;
|
||||
if (depth_out && !HasFloat32Output(convert))
|
||||
return false;
|
||||
if (biln && !SupportsBilinear(convert))
|
||||
|
||||
@@ -248,7 +248,6 @@ class ShaderConvertSelector
|
||||
{
|
||||
u32 shader : 8; // Main shader
|
||||
u32 mask : 8; // Variable color mask
|
||||
u32 depth_in : 1; // Depth texture input
|
||||
u32 depth_out : 1; // Depth texture output
|
||||
u32 biln : 1; // Shader bilinear (HW bilinear is specified separately)
|
||||
};
|
||||
@@ -259,11 +258,11 @@ class ShaderConvertSelector
|
||||
static_assert(sizeof(fields) == 4);
|
||||
|
||||
public:
|
||||
constexpr ShaderConvertSelector(ShaderConvert shader = ShaderConvert::COPY, u8 mask = 0xf, bool depth_in = false,
|
||||
constexpr ShaderConvertSelector(ShaderConvert shader = ShaderConvert::COPY, u8 mask = 0xf,
|
||||
bool depth_out = false, bool biln = false)
|
||||
: fields { static_cast<u32>(shader) }
|
||||
{
|
||||
*this = SetMask(mask).SetDepthInput(depth_in).SetDepthOutput(depth_out).SetBiln(biln);
|
||||
*this = SetMask(mask).SetDepthOutput(depth_out).SetBiln(biln);
|
||||
}
|
||||
|
||||
constexpr ShaderConvert Shader() const
|
||||
@@ -301,11 +300,6 @@ public:
|
||||
return fields.depth_out;
|
||||
}
|
||||
|
||||
constexpr bool DepthInput() const
|
||||
{
|
||||
return fields.depth_in;
|
||||
}
|
||||
|
||||
constexpr bool StencilOutput() const
|
||||
{
|
||||
return HasStencilOutput(Shader());
|
||||
@@ -351,7 +345,7 @@ public:
|
||||
return ShaderEntryPoint(Shader());
|
||||
}
|
||||
|
||||
constexpr ShaderConvertSelector SetMask(u8 mask) const
|
||||
constexpr ShaderConvertSelector SetMask(u8 mask = 0xf) const
|
||||
{
|
||||
ShaderConvertSelector tmp = *this;
|
||||
tmp.fields.mask = VariableWriteMask() ? (mask & 0xf) : DefaultMask();
|
||||
@@ -363,13 +357,6 @@ public:
|
||||
return SetMask((wr ? 1 : 0) | (wg ? 2 : 0) | (wb ? 4 : 0) | (wa ? 8 : 0));
|
||||
}
|
||||
|
||||
constexpr ShaderConvertSelector SetDepthInput(bool depth_in) const
|
||||
{
|
||||
ShaderConvertSelector tmp = *this;
|
||||
tmp.fields.depth_in = Float32Input() && depth_in;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
constexpr ShaderConvertSelector SetDepthOutput(bool depth_out) const
|
||||
{
|
||||
ShaderConvertSelector tmp = *this;
|
||||
@@ -386,7 +373,7 @@ public:
|
||||
|
||||
GSTexture::Format OutputFormat() const
|
||||
{
|
||||
if (fields.depth_out)
|
||||
if (DepthOutput())
|
||||
return GSTexture::Format::DepthStencil;
|
||||
else if (int bpp = IntegerOutputBpp())
|
||||
return bpp == 16 ? GSTexture::Format::UInt16 : GSTexture::Format::UInt32;
|
||||
@@ -403,7 +390,7 @@ public:
|
||||
private:
|
||||
// Helper variables for packing valid shaders into a contiguous range.
|
||||
static const std::span<const ShaderConvertSelector> SHADERS;
|
||||
static const std::array<u8, static_cast<u32>(ShaderConvert::Count) * 8> INDEX_REMAP;
|
||||
static const std::array<u8, static_cast<u32>(ShaderConvert::Count) * 4> INDEX_REMAP;
|
||||
static const u32 NUM_REMAPPED_SHADERS;
|
||||
|
||||
public:
|
||||
@@ -412,12 +399,11 @@ public:
|
||||
|
||||
u32 Index() const
|
||||
{
|
||||
if (VariableWriteMask() && !fields.depth_in && !fields.depth_out && !fields.biln)
|
||||
if (VariableWriteMask() && !fields.depth_out && !fields.biln)
|
||||
return GetShaderIndexForMask(Shader(), fields.mask) + NUM_REMAPPED_SHADERS;
|
||||
u32 remapped = INDEX_REMAP[(fields.depth_in << 0) +
|
||||
(fields.depth_out << 1) +
|
||||
(fields.biln << 2) +
|
||||
(fields.shader << 3)];
|
||||
u32 remapped = INDEX_REMAP[(fields.depth_out << 0) +
|
||||
(fields.biln << 1) +
|
||||
(fields.shader << 2)];
|
||||
pxAssert(remapped < NUM_REMAPPED_SHADERS);
|
||||
return remapped;
|
||||
}
|
||||
@@ -513,8 +499,7 @@ static inline ShaderConvertSelector GetConvertShader(GSTexture::Format src, GSTe
|
||||
break;
|
||||
}
|
||||
|
||||
return ShaderConvertSelector(shader, mask, src == GSTexture::Format::DepthStencil,
|
||||
dst == GSTexture::Format::DepthStencil);
|
||||
return ShaderConvertSelector(shader, mask, dst == GSTexture::Format::DepthStencil);
|
||||
}
|
||||
|
||||
static inline ShaderConvertSelector GetConvertShader(const GSTexture* src, const GSTexture* dst, u32 src_bpp, u32 dst_bpp, u8 mask = 0xf)
|
||||
|
||||
@@ -242,7 +242,6 @@ bool GSDevice11::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
sm_ps.AddMacro("HAS_BILN", static_cast<int>(shader.Biln()));
|
||||
sm_ps.AddMacro("HAS_STENCIL_OUTPUT", static_cast<int>(shader.StencilOutput()));
|
||||
sm_ps.AddMacro("HAS_INTEGER_OUTPUT", static_cast<int>(shader.IntegerOutputBpp() != 0));
|
||||
sm_ps.AddMacro("HAS_DEPTH_INPUT", 0); // unused
|
||||
sm_ps.AddMacro("HAS_DEPTH_OUTPUT", static_cast<int>(shader.DepthOutput()));
|
||||
sm_ps.AddMacro("HAS_FLOAT32_INPUT", static_cast<int>(shader.Float32Input()));
|
||||
sm_ps.AddMacro("HAS_FLOAT32_OUTPUT", static_cast<int>(shader.Float32Output()));
|
||||
@@ -1413,7 +1412,7 @@ void GSDevice11::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTextur
|
||||
ShaderConvertSelector shader, bool linear)
|
||||
{
|
||||
const u8 mask = shader.Mask();
|
||||
shader = ProcessShaderConvertSelector(shader); // Removes mask and depth output.
|
||||
shader = shader.SetMask(); // Mask is handled separately from program.
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, GetConvertShader(shader), nullptr, m_convert.bs[mask].get(), linear);
|
||||
}
|
||||
|
||||
@@ -1615,7 +1614,7 @@ void GSDevice11::FilteredDownsampleTexture(GSTexture* sTex, GSTexture* dTex, u32
|
||||
|
||||
void GSDevice11::DrawMultiStretchRects(const MultiStretchRect* rects, u32 num_rects, GSTexture* dTex, ShaderConvertSelector shader)
|
||||
{
|
||||
shader = ProcessShaderConvertSelector(shader);
|
||||
shader = shader.SetMask(); // Mask is handled separately from program.
|
||||
|
||||
IASetInputLayout(m_convert.il.get());
|
||||
IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
|
||||
@@ -280,11 +280,6 @@ private:
|
||||
protected:
|
||||
virtual void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
ShaderConvertSelector shader, bool linear) override;
|
||||
ShaderConvertSelector ProcessShaderConvertSelector(ShaderConvertSelector shader) const
|
||||
{
|
||||
// Depth input is handled same as color input. Mask is handled separately from program.
|
||||
return shader.SetDepthInput(false).SetMask(0xf);
|
||||
}
|
||||
public:
|
||||
GSDevice11();
|
||||
~GSDevice11() override;
|
||||
|
||||
@@ -1672,7 +1672,6 @@ void GSDevice12::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTextur
|
||||
ShaderConvertSelector shader, bool linear)
|
||||
{
|
||||
pxAssert(dTex);
|
||||
shader = ProcessShaderConvertSelector(shader); // Removes depth input
|
||||
const bool allow_discard = (shader.Mask() == 0xf);
|
||||
DoStretchRect(static_cast<GSTexture12*>(sTex), sRect, static_cast<GSTexture12*>(dTex), dRect,
|
||||
GetConvertPipeline(shader), linear, allow_discard);
|
||||
@@ -1768,8 +1767,6 @@ void GSDevice12::FilteredDownsampleTexture(GSTexture* sTex, GSTexture* dTex, u32
|
||||
void GSDevice12::DrawMultiStretchRects(
|
||||
const MultiStretchRect* rects, u32 num_rects, GSTexture* dTex, ShaderConvertSelector shader)
|
||||
{
|
||||
shader = ProcessShaderConvertSelector(shader); // Removes depth input
|
||||
|
||||
GSTexture* last_tex = rects[0].src;
|
||||
bool last_linear = rects[0].linear;
|
||||
u8 last_wmask = rects[0].wmask.wrgba;
|
||||
@@ -2766,7 +2763,6 @@ bool GSDevice12::CompileConvertPipelines()
|
||||
sm.AddMacro("HAS_BILN", static_cast<int>(shader.Biln()));
|
||||
sm.AddMacro("HAS_STENCIL_OUTPUT", static_cast<int>(shader.StencilOutput()));
|
||||
sm.AddMacro("HAS_INTEGER_OUTPUT", static_cast<int>(shader.IntegerOutputBpp() != 0));
|
||||
sm.AddMacro("HAS_DEPTH_INPUT", 0); // unused
|
||||
sm.AddMacro("HAS_DEPTH_OUTPUT", static_cast<int>(shader.DepthOutput()));
|
||||
sm.AddMacro("HAS_FLOAT32_INPUT", static_cast<int>(shader.Float32Input()));
|
||||
sm.AddMacro("HAS_FLOAT32_OUTPUT", static_cast<int>(shader.Float32Output()));
|
||||
|
||||
@@ -443,11 +443,6 @@ protected:
|
||||
ShaderConvertSelector shader, bool linear) override;
|
||||
virtual void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, const GSVector4& dRect,
|
||||
PresentShader shader, bool linear) override;
|
||||
ShaderConvertSelector ProcessShaderConvertSelector(ShaderConvertSelector shader) const
|
||||
{
|
||||
// Depth input handled same as color input.
|
||||
return shader.SetDepthInput(false);
|
||||
}
|
||||
public:
|
||||
GSDevice12();
|
||||
~GSDevice12() override;
|
||||
|
||||
@@ -1209,8 +1209,6 @@ bool GSDeviceMTL::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
name = [name stringByAppendingString:[NSString stringWithFormat:@" Mask=%x", shader.Mask()]];
|
||||
if (shader.Biln())
|
||||
name = [name stringByAppendingString:@" Biln"];
|
||||
if (shader.Float32Input())
|
||||
name = [name stringByAppendingString:shader.DepthInput() ? @" Depth" : @" Float"];
|
||||
if (shader.Float32Output())
|
||||
name = [name stringByAppendingString:shader.DepthOutput() ? @" → Depth" : @" → Float"];
|
||||
|
||||
@@ -1222,7 +1220,6 @@ bool GSDeviceMTL::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
if (scmask & 8) mask |= MTLColorWriteMaskAlpha;
|
||||
pdesc.colorAttachments[0].writeMask = mask;
|
||||
setFnConstantB(m_fn_constants, shader.Biln(), GSMTLConstantIndex_BILN);
|
||||
setFnConstantB(m_fn_constants, shader.DepthInput(), GSMTLConstantIndex_DEPTH_IN);
|
||||
setFnConstantB(m_fn_constants, shader.DepthOutput(), GSMTLConstantIndex_DEPTH_OUT);
|
||||
m_convert_pipeline[shader.Index()] = MakePipeline(pdesc, vs_convert, LoadShader(shader_name), name);
|
||||
}
|
||||
|
||||
@@ -156,7 +156,6 @@ enum GSMTLAttributes
|
||||
enum GSMTLFnConstants
|
||||
{
|
||||
GSMTLConstantIndex_BILN,
|
||||
GSMTLConstantIndex_DEPTH_IN,
|
||||
GSMTLConstantIndex_DEPTH_OUT,
|
||||
GSMTLConstantIndex_CAS_SHARPEN_ONLY,
|
||||
GSMTLConstantIndex_FRAMEBUFFER_FETCH,
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
using namespace metal;
|
||||
|
||||
constant bool BILN [[function_constant(GSMTLConstantIndex_BILN)]];
|
||||
constant bool DEPTH_IN [[function_constant(GSMTLConstantIndex_DEPTH_IN)]];
|
||||
constant bool DEPTH_OUT [[function_constant(GSMTLConstantIndex_DEPTH_OUT)]];
|
||||
constant bool COLOR_IN = !DEPTH_IN;
|
||||
constant bool COLOR_OUT = !DEPTH_OUT;
|
||||
|
||||
struct ConvertVSIn
|
||||
@@ -229,12 +227,11 @@ struct DepthOrColorOut
|
||||
|
||||
struct ConvertPSDepthOrColorRes
|
||||
{
|
||||
texture2d<float> color [[texture(GSMTLTextureIndexNonHW), function_constant(COLOR_IN)]];
|
||||
depth2d<float> depth [[texture(GSMTLTextureIndexNonHW), function_constant(DEPTH_IN)]];
|
||||
texture2d<float> texture [[texture(GSMTLTextureIndexNonHW)]];
|
||||
sampler s [[sampler(0)]];
|
||||
float sample(float2 coord)
|
||||
{
|
||||
return COLOR_IN ? color.sample(s, coord).x : depth.sample(s, coord);
|
||||
return texture.sample(s, coord).x;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -427,7 +427,6 @@ bool GSDeviceOGL::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
macro += fmt::format("#define HAS_BILN {}\n", static_cast<int>(shader.Biln()));
|
||||
macro += fmt::format("#define HAS_STENCIL_OUTPUT {}\n", static_cast<int>(shader.StencilOutput()));
|
||||
macro += fmt::format("#define HAS_INTEGER_OUTPUT {}\n", static_cast<int>(shader.IntegerOutputBpp() != 0));
|
||||
macro += fmt::format("#define HAS_DEPTH_INPUT {}\n", 0); // unused
|
||||
macro += fmt::format("#define HAS_DEPTH_OUTPUT {}\n", static_cast<int>(shader.DepthOutput()));
|
||||
macro += fmt::format("#define HAS_FLOAT32_INPUT {}\n", static_cast<int>(shader.Float32Input()));
|
||||
macro += fmt::format("#define HAS_FLOAT32_OUTPUT {}\n", static_cast<int>(shader.Float32Output()));
|
||||
@@ -1677,7 +1676,7 @@ void GSDeviceOGL::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTextu
|
||||
ShaderConvertSelector shader, bool linear)
|
||||
{
|
||||
const u8 mask = shader.Mask();
|
||||
shader = ProcessShaderConvertSelector(shader); // Removes mask and depth input.
|
||||
shader = shader.SetMask(); // Mask is handled separately from program.
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, GetConvertProgram(shader), false, OMColorMaskSelector(mask), linear);
|
||||
}
|
||||
|
||||
@@ -1868,7 +1867,7 @@ void GSDeviceOGL::DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect
|
||||
void GSDeviceOGL::DrawMultiStretchRects(
|
||||
const MultiStretchRect* rects, u32 num_rects, GSTexture* dTex, ShaderConvertSelector shader)
|
||||
{
|
||||
shader = ProcessShaderConvertSelector(shader);
|
||||
shader = shader.SetMask(); // Mask is handled separately from program.
|
||||
|
||||
IASetVAO(m_vao);
|
||||
IASetPrimitiveTopology(GL_TRIANGLE_STRIP);
|
||||
|
||||
@@ -291,11 +291,6 @@ private:
|
||||
protected:
|
||||
virtual void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
ShaderConvertSelector shader, bool linear) override;
|
||||
virtual ShaderConvertSelector ProcessShaderConvertSelector(ShaderConvertSelector shader) const
|
||||
{
|
||||
// Depth input is handled same as color. Color mask is handled separately.
|
||||
return shader.SetDepthInput(false).SetMask(0xf);
|
||||
}
|
||||
public:
|
||||
GSDeviceOGL();
|
||||
virtual ~GSDeviceOGL();
|
||||
|
||||
@@ -2925,7 +2925,6 @@ void GSDeviceVK::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTextur
|
||||
ShaderConvertSelector shader, bool linear)
|
||||
{
|
||||
pxAssert(dTex);
|
||||
shader = ProcessShaderConvertSelector(shader); // Removes depth input
|
||||
const bool allow_discard = (shader.Mask() == 0xf);
|
||||
DoStretchRect(static_cast<GSTextureVK*>(sTex), sRect, static_cast<GSTextureVK*>(dTex), dRect,
|
||||
GetConvertPipeline(shader), linear, allow_discard);
|
||||
@@ -2954,8 +2953,6 @@ void GSDeviceVK::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
|
||||
void GSDeviceVK::DrawMultiStretchRects(
|
||||
const MultiStretchRect* rects, u32 num_rects, GSTexture* dTex, ShaderConvertSelector shader)
|
||||
{
|
||||
shader = ProcessShaderConvertSelector(shader); // Removes depth input
|
||||
|
||||
GSTexture* last_tex = rects[0].src;
|
||||
bool last_linear = rects[0].linear;
|
||||
u8 last_wmask = rects[0].wmask.wrgba;
|
||||
@@ -4077,7 +4074,6 @@ bool GSDeviceVK::CompileConvertPipelines()
|
||||
macro += fmt::format("#define HAS_BILN {}\n", static_cast<int>(shader.Biln()));
|
||||
macro += fmt::format("#define HAS_STENCIL_OUTPUT {}\n", static_cast<int>(shader.StencilOutput()));
|
||||
macro += fmt::format("#define HAS_INTEGER_OUTPUT {}\n", static_cast<int>(shader.IntegerOutputBpp() != 0));
|
||||
macro += fmt::format("#define HAS_DEPTH_INPUT {}\n", 0); // unused
|
||||
macro += fmt::format("#define HAS_DEPTH_OUTPUT {}\n", static_cast<int>(shader.DepthOutput()));
|
||||
macro += fmt::format("#define HAS_FLOAT32_INPUT {}\n", static_cast<int>(shader.Float32Input()));
|
||||
macro += fmt::format("#define HAS_FLOAT32_OUTPUT {}\n", static_cast<int>(shader.Float32Output()));
|
||||
|
||||
@@ -495,11 +495,6 @@ protected:
|
||||
ShaderConvertSelector shader, bool linear) override;
|
||||
virtual void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, const GSVector4& dRect,
|
||||
PresentShader shader, bool linear) override;
|
||||
ShaderConvertSelector ProcessShaderConvertSelector(ShaderConvertSelector shader) const
|
||||
{
|
||||
// Depth input handled same as color input.
|
||||
return shader.SetDepthInput(false);
|
||||
}
|
||||
public:
|
||||
GSDeviceVK();
|
||||
~GSDeviceVK() override;
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
/// Version number for GS and other shaders. Increment whenever any of the contents of the
|
||||
/// shaders change, to invalidate the cache.
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 97; // Last changed in PR 14477
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 98; // Last changed in PR 14477
|
||||
|
||||
Reference in New Issue
Block a user