diff --git a/pcsx2/GS/GSState.cpp b/pcsx2/GS/GSState.cpp index b3c3685d85..66fba5fa93 100644 --- a/pcsx2/GS/GSState.cpp +++ b/pcsx2/GS/GSState.cpp @@ -2615,7 +2615,6 @@ void GSState::FlushPrim() m_quad_check_valid_shuffle = false; m_drawlist.clear(); m_drawlist_bbox.clear(); - m_drawlist_bbox_tex.clear(); if (GSConfig.ShouldDump(s_n, g_perfmon.GetFrame())) { @@ -4750,71 +4749,6 @@ GSState::PRIM_OVERLAP GSState::GetPrimitiveOverlapDrawlist(bool save_drawlist, b } } -template -void GSState::GetPrimitiveOverlapDrawlistTextureBBoxImpl(float bbox_scale) -{ - pxAssert(m_drawlist_bbox_tex.empty()); // Should only call this once per draw. - - constexpr int n = GSUtil::GetClassVertexCount(primclass); - const GSVertex* RESTRICT v = m_vertex->buff; - const u16* RESTRICT index = m_index->buff; - const u32 count = m_index->tail; - - for (u32 i = 0; i < count; i += n) - { - const float q = primclass == GS_SPRITE_CLASS ? v[index[i + 1]].RGBAQ.Q : v[index[i]].RGBAQ.Q; - GSVector4 bbox = GetTexCoordsImpl(v[index[i]], q); - - for (u32 j = 1; j < n; j++) - { - const GSVector4 tex = GetTexCoordsImpl(v[index[i + j]]); - bbox = bbox.min(tex).xyzw(bbox.max(tex)); - } - - bbox = bbox * bbox_scale; // Account for upscaling. - bbox = bbox.floor().xyzw(bbox.ceil()); // Round. - bbox += GSVector4(-1.0f, -1.0f, 1.0f, 1.0f); // +1 on all sides for bilinear. - - m_drawlist_bbox_tex.push_back(GSVector4i(bbox)); - } -} - -void GSState::GetPrimitiveOverlapDrawlistTextureBBox(float bbox_scale) -{ - pxAssert(PRIM->TME); - - switch (m_vt.m_primclass) - { - case GS_POINT_CLASS: - if (PRIM->FST) - GetPrimitiveOverlapDrawlistTextureBBoxImpl(bbox_scale); - else - GetPrimitiveOverlapDrawlistTextureBBoxImpl(bbox_scale); - break; - case GS_LINE_CLASS: - if (PRIM->FST) - GetPrimitiveOverlapDrawlistTextureBBoxImpl(bbox_scale); - else - GetPrimitiveOverlapDrawlistTextureBBoxImpl(bbox_scale); - break; - case GS_TRIANGLE_CLASS: - if (PRIM->FST) - GetPrimitiveOverlapDrawlistTextureBBoxImpl(bbox_scale); - else - GetPrimitiveOverlapDrawlistTextureBBoxImpl(bbox_scale); - break; - case GS_SPRITE_CLASS: - if (PRIM->FST) - GetPrimitiveOverlapDrawlistTextureBBoxImpl(bbox_scale); - else - GetPrimitiveOverlapDrawlistTextureBBoxImpl(bbox_scale); - break; - default: - pxAssert(false); - return; - } -} - GSState::PRIM_OVERLAP GSState::PrimitiveOverlap(bool save_drawlist) { // Assume that 1 triangle, 1 sprite, 1 line, or 3 points can't overlap. diff --git a/pcsx2/GS/GSState.h b/pcsx2/GS/GSState.h index f96fcc0db1..b5448a668f 100644 --- a/pcsx2/GS/GSState.h +++ b/pcsx2/GS/GSState.h @@ -392,7 +392,6 @@ public: PRIM_OVERLAP m_prim_overlap = PRIM_OVERLAP_UNKNOW; std::vector m_drawlist; std::vector m_drawlist_bbox; - std::vector m_drawlist_bbox_tex; struct GSPCRTCRegs { @@ -538,9 +537,6 @@ public: PRIM_OVERLAP GetPrimitiveOverlapDrawlist(bool save_drawlist = false, bool save_bbox = false, float bbox_scale = 1.0f, u32* max_size = nullptr); PRIM_OVERLAP PrimitiveOverlap(bool save_drawlist = false); - template - void GetPrimitiveOverlapDrawlistTextureBBoxImpl(float bbox_scale = 1.0f); - void GetPrimitiveOverlapDrawlistTextureBBox(float bbox_scale = 1.0f); bool SpriteDrawWithoutGaps(); void CalculatePrimitiveCoversWithoutGaps(); GIFRegTEX0 GetTex0Layer(u32 lod); diff --git a/pcsx2/GS/Renderers/Common/GSDevice.h b/pcsx2/GS/Renderers/Common/GSDevice.h index f3d90eb296..f53f9f58cc 100644 --- a/pcsx2/GS/Renderers/Common/GSDevice.h +++ b/pcsx2/GS/Renderers/Common/GSDevice.h @@ -1226,18 +1226,17 @@ struct alignas(16) GSHWDrawConfig EarlyResolve = 4 }; - GSTexture* rt; ///< Render target - GSTexture* ds; ///< Depth stencil - GSTexture* tex; ///< Source texture - GSTexture* pal; ///< Palette texture - const GSVertex* verts;///< Vertices to draw - const u16* indices; ///< Indices to draw - u32 nverts; ///< Number of vertices - u32 nindices; ///< Number of indices - u32 indices_per_prim; ///< Number of indices that make up one primitive - const std::vector* drawlist; ///< For reducing barriers on sprites - const std::vector* drawlist_bbox; ///< For RT copy when barriers not available. - const std::vector* drawlist_bbox_tex; ///< Additionally if we need to sample not from the same pixel of the RT. + GSTexture* rt; ///< Render target + GSTexture* ds; ///< Depth stencil + GSTexture* tex; ///< Source texture + GSTexture* pal; ///< Palette texture + const GSVertex* verts; ///< Vertices to draw + const u16* indices; ///< Indices to draw + u32 nverts; ///< Number of vertices + u32 nindices; ///< Number of indices + u32 indices_per_prim; ///< Number of indices that make up one primitive + const std::vector* drawlist; ///< For reducing barriers on sprites + const std::vector* drawlist_bbox; ///< For RT copy when barriers not available. GSVector4i scissor; ///< Scissor rect GSVector4i drawarea; ///< Area in the framebuffer which will be modified. GSVector4i samplearea; ///< Area in the texture which will be sampled. diff --git a/pcsx2/GS/Renderers/DX11/GSDevice11.cpp b/pcsx2/GS/Renderers/DX11/GSDevice11.cpp index 14dd06211e..1ec59424d8 100644 --- a/pcsx2/GS/Renderers/DX11/GSDevice11.cpp +++ b/pcsx2/GS/Renderers/DX11/GSDevice11.cpp @@ -3230,15 +3230,16 @@ void GSDevice11::SendHWDraw(const GSHWDrawConfig& config, pxAssert(config.drawlist && !config.drawlist->empty()); pxAssert(config.drawlist_bbox && static_cast(config.drawlist_bbox->size()) == draw_list_size); + if (config.tex_hazard != config.TEX_HAZARD_NONE) + FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, config.samplearea); + for (u32 n = 0, p = 0; n < draw_list_size; n++) { const u32 count = config.drawlist->at(n) * indices_per_prim; const GSVector4i bbox = config.drawlist_bbox->at(n).rintersect(config.drawarea); - const GSVector4i bbox_tex = config.drawlist_bbox_tex ? - config.drawlist_bbox_tex->at(n).rintersect(config.samplearea) : GSVector4i::zero(); - FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, bbox, bbox_tex); + FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, bbox); Draw(config, p, count); diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index c9955b3d6f..c70d17d58b 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -1358,10 +1358,10 @@ GSVector4i GSRendererHW::ComputeBoundingBoxRT(const GSVector2i& rtsize, float rt return GSVector4i(box * GSVector4(rtscale)).rintersect(GSVector4i(0, 0, rtsize.x, rtsize.y)); } -GSVector4i GSRendererHW::ComputeBoundingBoxTex(const GSVector2i& texsize, const GSVector4i& region, float texscale) +GSVector4i GSRendererHW::ComputeBoundingBoxTex(const GSVector2i& texsize, const GSVector4i& coverage, const GSVector4i& region, float texscale) { const GSVector4 offset = GSVector4(region.xyxy()) + GSVector4(-1.0f, -1.0f, 1.0f, 1.0f); // Region offset + round value - const GSVector4 box = m_vt.m_min.t.upld(m_vt.m_max.t) + offset; + const GSVector4 box = GSVector4(coverage) + offset; return GSVector4i(box * GSVector4(texscale)).rintersect(GSVector4i(0, 0, texsize.x, texsize.y)); } @@ -6206,16 +6206,6 @@ void GSRendererHW::DetermineBarriers(GSTextureCache::Target* rt, GSTextureCache: ComputeDrawlistGetSize(rt->m_scale); m_conf.drawlist = &m_drawlist; m_conf.drawlist_bbox = &m_drawlist_bbox; - - if (m_conf.tex_hazard != GSHWDrawConfig::TEX_HAZARD_NONE) - { - GetPrimitiveOverlapDrawlistTextureBBox(tex->GetScale()); - m_conf.drawlist_bbox_tex = &m_drawlist_bbox_tex; - } - else - { - m_conf.drawlist_bbox_tex = nullptr; - } } } @@ -9462,7 +9452,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta const GSVector4i tex_region = tex ? tex->GetRegionRect() : GSVector4i::zero(); m_conf.samplearea = m_channel_shuffle ? scissor : - GSVector4i::loadh(texsize).rintersect(ComputeBoundingBoxTex(texsize, tex_region, texscale)); + GSVector4i::loadh(texsize).rintersect(ComputeBoundingBoxTex(texsize, tmm.coverage, tex_region, texscale)); m_conf.scissor = (date_options.enabled && !date_options.barrier) ? m_conf.drawarea : scissor; diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.h b/pcsx2/GS/Renderers/HW/GSRendererHW.h index 13a677cd85..1a9d0362d5 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.h +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.h @@ -364,7 +364,7 @@ public: void ExpandLineIndices(); GSVector4 RealignTargetTextureCoordinate(const GSTextureCache::Source* tex); GSVector4i ComputeBoundingBoxRT(const GSVector2i& rtsize, float rtscale); - GSVector4i ComputeBoundingBoxTex(const GSVector2i& texsize, const GSVector4i& region, float texscale); + GSVector4i ComputeBoundingBoxTex(const GSVector2i& texsize, const GSVector4i& coverage, const GSVector4i& region, float texscale); void MergeSprite(GSTextureCache::Source* tex); float GetTextureScaleFactor() override; GSVector2i GetValidSize(const GSTextureCache::Source* tex = nullptr, const bool is_shuffle = false); diff --git a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp index 3bef910e8a..9cf9420e91 100644 --- a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp +++ b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp @@ -3172,6 +3172,9 @@ void GSDeviceOGL::SendHWDraw(const GSHWDrawConfig& config, else pxAssert(config.drawlist_bbox && static_cast(config.drawlist_bbox->size()) == draw_list_size); + if (!m_features.texture_barrier && config.tex_hazard != config.TEX_HAZARD_NONE) + FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, config.samplearea); + for (u32 n = 0, p = 0; n < draw_list_size; n++) { const u32 count = config.drawlist->at(n) * indices_per_prim; @@ -3183,9 +3186,7 @@ void GSDeviceOGL::SendHWDraw(const GSHWDrawConfig& config, else { const GSVector4i bbox = config.drawlist_bbox->at(n).rintersect(config.drawarea); - const GSVector4i bbox_tex = config.drawlist_bbox_tex ? - config.drawlist_bbox_tex->at(n).rintersect(config.samplearea) : GSVector4i::zero(); - FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, bbox, bbox_tex); + FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, bbox); } Draw(config, p, count);