diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index d5e7555217..5dfd9c4a23 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -3352,6 +3352,7 @@ void GSRendererHW::Draw() // Z isn't offset but RT is, so we need a temp Z to align it, hopefully nothing will ever write to the Z too, right?? if (ds && vertical_offset && (m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0) != (m_cached_ctx.FRAME.Block() - rt->m_TEX0.TBP0)) { + m_using_temp_z = true; const int z_vertical_offset = ((static_cast(m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0) / 32) / std::max(rt->m_TEX0.TBW, 1U)) * GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].pgs.y; if (g_texture_cache->GetTemporaryZ() != nullptr) { @@ -3373,19 +3374,24 @@ void GSRendererHW::Draw() if (g_texture_cache->GetTemporaryZ() == nullptr) { m_temp_z_full_copy = false; - u32 vertical_size = std::max(rt->m_unscaled_size.y, ds->m_unscaled_size.y); - GL_CACHE("HW: RT in RT Z copy on draw %d z_vert_offset %d z_offset %d", s_n, z_vertical_offset, vertical_offset); - GSVector4i dRect = GSVector4i(0, vertical_offset * ds->m_scale, ds->m_unscaled_size.x * ds->m_scale, (vertical_offset + ds->m_unscaled_size.y - z_vertical_offset) * ds->m_scale); + const u32 vertical_size = std::max(rt->m_unscaled_size.y, ds->m_unscaled_size.y); + const GSVector4i dRect = GSVector4i(0, vertical_offset * ds->m_scale, ds->m_unscaled_size.x * ds->m_scale, (vertical_offset + ds->m_unscaled_size.y - z_vertical_offset) * ds->m_scale); const int new_height = std::max(static_cast(vertical_size * ds->m_scale), dRect.w); - GSTexture* tex = g_gs_device->CreateDepthStencil(ds->m_unscaled_size.x * ds->m_scale, new_height, GSTexture::Format::DepthStencil, true); - g_gs_device->StretchRect(ds->m_texture, GSVector4(0.0f, z_vertical_offset / static_cast(ds->m_unscaled_size.y), 1.0f, (ds->m_unscaled_size.y - z_vertical_offset) / static_cast(ds->m_unscaled_size.y)), 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, vertical_offset - z_vertical_offset); - t_size.y = std::max(new_height, t_size.y); + if (GSTexture* tex = g_gs_device->CreateDepthStencil(ds->m_unscaled_size.x * ds->m_scale, new_height, GSTexture::Format::DepthStencil, true)) + { + GL_CACHE("HW: RT in RT Z copy on draw %d z_vert_offset %d z_offset %d", s_n, z_vertical_offset, vertical_offset); + g_gs_device->StretchRect(ds->m_texture, GSVector4(0.0f, z_vertical_offset / static_cast(ds->m_unscaled_size.y), 1.0f, (ds->m_unscaled_size.y - z_vertical_offset) / static_cast(ds->m_unscaled_size.y)), 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, vertical_offset - z_vertical_offset); + t_size.y = std::max(new_height, t_size.y); + } + else + { + DevCon.Warning("HW: Temporary depth buffer creation failed."); + m_using_temp_z = false; + } } - m_using_temp_z = true; - } } // Don't resize if the BPP don't match. @@ -3985,13 +3991,16 @@ void GSRendererHW::Draw() if (z_width != new_w || z_height != new_h) { - GSVector4i dRect = GSVector4i(0, 0, g_texture_cache->GetTemporaryZ()->GetWidth(), g_texture_cache->GetTemporaryZ()->GetHeight()); - - GSTexture* tex = g_gs_device->CreateDepthStencil(new_w * ds->m_scale, new_h * ds->m_scale, GSTexture::Format::DepthStencil, true); - 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); + if (GSTexture* tex = g_gs_device->CreateDepthStencil(new_w * ds->m_scale, new_h * ds->m_scale, GSTexture::Format::DepthStencil, true)) + { + 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); + } + else + DevCon.Warning("HW: Temporary depth buffer creation failed."); } } if (!m_texture_shuffle && !m_channel_shuffle)