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 .
*
* 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 .
*
* You should have received a copy of the GNU General Public License
* along with GNU Make ; see the file COPYING . If not , write to
* the Free Software Foundation , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
* http : //www.gnu.org/copyleft/gpl.html
*
*/
# pragma once
2009-05-18 11:08:04 +00:00
# include "GSdx.h"
2009-02-09 21:15:56 +00:00
# include "GSWnd.h"
# include "GSState.h"
2009-06-23 04:12:32 +00:00
# include "GSVertexTrace.h"
2009-02-09 21:15:56 +00:00
# include "GSVertexList.h"
# include "GSSettingsDlg.h"
# include "GSCapture.h"
2009-05-22 23:23:38 +00:00
class GSRenderer : public GSState
2009-02-09 21:15:56 +00:00
{
2009-05-22 23:23:38 +00:00
GSCapture m_capture ;
string m_snapshot ;
int m_shader ;
bool Merge ( int field ) ;
protected :
2009-02-09 21:15:56 +00:00
int m_interlace ;
int m_aspectratio ;
int m_filter ;
2009-10-26 15:52:45 +00:00
int m_upscale_multiplier ;
2009-02-09 21:15:56 +00:00
bool m_vsync ;
bool m_nativeres ;
2009-03-09 01:42:56 +00:00
bool m_aa1 ;
2009-03-24 09:11:03 +00:00
bool m_blur ;
2009-10-31 01:06:23 +00:00
bool m_framelimit ;
2009-02-09 21:15:56 +00:00
2009-10-12 19:58:03 +00:00
uint8 * m_tex_buff ;
2009-05-22 01:22:52 +00:00
virtual GSTexture * GetOutput ( int i ) = 0 ;
2009-02-09 21:15:56 +00:00
2009-06-23 04:12:32 +00:00
GSVertexTrace m_vt ;
// following functions need m_vt to be initialized
2009-06-27 03:32:33 +00:00
void GetTextureMinMax ( GSVector4i & r , bool linear ) ;
2009-06-23 04:12:32 +00:00
void GetAlphaMinMax ( ) ;
bool TryAlphaTest ( uint32 & fm , uint32 & zm ) ;
2009-06-27 03:32:33 +00:00
bool IsLinear ( ) ;
2009-06-23 04:12:32 +00:00
bool IsOpaque ( ) ;
2009-05-18 11:08:04 +00:00
public :
GSWnd m_wnd ;
2009-05-22 01:22:52 +00:00
GSDevice * m_dev ;
2009-02-09 21:15:56 +00:00
int s_n ;
bool s_dump ;
bool s_save ;
bool s_savez ;
2009-07-05 12:58:59 +00:00
int s_saven ;
2009-02-09 21:15:56 +00:00
public :
2009-09-18 19:54:56 +00:00
GSRenderer ( ) ;
2009-05-22 01:22:52 +00:00
virtual ~ GSRenderer ( ) ;
2009-02-09 21:15:56 +00:00
2009-09-17 07:40:38 +00:00
virtual bool CreateWnd ( const string & title , int w , int h ) ;
virtual bool CreateDevice ( GSDevice * dev ) ;
2009-09-18 00:16:52 +00:00
virtual void ResetDevice ( )
{
InvalidateTextureCache ( ) ;
ResetPrim ( ) ;
}
2009-05-22 01:22:52 +00:00
virtual void VSync ( int field ) ;
virtual bool MakeSnapshot ( const string & path ) ;
2009-08-16 16:45:26 +00:00
virtual void KeyEvent ( GSKeyEventData * e , int param = 0 ) ;
2009-05-22 01:22:52 +00:00
virtual bool CanUpscale ( )
{
2009-08-03 11:01:36 +00:00
return ! m_nativeres & & m_regs - > PMODE . EN ! = 0 ; // upscale ratio depends on the display size, with no output it may not be set correctly (ps2 logo to game transition)
2009-05-22 01:22:52 +00:00
}
2009-10-26 15:52:45 +00:00
virtual int upscale_Multiplier ( )
2009-10-21 22:57:20 +00:00
{
2009-10-26 15:52:45 +00:00
return m_upscale_multiplier ;
2009-10-21 22:57:20 +00:00
}
2009-10-12 19:58:03 +00:00
2009-12-01 05:59:43 +00:00
void SetAspectRatio ( int aspect ) { m_aspectratio = aspect ; }
void SetVsync ( bool enabled ) ;
2009-10-31 01:06:23 +00:00
void SetFrameLimit ( bool limit ) ;
2009-10-12 19:58:03 +00:00
// TODO : Implement proper locking here *if needed* (not sure yet if it is) --air
uint8 * GetTextureBufferLock ( ) { return m_tex_buff ; }
void ReleaseTextureBufferLock ( ) { }
2009-02-09 21:15:56 +00:00
} ;
2009-05-22 01:22:52 +00:00
template < class Vertex > class GSRendererT : public GSRenderer
2009-02-09 21:15:56 +00:00
{
protected :
Vertex * m_vertices ;
int m_count ;
int m_maxcount ;
GSVertexList < Vertex > m_vl ;
void Reset ( )
{
m_count = 0 ;
m_vl . RemoveAll ( ) ;
__super : : Reset ( ) ;
}
void ResetPrim ( )
{
m_vl . RemoveAll ( ) ;
}
void FlushPrim ( )
{
2009-07-22 03:55:28 +00:00
if ( m_count = = 0 ) return ;
if ( GSLocalMemory : : m_psm [ m_context - > FRAME . PSM ] . fmt < 3 & & GSLocalMemory : : m_psm [ m_context - > ZBUF . PSM ] . fmt < 3 )
2009-02-09 21:15:56 +00:00
{
2009-07-22 03:55:28 +00:00
// FIXME: berserk fpsm = 27 (8H)
2009-02-09 21:15:56 +00:00
2009-07-22 03:55:28 +00:00
if ( ! m_dev - > IsLost ( ) )
{
2009-07-22 14:28:14 +00:00
m_vt . Update ( m_vertices , m_count , GSUtil : : GetPrimClass ( PRIM - > PRIM ) ) ;
2009-06-27 03:32:33 +00:00
2009-07-22 03:55:28 +00:00
Draw ( ) ;
2009-02-09 21:15:56 +00:00
}
2009-07-22 03:55:28 +00:00
m_perfmon . Put ( GSPerfMon : : Draw , 1 ) ;
2009-02-09 21:15:56 +00:00
}
2009-07-22 03:55:28 +00:00
m_count = 0 ;
2009-02-09 21:15:56 +00:00
}
void GrowVertexBuffer ( )
{
m_maxcount = max ( 10000 , m_maxcount * 3 / 2 ) ;
m_vertices = ( Vertex * ) _aligned_realloc ( m_vertices , sizeof ( Vertex ) * m_maxcount , 16 ) ;
m_maxcount - = 100 ;
}
2009-05-14 16:41:52 +00:00
template < uint32 prim > __forceinline Vertex * DrawingKick ( bool skip , int & count )
2009-02-09 21:15:56 +00:00
{
switch ( prim )
{
case GS_POINTLIST : count = 1 ; break ;
case GS_LINELIST : count = 2 ; break ;
case GS_LINESTRIP : count = 2 ; break ;
case GS_TRIANGLELIST : count = 3 ; break ;
case GS_TRIANGLESTRIP : count = 3 ; break ;
case GS_TRIANGLEFAN : count = 3 ; break ;
case GS_SPRITE : count = 2 ; break ;
case GS_INVALID : count = 1 ; break ;
default : __assume ( 0 ) ;
}
if ( m_vl . GetCount ( ) < count )
{
return NULL ;
}
if ( m_count > = m_maxcount )
{
GrowVertexBuffer ( ) ;
}
Vertex * v = & m_vertices [ m_count ] ;
switch ( prim )
{
case GS_POINTLIST :
m_vl . GetAt ( 0 , v [ 0 ] ) ;
m_vl . RemoveAll ( ) ;
break ;
case GS_LINELIST :
m_vl . GetAt ( 0 , v [ 0 ] ) ;
m_vl . GetAt ( 1 , v [ 1 ] ) ;
m_vl . RemoveAll ( ) ;
break ;
case GS_LINESTRIP :
m_vl . GetAt ( 0 , v [ 0 ] ) ;
m_vl . GetAt ( 1 , v [ 1 ] ) ;
m_vl . RemoveAt ( 0 , 1 ) ;
break ;
case GS_TRIANGLELIST :
m_vl . GetAt ( 0 , v [ 0 ] ) ;
m_vl . GetAt ( 1 , v [ 1 ] ) ;
m_vl . GetAt ( 2 , v [ 2 ] ) ;
m_vl . RemoveAll ( ) ;
break ;
case GS_TRIANGLESTRIP :
m_vl . GetAt ( 0 , v [ 0 ] ) ;
m_vl . GetAt ( 1 , v [ 1 ] ) ;
m_vl . GetAt ( 2 , v [ 2 ] ) ;
m_vl . RemoveAt ( 0 , 2 ) ;
break ;
case GS_TRIANGLEFAN :
m_vl . GetAt ( 0 , v [ 0 ] ) ;
m_vl . GetAt ( 1 , v [ 1 ] ) ;
m_vl . GetAt ( 2 , v [ 2 ] ) ;
m_vl . RemoveAt ( 1 , 1 ) ;
break ;
case GS_SPRITE :
m_vl . GetAt ( 0 , v [ 0 ] ) ;
m_vl . GetAt ( 1 , v [ 1 ] ) ;
m_vl . RemoveAll ( ) ;
break ;
case GS_INVALID :
ASSERT ( 0 ) ;
m_vl . RemoveAll ( ) ;
return NULL ;
default :
__assume ( 0 ) ;
}
return ! skip ? v : NULL ;
}
virtual void Draw ( ) = 0 ;
public :
2009-09-18 19:54:56 +00:00
GSRendererT ( )
: GSRenderer ( )
2009-06-27 03:32:33 +00:00
, m_vertices ( NULL )
2009-02-09 21:15:56 +00:00
, m_count ( 0 )
, m_maxcount ( 0 )
{
}
2009-06-03 12:09:04 +00:00
virtual ~ GSRendererT ( )
2009-02-09 21:15:56 +00:00
{
if ( m_vertices ) _aligned_free ( m_vertices ) ;
}
} ;