mirror of https://github.com/PCSX2/pcsx2.git
GS: Reduce MAD buffering draw size
It's silly to draw to the whole double-sized render target, but discard half the pixels. Also centralizes the constant setup, get rid of the duplication.
This commit is contained in:
parent
b26acad721
commit
6ad222117d
|
@ -66,15 +66,11 @@ float4 ps_main3(PS_INPUT input) : SV_Target0
|
|||
const int vres = int(ZrH.z) >> 1; // vertical resolution of source texture
|
||||
const int lofs = ((((vres + 1) >> 1) << 1) - vres) & bank; // line alignment offset for bank 1
|
||||
const int vpos = int(input.p.y) + lofs; // vertical position of destination texture
|
||||
const float2 bofs = float2(0.0f, 0.5f * bank); // vertical offset of the current bank relative to source texture size
|
||||
const float2 vscale = float2(1.0f, 2.0f); // scaling factor from source to destination texture
|
||||
const float2 optr = input.t - bofs; // used to check if the current destination line is within the current bank
|
||||
const float2 iptr = optr * vscale; // pointer to the current pixel in the source texture
|
||||
|
||||
// if the index of current destination line belongs to the current fiels we update it, otherwise
|
||||
// we leave the old line in the destination buffer
|
||||
if ((optr.y >= 0.0f) && (optr.y < 0.5f) && ((vpos & 1) == field))
|
||||
return Texture.SampleLevel(Sampler, iptr, 0);
|
||||
if ((vpos & 1) == field)
|
||||
return Texture.SampleLevel(Sampler, input.t, 0);
|
||||
else
|
||||
discard;
|
||||
|
||||
|
|
|
@ -60,15 +60,11 @@ void ps_main3()
|
|||
int vres = int(ZrH.z) >> 1; // vertical resolution of source texture
|
||||
int lofs = ((((vres + 1) >> 1) << 1) - vres) & bank; // line alignment offset for bank 1
|
||||
int vpos = int(gl_FragCoord.y) + lofs; // vertical position of destination texture
|
||||
vec2 bofs = vec2(0.0f, 0.5f * float(bank)); // vertical offset of the current bank relative to source texture size
|
||||
vec2 vscale = vec2(1.0f, 2.0f); // scaling factor from source to destination texture
|
||||
vec2 optr = PSin_t - bofs; // used to check if the current destination line is within the current bank
|
||||
vec2 iptr = optr * vscale; // pointer to the current pixel in the source texture
|
||||
|
||||
// if the index of current destination line belongs to the current fiels we update it, otherwise
|
||||
// we leave the old line in the destination buffer
|
||||
if ((optr.y >= 0.0f) && (optr.y < 0.5f) && ((vpos & 1) == field))
|
||||
SV_Target0 = textureLod(TextureSampler, iptr, 0);
|
||||
if ((vpos & 1) == field)
|
||||
SV_Target0 = textureLod(TextureSampler, PSin_t, 0);
|
||||
else
|
||||
discard;
|
||||
}
|
||||
|
|
|
@ -82,15 +82,11 @@ void ps_main3()
|
|||
const int vres = int(ZrH.z) >> 1; // vertical resolution of source texture
|
||||
const int lofs = ((((vres + 1) >> 1) << 1) - vres) & bank; // line alignment offset for bank 1
|
||||
const int vpos = int(gl_FragCoord.y) + lofs; // vertical position of destination texture
|
||||
const vec2 bofs = vec2(0.0f, 0.5f * bank); // vertical offset of the current bank relative to source texture size
|
||||
const vec2 vscale = vec2(1.0f, 2.0f); // scaling factor from source to destination texture
|
||||
const vec2 optr = v_tex - bofs; // used to check if the current destination line is within the current bank
|
||||
const vec2 iptr = optr * vscale; // pointer to the current pixel in the source texture
|
||||
|
||||
// if the index of current destination line belongs to the current fiels we update it, otherwise
|
||||
// we leave the old line in the destination buffer
|
||||
if ((optr.y >= 0.0f) && (optr.y < 0.5f) && ((vpos & 1) == field))
|
||||
o_col0 = textureLod(samp0, iptr, 0);
|
||||
if ((vpos & 1) == field)
|
||||
o_col0 = textureLod(samp0, v_tex, 0);
|
||||
else
|
||||
discard;
|
||||
}
|
||||
|
|
|
@ -322,24 +322,49 @@ void GSDevice::Interlace(const GSVector2i& ds, int field, int mode, float yoffse
|
|||
float offset = yoffset * static_cast<float>(field);
|
||||
offset = GSConfig.DisableInterlaceOffset ? 0.0f : offset;
|
||||
|
||||
auto do_interlace = [this](GSTexture* sTex, GSTexture* dTex, ShaderInterlace shader, bool linear, float yoffset, int bufIdx) {
|
||||
const GSVector2i ds_i = dTex->GetSize();
|
||||
const GSVector2 ds = GSVector2(static_cast<float>(ds_i.x), static_cast<float>(ds_i.y));
|
||||
|
||||
GSVector4 sRect = GSVector4(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
GSVector4 dRect = GSVector4(0.0f, yoffset, ds.x, ds.y + yoffset);
|
||||
|
||||
// Select the top or bottom half for MAD buffering.
|
||||
if (shader == ShaderInterlace::MAD_BUFFER)
|
||||
{
|
||||
const float half_size = ds.y * 0.5f;
|
||||
if ((bufIdx >> 1) == 1)
|
||||
dRect.y += half_size;
|
||||
else
|
||||
dRect.w -= half_size;
|
||||
}
|
||||
|
||||
const InterlaceConstantBuffer cb = {
|
||||
GSVector4(static_cast<float>(bufIdx), 1.0f / ds.y, ds.y, MAD_SENSITIVITY)
|
||||
};
|
||||
|
||||
GL_PUSH("DoInterlace %dx%d Shader:%d Linear:%d", ds_i.x, ds_i.y, static_cast<int>(shader), linear);
|
||||
DoInterlace(sTex, sRect, dTex, dRect, shader, linear, cb);
|
||||
};
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 0: // Weave
|
||||
ResizeTarget(&m_weavebob, ds.x, ds.y);
|
||||
DoInterlace(m_merge, m_weavebob, 0, false, offset, field);
|
||||
do_interlace(m_merge, m_weavebob, ShaderInterlace::WEAVE, false, offset, field);
|
||||
m_current = m_weavebob;
|
||||
break;
|
||||
case 1: // Bob
|
||||
// Field is reversed here as we are countering the bounce.
|
||||
ResizeTarget(&m_weavebob, ds.x, ds.y);
|
||||
DoInterlace(m_merge, m_weavebob, 1, true, yoffset * (1 - field), 0);
|
||||
do_interlace(m_merge, m_weavebob, ShaderInterlace::BOB, true, yoffset * (1 - field), 0);
|
||||
m_current = m_weavebob;
|
||||
break;
|
||||
case 2: // Blend
|
||||
ResizeTarget(&m_weavebob, ds.x, ds.y);
|
||||
DoInterlace(m_merge, m_weavebob, 0, false, offset, field);
|
||||
do_interlace(m_merge, m_weavebob, ShaderInterlace::WEAVE, false, offset, field);
|
||||
ResizeTarget(&m_blend, ds.x, ds.y);
|
||||
DoInterlace(m_weavebob, m_blend, 2, false, 0, 0);
|
||||
do_interlace(m_weavebob, m_blend, ShaderInterlace::BLEND, false, 0, 0);
|
||||
m_current = m_blend;
|
||||
break;
|
||||
case 3: // FastMAD Motion Adaptive Deinterlacing
|
||||
|
@ -348,9 +373,9 @@ void GSDevice::Interlace(const GSVector2i& ds, int field, int mode, float yoffse
|
|||
bufIdx |= field;
|
||||
bufIdx &= 3;
|
||||
ResizeTarget(&m_mad, ds.x, ds.y * 2.0f);
|
||||
DoInterlace(m_merge, m_mad, 3, false, offset, bufIdx);
|
||||
do_interlace(m_merge, m_mad, ShaderInterlace::MAD_BUFFER, false, offset, bufIdx);
|
||||
ResizeTarget(&m_weavebob, ds.x, ds.y);
|
||||
DoInterlace(m_mad, m_weavebob, 4, false, 0, bufIdx);
|
||||
do_interlace(m_mad, m_weavebob, ShaderInterlace::MAD_RECONSTRUCT, false, 0, bufIdx);
|
||||
m_current = m_weavebob;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -55,6 +55,16 @@ enum class ShaderConvert
|
|||
Count
|
||||
};
|
||||
|
||||
enum class ShaderInterlace
|
||||
{
|
||||
WEAVE = 0,
|
||||
BOB = 1,
|
||||
BLEND = 2,
|
||||
MAD_BUFFER = 3,
|
||||
MAD_RECONSTRUCT = 4,
|
||||
Count
|
||||
};
|
||||
|
||||
static inline bool HasDepthOutput(ShaderConvert shader)
|
||||
{
|
||||
switch (shader)
|
||||
|
@ -192,7 +202,6 @@ class InterlaceConstantBuffer
|
|||
{
|
||||
public:
|
||||
GSVector4 ZrH; // data passed to the shader
|
||||
InterlaceConstantBuffer() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
@ -773,7 +782,7 @@ protected:
|
|||
GSTexture* FetchSurface(GSTexture::Type type, int width, int height, int levels, GSTexture::Format format, bool clear, bool prefer_reuse);
|
||||
|
||||
virtual void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c, const bool linear) = 0;
|
||||
virtual void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset, int bufIdx) = 0;
|
||||
virtual void DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb) = 0;
|
||||
virtual void DoFXAA(GSTexture* sTex, GSTexture* dTex) {}
|
||||
virtual void DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float params[4]) {}
|
||||
|
||||
|
|
|
@ -935,20 +935,11 @@ void GSDevice11::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
|||
}
|
||||
}
|
||||
|
||||
void GSDevice11::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset, int bufIdx)
|
||||
void GSDevice11::DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb)
|
||||
{
|
||||
const GSVector4 ds = GSVector4(dTex->GetSize());
|
||||
|
||||
const GSVector4 sRect(0, 0, 1, 1);
|
||||
const GSVector4 dRect(0.0f, yoffset, ds.x, ds.y + yoffset);
|
||||
|
||||
InterlaceConstantBuffer cb;
|
||||
|
||||
cb.ZrH = GSVector4(static_cast<float>(bufIdx), 1.0f / ds.y, ds.y, MAD_SENSITIVITY);
|
||||
|
||||
m_ctx->UpdateSubresource(m_interlace.cb.get(), 0, nullptr, &cb, 0, 0);
|
||||
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[shader].get(), m_interlace.cb.get(), linear);
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[static_cast<int>(shader)].get(), m_interlace.cb.get(), linear);
|
||||
}
|
||||
|
||||
void GSDevice11::DoFXAA(GSTexture* sTex, GSTexture* dTex)
|
||||
|
|
|
@ -127,7 +127,7 @@ private:
|
|||
std::unique_ptr<GSDownloadTexture> CreateDownloadTexture(u32 width, u32 height, GSTexture::Format format) final;
|
||||
|
||||
void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c, const bool linear) final;
|
||||
void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset = 0, int bufIdx = 0) final;
|
||||
void DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb) final;
|
||||
void DoFXAA(GSTexture* sTex, GSTexture* dTex) final;
|
||||
void DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float params[4]) final;
|
||||
|
||||
|
|
|
@ -823,30 +823,17 @@ void GSDevice12::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
|||
static_cast<GSTexture12*>(dTex)->TransitionToState(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
}
|
||||
|
||||
void GSDevice12::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset, int bufIdx)
|
||||
void GSDevice12::DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb)
|
||||
{
|
||||
const GSVector2i ds_i = dTex->GetSize();
|
||||
const GSVector4 ds = GSVector4(ds_i);
|
||||
|
||||
|
||||
const GSVector4 sRect(0, 0, 1, 1);
|
||||
const GSVector4 dRect(0.0f, yoffset, ds.x, ds.y + yoffset);
|
||||
|
||||
InterlaceConstantBuffer cb;
|
||||
|
||||
cb.ZrH = GSVector4(static_cast<float>(bufIdx), 1.0f / ds.y, ds.y, MAD_SENSITIVITY);
|
||||
|
||||
GL_PUSH("DoInterlace %dx%d Shader:%d Linear:%d", ds_i.x, ds_i.y, shader, linear);
|
||||
|
||||
static_cast<GSTexture12*>(dTex)->TransitionToState(D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
|
||||
const GSVector4i rc(0, 0, ds_i.x, ds_i.y);
|
||||
const GSVector4i rc = GSVector4i(dRect);
|
||||
EndRenderPass();
|
||||
OMSetRenderTargets(dTex, nullptr, rc);
|
||||
SetUtilityRootSignature();
|
||||
SetUtilityTexture(sTex, linear ? m_linear_sampler_cpu : m_point_sampler_cpu);
|
||||
BeginRenderPassForStretchRect(static_cast<GSTexture12*>(dTex), rc, rc, false);
|
||||
SetPipeline(m_interlace[shader].get());
|
||||
BeginRenderPassForStretchRect(static_cast<GSTexture12*>(dTex), dTex->GetRect(), rc, false);
|
||||
SetPipeline(m_interlace[static_cast<int>(shader)].get());
|
||||
SetUtilityPushConstants(&cb, sizeof(cb));
|
||||
DrawStretchRect(sRect, dRect, dTex->GetSize());
|
||||
EndRenderPass();
|
||||
|
|
|
@ -184,7 +184,7 @@ private:
|
|||
|
||||
void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE,
|
||||
const GSRegEXTBUF& EXTBUF, const GSVector4& c, const bool linear) final;
|
||||
void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset = 0, int bufIdx = 0) final;
|
||||
void DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb) final;
|
||||
void DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float params[4]) final;
|
||||
void DoFXAA(GSTexture* sTex, GSTexture* dTex) final;
|
||||
|
||||
|
|
|
@ -352,7 +352,7 @@ public:
|
|||
GSTexture* CreateSurface(GSTexture::Type type, int width, int height, int levels, GSTexture::Format format) override;
|
||||
|
||||
void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c, const bool linear) override;
|
||||
void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset, int bufIdx) override;
|
||||
void DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb) override;
|
||||
void DoFXAA(GSTexture* sTex, GSTexture* dTex) override;
|
||||
void DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float params[4]) override;
|
||||
|
||||
|
@ -371,7 +371,7 @@ public:
|
|||
std::unique_ptr<GSDownloadTexture> CreateDownloadTexture(u32 width, u32 height, GSTexture::Format format) override;
|
||||
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) override;
|
||||
void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, id<MTLRenderPipelineState> pipeline, bool linear, LoadAction load_action, void* frag_uniform, size_t frag_uniform_len);
|
||||
void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, id<MTLRenderPipelineState> pipeline, bool linear, LoadAction load_action, const void* frag_uniform, size_t frag_uniform_len);
|
||||
void DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect, const GSVector2i& ds);
|
||||
/// Copy from a position in sTex to the same position in the currently active render encoder using the given fs pipeline and rect
|
||||
void RenderCopy(GSTexture* sTex, id<MTLRenderPipelineState> pipeline, const GSVector4i& rect);
|
||||
|
|
|
@ -595,21 +595,13 @@ void GSDeviceMTL::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
|||
StretchRect(dTex, full_r, sTex[2], dRect[0], ShaderConvert::YUV, linear);
|
||||
}}
|
||||
|
||||
void GSDeviceMTL::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset, int bufIdx)
|
||||
void GSDeviceMTL::DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb)
|
||||
{ @autoreleasepool {
|
||||
id<MTLCommandBuffer> cmdbuf = GetRenderCmdBuf();
|
||||
GSScopedDebugGroupMTL dbg(cmdbuf, @"DoInterlace");
|
||||
|
||||
GSVector4 ds = GSVector4(dTex->GetSize());
|
||||
|
||||
GSVector4 sRect(0, 0, 1, 1);
|
||||
GSVector4 dRect(0.f, yoffset, ds.x, ds.y + yoffset);
|
||||
|
||||
GSMTLInterlacePSUniform cb = {};
|
||||
cb.ZrH = {static_cast<float>(bufIdx), 1.0f / ds.y, ds.y, MAD_SENSITIVITY};
|
||||
|
||||
const bool can_discard = shader == 0 || shader == 3;
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, m_interlace_pipeline[shader], linear, !can_discard ? LoadAction::DontCareIfFull : LoadAction::Load, &cb, sizeof(cb));
|
||||
const bool can_discard = shader == ShaderInterlace::WEAVE || shader == ShaderInterlace::MAD_BUFFER;
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, m_interlace_pipeline[static_cast<int>(shader)], linear, !can_discard ? LoadAction::DontCareIfFull : LoadAction::Load, &cb, sizeof(cb));
|
||||
}}
|
||||
|
||||
void GSDeviceMTL::DoFXAA(GSTexture* sTex, GSTexture* dTex)
|
||||
|
@ -1124,7 +1116,7 @@ void GSDeviceMTL::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r
|
|||
[encoder endEncoding];
|
||||
}}
|
||||
|
||||
void GSDeviceMTL::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, id<MTLRenderPipelineState> pipeline, bool linear, LoadAction load_action, void* frag_uniform, size_t frag_uniform_len)
|
||||
void GSDeviceMTL::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, id<MTLRenderPipelineState> pipeline, bool linear, LoadAction load_action, const void* frag_uniform, size_t frag_uniform_len)
|
||||
{
|
||||
FlushClears(sTex);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ fragment float4 ps_interlace0(ConvertShaderData data [[stage_in]], ConvertPSRes
|
|||
// Bob shader
|
||||
fragment float4 ps_interlace1(ConvertShaderData data [[stage_in]], ConvertPSRes res)
|
||||
{
|
||||
return res.sample_level(data.t);
|
||||
return res.sample_level(data.t, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -71,15 +71,11 @@ fragment float4 ps_interlace3(ConvertShaderData data [[stage_in]], ConvertPSRes
|
|||
const int vres = int(uniform.ZrH.z) >> 1; // vertical resolution of source texture
|
||||
const int lofs = ((((vres + 1) >> 1) << 1) - vres) & bank; // line alignment offset for bank 1
|
||||
const int vpos = int(data.p.y) + lofs; // vertical position of destination texture
|
||||
const float2 bofs = float2(0.0f, 0.5f * bank); // vertical offset of the current bank relative to source texture size
|
||||
const float2 vscale = float2(1.0f, 2.0f); // scaling factor from source to destination texture
|
||||
const float2 optr = data.t - bofs; // used to check if the current destination line is within the current bank
|
||||
const float2 iptr = optr * vscale; // pointer to the current pixel in the source texture
|
||||
|
||||
// if the index of current destination line belongs to the current fiels we update it, otherwise
|
||||
// we leave the old line in the destination buffer
|
||||
if ((optr.y >= 0.0f) && (optr.y < 0.5f) && ((vpos & 1) == field))
|
||||
return res.sample_level(iptr, 0);
|
||||
if ((vpos & 1) == field)
|
||||
return res.sample_level(data.t, 0);
|
||||
else
|
||||
discard_fragment();
|
||||
|
||||
|
|
|
@ -1453,21 +1453,14 @@ void GSDeviceOGL::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
|||
StretchRect(dTex, full_r, sTex[2], dRect[2], ShaderConvert::YUV, linear);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset, int bufIdx)
|
||||
void GSDeviceOGL::DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb)
|
||||
{
|
||||
GL_PUSH("DoInterlace");
|
||||
|
||||
OMSetColorMaskState();
|
||||
|
||||
const GSVector4 ds = GSVector4(dTex->GetSize());
|
||||
m_interlace.ps[static_cast<int>(shader)].Bind();
|
||||
m_interlace.ps[static_cast<int>(shader)].Uniform4fv(0, cb.ZrH.F32);
|
||||
|
||||
const GSVector4 sRect(0, 0, 1, 1);
|
||||
const GSVector4 dRect(0.0f, yoffset, ds.x, ds.y + yoffset);
|
||||
|
||||
m_interlace.ps[shader].Bind();
|
||||
m_interlace.ps[shader].Uniform4f(0, bufIdx, 1.0f / ds.y, ds.y, MAD_SENSITIVITY);
|
||||
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[shader], linear);
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[static_cast<int>(shader)], linear);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::DoFXAA(GSTexture* sTex, GSTexture* dTex)
|
||||
|
|
|
@ -277,7 +277,7 @@ private:
|
|||
GSTexture* CreateSurface(GSTexture::Type type, int width, int height, int levels, GSTexture::Format format) final;
|
||||
|
||||
void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c, const bool linear) final;
|
||||
void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset = 0, int bufIdx = 0) final;
|
||||
void DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb) final;
|
||||
void DoFXAA(GSTexture* sTex, GSTexture* dTex) final;
|
||||
void DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float params[4]) final;
|
||||
|
||||
|
|
|
@ -939,29 +939,16 @@ void GSDeviceVK::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
|||
static_cast<GSTextureVK*>(dTex)->TransitionToLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
}
|
||||
|
||||
void GSDeviceVK::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset, int bufIdx)
|
||||
void GSDeviceVK::DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb)
|
||||
{
|
||||
const GSVector2i ds_i = dTex->GetSize();
|
||||
const GSVector4 ds = GSVector4(ds_i);
|
||||
|
||||
|
||||
const GSVector4 sRect(0, 0, 1, 1);
|
||||
const GSVector4 dRect(0.0f, yoffset, ds.x, ds.y + yoffset);
|
||||
|
||||
InterlaceConstantBuffer cb;
|
||||
|
||||
cb.ZrH = GSVector4(static_cast<float>(bufIdx), 1.0f / ds.y, ds.y, MAD_SENSITIVITY);
|
||||
|
||||
GL_PUSH("DoInterlace %dx%d Shader:%d Linear:%d", ds_i.x, ds_i.y, shader, linear);
|
||||
|
||||
static_cast<GSTextureVK*>(dTex)->TransitionToLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
const GSVector4i rc(0, 0, ds_i.x, ds_i.y);
|
||||
const GSVector4i rc = GSVector4i(dRect);
|
||||
EndRenderPass();
|
||||
OMSetRenderTargets(dTex, nullptr, rc, false);
|
||||
SetUtilityTexture(sTex, linear ? m_linear_sampler : m_point_sampler);
|
||||
BeginRenderPassForStretchRect(static_cast<GSTextureVK*>(dTex), rc, rc, false);
|
||||
SetPipeline(m_interlace[shader]);
|
||||
BeginRenderPassForStretchRect(static_cast<GSTextureVK*>(dTex), dTex->GetRect(), rc, false);
|
||||
SetPipeline(m_interlace[static_cast<int>(shader)]);
|
||||
SetUtilityPushConstants(&cb, sizeof(cb));
|
||||
DrawStretchRect(sRect, dRect, dTex->GetSize());
|
||||
EndRenderPass();
|
||||
|
|
|
@ -155,7 +155,7 @@ private:
|
|||
|
||||
void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE,
|
||||
const GSRegEXTBUF& EXTBUF, const GSVector4& c, const bool linear) final;
|
||||
void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset = 0, int bufIdx = 0) final;
|
||||
void DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb) final;
|
||||
void DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float params[4]) final;
|
||||
void DoFXAA(GSTexture* sTex, GSTexture* dTex) final;
|
||||
|
||||
|
|
Loading…
Reference in New Issue