2012-11-01 15:19:01 +00:00
// Copyright (c) 2012- PPSSPP Project.
// 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
2012-11-04 22:01:49 +00:00
// the Free Software Foundation, version 2.0 or later versions.
2012-11-01 15:19:01 +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 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
# pragma once
2013-08-14 18:42:13 +00:00
# include <cmath>
2012-11-01 15:19:01 +00:00
# include "../Globals.h"
2012-11-24 14:19:29 +00:00
# include "ge_constants.h"
2013-09-20 16:51:26 +00:00
# include "Common/Common.h"
2012-11-01 15:19:01 +00:00
2013-08-10 09:22:22 +00:00
// PSP uses a curious 24-bit float - it's basically the top 24 bits of a regular IEEE754 32-bit float.
// This is used for light positions, transform matrices, you name it.
inline float getFloat24 ( unsigned int data )
{
data < < = 8 ;
float f ;
memcpy ( & f , & data , 4 ) ;
return f ;
}
// in case we ever want to generate PSP display lists...
inline unsigned int toFloat24 ( float f ) {
unsigned int i ;
memcpy ( & i , & f , 4 ) ;
return i > > 8 ;
}
2012-11-01 15:19:01 +00:00
struct GPUgstate
{
2012-12-21 15:49:42 +00:00
// Getting rid of this ugly union in favor of the accessor functions
// might be a good idea....
2012-11-01 15:19:01 +00:00
union
{
u32 cmdmem [ 256 ] ;
struct
{
2012-12-05 03:45:28 +00:00
u32 nop ,
vaddr ,
2012-11-01 15:19:01 +00:00
iaddr ,
pad00 ,
prim ,
bezier ,
spline ,
boundBox ,
jump ,
bjump ,
call ,
ret ,
end ,
pad01 ,
signal ,
finish ,
base ,
pad02 ,
vertType ,
offsetAddr ,
origin ,
region1 ,
region2 ,
lightingEnable ,
lightEnable [ 4 ] ,
clipEnable ,
cullfaceEnable ,
textureMapEnable ,
fogEnable ,
ditherEnable ,
alphaBlendEnable ,
alphaTestEnable ,
zTestEnable ,
stencilTestEnable ,
antiAliasEnable ,
patchCullEnable ,
colorTestEnable ,
logicOpEnable ,
pad03 ,
boneMatrixNumber ,
boneMatrixData ,
morphwgt [ 8 ] , //dont use
2012-12-28 18:33:26 +00:00
pad04 [ 2 ] ,
patchdivision ,
patchprimitive ,
patchfacing ,
pad04_a ,
2012-11-01 15:19:01 +00:00
2013-07-22 00:43:08 +00:00
worldmtxnum , // 0x3A
worldmtxdata , // 0x3B
viewmtxnum , // 0x3C
viewmtxdata , // 0x3D
projmtxnum , // 0x3E
projmtxdata , // 0x3F
texmtxnum , // 0x40
texmtxdata , // 0x41
viewportx1 , // 0x42
viewporty1 , // 0x43
viewportz1 , // 0x44
viewportx2 , // 0x45
viewporty2 , // 0x46
viewportz2 , // 0x47
texscaleu , // 0x48
texscalev , // 0x49
texoffsetu , // 0x4A
texoffsetv , // 0x4B
offsetx , // 0x4C
offsety , // 0x4D
2012-11-01 15:19:01 +00:00
pad111 [ 2 ] ,
2013-07-22 00:43:08 +00:00
shademodel , // 0x50
reversenormals , // 0x51
2012-11-01 15:19:01 +00:00
pad222 ,
2013-07-22 00:43:08 +00:00
materialupdate , // 0x53
materialemissive , // 0x54
materialambient , // 0x55
materialdiffuse , // 0x56
materialspecular , // 0x57
materialalpha , // 0x58
2012-11-25 17:12:20 +00:00
pad333 [ 2 ] ,
2013-07-22 00:43:08 +00:00
materialspecularcoef , // 0x5B
ambientcolor , // 0x5C
ambientalpha , // 0x5D
2013-07-22 00:56:58 +00:00
lmode , // 0x5E
ltype [ 4 ] , // 0x5F-0x62
lpos [ 12 ] , // 0x63-0x6E
ldir [ 12 ] , // 0x6F-0x7A
latt [ 12 ] , // 0x7B-0x86
lconv [ 4 ] , // 0x87-0x8A
lcutoff [ 4 ] , // 0x8B-0x8E
2013-07-22 01:40:19 +00:00
lcolor [ 12 ] , // 0x8F-0x9A
cullmode , // 0x9B
fbptr , // 0x9C
fbwidth , // 0x9D
zbptr , // 0x9E
zbwidth , // 0x9F
texaddr [ 8 ] , // 0xA0-0xA7
texbufwidth [ 8 ] , // 0xA8-0xAF
clutaddr , // 0xB0
clutaddrupper , // 0xB1
transfersrc , // 0xB2
transfersrcw , // 0xB3
transferdst , // 0xB4
transferdstw , // 0xB5
2012-11-01 15:19:01 +00:00
padxxx [ 2 ] ,
2013-07-22 01:40:19 +00:00
texsize [ 8 ] , // 0xB8-BF
texmapmode , // 0xC0
texshade , // 0xC1
texmode , // 0xC2
texformat , // 0xC3
loadclut , // 0xC4
2013-07-22 01:59:18 +00:00
clutformat , // 0xC5
texfilter , // 0xC6
texwrap , // 0xC7
texlevel , // 0xC8
texfunc , // 0xC9
texenvcolor , // 0xCA
texflush , // 0xCB
texsync , // 0xCC
fog1 , // 0xCD
fog2 , // 0xCE
fogcolor , // 0xCF
texlodslope , // 0xD0
padxxxxxx , // 0xD1
framebufpixformat , // 0xD2
clearmode , // 0xD3
2012-11-01 15:19:01 +00:00
scissor1 ,
scissor2 ,
minz ,
maxz ,
colortest ,
colorref ,
colormask ,
alphatest ,
stenciltest ,
stencilop ,
ztestfunc ,
blend ,
blendfixa ,
blendfixb ,
dith1 ,
dith2 ,
dith3 ,
dith4 ,
2013-07-22 01:59:18 +00:00
lop , // 0xE6
2012-11-01 15:19:01 +00:00
zmsk ,
2013-01-12 11:51:09 +00:00
pmskc ,
pmska ,
2012-11-22 19:57:41 +00:00
transferstart ,
transfersrcpos ,
transferdstpos ,
2012-12-17 18:04:19 +00:00
pad99 ,
transfersize ; // 0xEE
2012-11-01 15:19:01 +00:00
2012-12-17 18:04:19 +00:00
u32 pad05 [ 0xFF - 0xEE ] ;
2012-11-01 15:19:01 +00:00
} ;
} ;
2012-11-18 12:04:49 +00:00
float worldMatrix [ 12 ] ;
float viewMatrix [ 12 ] ;
float projMatrix [ 16 ] ;
float tgenMatrix [ 12 ] ;
2012-11-25 11:25:07 +00:00
float boneMatrix [ 12 * 8 ] ; // Eight bone matrices.
2012-11-24 14:19:29 +00:00
2013-10-06 22:51:31 +00:00
u32 getFrameBufRawAddress ( ) const { return ( fbptr & 0xFFFFFF ) | ( ( fbwidth & 0xFF0000 ) < < 8 ) ; }
// 0x44000000 is uncached VRAM.
u32 getFrameBufAddress ( ) const { return 0x44000000 | getFrameBufRawAddress ( ) ; }
2013-07-21 17:15:28 +00:00
GEBufferFormat FrameBufFormat ( ) const { return static_cast < GEBufferFormat > ( framebufpixformat & 3 ) ; }
2013-06-29 21:41:21 +00:00
int FrameBufStride ( ) const { return fbwidth & 0x7C0 ; }
2013-10-06 22:51:31 +00:00
u32 getDepthBufRawAddress ( ) const { return ( zbptr & 0xFFFFFF ) | ( ( zbwidth & 0xFF0000 ) < < 8 ) ; }
u32 getDepthBufAddress ( ) const { return 0x44000000 | getDepthBufRawAddress ( ) ; }
2013-07-21 18:59:01 +00:00
int DepthBufStride ( ) const { return zbwidth & 0x7C0 ; }
2013-06-29 21:41:21 +00:00
2012-12-21 15:49:42 +00:00
// Pixel Pipeline
2012-11-28 12:45:22 +00:00
bool isModeClear ( ) const { return clearmode & 1 ; }
2013-07-29 09:25:07 +00:00
bool isFogEnabled ( ) const { return fogEnable & 1 ; }
// Cull
2012-11-28 12:45:22 +00:00
bool isCullEnabled ( ) const { return cullfaceEnable & 1 ; }
2012-12-21 15:49:42 +00:00
int getCullMode ( ) const { return cullmode & 1 ; }
2013-08-03 06:56:37 +00:00
bool isClearModeDepthWriteEnabled ( ) const { return ( clearmode & 0x400 ) ! = 0 ; }
bool isClearModeColorMask ( ) const { return ( clearmode & 0x100 ) ! = 0 ; }
bool isClearModeAlphaMask ( ) const { return ( clearmode & 0x200 ) ! = 0 ; }
2013-08-24 17:20:07 +00:00
bool isClearModeDepthMask ( ) const { return ( clearmode & 0x400 ) ! = 0 ; }
2013-07-23 20:56:49 +00:00
u32 getClearModeColorMask ( ) const { return ( ( clearmode & 0x100 ) ? 0xFFFFFF : 0 ) | ( ( clearmode & 0x200 ) ? 0xFF000000 : 0 ) ; } // TODO: Different convention than getColorMask, confusing!
2013-07-29 09:25:07 +00:00
// Blend
2013-08-27 19:48:03 +00:00
GEBlendSrcFactor getBlendFuncA ( ) const { return ( GEBlendSrcFactor ) ( blend & 0xF ) ; }
2012-11-28 12:45:22 +00:00
u32 getFixA ( ) const { return blendfixa & 0xFFFFFF ; }
u32 getFixB ( ) const { return blendfixb & 0xFFFFFF ; }
2013-08-27 19:48:03 +00:00
GEBlendDstFactor getBlendFuncB ( ) const { return ( GEBlendDstFactor ) ( ( blend > > 4 ) & 0xF ) ; }
2013-09-14 14:34:36 +00:00
GEBlendMode getBlendEq ( ) const { return static_cast < GEBlendMode > ( ( blend > > 8 ) & 0x7 ) ; }
2013-02-27 14:37:17 +00:00
bool isAlphaBlendEnabled ( ) const { return alphaBlendEnable & 1 ; }
2013-08-30 12:46:36 +00:00
// AntiAlias
bool isAntiAliasEnabled ( ) const { return antiAliasEnable & 1 ; }
2013-07-29 09:25:07 +00:00
// Dither
2013-02-27 14:37:17 +00:00
bool isDitherEnabled ( ) const { return ditherEnable & 1 ; }
2013-07-22 01:35:31 +00:00
2013-07-29 09:25:07 +00:00
// Color Mask
2013-07-22 01:59:18 +00:00
u32 getColorMask ( ) const { return ( pmskc & 0xFFFFFF ) | ( ( pmska & 0xFF ) < < 24 ) ; }
bool isLogicOpEnabled ( ) const { return logicOpEnable & 1 ; }
GELogicOp getLogicOp ( ) const { return static_cast < GELogicOp > ( lop & 0xF ) ; }
2013-07-29 09:25:07 +00:00
// Depth Test
bool isDepthTestEnabled ( ) const { return zTestEnable & 1 ; }
bool isDepthWriteEnabled ( ) const { return ! ( zmsk & 1 ) ; }
2013-09-05 05:59:09 +00:00
GEComparison getDepthTestFunction ( ) const { return static_cast < GEComparison > ( ztestfunc & 0x7 ) ; }
2013-07-29 09:25:07 +00:00
u16 getDepthRangeMin ( ) const { return minz & 0xFFFF ; }
u16 getDepthRangeMax ( ) const { return maxz & 0xFFFF ; }
// Stencil Test
2013-07-22 01:48:14 +00:00
bool isStencilTestEnabled ( ) const { return stencilTestEnable & 1 ; }
2013-07-22 01:54:17 +00:00
GEComparison getStencilTestFunction ( ) const { return static_cast < GEComparison > ( stenciltest & 0x7 ) ; }
2013-07-22 01:48:14 +00:00
int getStencilTestRef ( ) const { return ( stenciltest > > 8 ) & 0xFF ; }
int getStencilTestMask ( ) const { return ( stenciltest > > 16 ) & 0xFF ; }
2013-07-22 01:54:17 +00:00
GEStencilOp getStencilOpSFail ( ) const { return static_cast < GEStencilOp > ( stencilop & 0x7 ) ; }
GEStencilOp getStencilOpZFail ( ) const { return static_cast < GEStencilOp > ( ( stencilop > > 8 ) & 0x7 ) ; }
GEStencilOp getStencilOpZPass ( ) const { return static_cast < GEStencilOp > ( ( stencilop > > 16 ) & 0x7 ) ; }
2013-07-22 01:48:14 +00:00
2013-07-29 09:25:07 +00:00
// Alpha Test
2013-07-22 02:06:44 +00:00
bool isAlphaTestEnabled ( ) const { return alphaTestEnable & 1 ; }
GEComparison getAlphaTestFunction ( ) { return static_cast < GEComparison > ( alphatest & 0x7 ) ; }
int getAlphaTestRef ( ) const { return ( alphatest > > 8 ) & 0xFF ; }
int getAlphaTestMask ( ) const { return ( alphatest > > 16 ) & 0xFF ; }
2013-07-29 09:25:07 +00:00
// Color Test
2013-07-22 02:06:44 +00:00
bool isColorTestEnabled ( ) const { return colorTestEnable & 1 ; }
GEComparison getColorTestFunction ( ) { return static_cast < GEComparison > ( colortest & 0x3 ) ; }
u32 getColorTestRef ( ) const { return colorref & 0xFFFFFF ; }
u32 getColorTestMask ( ) const { return colormask & 0xFFFFFF ; }
2013-07-22 01:35:31 +00:00
// Texturing
2013-09-16 04:39:28 +00:00
// TODO: Verify getTextureAddress() alignment?
u32 getTextureAddress ( int level ) const { return ( texaddr [ level ] & 0xFFFFF0 ) | ( ( texbufwidth [ level ] < < 8 ) & 0x0F000000 ) ; }
2013-07-30 15:23:02 +00:00
int getTextureWidth ( int level ) const { return 1 < < ( texsize [ level ] & 0xf ) ; }
int getTextureHeight ( int level ) const { return 1 < < ( ( texsize [ level ] > > 8 ) & 0xf ) ; }
2013-09-08 08:09:40 +00:00
u16 getTextureDimension ( int level ) const { return texsize [ level ] & 0xf0f ; }
2013-07-22 00:56:58 +00:00
bool isTextureMapEnabled ( ) const { return textureMapEnable & 1 ; }
2013-07-22 01:35:52 +00:00
GETexFunc getTextureFunction ( ) const { return static_cast < GETexFunc > ( texfunc & 0x7 ) ; }
2013-07-22 01:35:31 +00:00
bool isColorDoublingEnabled ( ) const { return ( texfunc & 0x10000 ) ! = 0 ; }
2013-08-20 13:28:16 +00:00
bool isTextureAlphaUsed ( ) const { return ( texfunc & 0x100 ) ! = 0 ; }
2013-07-22 01:44:04 +00:00
GETextureFormat getTextureFormat ( ) const { return static_cast < GETextureFormat > ( texformat & 0xF ) ; }
2013-07-29 09:25:07 +00:00
bool isTextureFormatIndexed ( ) const { return ( texformat & 4 ) ! = 0 ; } // GE_TFMT_CLUT4 - GE_TFMT_CLUT32 are 0b1xx.
2013-07-22 01:35:31 +00:00
int getTextureEnvColR ( ) const { return texenvcolor & 0xFF ; }
int getTextureEnvColG ( ) const { return ( texenvcolor > > 8 ) & 0xFF ; }
int getTextureEnvColB ( ) const { return ( texenvcolor > > 16 ) & 0xFF ; }
2013-08-24 18:10:56 +00:00
u32 getClutAddress ( ) const { return ( clutaddr & 0x00FFFFFF ) | ( ( clutaddrupper < < 8 ) & 0x0F000000 ) ; }
int getClutLoadBytes ( ) const { return ( loadclut & 0x3F ) * 32 ; }
2013-07-22 01:44:04 +00:00
GEPaletteFormat getClutPaletteFormat ( ) { return static_cast < GEPaletteFormat > ( clutformat & 3 ) ; }
2013-07-22 01:40:19 +00:00
int getClutIndexShift ( ) const { return ( clutformat > > 2 ) & 0x1F ; }
int getClutIndexMask ( ) const { return ( clutformat > > 8 ) & 0xFF ; }
int getClutIndexStartPos ( ) const { return ( ( clutformat > > 16 ) & 0x1F ) < < 4 ; }
2013-08-24 18:10:56 +00:00
int transformClutIndex ( int index ) const { return ( ( index > > getClutIndexShift ( ) ) & getClutIndexMask ( ) ) | getClutIndexStartPos ( ) ; }
2013-07-29 09:25:07 +00:00
bool isClutIndexSimple ( ) const { return ( clutformat & ~ 3 ) = = 0xC500FF00 ; } // Meaning, no special mask, shift, or start pos.
2013-08-24 17:51:17 +00:00
bool isTextureSwizzled ( ) const { return texmode & 1 ; }
2013-07-22 01:40:19 +00:00
2013-07-22 01:35:31 +00:00
// Lighting
2013-03-27 10:21:02 +00:00
bool isLightingEnabled ( ) const { return lightingEnable & 1 ; }
2013-07-22 01:13:55 +00:00
bool isLightChanEnabled ( int chan ) const { return lightEnable [ chan ] & 1 ; }
GELightComputation getLightComputation ( int chan ) const { return static_cast < GELightComputation > ( ltype [ chan ] & 0x3 ) ; }
bool isUsingPoweredDiffuseLight ( int chan ) const { return getLightComputation ( chan ) = = GE_LIGHTCOMP_BOTHWITHPOWDIFFUSE ; }
bool isUsingSpecularLight ( int chan ) const { return getLightComputation ( chan ) ! = GE_LIGHTCOMP_ONLYDIFFUSE ; }
2013-07-22 00:43:08 +00:00
bool isUsingSecondaryColor ( ) const { return lmode & 1 ; }
2013-07-22 01:13:55 +00:00
GELightType getLightType ( int chan ) const { return static_cast < GELightType > ( ( ltype [ chan ] > > 8 ) & 3 ) ; }
bool isDirectionalLight ( int chan ) const { return getLightType ( chan ) = = GE_LIGHTTYPE_DIRECTIONAL ; }
bool isPointLight ( int chan ) const { return getLightType ( chan ) = = GE_LIGHTTYPE_POINT ; }
bool isSpotLight ( int chan ) const { return getLightType ( chan ) = = GE_LIGHTTYPE_SPOT ; }
2013-09-14 14:34:36 +00:00
GEShadeMode getShadeMode ( ) const { return static_cast < GEShadeMode > ( shademodel & 1 ) ; }
2013-07-22 00:43:08 +00:00
unsigned int getAmbientR ( ) const { return ambientcolor & 0xFF ; }
unsigned int getAmbientG ( ) const { return ( ambientcolor > > 8 ) & 0xFF ; }
unsigned int getAmbientB ( ) const { return ( ambientcolor > > 16 ) & 0xFF ; }
unsigned int getAmbientA ( ) const { return ambientalpha & 0xFF ; }
unsigned int getMaterialAmbientR ( ) const { return materialambient & 0xFF ; }
unsigned int getMaterialAmbientG ( ) const { return ( materialambient > > 8 ) & 0xFF ; }
unsigned int getMaterialAmbientB ( ) const { return ( materialambient > > 16 ) & 0xFF ; }
unsigned int getMaterialAmbientA ( ) const { return materialalpha & 0xFF ; }
2013-07-22 00:56:58 +00:00
unsigned int getMaterialDiffuseR ( ) const { return materialdiffuse & 0xFF ; }
unsigned int getMaterialDiffuseG ( ) const { return ( materialdiffuse > > 8 ) & 0xFF ; }
unsigned int getMaterialDiffuseB ( ) const { return ( materialdiffuse > > 16 ) & 0xFF ; }
2013-07-22 00:43:08 +00:00
unsigned int getMaterialEmissiveR ( ) const { return materialemissive & 0xFF ; }
unsigned int getMaterialEmissiveG ( ) const { return ( materialemissive > > 8 ) & 0xFF ; }
unsigned int getMaterialEmissiveB ( ) const { return ( materialemissive > > 16 ) & 0xFF ; }
2013-07-22 01:29:27 +00:00
unsigned int getMaterialSpecularR ( ) const { return materialspecular & 0xFF ; }
unsigned int getMaterialSpecularG ( ) const { return ( materialspecular > > 8 ) & 0xFF ; }
unsigned int getMaterialSpecularB ( ) const { return ( materialspecular > > 16 ) & 0xFF ; }
unsigned int getLightAmbientColorR ( int chan ) const { return lcolor [ chan * 3 ] & 0xFF ; }
unsigned int getLightAmbientColorG ( int chan ) const { return ( lcolor [ chan * 3 ] > > 8 ) & 0xFF ; }
unsigned int getLightAmbientColorB ( int chan ) const { return ( lcolor [ chan * 3 ] > > 16 ) & 0xFF ; }
2013-07-22 00:56:58 +00:00
unsigned int getDiffuseColorR ( int chan ) const { return lcolor [ 1 + chan * 3 ] & 0xFF ; }
unsigned int getDiffuseColorG ( int chan ) const { return ( lcolor [ 1 + chan * 3 ] > > 8 ) & 0xFF ; }
unsigned int getDiffuseColorB ( int chan ) const { return ( lcolor [ 1 + chan * 3 ] > > 16 ) & 0xFF ; }
2013-07-22 01:29:27 +00:00
unsigned int getSpecularColorR ( int chan ) const { return lcolor [ 2 + chan * 3 ] & 0xFF ; }
unsigned int getSpecularColorG ( int chan ) const { return ( lcolor [ 2 + chan * 3 ] > > 8 ) & 0xFF ; }
unsigned int getSpecularColorB ( int chan ) const { return ( lcolor [ 2 + chan * 3 ] > > 16 ) & 0xFF ; }
2013-09-22 07:51:32 +00:00
int getPatchDivisionU ( ) const { return patchdivision & 0x7F ; }
int getPatchDivisionV ( ) const { return ( patchdivision > > 8 ) & 0x7F ; }
2012-12-21 15:49:42 +00:00
// UV gen
2013-07-24 11:55:10 +00:00
GETexMapMode getUVGenMode ( ) const { return static_cast < GETexMapMode > ( texmapmode & 3 ) ; } // 2 bits
GETexProjMapMode getUVProjMode ( ) const { return static_cast < GETexProjMapMode > ( ( texmapmode > > 8 ) & 3 ) ; } // 2 bits
2012-12-20 13:10:42 +00:00
int getUVLS0 ( ) const { return texshade & 0x3 ; } // 2 bits
int getUVLS1 ( ) const { return ( texshade > > 8 ) & 0x3 ; } // 2 bits
2013-07-23 18:47:18 +00:00
bool isTexCoordClampedS ( ) const { return texwrap & 1 ; }
bool isTexCoordClampedT ( ) const { return ( texwrap > > 8 ) & 1 ; }
2013-03-15 23:40:37 +00:00
int getScissorX1 ( ) const { return scissor1 & 0x3FF ; }
int getScissorY1 ( ) const { return ( scissor1 > > 10 ) & 0x3FF ; }
int getScissorX2 ( ) const { return scissor2 & 0x3FF ; }
int getScissorY2 ( ) const { return ( scissor2 > > 10 ) & 0x3FF ; }
2013-07-10 19:57:25 +00:00
int getRegionX1 ( ) const { return region1 & 0x3FF ; }
int getRegionY1 ( ) const { return ( region1 > > 10 ) & 0x3FF ; }
int getRegionX2 ( ) const { return ( region2 & 0x3FF ) ; }
2013-09-14 14:34:36 +00:00
int getRegionY2 ( ) const { return ( region2 > > 10 ) & 0x3FF ; }
2013-09-14 18:06:48 +00:00
float getViewportX1 ( ) const { return fabsf ( getFloat24 ( viewportx1 ) * 2.0f ) ; }
float getViewportY1 ( ) const { return fabsf ( getFloat24 ( viewporty1 ) * 2.0f ) ; }
// Fixed 16 point.
int getOffsetX16 ( ) const { return offsetx & 0xFFFF ; }
// Fixed 16 point.
int getOffsetY16 ( ) const { return offsety & 0xFFFF ; }
float getOffsetX ( ) const { return ( float ) getOffsetX16 ( ) / 16.0f ; }
float getOffsetY ( ) const { return ( float ) getOffsetY16 ( ) / 16.0f ; }
2013-07-10 19:57:25 +00:00
2012-12-21 15:49:42 +00:00
// Vertex type
bool isModeThrough ( ) const { return ( vertType & GE_VTYPE_THROUGH ) ! = 0 ; }
2013-08-24 18:11:34 +00:00
bool areNormalsReversed ( ) const { return reversenormals & 1 ; }
2013-02-02 12:40:26 +00:00
2013-07-24 15:59:21 +00:00
GEPatchPrimType getPatchPrimitiveType ( ) const { return static_cast < GEPatchPrimType > ( patchprimitive & 3 ) ; }
2013-08-24 17:41:45 +00:00
// Transfers
u32 getTransferSrcAddress ( ) const { return ( transfersrc & 0xFFFFF0 ) | ( ( transfersrcw & 0xFF0000 ) < < 8 ) ; }
u32 getTransferSrcStride ( ) const { return transfersrcw & 0x3F8 ; }
int getTransferSrcX ( ) const { return ( transfersrcpos > > 0 ) & 0x3FF ; }
int getTransferSrcY ( ) const { return ( transfersrcpos > > 10 ) & 0x3FF ; }
u32 getTransferDstAddress ( ) const { return ( transferdst & 0xFFFFF0 ) | ( ( transferdstw & 0xFF0000 ) < < 8 ) ; }
u32 getTransferDstStride ( ) const { return transferdstw & 0x3F8 ; }
int getTransferDstX ( ) const { return ( transferdstpos > > 0 ) & 0x3FF ; }
int getTransferDstY ( ) const { return ( transferdstpos > > 10 ) & 0x3FF ; }
int getTransferWidth ( ) const { return ( ( transfersize > > 0 ) & 0x3FF ) + 1 ; }
int getTransferHeight ( ) const { return ( ( transfersize > > 10 ) & 0x3FF ) + 1 ; }
int getTransferBpp ( ) const { return ( transferstart & 1 ) ? 4 : 2 ; }
2012-12-20 13:10:42 +00:00
// Real data in the context ends here
2013-09-20 07:33:32 +00:00
void Save ( u32_le * ptr ) ;
void Restore ( u32_le * ptr ) ;
2012-12-20 13:10:42 +00:00
} ;
2013-02-18 22:44:32 +00:00
enum SkipDrawReasonFlags {
SKIPDRAW_SKIPFRAME = 1 ,
2013-03-03 12:00:21 +00:00
SKIPDRAW_NON_DISPLAYED_FB = 2 , // Skip drawing to FBO:s that have not been displayed.
SKIPDRAW_BAD_FB_TEXTURE = 4 ,
2013-02-18 22:44:32 +00:00
} ;
2013-09-21 21:37:14 +00:00
inline bool vertTypeIsSkinningEnabled ( u32 vertType ) { return ( ( vertType & GE_VTYPE_WEIGHT_MASK ) ! = GE_VTYPE_WEIGHT_NONE ) ; }
inline int vertTypeGetNumBoneWeights ( u32 vertType ) { return 1 + ( ( vertType & GE_VTYPE_WEIGHTCOUNT_MASK ) > > GE_VTYPE_WEIGHTCOUNT_SHIFT ) ; }
inline int vertTypeGetWeightMask ( u32 vertType ) { return vertType & GE_VTYPE_WEIGHT_MASK ; }
2013-09-21 21:44:11 +00:00
inline int vertTypeGetTexCoordMask ( u32 vertType ) { return vertType & GE_VTYPE_TC_MASK ; }
2013-09-21 21:37:14 +00:00
2012-11-18 22:14:50 +00:00
// The rest is cached simplified/converted data for fast access.
// Does not need to be saved when saving/restoring context.
2013-07-27 22:18:41 +00:00
struct UVScale {
float uScale , vScale ;
float uOff , vOff ;
} ;
2012-11-18 12:04:49 +00:00
struct GPUStateCache
{
2012-11-01 15:19:01 +00:00
u32 vertexAddr ;
u32 indexAddr ;
2013-02-02 12:38:34 +00:00
u32 offsetAddr ;
2012-11-01 15:19:01 +00:00
bool textureChanged ;
2013-05-08 14:52:54 +00:00
bool textureFullAlpha ;
2013-04-21 22:08:47 +00:00
bool framebufChanged ;
2012-11-01 15:19:01 +00:00
2013-02-18 22:44:32 +00:00
int skipDrawReason ;
2013-07-27 22:18:41 +00:00
UVScale uv ;
2013-02-14 23:30:02 +00:00
bool flipTexture ;
2012-11-01 15:19:01 +00:00
float lightpos [ 4 ] [ 3 ] ;
float lightdir [ 4 ] [ 3 ] ;
float lightatt [ 4 ] [ 3 ] ;
2013-02-12 20:00:51 +00:00
float lightColor [ 3 ] [ 4 ] [ 3 ] ; // Ambient Diffuse Specular
2013-04-09 16:25:22 +00:00
float lightangle [ 4 ] ; // spotlight cone angle (cosine)
float lightspotCoef [ 4 ] ; // spotlight dropoff
2012-11-01 15:19:01 +00:00
float morphWeights [ 8 ] ;
u32 curTextureWidth ;
u32 curTextureHeight ;
2013-02-21 20:37:19 +00:00
u32 actualTextureHeight ;
2012-11-26 19:38:26 +00:00
float vpWidth ;
float vpHeight ;
2013-02-02 12:38:34 +00:00
2013-03-15 23:40:37 +00:00
u32 curRTWidth ;
u32 curRTHeight ;
2013-02-02 22:47:35 +00:00
u32 getRelativeAddress ( u32 data ) const ;
2012-11-18 12:04:49 +00:00
} ;
2012-11-01 15:19:01 +00:00
2012-11-18 12:04:49 +00:00
// TODO: Implement support for these.
2013-08-07 21:32:28 +00:00
struct GPUStatistics {
2013-08-07 20:32:04 +00:00
void Reset ( ) {
// Never add a vtable :)
2012-11-25 11:25:07 +00:00
memset ( this , 0 , sizeof ( * this ) ) ;
2012-11-22 22:07:15 +00:00
}
2013-08-07 20:32:04 +00:00
void ResetFrame ( ) {
2012-11-22 22:07:15 +00:00
numDrawCalls = 0 ;
2013-01-19 16:05:08 +00:00
numCachedDrawCalls = 0 ;
2013-01-24 23:36:59 +00:00
numVertsSubmitted = 0 ;
2013-01-19 16:05:08 +00:00
numCachedVertsDrawn = 0 ;
2013-01-24 23:36:59 +00:00
numUncachedVertsDrawn = 0 ;
2013-01-19 16:05:08 +00:00
numTrackedVertexArrays = 0 ;
2013-01-06 11:27:01 +00:00
numTextureInvalidations = 0 ;
2012-11-22 22:07:15 +00:00
numTextureSwitches = 0 ;
numShaderSwitches = 0 ;
2012-12-21 20:49:09 +00:00
numFlushes = 0 ;
numTexturesDecoded = 0 ;
2013-08-27 18:58:27 +00:00
numAlphaTestedDraws = 0 ;
numNonAlphaTestedDraws = 0 ;
2013-01-10 22:49:33 +00:00
msProcessingDisplayLists = 0 ;
2013-05-31 17:40:16 +00:00
vertexGPUCycles = 0 ;
otherGPUCycles = 0 ;
2013-08-23 09:26:13 +00:00
memset ( gpuCommandsAtCallLevel , 0 , sizeof ( gpuCommandsAtCallLevel ) ) ;
2012-11-22 22:07:15 +00:00
}
2012-11-18 12:04:49 +00:00
// Per frame statistics
int numDrawCalls ;
2013-01-19 16:05:08 +00:00
int numCachedDrawCalls ;
2012-12-21 18:16:17 +00:00
int numFlushes ;
2013-01-24 23:36:59 +00:00
int numVertsSubmitted ;
2013-01-19 16:05:08 +00:00
int numCachedVertsDrawn ;
2013-01-24 23:36:59 +00:00
int numUncachedVertsDrawn ;
2013-01-19 16:05:08 +00:00
int numTrackedVertexArrays ;
2013-01-06 11:27:01 +00:00
int numTextureInvalidations ;
2012-11-18 12:04:49 +00:00
int numTextureSwitches ;
int numShaderSwitches ;
2012-12-21 20:49:09 +00:00
int numTexturesDecoded ;
2013-01-10 22:49:33 +00:00
double msProcessingDisplayLists ;
2013-05-31 17:40:16 +00:00
int vertexGPUCycles ;
int otherGPUCycles ;
2013-08-23 09:26:13 +00:00
int gpuCommandsAtCallLevel [ 4 ] ;
2012-11-18 12:04:49 +00:00
2013-08-27 18:58:27 +00:00
int numAlphaTestedDraws ;
int numNonAlphaTestedDraws ;
2012-11-26 16:35:08 +00:00
// Total statistics, updated by the GPU core in UpdateStats
2013-08-07 20:32:04 +00:00
int numVBlanks ;
int numFlips ;
2012-11-26 16:35:08 +00:00
int numTextures ;
int numVertexShaders ;
int numFragmentShaders ;
int numShaders ;
2013-01-11 01:00:51 +00:00
int numFBOs ;
2012-11-01 15:19:01 +00:00
} ;
2013-09-08 05:30:30 +00:00
bool GPU_Init ( ) ;
2013-08-07 15:07:13 +00:00
void GPU_Shutdown ( ) ;
2012-11-01 15:19:01 +00:00
void InitGfxState ( ) ;
2012-11-06 16:05:27 +00:00
void ShutdownGfxState ( ) ;
2012-11-01 15:19:01 +00:00
void ReapplyGfxState ( ) ;
2012-11-06 16:05:27 +00:00
class GPUInterface ;
2013-09-22 17:22:33 +00:00
class GPUDebugInterface ;
2012-11-06 16:05:27 +00:00
2012-11-01 15:19:01 +00:00
extern GPUgstate gstate ;
2012-11-18 12:04:49 +00:00
extern GPUStateCache gstate_c ;
extern GPUInterface * gpu ;
2013-09-22 17:22:33 +00:00
extern GPUDebugInterface * gpuDebug ;
2012-11-24 14:19:29 +00:00
extern GPUStatistics gpuStats ;
2013-02-02 12:38:34 +00:00
2013-02-02 22:47:35 +00:00
inline u32 GPUStateCache : : getRelativeAddress ( u32 data ) const {
2013-09-14 21:33:55 +00:00
u32 baseExtended = ( ( gstate . base & 0x000F0000 ) < < 8 ) | data ;
2013-02-02 12:38:34 +00:00
return ( gstate_c . offsetAddr + baseExtended ) & 0x0FFFFFFF ;
}