@@ -3815,23 +3815,54 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
38153815 if (GSConfig.UserHacks_TextureInsideRt >= GSTextureInRtMode::InsideTargets && t->Inside (dst->m_TEX0 .TBP0 , dst->m_TEX0 .TBW , dst->m_TEX0 .PSM , dst->m_valid ) &&
38163816 GSLocalMemory::m_psm[t->m_TEX0 .PSM ].bpp == GSLocalMemory::m_psm[dst->m_TEX0 .PSM ].bpp )
38173817 {
3818- dst->m_TEX0 .TBP0 = t->m_TEX0 .TBP0 ;
3819- dst->m_valid = t->m_valid ;
3820- dst->m_drawn_since_read = t->m_drawn_since_read ;
3821- dst->m_end_block = t->m_end_block ;
3822- dst->m_valid_rgb = true ;
3823- t->m_valid_rgb = false ;
3824- t->m_was_dst_matched = true ;
3818+ // if this part is dirty, then let's break it in two.
3819+ GSVector4i dirty_rect = t->m_dirty .GetTotalRect (t->m_TEX0 , t->m_unscaled_size );
3820+ if (GSLocalMemory::GetStartBlockAddress (t->m_TEX0 .TBP0 , t->m_TEX0 .TBW , t->m_TEX0 .PSM , dirty_rect) >= dst->m_TEX0 .TBP0 )
3821+ {
3822+ t->m_valid .w = dirty_rect.y ;
38253823
3826- dst->ResizeTexture (t->m_unscaled_size .x , t->m_unscaled_size .y );
3824+ if (t->m_valid .rempty ())
3825+ {
3826+ if (src && src->m_target && src->m_from_target == t)
3827+ {
3828+ src->m_from_target = nullptr ;
3829+ src->m_texture = t->m_texture ;
3830+ src->m_target_direct = false ;
3831+ src->m_shared_texture = false ;
38273832
3828- const ShaderConvert shader = (GSLocalMemory::m_psm[dst->m_TEX0 .PSM ].trbpp == 16 ) ? ShaderConvert::RGB5A1_TO_FLOAT16 :
3829- (GSLocalMemory::m_psm[dst->m_TEX0 .PSM ].trbpp == 32 ) ? ShaderConvert::RGBA8_TO_FLOAT32 :
3830- ShaderConvert::RGBA8_TO_FLOAT24;
3833+ t->m_texture = nullptr ;
3834+ i = list.erase (j);
3835+ delete t;
3836+ }
3837+ else
3838+ {
3839+ InvalidateSourcesFromTarget (t);
3840+ i = list.erase (j);
3841+ delete t;
3842+ }
3843+ }
3844+ else
3845+ t->UpdateValidity (t->m_valid , true );
3846+ }
3847+ else
3848+ {
3849+ dst->m_TEX0 .TBP0 = t->m_TEX0 .TBP0 ;
3850+ dst->m_valid = t->m_valid ;
3851+ dst->m_drawn_since_read = t->m_drawn_since_read ;
3852+ dst->m_end_block = t->m_end_block ;
3853+ dst->m_valid_rgb = true ;
3854+ t->m_valid_rgb = false ;
3855+ t->m_was_dst_matched = true ;
38313856
3832- g_gs_device->StretchRect (t->m_texture , GSVector4 (0 , 0 , 1 , 1 ),
3833- dst->m_texture , GSVector4 (t->GetUnscaledRect ()) * GSVector4 (dst->GetScale ()), shader, false );
3857+ dst->ResizeTexture (t->m_unscaled_size .x , t->m_unscaled_size .y );
38343858
3859+ const ShaderConvert shader = (GSLocalMemory::m_psm[dst->m_TEX0 .PSM ].trbpp == 16 ) ? ShaderConvert::RGB5A1_TO_FLOAT16 :
3860+ (GSLocalMemory::m_psm[dst->m_TEX0 .PSM ].trbpp == 32 ) ? ShaderConvert::RGBA8_TO_FLOAT32 :
3861+ ShaderConvert::RGBA8_TO_FLOAT24;
3862+
3863+ g_gs_device->StretchRect (t->m_texture , GSVector4 (0 , 0 , 1 , 1 ),
3864+ dst->m_texture , GSVector4 (t->GetUnscaledRect ()) * GSVector4 (dst->GetScale ()), shader, false );
3865+ }
38353866 break ;
38363867 }
38373868 else
@@ -3858,7 +3889,18 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
38583889
38593890 if (height_adjust < t->m_unscaled_size .y )
38603891 {
3861- t->m_TEX0 .TBP0 = GSLocalMemory::GetStartBlockAddress (t->m_TEX0 .TBP0 , t->m_TEX0 .TBW , t->m_TEX0 .PSM , GSVector4i (0 , height_adjust, t->m_valid .z , t->m_valid .w ));
3892+ u32 new_base_tbp = GSLocalMemory::GetStartBlockAddress (t->m_TEX0 .TBP0 , t->m_TEX0 .TBW , t->m_TEX0 .PSM , GSVector4i (0 , height_adjust, t->m_valid .z , t->m_valid .w ));
3893+ if (t->m_dirty .size () > 0 )
3894+ {
3895+ u32 dirty_end = GSLocalMemory::GetEndBlockAddress (t->m_TEX0 .TBP0 , t->m_TEX0 .TBW , t->m_TEX0 .PSM , t->m_dirty .GetTotalRect (t->m_TEX0 , t->m_unscaled_size ));
3896+
3897+ if (new_base_tbp >= dirty_end)
3898+ t->m_dirty .clear ();
3899+ else
3900+ t->Update (true );
3901+ }
3902+
3903+ t->m_TEX0 .TBP0 = new_base_tbp;
38623904 t->m_valid .w -= height_adjust;
38633905 t->ResizeValidity (t->m_valid );
38643906
@@ -4368,16 +4410,19 @@ void GSTextureCache::InvalidateContainedTargets(u32 start_bp, u32 end_bp, u32 wr
43684410 const u32 end_width = write_bw * 64 ;
43694411 const u32 end_height = ((end_page_offset / std::max (write_bw, 1U )) * GSLocalMemory::m_psm[write_psm].pgs .y ) + GSLocalMemory::m_psm[write_psm].pgs .y ;
43704412 const GSVector4i r = GSVector4i (0 , 0 , end_width, end_height);
4371- const GSVector4i invalidate_r = TranslateAlignedRectByPage (t, start_bp, write_psm, write_bw, r, false ).rintersect (t->m_valid ); // it is invalidation but we need a real rect.
4413+ const GSVector4i invalidate_r = TranslateAlignedRectByPage (t, start_bp, write_psm, write_bw, r, true ).rintersect (t->m_valid ); // it is invalidation but we need a real rect.
43724414
43734415 if (offset == 0 || dirty_rect.rempty () || !dirty_rect.rintersect (invalidate_r).rempty ())
43744416 {
43754417 if (write_bw == t->m_TEX0 .TBW && GSLocalMemory::m_psm[t->m_TEX0 .PSM ].bpp == GSLocalMemory::m_psm[write_psm].bpp )
43764418 {
4377-
43784419 RGBAMask mask;
43794420 mask._u32 = GSUtil::GetChannelMask (write_psm, fb_mask);
4380- AddDirtyRectTarget (t, invalidate_r, t->m_TEX0 .PSM , t->m_TEX0 .TBW , mask, false );
4421+
4422+ if (write_bw != t->m_TEX0 .TBW )
4423+ DirtyRectByPage (start_bp, write_psm, write_bw, t, r);
4424+ else
4425+ AddDirtyRectTarget (t, invalidate_r, t->m_TEX0 .PSM , t->m_TEX0 .TBW , mask, false );
43814426 }
43824427
43834428 ++i;
0 commit comments