mirror of https://github.com/PCSX2/pcsx2.git
GS: Store clear colour as RGBA32
And defer clears until draw time for DX11 and OpenGL.
This commit is contained in:
parent
f6bcfc3abd
commit
350037fc75
|
@ -243,6 +243,11 @@ public:
|
|||
return GSVector4(GSVector4i::load((int)rgba).u8to32() << shift);
|
||||
}
|
||||
|
||||
__forceinline static GSVector4 unorm8(u32 rgba)
|
||||
{
|
||||
return rgba32(rgba) * GSVector4::cxpr(1.0f / 255.0f);
|
||||
}
|
||||
|
||||
__forceinline GSVector4 abs() const
|
||||
{
|
||||
return *this & cast(GSVector4i::x7fffffff());
|
||||
|
|
|
@ -470,7 +470,7 @@ void GSDevice::ClearCurrent()
|
|||
m_cas = nullptr;
|
||||
}
|
||||
|
||||
void GSDevice::Merge(GSTexture* sTex[3], GSVector4* sRect, GSVector4* dRect, const GSVector2i& fs, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c)
|
||||
void GSDevice::Merge(GSTexture* sTex[3], GSVector4* sRect, GSVector4* dRect, const GSVector2i& fs, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, u32 c)
|
||||
{
|
||||
if (ResizeRenderTarget(&m_merge, fs.x, fs.y, false, false))
|
||||
DoMerge(sTex, sRect, m_merge, dRect, PMODE, EXTBUF, c, GSConfig.PCRTCOffsets);
|
||||
|
|
|
@ -786,7 +786,7 @@ protected:
|
|||
virtual GSTexture* CreateSurface(GSTexture::Type type, int width, int height, int levels, GSTexture::Format format) = 0;
|
||||
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 DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, u32 c, const bool linear) = 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) = 0;
|
||||
virtual void DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float params[4]) = 0;
|
||||
|
@ -877,7 +877,6 @@ public:
|
|||
/// Returns the amount of GPU time utilized since the last time this method was called.
|
||||
virtual float GetAndResetAccumulatedGPUTime() = 0;
|
||||
|
||||
virtual void ClearRenderTarget(GSTexture* t, const GSVector4& c) = 0;
|
||||
virtual void ClearRenderTarget(GSTexture* t, u32 c) = 0;
|
||||
virtual void InvalidateRenderTarget(GSTexture* t) = 0;
|
||||
virtual void ClearDepth(GSTexture* t, float d) = 0;
|
||||
|
@ -919,7 +918,7 @@ public:
|
|||
virtual void ClearSamplerCache() = 0;
|
||||
|
||||
void ClearCurrent();
|
||||
void Merge(GSTexture* sTex[3], GSVector4* sRect, GSVector4* dRect, const GSVector2i& fs, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c);
|
||||
void Merge(GSTexture* sTex[3], GSVector4* sRect, GSVector4* dRect, const GSVector2i& fs, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, u32 c);
|
||||
void Interlace(const GSVector2i& ds, int field, int mode, float yoffset);
|
||||
void FXAA();
|
||||
void ShadeBoost();
|
||||
|
|
|
@ -220,13 +220,7 @@ bool GSRenderer::Merge(int field)
|
|||
tex[0] = nullptr;
|
||||
}
|
||||
|
||||
const GSVector4 c = GSVector4(
|
||||
static_cast<int>(m_regs->BGCOLOR.R),
|
||||
static_cast<int>(m_regs->BGCOLOR.G),
|
||||
static_cast<int>(m_regs->BGCOLOR.B),
|
||||
static_cast<int>(m_regs->PMODE.ALP)) /
|
||||
255;
|
||||
|
||||
const u32 c = (m_regs->BGCOLOR.U32[0] & 0x00FFFFFFu) | (m_regs->PMODE.ALP << 24);
|
||||
g_gs_device->Merge(tex, src_gs_read, dst, fs, m_regs->PMODE, m_regs->EXTBUF, c);
|
||||
|
||||
if (isReallyInterlaced() && GSConfig.InterlaceMode != GSInterlaceMode::Off)
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
|
||||
union alignas(16) ClearValue
|
||||
{
|
||||
float color[4];
|
||||
u32 color;
|
||||
float depth;
|
||||
};
|
||||
|
||||
|
@ -139,13 +139,14 @@ public:
|
|||
__fi u32 GetLastFrameUsed() const { return m_last_frame_used; }
|
||||
void SetLastFrameUsed(u32 frame) { m_last_frame_used = frame; }
|
||||
|
||||
__fi GSVector4 GetClearColor() const { return GSVector4::load<false>(m_clear_value.color); }
|
||||
__fi u32 GetClearColor() const { return m_clear_value.color; }
|
||||
__fi float GetClearDepth() const { return m_clear_value.depth; }
|
||||
__fi GSVector4 GetUNormClearColor() const { return GSVector4::unorm8(m_clear_value.color); }
|
||||
|
||||
__fi void SetClearColor(const GSVector4& color)
|
||||
__fi void SetClearColor(u32 color)
|
||||
{
|
||||
m_state = State::Cleared;
|
||||
GSVector4::store<false>(m_clear_value.color, color);
|
||||
m_clear_value.color = color;
|
||||
}
|
||||
__fi void SetClearDepth(float depth)
|
||||
{
|
||||
|
|
|
@ -1057,38 +1057,43 @@ void GSDevice11::DrawIndexedPrimitive(int offset, int count)
|
|||
m_ctx->DrawIndexed(count, m_index.start + offset, m_vertex.start);
|
||||
}
|
||||
|
||||
void GSDevice11::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
||||
{
|
||||
if (!t)
|
||||
return;
|
||||
m_ctx->ClearRenderTargetView(*(GSTexture11*)t, c.v);
|
||||
}
|
||||
|
||||
void GSDevice11::ClearRenderTarget(GSTexture* t, u32 c)
|
||||
{
|
||||
if (!t)
|
||||
return;
|
||||
const GSVector4 color = GSVector4::rgba32(c) * (1.0f / 255);
|
||||
|
||||
m_ctx->ClearRenderTargetView(*(GSTexture11*)t, color.v);
|
||||
t->SetClearColor(c);
|
||||
}
|
||||
|
||||
void GSDevice11::InvalidateRenderTarget(GSTexture* t)
|
||||
{
|
||||
if (t->IsDepthStencil())
|
||||
m_ctx->DiscardView(static_cast<ID3D11DepthStencilView*>(*static_cast<GSTexture11*>(t)));
|
||||
else
|
||||
m_ctx->DiscardView(static_cast<ID3D11RenderTargetView*>(*static_cast<GSTexture11*>(t)));
|
||||
t->SetState(GSTexture::State::Invalidated);
|
||||
}
|
||||
|
||||
void GSDevice11::ClearDepth(GSTexture* t, float d)
|
||||
{
|
||||
m_ctx->ClearDepthStencilView(*(GSTexture11*)t, D3D11_CLEAR_DEPTH, d, 0);
|
||||
t->SetClearDepth(d);
|
||||
}
|
||||
|
||||
void GSDevice11::ClearStencil(GSTexture* t, u8 c)
|
||||
void GSDevice11::CommitClear(GSTexture* t)
|
||||
{
|
||||
m_ctx->ClearDepthStencilView(*(GSTexture11*)t, D3D11_CLEAR_STENCIL, 0, c);
|
||||
GSTexture11* T = static_cast<GSTexture11*>(t);
|
||||
if (!T->IsRenderTargetOrDepthStencil() || T->GetState() == GSTexture::State::Dirty)
|
||||
return;
|
||||
|
||||
if (T->IsDepthStencil())
|
||||
{
|
||||
if (T->GetState() == GSTexture::State::Invalidated)
|
||||
m_ctx->DiscardView(static_cast<ID3D11DepthStencilView*>(*T));
|
||||
else
|
||||
m_ctx->ClearDepthStencilView(*T, D3D11_CLEAR_DEPTH, T->GetClearDepth(), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (T->GetState() == GSTexture::State::Invalidated)
|
||||
m_ctx->DiscardView(static_cast<ID3D11RenderTargetView*>(*T));
|
||||
else
|
||||
m_ctx->ClearRenderTargetView(*T, T->GetUNormClearColor().F32);
|
||||
}
|
||||
|
||||
T->SetState(GSTexture::State::Dirty);
|
||||
}
|
||||
|
||||
void GSDevice11::PushDebugGroup(const char* fmt, ...)
|
||||
|
@ -1176,6 +1181,9 @@ std::unique_ptr<GSDownloadTexture> GSDevice11::CreateDownloadTexture(u32 width,
|
|||
|
||||
void GSDevice11::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY)
|
||||
{
|
||||
CommitClear(sTex);
|
||||
CommitClear(dTex);
|
||||
|
||||
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
|
||||
|
||||
D3D11_BOX box = {(UINT)r.left, (UINT)r.top, 0U, (UINT)r.right, (UINT)r.bottom, 1U};
|
||||
|
@ -1192,6 +1200,7 @@ void GSDevice11::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
|
|||
void GSDevice11::CloneTexture(GSTexture* src, GSTexture** dest, const GSVector4i& rect)
|
||||
{
|
||||
pxAssertMsg(src->GetType() == GSTexture::Type::DepthStencil || src->GetType() == GSTexture::Type::RenderTarget, "Source is RT or DS.");
|
||||
CommitClear(src);
|
||||
|
||||
const int w = src->GetWidth();
|
||||
const int h = src->GetHeight();
|
||||
|
@ -1231,7 +1240,7 @@ void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
|
|||
|
||||
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear)
|
||||
{
|
||||
ASSERT(sTex);
|
||||
CommitClear(sTex);
|
||||
|
||||
const bool draw_in_depth = dTex && dTex->IsDepthStencil();
|
||||
|
||||
|
@ -1303,7 +1312,7 @@ void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
|
|||
|
||||
void GSDevice11::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, PresentShader shader, float shaderTime, bool linear)
|
||||
{
|
||||
ASSERT(sTex);
|
||||
CommitClear(sTex);
|
||||
|
||||
GSVector2i ds;
|
||||
if (dTex)
|
||||
|
@ -1480,6 +1489,7 @@ void GSDevice11::DoMultiStretchRects(const MultiStretchRect* rects, u32 num_rect
|
|||
IAUnmapIndexBuffer(icount);
|
||||
IASetIndexBuffer(m_ib.get());
|
||||
|
||||
CommitClear(rects[0].src);
|
||||
PSSetShaderResource(0, rects[0].src);
|
||||
PSSetSamplerState(rects[0].linear ? m_convert.ln.get() : m_convert.pt.get());
|
||||
|
||||
|
@ -1489,7 +1499,7 @@ void GSDevice11::DoMultiStretchRects(const MultiStretchRect* rects, u32 num_rect
|
|||
}
|
||||
|
||||
|
||||
void GSDevice11::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c, const bool linear)
|
||||
void GSDevice11::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, u32 c, const bool linear)
|
||||
{
|
||||
const GSVector4 full_r(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
const bool feedback_write_2 = PMODE.EN2 && sTex[2] != nullptr && EXTBUF.FBIN == 1;
|
||||
|
@ -1504,7 +1514,7 @@ void GSDevice11::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
|||
// Upload constant to select YUV algo, but skip constant buffer update if we don't need it
|
||||
if (feedback_write_2 || feedback_write_1 || sTex[0])
|
||||
{
|
||||
const MergeConstantBuffer cb = {c, EXTBUF.EMODA, EXTBUF.EMODC};
|
||||
const MergeConstantBuffer cb = {GSVector4::unorm8(c), EXTBUF.EMODA, EXTBUF.EMODC};
|
||||
m_ctx->UpdateSubresource(m_merge.cb.get(), 0, nullptr, &cb, 0, 0);
|
||||
}
|
||||
|
||||
|
@ -1799,7 +1809,7 @@ void GSDevice11::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vert
|
|||
{
|
||||
// sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows
|
||||
|
||||
ClearStencil(ds, 0);
|
||||
m_ctx->ClearDepthStencilView(*static_cast<GSTexture11*>(ds), D3D11_CLEAR_STENCIL, 0.0f, 0);
|
||||
|
||||
// om
|
||||
|
||||
|
@ -2067,8 +2077,16 @@ void GSDevice11::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector
|
|||
ID3D11RenderTargetView* rtv = nullptr;
|
||||
ID3D11DepthStencilView* dsv = nullptr;
|
||||
|
||||
if (rt) rtv = *(GSTexture11*)rt;
|
||||
if (ds) dsv = *(GSTexture11*)ds;
|
||||
if (rt)
|
||||
{
|
||||
CommitClear(rt);
|
||||
rtv = *static_cast<GSTexture11*>(rt);
|
||||
}
|
||||
if (ds)
|
||||
{
|
||||
CommitClear(ds);
|
||||
dsv = *static_cast<GSTexture11*>(ds);
|
||||
}
|
||||
|
||||
const bool changed = (m_state.rt_view != rtv || m_state.dsv != dsv);
|
||||
g_perfmon.Put(GSPerfMon::RenderPasses, static_cast<double>(changed));
|
||||
|
|
|
@ -129,7 +129,7 @@ private:
|
|||
void PopTimestampQuery();
|
||||
void KickTimestampQuery();
|
||||
|
||||
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 DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, u32 c, const bool linear) 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;
|
||||
|
@ -309,11 +309,9 @@ public:
|
|||
void DrawIndexedPrimitive();
|
||||
void DrawIndexedPrimitive(int offset, int count);
|
||||
|
||||
void ClearRenderTarget(GSTexture* t, const GSVector4& c) override;
|
||||
void ClearRenderTarget(GSTexture* t, u32 c) override;
|
||||
void InvalidateRenderTarget(GSTexture* t) override;
|
||||
void ClearDepth(GSTexture* t, float v) override;
|
||||
void ClearStencil(GSTexture* t, u8 c);
|
||||
|
||||
void PushDebugGroup(const char* fmt, ...) override;
|
||||
void PopDebugGroup() override;
|
||||
|
@ -322,6 +320,7 @@ public:
|
|||
GSTexture* CreateSurface(GSTexture::Type type, int width, int height, int levels, GSTexture::Format format) override;
|
||||
std::unique_ptr<GSDownloadTexture> CreateDownloadTexture(u32 width, u32 height, GSTexture::Format format) override;
|
||||
|
||||
void CommitClear(GSTexture* t);
|
||||
void CloneTexture(GSTexture* src, GSTexture** dest, const GSVector4i& rect);
|
||||
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) override;
|
||||
|
|
|
@ -67,6 +67,7 @@ bool GSTexture11::Update(const GSVector4i& r, const void* data, int pitch, int l
|
|||
if (layer >= m_mipmap_levels)
|
||||
return false;
|
||||
|
||||
GSDevice11::GetInstance()->CommitClear(this);
|
||||
g_perfmon.Put(GSPerfMon::TextureUploads, 1);
|
||||
|
||||
const u32 bs = GetCompressedBlockSize();
|
||||
|
@ -82,41 +83,19 @@ bool GSTexture11::Update(const GSVector4i& r, const void* data, int pitch, int l
|
|||
|
||||
bool GSTexture11::Map(GSMap& m, const GSVector4i* r, int layer)
|
||||
{
|
||||
if (r != NULL)
|
||||
{
|
||||
// ASSERT(0); // not implemented
|
||||
return false;
|
||||
}
|
||||
|
||||
if (layer >= m_mipmap_levels)
|
||||
return false;
|
||||
|
||||
if (m_texture && m_desc.Usage == D3D11_USAGE_STAGING)
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE map;
|
||||
UINT subresource = layer;
|
||||
|
||||
if (SUCCEEDED(GSDevice11::GetInstance()->GetD3DContext()->Map(m_texture.get(), subresource, D3D11_MAP_READ_WRITE, 0, &map)))
|
||||
{
|
||||
m.bits = (u8*)map.pData;
|
||||
m.pitch = (int)map.RowPitch;
|
||||
m_mapped_subresource = layer;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Not supported
|
||||
return false;
|
||||
}
|
||||
|
||||
void GSTexture11::Unmap()
|
||||
{
|
||||
const UINT subresource = m_mapped_subresource;
|
||||
m_needs_mipmaps_generated |= (m_mapped_subresource == 0);
|
||||
GSDevice11::GetInstance()->GetD3DContext()->Unmap(m_texture.get(), subresource);
|
||||
pxFailRel("Should not be called.");
|
||||
}
|
||||
|
||||
bool GSTexture11::Save(const std::string& fn)
|
||||
{
|
||||
GSDevice11::GetInstance()->CommitClear(this);
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc = m_desc;
|
||||
desc.Usage = D3D11_USAGE_STAGING;
|
||||
desc.BindFlags = 0;
|
||||
|
@ -342,6 +321,9 @@ void GSDownloadTexture11::CopyFromTexture(
|
|||
pxAssert(src.z <= stex->GetWidth() && src.w <= stex->GetHeight());
|
||||
pxAssert(static_cast<u32>(drc.z) <= m_width && static_cast<u32>(drc.w) <= m_height);
|
||||
pxAssert(src_level < static_cast<u32>(stex->GetMipmapLevels()));
|
||||
|
||||
GSDevice11::GetInstance()->CommitClear(stex);
|
||||
|
||||
g_perfmon.Put(GSPerfMon::Readbacks, 1);
|
||||
|
||||
if (IsMapped())
|
||||
|
|
|
@ -639,27 +639,16 @@ void GSDevice12::DrawIndexedPrimitive(int offset, int count)
|
|||
g_d3d12_context->GetCommandList()->DrawIndexedInstanced(count, 1, m_index.start + offset, m_vertex.start, 0);
|
||||
}
|
||||
|
||||
void GSDevice12::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
||||
void GSDevice12::ClearRenderTarget(GSTexture* t, u32 c)
|
||||
{
|
||||
if (!t)
|
||||
return;
|
||||
|
||||
if (m_current_render_target == t)
|
||||
EndRenderPass();
|
||||
|
||||
static_cast<GSTexture12*>(t)->SetClearColor(c);
|
||||
}
|
||||
|
||||
void GSDevice12::ClearRenderTarget(GSTexture* t, u32 c)
|
||||
{
|
||||
ClearRenderTarget(t, GSVector4::rgba32(c) * (1.0f / 255));
|
||||
t->SetClearColor(c);
|
||||
}
|
||||
|
||||
void GSDevice12::InvalidateRenderTarget(GSTexture* t)
|
||||
{
|
||||
if (!t)
|
||||
return;
|
||||
|
||||
if (m_current_render_target == t || m_current_depth_target == t)
|
||||
EndRenderPass();
|
||||
|
||||
|
@ -668,13 +657,10 @@ void GSDevice12::InvalidateRenderTarget(GSTexture* t)
|
|||
|
||||
void GSDevice12::ClearDepth(GSTexture* t, float d)
|
||||
{
|
||||
if (!t)
|
||||
return;
|
||||
|
||||
if (m_current_depth_target == t)
|
||||
EndRenderPass();
|
||||
|
||||
static_cast<GSTexture12*>(t)->SetClearDepth(d);
|
||||
t->SetClearDepth(d);
|
||||
}
|
||||
|
||||
void GSDevice12::LookupNativeFormat(GSTexture::Format format, DXGI_FORMAT* d3d_format, DXGI_FORMAT* srv_format,
|
||||
|
@ -771,7 +757,7 @@ void GSDevice12::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
|
|||
{
|
||||
dTexVK->TransitionToState(D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
g_d3d12_context->GetCommandList()->ClearRenderTargetView(
|
||||
dTexVK->GetWriteDescriptor(), sTexVK->GetClearColor().v, 0, nullptr);
|
||||
dTexVK->GetWriteDescriptor(), sTexVK->GetUNormClearColor().v, 0, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1027,19 +1013,17 @@ void GSDevice12::BeginRenderPassForStretchRect(
|
|||
|
||||
if (dTex->GetType() != GSTexture::Type::DepthStencil)
|
||||
{
|
||||
const GSVector4 clear_color(dTex->GetClearColor());
|
||||
BeginRenderPass(load_op, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
clear_color);
|
||||
dTex->GetClearColor());
|
||||
}
|
||||
else
|
||||
{
|
||||
const float clear_depth = dTex->GetClearDepth();
|
||||
BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
|
||||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, load_op, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
GSVector4::zero(), clear_depth);
|
||||
0, dTex->GetClearDepth());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1103,7 +1087,7 @@ void GSDevice12::DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect,
|
|||
}
|
||||
|
||||
void GSDevice12::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect,
|
||||
const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c, const bool linear)
|
||||
const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, u32 c, const bool linear)
|
||||
{
|
||||
GL_PUSH("DoMerge");
|
||||
|
||||
|
@ -1126,7 +1110,7 @@ void GSDevice12::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
|||
if (feedback_write_2 || feedback_write_1 || sTex[0])
|
||||
{
|
||||
SetUtilityRootSignature();
|
||||
const MergeConstantBuffer uniforms = {c, EXTBUF.EMODA, EXTBUF.EMODC};
|
||||
const MergeConstantBuffer uniforms = {GSVector4::unorm8(c), EXTBUF.EMODA, EXTBUF.EMODC};
|
||||
SetUtilityPushConstants(&uniforms, sizeof(uniforms));
|
||||
}
|
||||
|
||||
|
@ -2711,8 +2695,7 @@ bool GSDevice12::InRenderPass()
|
|||
void GSDevice12::BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE color_begin,
|
||||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE color_end, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE depth_begin,
|
||||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE depth_end, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE stencil_begin,
|
||||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE stencil_end, const GSVector4& clear_color /* = GSVector4::zero() */,
|
||||
float clear_depth /* = 0.0f */, u8 clear_stencil /* = 0 */)
|
||||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE stencil_end, u32 clear_color, float clear_depth, u8 clear_stencil)
|
||||
{
|
||||
if (m_in_render_pass)
|
||||
EndRenderPass();
|
||||
|
@ -2731,7 +2714,8 @@ void GSDevice12::BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE color_b
|
|||
{
|
||||
LookupNativeFormat(m_current_render_target->GetFormat(), nullptr,
|
||||
&rt.BeginningAccess.Clear.ClearValue.Format, nullptr, nullptr);
|
||||
GSVector4::store<false>(rt.BeginningAccess.Clear.ClearValue.Color, clear_color);
|
||||
GSVector4::store<false>(rt.BeginningAccess.Clear.ClearValue.Color,
|
||||
GSVector4::unorm8(clear_color));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3026,8 +3010,7 @@ void GSDevice12::SetupDATE(GSTexture* rt, GSTexture* ds, bool datm, const GSVect
|
|||
SetStencilRef(1);
|
||||
BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, GSVector4::zero(),
|
||||
0.0f, 0);
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, 0, 0.0f, 0);
|
||||
if (ApplyUtilityState())
|
||||
DrawPrimitive();
|
||||
|
||||
|
@ -3062,7 +3045,7 @@ GSTexture12* GSDevice12::SetupPrimitiveTrackingDATE(GSHWDrawConfig& config, Pipe
|
|||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
|
||||
config.ds ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
GSVector4::zero(), config.ds ? static_cast<GSTexture12*>(config.ds)->GetClearDepth() : 0.0f);
|
||||
0, config.ds ? config.ds->GetClearDepth() : 0.0f);
|
||||
|
||||
// draw the quad to prefill the image
|
||||
const GSVector4 src = GSVector4(config.drawarea) / GSVector4(rtsize).xyxy();
|
||||
|
@ -3252,7 +3235,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
|||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
|
||||
stencil_DATE ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD :
|
||||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
draw_rt ? draw_rt->GetClearColor() : GSVector4::zero(), draw_ds ? draw_ds->GetClearDepth() : 0.0f, 1);
|
||||
draw_rt ? draw_rt->GetClearColor() : 0, draw_ds ? draw_ds->GetClearDepth() : 0.0f, 1);
|
||||
}
|
||||
|
||||
// rt -> hdr blit if enabled
|
||||
|
|
|
@ -204,7 +204,7 @@ private:
|
|||
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) final;
|
||||
const GSRegEXTBUF& EXTBUF, u32 c, const bool linear) 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;
|
||||
|
@ -279,7 +279,6 @@ public:
|
|||
void DrawIndexedPrimitive();
|
||||
void DrawIndexedPrimitive(int offset, int count);
|
||||
|
||||
void ClearRenderTarget(GSTexture* t, const GSVector4& c) override;
|
||||
void ClearRenderTarget(GSTexture* t, u32 c) override;
|
||||
void InvalidateRenderTarget(GSTexture* t) override;
|
||||
void ClearDepth(GSTexture* t, float d) override;
|
||||
|
@ -369,7 +368,7 @@ public:
|
|||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE depth_end = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE stencil_begin = D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
|
||||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE stencil_end = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
const GSVector4& clear_color = GSVector4::zero(), float clear_depth = 0.0f, u8 clear_stencil = 0);
|
||||
const u32 clear_color = 0, float clear_depth = 0.0f, u8 clear_stencil = 0);
|
||||
void EndRenderPass();
|
||||
|
||||
void SetViewport(const D3D12_VIEWPORT& viewport);
|
||||
|
|
|
@ -670,7 +670,7 @@ void GSTexture12::CommitClear(ID3D12GraphicsCommandList* cmdlist)
|
|||
else
|
||||
{
|
||||
TransitionToState(cmdlist, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
cmdlist->ClearRenderTargetView(GetWriteDescriptor(), m_clear_value.color, 0, nullptr);
|
||||
cmdlist->ClearRenderTargetView(GetWriteDescriptor(), GSVector4::unorm8(m_clear_value.color).v, 0, nullptr);
|
||||
}
|
||||
|
||||
SetState(GSTexture::State::Dirty);
|
||||
|
|
|
@ -367,7 +367,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 DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, u32 c, const bool linear) 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;
|
||||
|
@ -404,7 +404,6 @@ public:
|
|||
float GetAndResetAccumulatedGPUTime() override;
|
||||
void AccumulateCommandBufferTime(id<MTLCommandBuffer> buffer);
|
||||
|
||||
void ClearRenderTarget(GSTexture* t, const GSVector4& c) override;
|
||||
void ClearRenderTarget(GSTexture* t, u32 c) override;
|
||||
void ClearDepth(GSTexture* t, float d) override;
|
||||
void InvalidateRenderTarget(GSTexture* t) override;
|
||||
|
|
|
@ -410,7 +410,7 @@ void GSDeviceMTL::BeginRenderPass(NSString* name, GSTexture* color, MTLLoadActio
|
|||
} \
|
||||
}
|
||||
|
||||
CHECK_CLEAR(mc, color_load, color_clear, GetClearColor)
|
||||
CHECK_CLEAR(mc, color_load, color_clear, GetUNormClearColor)
|
||||
CHECK_CLEAR(md, depth_load, depth_clear, GetClearDepth)
|
||||
#undef CHECK_CLEAR
|
||||
// Stencil and depth are one texture, stencil clears aren't supported
|
||||
|
@ -567,7 +567,7 @@ GSTexture* GSDeviceMTL::CreateSurface(GSTexture::Type type, int width, int heigh
|
|||
}
|
||||
}}
|
||||
|
||||
void GSDeviceMTL::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c, const bool linear)
|
||||
void GSDeviceMTL::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, u32 c, const bool linear)
|
||||
{ @autoreleasepool {
|
||||
id<MTLCommandBuffer> cmdbuf = GetRenderCmdBuf();
|
||||
GSScopedDebugGroupMTL dbg(cmdbuf, @"DoMerge");
|
||||
|
@ -579,7 +579,8 @@ void GSDeviceMTL::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
|||
|
||||
ClearRenderTarget(dTex, c);
|
||||
|
||||
vector_float4 cb_c = { c.r, c.g, c.b, c.a };
|
||||
const GSVector4 unorm_c = GSVector4::unorm8(c);
|
||||
vector_float4 cb_c = { unorm_c.r, unorm_c.g, unorm_c.b, unorm_c.a };
|
||||
GSMTLConvertPSUniform cb_yuv = {};
|
||||
cb_yuv.emoda = EXTBUF.EMODA;
|
||||
cb_yuv.emodc = EXTBUF.EMODC;
|
||||
|
@ -1430,27 +1431,18 @@ void GSDeviceMTL::AccumulateCommandBufferTime(id<MTLCommandBuffer> buffer)
|
|||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
void GSDeviceMTL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
||||
{
|
||||
if (!t) return;
|
||||
t->SetClearColor(c);
|
||||
}
|
||||
|
||||
void GSDeviceMTL::ClearRenderTarget(GSTexture* t, uint32 c)
|
||||
{
|
||||
GSVector4 color = GSVector4::rgba32(c) * (1.f / 255.f);
|
||||
ClearRenderTarget(t, color);
|
||||
t->SetClearColor(c);
|
||||
}
|
||||
|
||||
void GSDeviceMTL::ClearDepth(GSTexture* t, float d)
|
||||
{
|
||||
if (!t) return;
|
||||
t->SetClearDepth(d);
|
||||
}
|
||||
|
||||
void GSDeviceMTL::InvalidateRenderTarget(GSTexture* t)
|
||||
{
|
||||
if (!t) return;
|
||||
t->SetState(GSTexture::State::Invalidated);
|
||||
}
|
||||
|
||||
|
|
|
@ -859,132 +859,121 @@ void GSDeviceOGL::DrawIndexedPrimitive(int offset, int count)
|
|||
static_cast<GLint>(m_vertex.start));
|
||||
}
|
||||
|
||||
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
||||
void GSDeviceOGL::CommitClear(GSTexture* t, bool use_write_fbo)
|
||||
{
|
||||
if (!t)
|
||||
return;
|
||||
|
||||
GSTextureOGL* T = static_cast<GSTextureOGL*>(t);
|
||||
if (T->HasBeenCleaned())
|
||||
if (!T->IsRenderTargetOrDepthStencil() || T->GetState() == GSTexture::State::Dirty)
|
||||
return;
|
||||
|
||||
// Performance note: potentially T->Clear() could be used. Main purpose of
|
||||
// Clear() is to avoid the framebuffer setup cost. However, in this context,
|
||||
// the texture 't' will be set as the render target of the framebuffer and
|
||||
// therefore will require a framebuffer setup.
|
||||
|
||||
// So using the old/standard path is faster/better albeit verbose.
|
||||
|
||||
GL_PUSH("Clear RT %d", T->GetID());
|
||||
|
||||
// TODO: check size of scissor before toggling it
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
const u32 old_color_mask = GLState::wrgba;
|
||||
OMSetColorMaskState();
|
||||
|
||||
OMSetFBO(m_fbo);
|
||||
OMAttachRt(T);
|
||||
|
||||
if (T->IsIntegerFormat())
|
||||
if (use_write_fbo)
|
||||
{
|
||||
if (T->IsUnsignedFormat())
|
||||
glClearBufferuiv(GL_COLOR, 0, c.U32);
|
||||
else
|
||||
glClearBufferiv(GL_COLOR, 0, c.I32);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_write);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
(t->GetType() == GSTexture::Type::RenderTarget) ? static_cast<GSTextureOGL*>(t)->GetID() : 0, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, m_features.framebuffer_fetch ? GL_DEPTH_ATTACHMENT : GL_DEPTH_STENCIL_ATTACHMENT,
|
||||
GL_TEXTURE_2D, (t->GetType() == GSTexture::Type::DepthStencil) ? static_cast<GSTextureOGL*>(t)->GetID() : 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glClearBufferfv(GL_COLOR, 0, c.v);
|
||||
OMSetFBO(m_fbo);
|
||||
if (T->GetType() == GSTexture::Type::DepthStencil)
|
||||
{
|
||||
if (GLState::rt && GLState::rt->GetSize() != T->GetSize())
|
||||
OMAttachRt(nullptr);
|
||||
OMAttachDs(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GLState::ds && GLState::ds->GetSize() != T->GetSize())
|
||||
OMAttachDs(nullptr);
|
||||
OMAttachRt(T);
|
||||
}
|
||||
}
|
||||
|
||||
OMSetColorMaskState(OMColorMaskSelector(old_color_mask));
|
||||
if (T->GetState() == GSTexture::State::Invalidated)
|
||||
{
|
||||
if (GLAD_GL_VERSION_4_3)
|
||||
{
|
||||
if (T->GetType() == GSTexture::Type::DepthStencil)
|
||||
{
|
||||
const GLenum attachments[] = {GL_DEPTH_STENCIL_ATTACHMENT};
|
||||
glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, std::size(attachments), attachments);
|
||||
}
|
||||
else
|
||||
{
|
||||
const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
|
||||
glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, std::size(attachments), attachments);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
if (T->GetType() == GSTexture::Type::DepthStencil)
|
||||
{
|
||||
const float d = T->GetClearDepth();
|
||||
if (GLState::depth_mask)
|
||||
{
|
||||
glClearBufferfv(GL_DEPTH, 0, &d);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDepthMask(true);
|
||||
glClearBufferfv(GL_DEPTH, 0, &d);
|
||||
glDepthMask(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const u32 old_color_mask = GLState::wrgba;
|
||||
OMSetColorMaskState();
|
||||
|
||||
T->WasCleaned();
|
||||
const GSVector4 c_unorm = T->GetUNormClearColor();
|
||||
|
||||
if (T->IsIntegerFormat())
|
||||
{
|
||||
if (T->IsUnsignedFormat())
|
||||
glClearBufferuiv(GL_COLOR, 0, c_unorm.U32);
|
||||
else
|
||||
glClearBufferiv(GL_COLOR, 0, c_unorm.I32);
|
||||
}
|
||||
else
|
||||
{
|
||||
glClearBufferfv(GL_COLOR, 0, c_unorm.v);
|
||||
}
|
||||
|
||||
OMSetColorMaskState(OMColorMaskSelector(old_color_mask));
|
||||
}
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
T->SetState(GSTexture::State::Dirty);
|
||||
|
||||
if (use_write_fbo)
|
||||
{
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
|
||||
(t->GetType() == GSTexture::Type::RenderTarget) ? GL_COLOR_ATTACHMENT0 :
|
||||
(m_features.framebuffer_fetch ? GL_DEPTH_ATTACHMENT : GL_DEPTH_STENCIL_ATTACHMENT),
|
||||
GL_TEXTURE_2D, 0, 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, GLState::fbo);
|
||||
}
|
||||
}
|
||||
|
||||
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, u32 c)
|
||||
{
|
||||
if (!t)
|
||||
return;
|
||||
|
||||
const GSVector4 color = GSVector4::rgba32(c) * (1.0f / 255);
|
||||
ClearRenderTarget(t, color);
|
||||
t->SetClearColor(c);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::InvalidateRenderTarget(GSTexture* t)
|
||||
{
|
||||
GSTextureOGL* T = static_cast<GSTextureOGL*>(t);
|
||||
if (!T || T->HasBeenCleaned())
|
||||
return;
|
||||
|
||||
if (GLAD_GL_VERSION_4_3 || GLAD_GL_ES_VERSION_3_0)
|
||||
{
|
||||
OMSetFBO(m_fbo);
|
||||
|
||||
if (T->GetType() == GSTexture::Type::DepthStencil)
|
||||
{
|
||||
OMAttachDs(T);
|
||||
const GLenum attachments[] = {GL_DEPTH_STENCIL_ATTACHMENT};
|
||||
glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, std::size(attachments), attachments);
|
||||
}
|
||||
else
|
||||
{
|
||||
OMAttachRt(T);
|
||||
const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
|
||||
glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, std::size(attachments), attachments);
|
||||
}
|
||||
}
|
||||
t->SetState(GSTexture::State::Invalidated);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::ClearDepth(GSTexture* t, float d)
|
||||
{
|
||||
if (!t)
|
||||
return;
|
||||
|
||||
GSTextureOGL* T = static_cast<GSTextureOGL*>(t);
|
||||
|
||||
GL_PUSH("Clear Depth %d", T->GetID());
|
||||
|
||||
OMSetFBO(m_fbo);
|
||||
// RT must be detached, if RT is too small, depth won't be fully cleared
|
||||
// AT tolenico 2 map clip bug
|
||||
OMAttachRt(NULL);
|
||||
OMAttachDs(T);
|
||||
|
||||
// TODO: check size of scissor before toggling it
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
if (GLState::depth_mask)
|
||||
{
|
||||
glClearBufferfv(GL_DEPTH, 0, &d);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDepthMask(true);
|
||||
glClearBufferfv(GL_DEPTH, 0, &d);
|
||||
glDepthMask(false);
|
||||
}
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::ClearStencil(GSTexture* t, u8 c)
|
||||
{
|
||||
if (!t)
|
||||
return;
|
||||
|
||||
GSTextureOGL* T = static_cast<GSTextureOGL*>(t);
|
||||
|
||||
GL_PUSH("Clear Stencil %d", T->GetID());
|
||||
|
||||
// Keep SCISSOR_TEST enabled on purpose to reduce the size
|
||||
// of clean in DATE (impact big upscaling)
|
||||
OMSetFBO(m_fbo);
|
||||
OMAttachDs(T);
|
||||
const GLint color = c;
|
||||
|
||||
glClearBufferiv(GL_STENCIL, 0, &color);
|
||||
t->SetClearDepth(d);
|
||||
}
|
||||
|
||||
std::unique_ptr<GSDownloadTexture> GSDeviceOGL::CreateDownloadTexture(u32 width, u32 height, GSTexture::Format format)
|
||||
|
@ -1229,6 +1218,8 @@ std::string GSDeviceOGL::GetPSSource(const PSSelector& sel)
|
|||
// Copy a sub part of texture (same as below but force a conversion)
|
||||
void GSDeviceOGL::BlitRect(GSTexture* sTex, const GSVector4i& r, const GSVector2i& dsize, bool at_origin, bool linear)
|
||||
{
|
||||
CommitClear(sTex, true);
|
||||
|
||||
GL_PUSH(fmt::format("CopyRectConv from {}", static_cast<GSTextureOGL*>(sTex)->GetID()).c_str());
|
||||
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
|
||||
|
||||
|
@ -1258,6 +1249,8 @@ void GSDeviceOGL::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r
|
|||
|
||||
const GLuint& sid = static_cast<GSTextureOGL*>(sTex)->GetID();
|
||||
const GLuint& did = static_cast<GSTextureOGL*>(dTex)->GetID();
|
||||
CommitClear(sTex, false);
|
||||
CommitClear(dTex, false);
|
||||
|
||||
GL_PUSH("CopyRect from %d to %d", sid, did);
|
||||
|
||||
|
@ -1321,7 +1314,7 @@ void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture
|
|||
|
||||
void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, const GLProgram& ps, bool alpha_blend, OMColorMaskSelector cms, bool linear)
|
||||
{
|
||||
ASSERT(sTex);
|
||||
CommitClear(sTex, true);
|
||||
|
||||
const bool draw_in_depth = dTex->IsDepthStencil();
|
||||
|
||||
|
@ -1364,7 +1357,7 @@ void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture
|
|||
|
||||
void GSDeviceOGL::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, PresentShader shader, float shaderTime, bool linear)
|
||||
{
|
||||
ASSERT(sTex);
|
||||
CommitClear(sTex, true);
|
||||
|
||||
const GSVector2i ds(dTex ? dTex->GetSize() : GSVector2i(GetWindowWidth(), GetWindowHeight()));
|
||||
DisplayConstantBuffer cb;
|
||||
|
@ -1402,6 +1395,8 @@ void GSDeviceOGL::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture
|
|||
|
||||
void GSDeviceOGL::UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize)
|
||||
{
|
||||
CommitClear(sTex, false);
|
||||
|
||||
const ShaderConvert shader = (dSize == 16) ? ShaderConvert::CLUT_4 : ShaderConvert::CLUT_8;
|
||||
GLProgram& prog = m_convert.ps[static_cast<int>(shader)];
|
||||
prog.Bind();
|
||||
|
@ -1422,6 +1417,8 @@ void GSDeviceOGL::UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX,
|
|||
|
||||
void GSDeviceOGL::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM)
|
||||
{
|
||||
CommitClear(sTex, false);
|
||||
|
||||
const ShaderConvert shader = ShaderConvert::RGBA_TO_8I;
|
||||
GLProgram& prog = m_convert.ps[static_cast<int>(shader)];
|
||||
prog.Bind();
|
||||
|
@ -1561,7 +1558,7 @@ void GSDeviceOGL::DoMultiStretchRects(const MultiStretchRect* rects, u32 num_rec
|
|||
DrawIndexedPrimitive();
|
||||
}
|
||||
|
||||
void GSDeviceOGL::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c, const bool linear)
|
||||
void GSDeviceOGL::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, u32 c, const bool linear)
|
||||
{
|
||||
GL_PUSH("DoMerge");
|
||||
|
||||
|
@ -1609,7 +1606,7 @@ void GSDeviceOGL::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
|||
{
|
||||
// Blend with a constant alpha
|
||||
m_merge_obj.ps[1].Bind();
|
||||
m_merge_obj.ps[1].Uniform4fv(0, c.v);
|
||||
m_merge_obj.ps[1].Uniform4fv(0, GSVector4::unorm8(c).v);
|
||||
StretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[1], true, OMColorMaskSelector(), linear);
|
||||
}
|
||||
else
|
||||
|
@ -1719,7 +1716,10 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
|
|||
|
||||
// sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows
|
||||
|
||||
ClearStencil(ds, 0);
|
||||
OMSetRenderTargets(nullptr, ds, &GLState::scissor);
|
||||
|
||||
const GLint clear_color = 0;
|
||||
glClearBufferiv(GL_STENCIL, 0, &clear_color);
|
||||
|
||||
m_convert.ps[static_cast<int>(datm ? ShaderConvert::DATM_1 : ShaderConvert::DATM_0)].Bind();
|
||||
|
||||
|
@ -1730,7 +1730,6 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
|
|||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
OMSetRenderTargets(NULL, ds, &GLState::scissor);
|
||||
|
||||
// ia
|
||||
|
||||
|
@ -2014,30 +2013,24 @@ void GSDeviceOGL::RenderBlankFrame()
|
|||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::OMAttachRt(GSTextureOGL* rt)
|
||||
void GSDeviceOGL::OMAttachRt(GSTexture* rt)
|
||||
{
|
||||
if (rt)
|
||||
rt->WasAttached();
|
||||
if (GLState::rt == rt)
|
||||
return;
|
||||
|
||||
if (GLState::rt != rt)
|
||||
{
|
||||
GLState::rt = rt;
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt ? rt->GetID() : 0, 0);
|
||||
}
|
||||
GLState::rt = static_cast<GSTextureOGL*>(rt);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt ? static_cast<GSTextureOGL*>(rt)->GetID() : 0, 0);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::OMAttachDs(GSTextureOGL* ds)
|
||||
void GSDeviceOGL::OMAttachDs(GSTexture* ds)
|
||||
{
|
||||
if (ds)
|
||||
ds->WasAttached();
|
||||
if (GLState::ds == ds)
|
||||
return;
|
||||
|
||||
if (GLState::ds != ds)
|
||||
{
|
||||
GLState::ds = ds;
|
||||
GLState::ds = static_cast<GSTextureOGL*>(ds);
|
||||
|
||||
const GLenum target = m_features.framebuffer_fetch ? GL_DEPTH_ATTACHMENT : GL_DEPTH_STENCIL_ATTACHMENT;
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, target, GL_TEXTURE_2D, ds ? ds->GetID() : 0, 0);
|
||||
}
|
||||
const GLenum target = m_features.framebuffer_fetch ? GL_DEPTH_ATTACHMENT : GL_DEPTH_STENCIL_ATTACHMENT;
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, target, GL_TEXTURE_2D, ds ? static_cast<GSTextureOGL*>(ds)->GetID() : 0, 0);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::OMSetFBO(GLuint fbo)
|
||||
|
@ -2128,27 +2121,26 @@ void GSDeviceOGL::OMSetBlendState(bool enable, GLenum src_factor, GLenum dst_fac
|
|||
|
||||
void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor)
|
||||
{
|
||||
GSTextureOGL* RT = static_cast<GSTextureOGL*>(rt);
|
||||
GSTextureOGL* DS = static_cast<GSTextureOGL*>(ds);
|
||||
g_perfmon.Put(GSPerfMon::RenderPasses, static_cast<double>(GLState::rt != rt || GLState::ds != ds));
|
||||
|
||||
g_perfmon.Put(GSPerfMon::RenderPasses, static_cast<double>(GLState::rt != RT || GLState::ds != DS));
|
||||
// Split up to avoid unbind/bind calls when clearing.
|
||||
|
||||
OMSetFBO(m_fbo);
|
||||
if (rt)
|
||||
{
|
||||
OMAttachRt(RT);
|
||||
}
|
||||
OMAttachRt(rt);
|
||||
else
|
||||
{
|
||||
OMAttachRt();
|
||||
}
|
||||
|
||||
// Note: it must be done after OMSetFBO
|
||||
if (ds)
|
||||
OMAttachDs(DS);
|
||||
OMAttachDs(ds);
|
||||
else
|
||||
OMAttachDs();
|
||||
|
||||
if (rt)
|
||||
CommitClear(rt, false);
|
||||
if (ds)
|
||||
CommitClear(ds, false);
|
||||
|
||||
if (rt || ds)
|
||||
{
|
||||
const GSVector2i size = rt ? rt->GetSize() : ds->GetSize();
|
||||
|
@ -2253,7 +2245,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
|||
case GSHWDrawConfig::DestinationAlphaMode::StencilOne:
|
||||
if (m_features.texture_barrier)
|
||||
{
|
||||
ClearStencil(config.ds, 1);
|
||||
// Cleared after RT bind.
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
|
@ -2418,6 +2410,13 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
|||
OMSetColorMaskState(config.colormask);
|
||||
SetupOM(config.depth);
|
||||
|
||||
// Clear stencil as close as possible to the RT bind, to avoid framebuffer swaps.
|
||||
if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne && m_features.texture_barrier)
|
||||
{
|
||||
constexpr GLint clear_color = 1;
|
||||
glClearBufferiv(GL_STENCIL, 0, &clear_color);
|
||||
}
|
||||
|
||||
SendHWDraw(config, psel.ps.IsFeedbackLoop());
|
||||
|
||||
if (config.separate_alpha_pass)
|
||||
|
|
|
@ -250,7 +250,7 @@ private:
|
|||
|
||||
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 DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, u32 c, const bool linear) override;
|
||||
void DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb) override;
|
||||
|
||||
bool CompileFXAAProgram();
|
||||
|
@ -266,8 +266,8 @@ private:
|
|||
void RenderImGui();
|
||||
void RenderBlankFrame();
|
||||
|
||||
void OMAttachRt(GSTextureOGL* rt = nullptr);
|
||||
void OMAttachDs(GSTextureOGL* ds = nullptr);
|
||||
void OMAttachRt(GSTexture* rt = nullptr);
|
||||
void OMAttachDs(GSTexture* ds = nullptr);
|
||||
void OMSetFBO(GLuint fbo);
|
||||
|
||||
void DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect, const GSVector2i& ds);
|
||||
|
@ -285,6 +285,7 @@ public:
|
|||
|
||||
__fi u32 GetFBORead() const { return m_fbo_read; }
|
||||
__fi u32 GetFBOWrite() const { return m_fbo_write; }
|
||||
void CommitClear(GSTexture* t, bool use_write_fbo);
|
||||
|
||||
RenderAPI GetRenderAPI() const override;
|
||||
bool HasSurface() const override;
|
||||
|
@ -310,11 +311,9 @@ public:
|
|||
void DrawIndexedPrimitive();
|
||||
void DrawIndexedPrimitive(int offset, int count);
|
||||
|
||||
void ClearRenderTarget(GSTexture* t, const GSVector4& c) override;
|
||||
void ClearRenderTarget(GSTexture* t, u32 c) override;
|
||||
void InvalidateRenderTarget(GSTexture* t) override;
|
||||
void ClearDepth(GSTexture* t, float d) override;
|
||||
void ClearStencil(GSTexture* t, u8 c);
|
||||
|
||||
std::unique_ptr<GSDownloadTexture> CreateDownloadTexture(u32 width, u32 height, GSTexture::Format format) override;
|
||||
|
||||
|
|
|
@ -183,16 +183,6 @@ void* GSTextureOGL::GetNativeHandle() const
|
|||
return reinterpret_cast<void*>(static_cast<uintptr_t>(m_texture_id));
|
||||
}
|
||||
|
||||
void GSTextureOGL::Clear(const void* data)
|
||||
{
|
||||
glClearTexImage(m_texture_id, 0, m_int_format, m_int_type, data);
|
||||
}
|
||||
|
||||
void GSTextureOGL::Clear(const void* data, const GSVector4i& area)
|
||||
{
|
||||
glClearTexSubImage(m_texture_id, 0, area.x, area.y, 0, area.width(), area.height(), 1, m_int_format, m_int_type, data);
|
||||
}
|
||||
|
||||
bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch, int layer)
|
||||
{
|
||||
ASSERT(m_type != Type::DepthStencil);
|
||||
|
@ -205,8 +195,7 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch, int
|
|||
// overflow the pbo buffer
|
||||
// Data upload is rather small typically 64B or 1024B. So don't bother with PBO
|
||||
// and directly send the data to the GL synchronously
|
||||
|
||||
m_clean = false;
|
||||
GSDeviceOGL::GetInstance()->CommitClear(this, true);
|
||||
|
||||
const u32 preferred_pitch = Common::AlignUpPow2(r.width() << m_int_shift, TEXTURE_UPLOAD_PITCH_ALIGNMENT);
|
||||
const u32 map_size = r.height() * preferred_pitch;
|
||||
|
@ -269,6 +258,8 @@ bool GSTextureOGL::Map(GSMap& m, const GSVector4i* _r, int layer)
|
|||
if (layer >= m_mipmap_levels || IsCompressedFormat())
|
||||
return false;
|
||||
|
||||
GSDeviceOGL::GetInstance()->CommitClear(this, true);
|
||||
|
||||
GSVector4i r = _r ? *_r : GSVector4i(0, 0, m_size.x, m_size.y);
|
||||
// Will need some investigation
|
||||
ASSERT(r.width() != 0);
|
||||
|
@ -286,8 +277,6 @@ bool GSTextureOGL::Map(GSMap& m, const GSVector4i* _r, int layer)
|
|||
GL_PUSH_("Upload Texture %d", m_texture_id); // POP is in Unmap
|
||||
g_perfmon.Put(GSPerfMon::TextureUploads, 1);
|
||||
|
||||
m_clean = false;
|
||||
|
||||
const auto map = GSDeviceOGL::GetTextureUploadBuffer()->Map(TEXTURE_UPLOAD_ALIGNMENT, upload_size);
|
||||
m.bits = static_cast<u8*>(map.pointer);
|
||||
|
||||
|
@ -309,6 +298,8 @@ void GSTextureOGL::Unmap()
|
|||
{
|
||||
if (m_type == Type::Texture || m_type == Type::RenderTarget)
|
||||
{
|
||||
GSDeviceOGL::GetInstance()->CommitClear(this, true);
|
||||
|
||||
const u32 pitch = Common::AlignUpPow2(m_r_w << m_int_shift, TEXTURE_UPLOAD_PITCH_ALIGNMENT);
|
||||
const u32 upload_size = pitch * m_r_h;
|
||||
GLStreamBuffer* sb = GSDeviceOGL::GetTextureUploadBuffer();
|
||||
|
@ -334,11 +325,14 @@ void GSTextureOGL::Unmap()
|
|||
void GSTextureOGL::GenerateMipmap()
|
||||
{
|
||||
ASSERT(m_mipmap_levels > 1);
|
||||
GSDeviceOGL::GetInstance()->CommitClear(this, true);
|
||||
glGenerateTextureMipmap(m_texture_id);
|
||||
}
|
||||
|
||||
bool GSTextureOGL::Save(const std::string& fn)
|
||||
{
|
||||
GSDeviceOGL::GetInstance()->CommitClear(this, true);
|
||||
|
||||
// Collect the texture data
|
||||
u32 pitch = 4 * m_size.x;
|
||||
u32 buf_size = pitch * m_size.y * 2; // Note *2 for security (depth/stencil)
|
||||
|
@ -351,7 +345,7 @@ bool GSTextureOGL::Save(const std::string& fn)
|
|||
|
||||
if (IsDepthStencil())
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, GSDeviceOGL::GetInstance()->GetFBORead());
|
||||
|
||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_texture_id, 0);
|
||||
glReadPixels(0, 0, m_size.x, m_size.y, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image.get());
|
||||
|
@ -369,7 +363,7 @@ bool GSTextureOGL::Save(const std::string& fn)
|
|||
}
|
||||
else
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, GSDeviceOGL::GetInstance()->GetFBORead());
|
||||
|
||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture_id, 0);
|
||||
|
||||
|
@ -399,8 +393,6 @@ void GSTextureOGL::Swap(GSTexture* tex)
|
|||
GSTexture::Swap(tex);
|
||||
|
||||
std::swap(m_texture_id, static_cast<GSTextureOGL*>(tex)->m_texture_id);
|
||||
std::swap(m_fbo_read, static_cast<GSTextureOGL*>(tex)->m_fbo_read);
|
||||
std::swap(m_clean, static_cast<GSTextureOGL*>(tex)->m_clean);
|
||||
std::swap(m_r_x, static_cast<GSTextureOGL*>(tex)->m_r_x);
|
||||
std::swap(m_r_x, static_cast<GSTextureOGL*>(tex)->m_r_y);
|
||||
std::swap(m_r_w, static_cast<GSTextureOGL*>(tex)->m_r_w);
|
||||
|
@ -491,6 +483,7 @@ void GSDownloadTextureOGL::CopyFromTexture(
|
|||
const GSVector4i& drc, GSTexture* stex, const GSVector4i& src, u32 src_level, bool use_transfer_pitch)
|
||||
{
|
||||
GSTextureOGL* const glTex = static_cast<GSTextureOGL*>(stex);
|
||||
GSDeviceOGL::GetInstance()->CommitClear(glTex, true);
|
||||
|
||||
pxAssert(glTex->GetFormat() == m_format);
|
||||
pxAssert(drc.width() == src.width() && drc.height() == src.height());
|
||||
|
|
|
@ -22,8 +22,6 @@ class GSTextureOGL final : public GSTexture
|
|||
{
|
||||
private:
|
||||
GLuint m_texture_id = 0; // the texture id
|
||||
GLuint m_fbo_read = 0;
|
||||
bool m_clean = false;
|
||||
|
||||
// Avoid alignment constrain
|
||||
//GSVector4i m_r;
|
||||
|
@ -66,13 +64,7 @@ public:
|
|||
return (m_int_type == GL_UNSIGNED_BYTE || m_int_type == GL_UNSIGNED_SHORT || m_int_type == GL_UNSIGNED_INT);
|
||||
}
|
||||
|
||||
u32 GetID() { return m_texture_id; }
|
||||
bool HasBeenCleaned() { return m_clean; }
|
||||
void WasAttached() { m_clean = false; }
|
||||
void WasCleaned() { m_clean = true; }
|
||||
|
||||
void Clear(const void* data);
|
||||
void Clear(const void* data, const GSVector4i& area);
|
||||
__fi u32 GetID() { return m_texture_id; }
|
||||
};
|
||||
|
||||
class GSDownloadTextureOGL final : public GSDownloadTexture
|
||||
|
|
|
@ -790,24 +790,16 @@ void GSDeviceVK::DrawIndexedPrimitive(int offset, int count)
|
|||
vkCmdDrawIndexed(g_vulkan_context->GetCurrentCommandBuffer(), count, 1, m_index.start + offset, m_vertex.start, 0);
|
||||
}
|
||||
|
||||
void GSDeviceVK::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
||||
void GSDeviceVK::ClearRenderTarget(GSTexture* t, u32 c)
|
||||
{
|
||||
if (!t)
|
||||
return;
|
||||
|
||||
if (m_current_render_target == t)
|
||||
EndRenderPass();
|
||||
|
||||
static_cast<GSTextureVK*>(t)->SetClearColor(c);
|
||||
t->SetClearColor(c);
|
||||
}
|
||||
|
||||
void GSDeviceVK::ClearRenderTarget(GSTexture* t, u32 c) { ClearRenderTarget(t, GSVector4::rgba32(c) * (1.0f / 255)); }
|
||||
|
||||
void GSDeviceVK::InvalidateRenderTarget(GSTexture* t)
|
||||
{
|
||||
if (!t)
|
||||
return;
|
||||
|
||||
if (m_current_render_target == t || m_current_depth_target == t)
|
||||
EndRenderPass();
|
||||
|
||||
|
@ -816,9 +808,6 @@ void GSDeviceVK::InvalidateRenderTarget(GSTexture* t)
|
|||
|
||||
void GSDeviceVK::ClearDepth(GSTexture* t, float d)
|
||||
{
|
||||
if (!t)
|
||||
return;
|
||||
|
||||
if (m_current_depth_target == t)
|
||||
EndRenderPass();
|
||||
|
||||
|
@ -903,7 +892,7 @@ void GSDeviceVK::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((dTexVK->GetClearColor() == (sTexVK->GetClearColor())).alltrue())
|
||||
if (dTexVK->GetClearColor() == sTexVK->GetClearColor())
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -916,7 +905,7 @@ void GSDeviceVK::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
|
|||
// so use an attachment clear
|
||||
VkClearAttachment ca;
|
||||
ca.aspectMask = depth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
GSVector4::store<false>(ca.clearValue.color.float32, sTexVK->GetClearColor());
|
||||
GSVector4::store<false>(ca.clearValue.color.float32, sTexVK->GetUNormClearColor());
|
||||
ca.clearValue.depthStencil.depth = sTexVK->GetClearDepth();
|
||||
ca.clearValue.depthStencil.stencil = 0;
|
||||
ca.colorAttachment = 0;
|
||||
|
@ -1277,12 +1266,13 @@ void GSDeviceVK::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offs
|
|||
}
|
||||
|
||||
void GSDeviceVK::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect,
|
||||
const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c, const bool linear)
|
||||
const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, u32 c, const bool linear)
|
||||
{
|
||||
GL_PUSH("DoMerge");
|
||||
|
||||
const GSVector4 full_r(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
const u32 yuv_constants[4] = {EXTBUF.EMODA, EXTBUF.EMODC};
|
||||
const GSVector4 bg_color = GSVector4::unorm8(c);
|
||||
const bool feedback_write_2 = PMODE.EN2 && sTex[2] != nullptr && EXTBUF.FBIN == 1;
|
||||
const bool feedback_write_1 = PMODE.EN1 && sTex[2] != nullptr && EXTBUF.FBIN == 0;
|
||||
const bool feedback_write_2_but_blend_bg = feedback_write_2 && PMODE.SLBG == 1;
|
||||
|
@ -1362,7 +1352,7 @@ void GSDeviceVK::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
|||
// 1st output is enabled. It must be blended
|
||||
SetUtilityTexture(sTex[0], sampler);
|
||||
SetPipeline(m_merge[PMODE.MMOD]);
|
||||
SetUtilityPushConstants(&c, sizeof(c));
|
||||
SetUtilityPushConstants(&bg_color, sizeof(bg_color));
|
||||
DrawStretchRect(sRect[0], dRect[0], dTex->GetSize());
|
||||
}
|
||||
|
||||
|
@ -3136,10 +3126,10 @@ void GSDeviceVK::BeginClearRenderPass(VkRenderPass rp, const GSVector4i& rect, c
|
|||
vkCmdBeginRenderPass(g_vulkan_context->GetCurrentCommandBuffer(), &begin_info, VK_SUBPASS_CONTENTS_INLINE);
|
||||
}
|
||||
|
||||
void GSDeviceVK::BeginClearRenderPass(VkRenderPass rp, const GSVector4i& rect, const GSVector4& clear_color)
|
||||
void GSDeviceVK::BeginClearRenderPass(VkRenderPass rp, const GSVector4i& rect, u32 clear_color)
|
||||
{
|
||||
alignas(16) VkClearValue cv;
|
||||
GSVector4::store<true>((void*)cv.color.float32, clear_color);
|
||||
GSVector4::store<true>((void*)cv.color.float32, GSVector4::unorm8(clear_color));
|
||||
BeginClearRenderPass(rp, rect, &cv, 1);
|
||||
}
|
||||
|
||||
|
@ -3742,7 +3732,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
|||
alignas(16) VkClearValue cvs[2];
|
||||
u32 cv_count = 0;
|
||||
if (draw_rt)
|
||||
GSVector4::store<true>(&cvs[cv_count++].color, draw_rt->GetClearColor());
|
||||
GSVector4::store<true>(&cvs[cv_count++].color, draw_rt->GetUNormClearColor());
|
||||
|
||||
// the only time the stencil value is used here is DATE_one, so setting it to 1 is fine (not used otherwise)
|
||||
if (draw_ds)
|
||||
|
@ -3834,7 +3824,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
|||
{
|
||||
alignas(16) VkClearValue cvs[2];
|
||||
u32 cv_count = 0;
|
||||
GSVector4::store<true>(&cvs[cv_count++].color, draw_rt->GetClearColor());
|
||||
GSVector4::store<true>(&cvs[cv_count++].color, draw_rt->GetUNormClearColor());
|
||||
if (draw_ds)
|
||||
cvs[cv_count++].depthStencil = {draw_ds->GetClearDepth(), 1};
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ private:
|
|||
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) final;
|
||||
const GSRegEXTBUF& EXTBUF, u32 c, const bool linear) 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;
|
||||
|
@ -265,7 +265,6 @@ public:
|
|||
void DrawIndexedPrimitive();
|
||||
void DrawIndexedPrimitive(int offset, int count);
|
||||
|
||||
void ClearRenderTarget(GSTexture* t, const GSVector4& c) override;
|
||||
void ClearRenderTarget(GSTexture* t, u32 c) override;
|
||||
void InvalidateRenderTarget(GSTexture* t) override;
|
||||
void ClearDepth(GSTexture* t, float d) override;
|
||||
|
@ -352,7 +351,7 @@ public:
|
|||
bool InRenderPass();
|
||||
void BeginRenderPass(VkRenderPass rp, const GSVector4i& rect);
|
||||
void BeginClearRenderPass(VkRenderPass rp, const GSVector4i& rect, const VkClearValue* cv, u32 cv_count);
|
||||
void BeginClearRenderPass(VkRenderPass rp, const GSVector4i& rect, const GSVector4& clear_color);
|
||||
void BeginClearRenderPass(VkRenderPass rp, const GSVector4i& rect, u32 clear_color);
|
||||
void BeginClearRenderPass(VkRenderPass rp, const GSVector4i& rect, float depth, u8 stencil);
|
||||
void EndRenderPass();
|
||||
|
||||
|
|
|
@ -547,7 +547,7 @@ void GSTextureVK::CommitClear(VkCommandBuffer cmdbuf)
|
|||
else
|
||||
{
|
||||
alignas(16) VkClearColorValue cv;
|
||||
GSVector4::store<true>(cv.float32, GetClearColor());
|
||||
GSVector4::store<true>(cv.float32, GetUNormClearColor());
|
||||
const VkImageSubresourceRange srr = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u};
|
||||
vkCmdClearColorImage(cmdbuf, m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &cv, 1, &srr);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue