2010-04-25 00:31:27 +00:00
/*
2009-02-09 21:15:56 +00:00
* Copyright ( C ) 2007 - 2009 Gabest
* http : //www.gabest.org
*
* This Program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 , or ( at your option )
* any later version .
2010-04-25 00:31:27 +00:00
*
2009-02-09 21:15:56 +00:00
* This Program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2010-04-25 00:31:27 +00:00
*
2009-02-09 21:15:56 +00:00
* You should have received a copy of the GNU General Public License
* along with GNU Make ; see the file COPYING . If not , write to
2012-09-09 18:16:11 +00:00
* the Free Software Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA USA .
2009-02-09 21:15:56 +00:00
* http : //www.gnu.org/copyleft/gpl.html
*
*/
# pragma once
# include "GSRenderer.h"
2017-08-04 18:37:44 +00:00
# include "GSFastList.h"
2011-03-08 01:48:15 +00:00
# include "GSDirtyRect.h"
2009-02-09 21:15:56 +00:00
2009-05-22 01:22:52 +00:00
class GSTextureCache
2009-02-09 21:15:56 +00:00
{
public :
2009-06-27 03:32:33 +00:00
enum { RenderTarget , DepthStencil } ;
2011-02-07 01:59:05 +00:00
class Surface : public GSAlignedClass < 32 >
2009-02-09 21:15:56 +00:00
{
protected :
2009-05-22 01:22:52 +00:00
GSRenderer * m_renderer ;
2009-02-09 21:15:56 +00:00
public :
2009-05-22 01:22:52 +00:00
GSTexture * m_texture ;
2009-02-09 21:15:56 +00:00
GIFRegTEX0 m_TEX0 ;
2009-06-17 11:24:42 +00:00
GIFRegTEXA m_TEXA ;
2009-06-27 03:32:33 +00:00
int m_age ;
2011-02-20 23:53:00 +00:00
uint8 * m_temp ;
2015-06-17 18:02:03 +00:00
bool m_32_bits_fmt ; // Allow to detect the casting of 32 bits as 16 bits texture
2016-04-21 17:08:41 +00:00
bool m_shared_texture ;
2009-02-09 21:15:56 +00:00
2009-06-27 03:32:33 +00:00
public :
2011-02-20 23:53:00 +00:00
Surface ( GSRenderer * r , uint8 * temp ) ;
2009-06-27 03:32:33 +00:00
virtual ~ Surface ( ) ;
2009-02-09 21:15:56 +00:00
2016-09-30 19:36:52 +00:00
void UpdateAge ( ) ;
2009-02-09 21:15:56 +00:00
} ;
2018-11-04 21:06:24 +00:00
class Palette
{
private :
uint32 * m_clut ; // Pointer to a copy of relevant clut
2018-11-13 18:22:13 +00:00
GSTexture * m_tex_palette ; // Pointer to valid texture with relevant clut as content, if instantiated by the constructor
const GSRenderer * m_renderer ; // Pointer to the current renderer, needed to recycle the eventually referenced GSTexture on destruction
2018-11-04 21:06:24 +00:00
public :
2018-11-13 18:22:13 +00:00
Palette ( const GSRenderer * renderer , uint16 pal , bool need_gs_texture ) ; // Creates a copy of the current clut and, if needed (need_gs_texture == true), a texture with its content
~ Palette ( ) ; // Default destructor, frees clut copy and eventually recycles palette texture
2018-11-04 21:06:24 +00:00
// Disable copy constructor and copy operator
Palette ( const Palette & ) = delete ;
Palette & operator = ( const Palette & ) = delete ;
// Disable move constructor and move operator
Palette ( const Palette & & ) = delete ;
Palette & operator = ( const Palette & & ) = delete ;
// Getter for clut pointer
uint32 * GetClut ( ) ;
2018-11-13 18:22:13 +00:00
// Getter for palette texture pointer, may be nullptr if object has been instantiated with need_gs_texture == false
2018-11-04 21:06:24 +00:00
GSTexture * GetPaletteGSTexture ( ) ;
} ;
struct PaletteKey {
const uint32 * clut ;
uint16 pal ;
} ;
struct PaletteKeyHash {
// Calculate hash
2018-11-10 17:50:19 +00:00
std : : size_t operator ( ) ( const PaletteKey & key ) const ;
2018-11-04 21:06:24 +00:00
} ;
struct PaletteKeyEqual {
// Compare clut contents
2018-11-10 17:50:19 +00:00
bool operator ( ) ( const PaletteKey & lhs , const PaletteKey & rhs ) const ;
2018-11-04 21:06:24 +00:00
} ;
2009-06-27 03:32:33 +00:00
class Source : public Surface
2009-02-09 21:15:56 +00:00
{
2009-06-28 02:02:14 +00:00
struct { GSVector4i * rect ; uint32 count ; } m_write ;
2016-09-30 19:36:52 +00:00
void Write ( const GSVector4i & r , int layer ) ;
void Flush ( uint32 count , int layer ) ;
2009-06-28 02:02:14 +00:00
2009-02-09 21:15:56 +00:00
public :
2018-11-04 21:06:24 +00:00
std : : shared_ptr < Palette > m_palette_obj ; // Shared pointer to the relevant Palette object (if any)
2009-06-27 03:32:33 +00:00
GSTexture * m_palette ;
2018-11-04 21:06:24 +00:00
bool m_should_have_tex_palette ; // Enables m_clut (and possibly m_palette) recycling on object destruction
2009-07-01 21:14:12 +00:00
uint32 m_valid [ MAX_PAGES ] ; // each uint32 bits map to the 32 blocks of that page
2009-06-27 03:32:33 +00:00
uint32 * m_clut ;
bool m_target ;
2009-07-01 21:14:12 +00:00
bool m_complete ;
2011-04-25 18:18:21 +00:00
bool m_repeating ;
2012-06-19 01:12:01 +00:00
bool m_spritehack_t ;
2017-08-04 18:37:44 +00:00
std : : vector < GSVector2i > * m_p2t ;
2016-04-29 15:31:09 +00:00
// Keep a trace of the target origin. There is no guarantee that pointer will
// still be valid on future. However it ought to be good when the source is created
// so it can be used to access un-converted data for the current draw call.
GSTexture * m_from_target ;
2016-09-30 19:37:24 +00:00
GIFRegTEX0 m_layer_TEX0 [ 7 ] ; // Detect already loaded value
2017-08-04 18:37:44 +00:00
// Keep a GSTextureCache::SourceMap::m_map iterator to allow fast erase
std : : array < uint16 , MAX_PAGES > m_erase_it ;
2017-01-22 22:05:02 +00:00
uint32 * m_pages_as_bit ;
2009-02-09 21:15:56 +00:00
2009-06-27 03:32:33 +00:00
public :
2016-04-24 20:30:56 +00:00
Source ( GSRenderer * r , const GIFRegTEX0 & TEX0 , const GIFRegTEXA & TEXA , uint8 * temp , bool dummy_container = false ) ;
2009-06-27 03:32:33 +00:00
virtual ~ Source ( ) ;
2009-02-09 21:15:56 +00:00
2016-09-30 19:36:52 +00:00
void Update ( const GSVector4i & rect , int layer = 0 ) ;
2016-09-30 19:37:24 +00:00
void UpdateLayer ( const GIFRegTEX0 & TEX0 , const GSVector4i & rect , int layer = 0 ) ;
2009-02-09 21:15:56 +00:00
} ;
2009-06-27 03:32:33 +00:00
class Target : public Surface
2009-02-09 21:15:56 +00:00
{
public :
2009-06-27 03:32:33 +00:00
int m_type ;
2009-02-09 21:15:56 +00:00
bool m_used ;
2009-06-27 03:32:33 +00:00
GSDirtyRectList m_dirty ;
2009-07-12 13:46:05 +00:00
GSVector4i m_valid ;
2015-06-10 08:07:40 +00:00
bool m_depth_supported ;
2015-06-25 17:09:26 +00:00
bool m_dirty_alpha ;
2016-03-06 13:24:20 +00:00
uint32 m_end_block ; // Hint of the target area
2009-02-09 21:15:56 +00:00
public :
2015-06-10 08:07:40 +00:00
Target ( GSRenderer * r , const GIFRegTEX0 & TEX0 , uint8 * temp , bool depth_supported ) ;
2009-05-14 16:41:52 +00:00
2016-03-06 13:25:14 +00:00
void UpdateValidity ( const GSVector4i & rect ) ;
2016-05-05 10:17:57 +00:00
bool Inside ( uint32 bp , uint32 bw , uint32 psm , const GSVector4i & rect ) ;
2016-03-06 13:24:20 +00:00
2016-09-30 19:36:52 +00:00
void Update ( ) ;
2009-02-09 21:15:56 +00:00
} ;
2018-11-04 21:06:24 +00:00
class PaletteMap
{
private :
static const uint16 MAX_SIZE = 65535 ; // Max size of each map.
const GSRenderer * m_renderer ; // Reference to the current renderer
// Array of 2 maps, the first for 64B palettes and the second for 1024B palettes.
// Each map stores the key PaletteKey (clut copy, pal value) pointing to the relevant shared pointer to Palette object.
// There is one PaletteKey per Palette, and the hashing and comparison of PaletteKey is done with custom operators PaletteKeyHash and PaletteKeyEqual.
std : : array < std : : unordered_map < PaletteKey , std : : shared_ptr < Palette > , PaletteKeyHash , PaletteKeyEqual > , 2 > m_maps ;
public :
PaletteMap ( const GSRenderer * renderer ) ; // Default constructor
// Retrieves a shared pointer to a valid Palette from m_maps or creates a new one adding it to the data structure
2018-11-13 18:22:13 +00:00
std : : shared_ptr < Palette > LookupPalette ( uint16 pal , bool need_gs_texture ) ;
2018-11-04 21:06:24 +00:00
2018-11-13 18:22:13 +00:00
void Clear ( ) ; // Clears m_maps, thus deletes Palette objects
2018-11-04 21:06:24 +00:00
} ;
2011-02-19 03:36:30 +00:00
class SourceMap
2009-02-09 21:15:56 +00:00
{
2011-02-19 03:36:30 +00:00
public :
2017-05-26 15:41:52 +00:00
std : : unordered_set < Source * > m_surfaces ;
2017-08-04 18:37:44 +00:00
std : : array < FastList < Source * > , MAX_PAGES > m_map ;
2014-10-24 18:49:30 +00:00
uint32 m_pages [ 16 ] ; // bitmap of all pages
2009-06-27 03:32:33 +00:00
bool m_used ;
2009-07-01 21:14:12 +00:00
SourceMap ( ) : m_used ( false ) { memset ( m_pages , 0 , sizeof ( m_pages ) ) ; }
2009-02-09 21:15:56 +00:00
2016-04-28 15:03:41 +00:00
void Add ( Source * s , const GIFRegTEX0 & TEX0 , GSOffset * off ) ;
2009-06-27 03:32:33 +00:00
void RemoveAll ( ) ;
2015-05-13 18:00:25 +00:00
void RemovePartial ( ) ;
2009-06-27 03:32:33 +00:00
void RemoveAt ( Source * s ) ;
2011-02-19 03:36:30 +00:00
} ;
2009-02-09 21:15:56 +00:00
2011-02-19 03:36:30 +00:00
protected :
GSRenderer * m_renderer ;
2018-11-04 21:06:24 +00:00
PaletteMap m_palette_map ;
2011-02-19 03:36:30 +00:00
SourceMap m_src ;
2017-08-04 18:37:44 +00:00
FastList < Target * > m_dst [ 2 ] ;
2011-02-19 03:36:30 +00:00
bool m_paltex ;
2012-06-19 01:12:01 +00:00
int m_spritehack ;
2015-06-26 07:25:50 +00:00
bool m_preload_frame ;
2011-02-19 03:36:30 +00:00
uint8 * m_temp ;
2015-06-07 16:42:30 +00:00
bool m_can_convert_depth ;
2017-10-04 21:50:36 +00:00
bool m_cpu_fb_conversion ;
2017-02-13 11:16:27 +00:00
CRCHackLevel m_crc_hack_level ;
2016-03-20 17:05:36 +00:00
static bool m_disable_partial_invalidation ;
2016-10-06 23:43:04 +00:00
bool m_texture_inside_rt ;
2017-01-22 21:27:38 +00:00
static bool m_wrap_gs_mem ;
2009-02-09 21:15:56 +00:00
2016-10-06 23:43:04 +00:00
virtual Source * CreateSource ( const GIFRegTEX0 & TEX0 , const GIFRegTEXA & TEXA , Target * t = NULL , bool half_right = false , int x_offset = 0 , int y_offset = 0 ) ;
2009-07-31 23:59:06 +00:00
virtual Target * CreateTarget ( const GIFRegTEX0 & TEX0 , int w , int h , int type ) ;
virtual int Get8bitFormat ( ) = 0 ;
// TODO: virtual void Write(Source* s, const GSVector4i& r) = 0;
// TODO: virtual void Write(Target* t, const GSVector4i& r) = 0;
2009-02-09 21:15:56 +00:00
2015-06-07 16:42:30 +00:00
virtual bool CanConvertDepth ( ) { return m_can_convert_depth ; }
2009-02-09 21:15:56 +00:00
public :
2009-05-22 01:22:52 +00:00
GSTextureCache ( GSRenderer * r ) ;
virtual ~ GSTextureCache ( ) ;
2011-05-09 01:36:57 +00:00
virtual void Read ( Target * t , const GSVector4i & r ) = 0 ;
2016-03-19 10:28:15 +00:00
virtual void Read ( Source * t , const GSVector4i & r ) = 0 ;
2009-05-22 01:22:52 +00:00
void RemoveAll ( ) ;
2015-05-13 18:00:25 +00:00
void RemovePartial ( ) ;
2009-02-09 21:15:56 +00:00
2009-06-27 03:32:33 +00:00
Source * LookupSource ( const GIFRegTEX0 & TEX0 , const GIFRegTEXA & TEXA , const GSVector4i & r ) ;
2016-04-29 19:00:32 +00:00
Source * LookupDepthSource ( const GIFRegTEX0 & TEX0 , const GIFRegTEXA & TEXA , const GSVector4i & r , bool palette = false ) ;
2016-04-21 17:13:47 +00:00
2016-10-03 18:34:04 +00:00
Target * LookupTarget ( const GIFRegTEX0 & TEX0 , int w , int h , int type , bool used , uint32 fbmask = 0 ) ;
2015-06-26 07:25:50 +00:00
Target * LookupTarget ( const GIFRegTEX0 & TEX0 , int w , int h , int real_h ) ;
2009-02-09 21:15:56 +00:00
2015-06-05 21:37:06 +00:00
void InvalidateVideoMemType ( int type , uint32 bp ) ;
2016-03-19 10:39:56 +00:00
void InvalidateVideoMemSubTarget ( GSTextureCache : : Target * rt ) ;
2015-05-15 18:40:09 +00:00
void InvalidateVideoMem ( GSOffset * off , const GSVector4i & r , bool target = true ) ;
void InvalidateLocalMem ( GSOffset * off , const GSVector4i & r ) ;
2009-02-09 21:15:56 +00:00
2009-05-22 01:22:52 +00:00
void IncAge ( ) ;
2010-03-14 19:35:10 +00:00
bool UserHacks_HalfPixelOffset ;
2016-10-13 09:08:47 +00:00
void ScaleTexture ( GSTexture * texture ) ;
2015-06-13 06:32:11 +00:00
const char * to_string ( int type ) {
return ( type = = DepthStencil ) ? " Depth " : " Color " ;
}
2015-07-10 19:11:14 +00:00
void PrintMemoryUsage ( ) ;
2018-11-04 21:06:24 +00:00
2018-11-13 18:22:13 +00:00
void AttachPaletteToSource ( Source * s , uint16 pal , bool need_gs_texture ) ;
2009-02-09 21:15:56 +00:00
} ;