From e35c84c2c6be24b29e24f2580876a20cd264e1db Mon Sep 17 00:00:00 2001 From: lightningterror <18107717+lightningterror@users.noreply.github.com> Date: Thu, 29 Jan 2026 15:21:09 +0100 Subject: [PATCH] GS: Update Shader/texture copies counter handling. Add the copy counters in the function themselves, easier to track. This also tracks other shader copies such as setupdate, primid date, post processing such as shade boost and others which weren't tracked before. --- pcsx2/GS/Renderers/DX11/GSDevice11.cpp | 11 +++++++--- pcsx2/GS/Renderers/DX12/GSDevice12.cpp | 11 +++++++--- pcsx2/GS/Renderers/HW/GSRendererHW.cpp | 14 ------------- pcsx2/GS/Renderers/HW/GSTextureCache.cpp | 25 ----------------------- pcsx2/GS/Renderers/Metal/GSDeviceMTL.mm | 5 ++--- pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp | 12 +++++++---- pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp | 11 +++++++--- 7 files changed, 34 insertions(+), 55 deletions(-) diff --git a/pcsx2/GS/Renderers/DX11/GSDevice11.cpp b/pcsx2/GS/Renderers/DX11/GSDevice11.cpp index 612f39a1ce..b3daf3754c 100644 --- a/pcsx2/GS/Renderers/DX11/GSDevice11.cpp +++ b/pcsx2/GS/Renderers/DX11/GSDevice11.cpp @@ -1314,6 +1314,8 @@ void GSDevice11::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTextur void GSDevice11::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear) { + g_perfmon.Put(GSPerfMon::TextureCopies, 1); + CommitClear(sTex); const bool draw_in_depth = dTex && dTex->IsDepthStencil(); @@ -1381,6 +1383,8 @@ void GSDevice11::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTextur void GSDevice11::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, PresentShader shader, float shaderTime, bool linear) { + g_perfmon.Put(GSPerfMon::TextureCopies, 1); + CommitClear(sTex); GSVector2i ds; @@ -1540,6 +1544,8 @@ void GSDevice11::DrawMultiStretchRects(const MultiStretchRect* rects, u32 num_re void GSDevice11::DoMultiStretchRects(const MultiStretchRect* rects, u32 num_rects, const GSVector2& ds) { + g_perfmon.Put(GSPerfMon::TextureCopies, 1); + // Don't use primitive restart here, it ends up slower on some drivers. const u32 vertex_reserve_size = num_rects * 4; const u32 index_reserve_size = num_rects * 6; @@ -2181,6 +2187,8 @@ void GSDevice11::RenderImGui() void GSDevice11::SetupDATE(GSTexture* rt, GSTexture* ds, SetDATM datm, const GSVector4i& bbox) { + g_perfmon.Put(GSPerfMon::TextureCopies, 1); + // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows CommitClear(rt); @@ -2623,7 +2631,6 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config) const GSVector4 dRect(config.colclip_update_area); const GSVector4 sRect = dRect / GSVector4(size.x, size.y).xyxy(); StretchRect(colclip_rt, sRect, config.rt, dRect, ShaderConvert::COLCLIP_RESOLVE, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); Recycle(colclip_rt); g_gs_device->SetColorClipTexture(nullptr); @@ -2652,7 +2659,6 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config) const GSVector4 dRect = GSVector4((config.colclip_mode == GSHWDrawConfig::ColClipMode::ConvertOnly) ? GSVector4i::loadh(rtsize) : config.drawarea); const GSVector4 sRect = dRect / GSVector4(rtsize.x, rtsize.y).xyxy(); StretchRect(config.rt, sRect, colclip_rt, dRect, ShaderConvert::COLCLIP_INIT, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); } } @@ -2837,7 +2843,6 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config) const GSVector4 dRect(config.colclip_update_area); const GSVector4 sRect = dRect / GSVector4(size.x, size.y).xyxy(); StretchRect(colclip_rt, sRect, config.rt, dRect, ShaderConvert::COLCLIP_RESOLVE, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); Recycle(colclip_rt); g_gs_device->SetColorClipTexture(nullptr); diff --git a/pcsx2/GS/Renderers/DX12/GSDevice12.cpp b/pcsx2/GS/Renderers/DX12/GSDevice12.cpp index 56c0c9dc2a..ab5ce80a34 100644 --- a/pcsx2/GS/Renderers/DX12/GSDevice12.cpp +++ b/pcsx2/GS/Renderers/DX12/GSDevice12.cpp @@ -1748,6 +1748,8 @@ void GSDevice12::DrawMultiStretchRects( void GSDevice12::DoMultiStretchRects( const MultiStretchRect* rects, u32 num_rects, GSTexture12* dTex, ShaderConvert shader) { + g_perfmon.Put(GSPerfMon::TextureCopies, 1); + // Set up vertices first. const u32 vertex_reserve_size = num_rects * 4 * sizeof(GSVertexPT1); const u32 index_reserve_size = num_rects * 6 * sizeof(u16); @@ -1885,6 +1887,8 @@ void GSDevice12::DoStretchRect(GSTexture12* sTex, const GSVector4& sRect, GSText void GSDevice12::DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect, const GSVector2i& ds) { + g_perfmon.Put(GSPerfMon::TextureCopies, 1); + // ia const float left = dRect.x * 2 / ds.x - 1.0f; const float top = 1.0f - dRect.y * 2 / ds.y; @@ -3906,6 +3910,8 @@ void GSDevice12::SetPSConstantBuffer(const GSHWDrawConfig::PSConstantBuffer& cb) void GSDevice12::SetupDATE(GSTexture* rt, GSTexture* ds, SetDATM datm, const GSVector4i& bbox) { + g_perfmon.Put(GSPerfMon::TextureCopies, 1); + GL_PUSH("SetupDATE {%d,%d} %dx%d", bbox.left, bbox.top, bbox.width(), bbox.height()); const GSVector2i size(ds->GetSize()); @@ -3938,6 +3944,8 @@ void GSDevice12::SetupDATE(GSTexture* rt, GSTexture* ds, SetDATM datm, const GSV GSTexture12* GSDevice12::SetupPrimitiveTrackingDATE(GSHWDrawConfig& config, PipelineSelector& pipe) { + g_perfmon.Put(GSPerfMon::TextureCopies, 1); + // How this is done: // - can't put a barrier for the image in the middle of the normal render pass, so that's out // - so, instead of just filling the int texture with INT_MAX, we sample the RT and use -1 for failing values @@ -4084,7 +4092,6 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config) SetPipeline(m_colclip_finish_pipelines[pipe.ds].get()); SetUtilityTexture(colclip_rt, m_point_sampler_cpu); DrawStretchRect(sRect, GSVector4(config.colclip_update_area), rtsize); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); Recycle(colclip_rt); g_gs_device->SetColorClipTexture(nullptr); @@ -4286,7 +4293,6 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config) const GSVector4 drawareaf = GSVector4((config.colclip_mode == GSHWDrawConfig::ColClipMode::ConvertOnly) ? GSVector4i::loadh(rtsize) : config.drawarea); const GSVector4 sRect(drawareaf / GSVector4(rtsize.x, rtsize.y).xyxy()); DrawStretchRect(sRect, GSVector4(drawareaf), rtsize); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); GL_POP(); @@ -4364,7 +4370,6 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config) SetPipeline(m_colclip_finish_pipelines[pipe.ds].get()); SetUtilityTexture(colclip_rt, m_point_sampler_cpu); DrawStretchRect(sRect, GSVector4(config.colclip_update_area), rtsize); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); Recycle(colclip_rt); g_gs_device->SetColorClipTexture(nullptr); diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index 416b53bbee..22b95bdb06 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -3846,7 +3846,6 @@ void GSRendererHW::Draw() GL_CACHE("HW: RT in RT Z copy back draw %d z_vert_offset %d z_offset %d", s_n, z_vertical_offset, vertical_offset); g_gs_device->StretchRect(g_texture_cache->GetTemporaryZ(), sRect, ds->m_texture, GSVector4(dRect), ShaderConvert::DEPTH_COPY, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); } g_texture_cache->InvalidateTemporaryZ(); @@ -3863,7 +3862,6 @@ void GSRendererHW::Draw() dRect = dRect.min_u32(GSVector4i(ds->m_unscaled_size.x * ds->m_scale, ds->m_unscaled_size.y * ds->m_scale).xyxy()); g_gs_device->StretchRect(ds->m_texture, sRect, g_texture_cache->GetTemporaryZ(), GSVector4(dRect), ShaderConvert::DEPTH_COPY, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); z_address_info.rect_since = GSVector4i::zero(); g_texture_cache->SetTemporaryZInfo(z_address_info); } @@ -3911,7 +3909,6 @@ void GSRendererHW::Draw() if (m_cached_ctx.TEST.ZTST > ZTST_ALWAYS || !dRect.rintersect(GSVector4i(GSVector4(m_r) * ds->m_scale)).eq(dRect)) { g_gs_device->StretchRect(ds->m_texture, sRect, tex, GSVector4(dRect), ShaderConvert::DEPTH_COPY, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); } g_texture_cache->SetTemporaryZ(tex); g_texture_cache->SetTemporaryZInfo(ds->m_TEX0.TBP0, page_offset, rt_page_offset); @@ -4523,7 +4520,6 @@ void GSRendererHW::Draw() { const GSVector4i dRect = GSVector4i(0, 0, g_texture_cache->GetTemporaryZ()->GetWidth(), g_texture_cache->GetTemporaryZ()->GetHeight()); g_gs_device->StretchRect(g_texture_cache->GetTemporaryZ(), GSVector4(0.0f, 0.0f, 1.0f, 1.0f), tex, GSVector4(dRect), ShaderConvert::DEPTH_COPY, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); g_texture_cache->InvalidateTemporaryZ(); g_texture_cache->SetTemporaryZ(tex); } @@ -4830,7 +4826,6 @@ void GSRendererHW::Draw() GL_CACHE("HW: RT in RT Z copy back draw %d z_vert_offset %d rt_vert_offset %d z_horz_offset %d rt_horz_offset %d", s_n, z_vertical_offset, vertical_offset, z_horizontal_offset, horizontal_offset); g_gs_device->StretchRect(g_texture_cache->GetTemporaryZ(), sRect, ds->m_texture, GSVector4(dRect), ShaderConvert::DEPTH_COPY, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); } else if (m_temp_z_full_copy) { @@ -4843,7 +4838,6 @@ void GSRendererHW::Draw() GL_CACHE("HW: RT in RT Z copy back draw %d z_vert_offset %d z_offset %d", s_n, z_vertical_offset, vertical_offset); g_gs_device->StretchRect(g_texture_cache->GetTemporaryZ(), sRect, ds->m_texture, GSVector4(dRect), ShaderConvert::DEPTH_COPY, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); } m_temp_z_full_copy = false; @@ -7092,8 +7086,6 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c if (m_downscale_source) { - g_perfmon.Put(GSPerfMon::TextureCopies, 1); - // Can't use box filtering on depth (yet), or fractional scales. if (src_target->m_texture->IsDepthStencil() || std::floor(src_target->GetScale()) != src_target->GetScale()) { @@ -7121,9 +7113,7 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c } else { - g_perfmon.Put(GSPerfMon::TextureCopies, 1); const GSVector4i offset = copy_range - GSVector4i(copy_dst_offset).xyxy(); - // Adjust for bilinear, must be done after calculating offset. copy_range.x -= 1; copy_range.y -= 1; @@ -9230,11 +9220,7 @@ bool GSRendererHW::OI_BlitFMV(GSTextureCache::Target* _rt, GSTextureCache::Sourc const GSVector4 sRect(m_vt.m_min.t.x / tw, m_vt.m_min.t.y / th, m_vt.m_max.t.x / tw, m_vt.m_max.t.y / th); const GSVector4i r_full_new(0, 0, tw, th); g_gs_device->StretchRect(tex->m_texture, sRect, rt, dRect, ShaderConvert::COPY, m_vt.IsRealLinear()); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); - g_gs_device->CopyRect(rt, tex->m_texture, r_full_new, 0, 0); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); - g_gs_device->Recycle(rt); } diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp index f421dd86c7..af3a5efe3e 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp @@ -2834,7 +2834,6 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe else g_gs_device->StretchRect(dst->m_texture, sRect, tex, dRect, (type == RenderTarget) ? ShaderConvert::COPY : ShaderConvert::DEPTH_COPY, type == RenderTarget && !preserve_scale); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); m_target_memory_usage = (m_target_memory_usage - dst->m_texture->GetMemUsage()) + tex->GetMemUsage(); // If we're changing resolution scale, just toss the texture, it's not going to get reused. @@ -2865,7 +2864,6 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe if (!tex) return nullptr; g_gs_device->StretchRect(dst->m_texture, sRect, tex, dRect, ShaderConvert::FLOAT32_TO_FLOAT24, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); g_gs_device->Recycle(dst->m_texture); dst->m_texture = tex; @@ -2938,7 +2936,6 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe g_gs_device->StretchRect(dst->m_texture, source_rect, tex, dRect, (type == RenderTarget) ? ShaderConvert::COPY : ShaderConvert::DEPTH_COPY, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); m_target_memory_usage = m_target_memory_usage + tex->GetMemUsage(); // Don't kill the target here as it's being used for the source. @@ -2962,7 +2959,6 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe else g_gs_device->StretchRect(dst->m_texture, source_rect, tex, dRect, (type == RenderTarget) ? ShaderConvert::COPY : ShaderConvert::DEPTH_COPY, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); m_target_memory_usage = (m_target_memory_usage - dst->m_texture->GetMemUsage()) + tex->GetMemUsage(); g_gs_device->Recycle(dst->m_texture); @@ -3045,7 +3041,6 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe g_gs_device->StretchRect(dst_match->m_texture, GSVector4(0, 0, 1, 1), dst->m_texture, GSVector4(dst->GetUnscaledRect()) * GSVector4(dst->GetScale()), shader, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); dst_match->m_valid_rgb = !used; dst_match->m_was_dst_matched = true; @@ -3326,7 +3321,6 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe { dst_match->UnscaleRTAlpha(); g_gs_device->StretchRect(dst_match->m_texture, sRect, dst->m_texture, dRect, shader, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); } } @@ -4022,7 +4016,6 @@ void GSTextureCache::Target::ScaleRTAlpha() const GSVector4 dRect(m_texture->GetRect().rintersect(valid_rect)); const GSVector4 sRect = dRect / GSVector4(rtsize.x, rtsize.y).xyxy(); g_gs_device->StretchRect(m_texture, sRect, temp_rt, dRect, ShaderConvert::RTA_CORRECTION, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); g_gs_device->Recycle(m_texture); m_texture = temp_rt; } @@ -4048,7 +4041,6 @@ void GSTextureCache::Target::UnscaleRTAlpha() const GSVector4 dRect(m_texture->GetRect().rintersect(valid_rect)); const GSVector4 sRect = dRect / GSVector4(rtsize.x, rtsize.y).xyxy(); g_gs_device->StretchRect(m_texture, sRect, temp_rt, dRect, ShaderConvert::RTA_DECORRECTION, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); g_gs_device->Recycle(m_texture); m_texture = temp_rt; } @@ -4108,7 +4100,6 @@ void GSTextureCache::ScaleTargetForDisplay(Target* t, const GIFRegTEX0& dispfb, // Fill the new texture with the old data, and discard the old texture. g_gs_device->StretchRect(old_texture, new_texture, GSVector4(old_texture->GetSize()).zwxy(), ShaderConvert::COPY, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); m_target_memory_usage = (m_target_memory_usage - old_texture->GetMemUsage()) + new_texture->GetMemUsage(); g_gs_device->Recycle(old_texture); t->m_texture = new_texture; @@ -4242,7 +4233,6 @@ bool GSTextureCache::CopyRGBFromDepthToColor(Target* dst, Target* depth_src) const GSVector4 convert_rect = GSVector4(depth_src->GetUnscaledRect().rintersect(GSVector4i::loadh(new_size))); g_gs_device->StretchRect(depth_src->m_texture, convert_rect / GSVector4(depth_src->GetUnscaledSize()).xyxy(), tex, convert_rect * GSVector4(dst->GetScale()), shader, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); } // Copy in alpha if we're a new texture. @@ -4253,7 +4243,6 @@ bool GSTextureCache::CopyRGBFromDepthToColor(Target* dst, Target* depth_src) const GSVector4 copy_rect = GSVector4(tex->GetRect().rintersect(dst->m_texture->GetRect())); g_gs_device->StretchRect(dst->m_texture, copy_rect / GSVector4(GSVector4i(dst->m_texture->GetSize()).xyxy()), tex, copy_rect, false, false, false, true); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); } g_gs_device->Recycle(dst->m_texture); @@ -5291,7 +5280,6 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u const GSVector4 src_rect = GSVector4(scaled_sx, scaled_sy, scaled_sx + scaled_w, scaled_sy + scaled_h); const GSVector4 tmp_rect = src_rect / (GSVector4(tmp_texture->GetSize()).xyxy()); const GSVector4 dst_rect = GSVector4(scaled_dx, scaled_dy, (scaled_dx + scaled_w), (scaled_dy + scaled_h)); - g_perfmon.Put(GSPerfMon::TextureCopies, 2); g_gs_device->StretchRect(src->m_texture, tmp_rect, tmp_texture, src_rect, ShaderConvert::DEPTH_COPY, false); g_gs_device->StretchRect(tmp_texture, tmp_rect, dst->m_texture, dst_rect, ShaderConvert::DEPTH_COPY, false); } @@ -5302,7 +5290,6 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u const GSVector4 src_rect = GSVector4(scaled_sx, scaled_sy, scaled_sx + scaled_w, scaled_sy + scaled_h); const GSVector4 tmp_rect = src_rect / (GSVector4(tmp_texture->GetSize()).xyxy()); const GSVector4 dst_rect = GSVector4(scaled_dx, scaled_dy, (scaled_dx + scaled_w), (scaled_dy + scaled_h)); - g_perfmon.Put(GSPerfMon::TextureCopies, 2); g_gs_device->StretchRect(src->m_texture, tmp_rect, tmp_texture, src_rect, false, false, false, true); g_gs_device->StretchRect(tmp_texture, tmp_rect, dst->m_texture, dst_rect, false, false, false, true); } @@ -5330,7 +5317,6 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u { const ShaderConvert shader = ShaderConvert::COPY; const GSVector4 dst_rect = GSVector4(scaled_dx, scaled_dy, (scaled_dx + scaled_w), (scaled_dy + scaled_h)); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); g_gs_device->StretchRect(src->m_texture, src_rect, dst->m_texture, dst_rect, false, false, false, true, shader); } else if (src->m_type != dst->m_type) @@ -5348,13 +5334,11 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u default: break; } - g_perfmon.Put(GSPerfMon::TextureCopies, 1); g_gs_device->StretchRect(src->m_texture, src_rect, dst->m_texture, scaled_src_rect, shader, false); } else if (src->m_texture->IsDepthStencil()) { const GSVector4 dst_rect = GSVector4(scaled_dx, scaled_dy, (scaled_dx + scaled_w), (scaled_dy + scaled_h)); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); g_gs_device->StretchRect(src->m_texture, src_rect, dst->m_texture, dst_rect, ShaderConvert::DEPTH_COPY, false); } else @@ -6296,7 +6280,6 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con { if (dst->m_rt_alpha_scale) { - g_perfmon.Put(GSPerfMon::TextureCopies, 1); const GSVector4 sRectF = GSVector4(sRect) / GSVector4(1, 1, sTex->GetWidth(), sTex->GetHeight()); g_gs_device->StretchRect( sTex, sRectF, dTex, GSVector4(destX, destY, sRect.width(), sRect.height()), ShaderConvert::RTA_DECORRECTION, false); @@ -6348,8 +6331,6 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con sTex, sRectF, dTex, GSVector4(destX, destY, new_size.x, new_size.y), shader, false); } - g_perfmon.Put(GSPerfMon::TextureCopies, 1); - #ifdef PCSX2_DEVBUILD if (GSConfig.UseDebugDevice) { @@ -6799,7 +6780,6 @@ GSTextureCache::Source* GSTextureCache::CreateMergedSource(GIFRegTEX0 TEX0, GIFR // Sort rect list by the texture, we want to batch as many as possible together. g_gs_device->SortMultiStretchRects(copy_queue, copy_count); g_gs_device->DrawMultiStretchRects(copy_queue, copy_count, dtex, ShaderConvert::COPY); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); if (lmtex) g_gs_device->Recycle(lmtex); @@ -7090,7 +7070,6 @@ GSTexture* GSTextureCache::LookupPaletteSource(u32 CBP, u32 CPSM, u32 CBW, GSVec return nullptr; g_gs_device->StretchRect(t->m_texture, GSVector4(0, 0, 1, 1), tex, GSVector4(GSVector4i::loadh(t->m_unscaled_size)), (t->m_type == RenderTarget) ? ShaderConvert::COPY : ShaderConvert::DEPTH_COPY, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); m_target_memory_usage = (m_target_memory_usage - t->m_texture->GetMemUsage()) + tex->GetMemUsage(); g_gs_device->Recycle(t->m_texture); @@ -7238,7 +7217,6 @@ void GSTextureCache::Read(Target* t, const GSVector4i& r) if (tmp) { g_gs_device->StretchRect(t->m_texture, src, tmp, GSVector4(drc), ps_shader, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); dltex->get()->CopyFromTexture(drc, tmp, drc, 0, true); g_gs_device->Recycle(tmp); } @@ -7907,7 +7885,6 @@ void GSTextureCache::Target::Update(bool cannot_scale) //GL_CACHE("TC: RT in RT Updating Z copy on draw %d z_offset %d", s_n, z_address_info.offset); const GSVector4i dRect = GSVector4i(total_rect.x * m_scale, (z_address_info.offset + total_rect.y) * m_scale, (total_rect.z + (1.0f / m_scale)) * m_scale, (z_address_info.offset + total_rect.w + (1.0f / m_scale)) * m_scale); g_gs_device->StretchRect(m_texture, GSVector4(total_rect.x / static_cast(m_unscaled_size.x), total_rect.y / static_cast(m_unscaled_size.y), (total_rect.z + (1.0f / m_scale)) / static_cast(m_unscaled_size.x), (total_rect.w + (1.0f / m_scale)) / static_cast(m_unscaled_size.y)), g_texture_cache->GetTemporaryZ(), GSVector4(dRect), ShaderConvert::DEPTH_COPY, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); } } } @@ -8057,14 +8034,12 @@ bool GSTextureCache::Target::ResizeTexture(int new_unscaled_width, int new_unsca { // Can't do partial copies in DirectX for depth textures, and it's probably not ideal in other // APIs either. So use a fullscreen quad setting depth instead. - g_perfmon.Put(GSPerfMon::TextureCopies, 1); g_gs_device->StretchRect(m_texture, tex, GSVector4(rc), ShaderConvert::DEPTH_COPY, true); } else { if (require_new_rect) { - g_perfmon.Put(GSPerfMon::TextureCopies, 1); g_gs_device->StretchRect(m_texture, tex, GSVector4(rc), ShaderConvert::COPY, false); } else diff --git a/pcsx2/GS/Renderers/Metal/GSDeviceMTL.mm b/pcsx2/GS/Renderers/Metal/GSDeviceMTL.mm index 42d339049e..86b66d968f 100644 --- a/pcsx2/GS/Renderers/Metal/GSDeviceMTL.mm +++ b/pcsx2/GS/Renderers/Metal/GSDeviceMTL.mm @@ -1587,6 +1587,7 @@ void GSDeviceMTL::DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect [m_current_render.encoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; + g_perfmon.Put(GSPerfMon::TextureCopies, 1); g_perfmon.Put(GSPerfMon::DrawCalls, 1); } @@ -1597,6 +1598,7 @@ void GSDeviceMTL::RenderCopy(GSTexture* sTex, id pipelin MRESetPipeline(pipeline); MRESetTexture(sTex, GSMTLTextureIndexNonHW); [m_current_render.encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:3]; + g_perfmon.Put(GSPerfMon::TextureCopies, 1); g_perfmon.Put(GSPerfMon::DrawCalls, 1); } @@ -2164,7 +2166,6 @@ void GSDeviceMTL::RenderHW(GSHWDrawConfig& config) { BeginRenderPass(@"ColorClip Resolve", config.rt, MTLLoadActionLoad, nullptr, MTLLoadActionDontCare); RenderCopy(colclip_rt, m_colclip_resolve_pipeline, config.colclip_update_area); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); Recycle(colclip_rt); @@ -2194,7 +2195,6 @@ void GSDeviceMTL::RenderHW(GSHWDrawConfig& config) case GSTexture::State::Dirty: BeginRenderPass(@"ColorClip Init", colclip_rt, MTLLoadActionDontCare, nullptr, MTLLoadActionDontCare); RenderCopy(config.rt, m_colclip_init_pipeline, copy_rect); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); break; case GSTexture::State::Cleared: @@ -2306,7 +2306,6 @@ void GSDeviceMTL::RenderHW(GSHWDrawConfig& config) { BeginRenderPass(@"ColorClip Resolve", config.rt, MTLLoadActionLoad, nullptr, MTLLoadActionDontCare); RenderCopy(colclip_rt, m_colclip_resolve_pipeline, config.colclip_update_area); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); Recycle(colclip_rt); diff --git a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp index 98317798b5..bc7031ff15 100644 --- a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp +++ b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp @@ -1423,10 +1423,11 @@ 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) { + g_perfmon.Put(GSPerfMon::TextureCopies, 1); + CommitClear(sTex, true); GL_PUSH(fmt::format("CopyRectConv from {}", static_cast(sTex)->GetID()).c_str()); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); // NOTE: This previously used glCopyTextureSubImage2D(), but this appears to leak memory in // the loading screens of Evolution Snowboarding in Intel/NVIDIA drivers. @@ -1657,6 +1658,8 @@ void GSDeviceOGL::FilteredDownsampleTexture(GSTexture* sTex, GSTexture* dTex, u3 void GSDeviceOGL::DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect, const GSVector2i& ds) { + g_perfmon.Put(GSPerfMon::TextureCopies, 1); + // Original code from DX const float left = dRect.x * 2 / ds.x - 1.0f; const float right = dRect.z * 2 / ds.x - 1.0f; @@ -1727,6 +1730,8 @@ void GSDeviceOGL::DrawMultiStretchRects( void GSDeviceOGL::DoMultiStretchRects(const MultiStretchRect* rects, u32 num_rects, const GSVector2& ds) { + g_perfmon.Put(GSPerfMon::TextureCopies, 1); + const u32 vertex_reserve_size = num_rects * 4 * sizeof(GSVertexPT1); const u32 index_reserve_size = num_rects * 6 * sizeof(u16); auto vertex_map = m_vertex_stream_buffer->Map(sizeof(GSVertexPT1), vertex_reserve_size); @@ -1922,6 +1927,8 @@ void GSDeviceOGL::DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float par void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, SetDATM datm, const GSVector4i& bbox) { + g_perfmon.Put(GSPerfMon::TextureCopies, 1); + GL_PUSH("DATE First Pass"); // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows @@ -2458,7 +2465,6 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config) const GSVector4 dRect(config.colclip_update_area); const GSVector4 sRect = dRect / GSVector4(size.x, size.y).xyxy(); StretchRect(colclip_rt, sRect, config.rt, dRect, ShaderConvert::COLCLIP_RESOLVE, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); Recycle(colclip_rt); g_gs_device->SetColorClipTexture(nullptr); @@ -2493,7 +2499,6 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config) const GSVector4 dRect = GSVector4((config.colclip_mode == GSHWDrawConfig::ColClipMode::ConvertOnly) ? GSVector4i::loadh(rtsize) : config.drawarea); const GSVector4 sRect = dRect / GSVector4(rtsize.x, rtsize.y).xyxy(); StretchRect(config.rt, sRect, colclip_rt, dRect, ShaderConvert::COLCLIP_INIT, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); } } @@ -2762,7 +2767,6 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config) const GSVector4 dRect(config.colclip_update_area); const GSVector4 sRect = dRect / GSVector4(size.x, size.y).xyxy(); StretchRect(colclip_rt, sRect, config.rt, dRect, ShaderConvert::COLCLIP_RESOLVE, false); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); Recycle(colclip_rt); g_gs_device->SetColorClipTexture(nullptr); diff --git a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp index 39fb67072b..5f5f08528a 100644 --- a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp +++ b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp @@ -2929,6 +2929,8 @@ void GSDeviceVK::DrawMultiStretchRects( void GSDeviceVK::DoMultiStretchRects( const MultiStretchRect* rects, u32 num_rects, GSTextureVK* dTex, ShaderConvert shader) { + g_perfmon.Put(GSPerfMon::TextureCopies, 1); + // Set up vertices first. const u32 vertex_reserve_size = num_rects * 4 * sizeof(GSVertexPT1); const u32 index_reserve_size = num_rects * 6 * sizeof(u16); @@ -3082,6 +3084,8 @@ void GSDeviceVK::DoStretchRect(GSTextureVK* sTex, const GSVector4& sRect, GSText void GSDeviceVK::DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect, const GSVector2i& ds) { + g_perfmon.Put(GSPerfMon::TextureCopies, 1); + // ia const float left = dRect.x * 2 / ds.x - 1.0f; const float top = 1.0f - dRect.y * 2 / ds.y; @@ -5468,6 +5472,8 @@ void GSDeviceVK::SetPSConstantBuffer(const GSHWDrawConfig::PSConstantBuffer& cb) void GSDeviceVK::SetupDATE(GSTexture* rt, GSTexture* ds, SetDATM datm, const GSVector4i& bbox) { + g_perfmon.Put(GSPerfMon::TextureCopies, 1); + GL_PUSH("SetupDATE {%d,%d} %dx%d", bbox.left, bbox.top, bbox.width(), bbox.height()); const GSVector2i size(ds->GetSize()); @@ -5495,6 +5501,8 @@ void GSDeviceVK::SetupDATE(GSTexture* rt, GSTexture* ds, SetDATM datm, const GSV GSTextureVK* GSDeviceVK::SetupPrimitiveTrackingDATE(GSHWDrawConfig& config) { + g_perfmon.Put(GSPerfMon::TextureCopies, 1); + // How this is done: // - can't put a barrier for the image in the middle of the normal render pass, so that's out // - so, instead of just filling the int texture with INT_MAX, we sample the RT and use -1 for failing values @@ -5676,7 +5684,6 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config) SetPipeline(m_colclip_finish_pipelines[pipe.ds][pipe.IsRTFeedbackLoop()]); SetUtilityTexture(colclip_rt, m_point_sampler); DrawStretchRect(sRect, drawareaf, rtsize); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); Recycle(colclip_rt); g_gs_device->SetColorClipTexture(nullptr); @@ -5893,7 +5900,6 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config) const GSVector4 drawareaf = GSVector4((config.colclip_mode == GSHWDrawConfig::ColClipMode::ConvertOnly) ? GSVector4i::loadh(rtsize) : config.drawarea); const GSVector4 sRect(drawareaf / GSVector4(rtsize).xyxy()); DrawStretchRect(sRect, drawareaf, rtsize); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); GL_POP(); OMSetRenderTargets(draw_rt, draw_ds, config.scissor, static_cast(pipe.feedback_loop_flags)); @@ -5995,7 +6001,6 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config) SetPipeline(m_colclip_finish_pipelines[pipe.ds][pipe.IsRTFeedbackLoop()]); SetUtilityTexture(colclip_rt, m_point_sampler); DrawStretchRect(sRect, drawareaf, rtsize); - g_perfmon.Put(GSPerfMon::TextureCopies, 1); Recycle(colclip_rt); g_gs_device->SetColorClipTexture(nullptr);