2015-10-24 21:24:06 +00:00
# pragma once
2017-02-08 16:35:41 +00:00
# include <string>
2017-02-24 19:50:27 +00:00
# include <cstring>
2017-02-08 16:35:41 +00:00
# include <cstdint>
2020-09-29 10:44:47 +00:00
2022-01-30 23:49:02 +00:00
# include "Common/CommonFuncs.h"
2015-10-24 21:24:06 +00:00
2023-01-09 11:21:33 +00:00
// VS_BIT_LIGHT_UBERSHADER indicates that some groups of these will be
// sent to the shader and processed there. This cuts down the number of shaders ("ubershader approach").
2019-02-16 14:54:56 +00:00
enum VShaderBit : uint8_t {
2015-10-24 21:24:06 +00:00
VS_BIT_LMODE = 0 ,
VS_BIT_IS_THROUGH = 1 ,
2023-01-10 14:27:05 +00:00
// bit 2 is free.
2015-10-24 21:24:06 +00:00
VS_BIT_HAS_COLOR = 3 ,
2023-01-10 14:27:05 +00:00
// bit 4 is free.
2020-12-13 15:04:16 +00:00
VS_BIT_VERTEX_RANGE_CULLING = 5 ,
2022-10-22 15:34:23 +00:00
VS_BIT_SIMPLE_STEREO = 6 ,
2017-12-02 16:52:21 +00:00
// 7 is free.
2015-10-24 21:24:06 +00:00
VS_BIT_USE_HW_TRANSFORM = 8 ,
VS_BIT_HAS_NORMAL = 9 , // conditioned on hw transform
VS_BIT_NORM_REVERSE = 10 ,
2017-01-06 16:21:17 +00:00
VS_BIT_HAS_TEXCOORD = 11 ,
VS_BIT_HAS_COLOR_TESS = 12 , // 1 bit
VS_BIT_HAS_TEXCOORD_TESS = 13 , // 1 bit
2017-12-02 16:52:21 +00:00
VS_BIT_NORM_REVERSE_TESS = 14 , // 1 bit
2018-07-17 15:52:20 +00:00
VS_BIT_HAS_NORMAL_TESS = 15 , // 1 bit
2015-10-24 21:24:06 +00:00
VS_BIT_UVGEN_MODE = 16 ,
VS_BIT_UVPROJ_MODE = 18 , // 2, can overlap with LS0
VS_BIT_LS0 = 18 , // 2
VS_BIT_LS1 = 20 , // 2
2018-04-10 10:22:02 +00:00
VS_BIT_BONES = 22 , // 3 should be enough, not 8
// 25 - 29 are free.
VS_BIT_ENABLE_BONES = 30 ,
2022-09-25 11:59:52 +00:00
// If this is set along with LIGHTING_ENABLE, all other lighting bits below
// are passed to the shader directly instead.
VS_BIT_LIGHT_UBERSHADER = 31 ,
2015-10-24 21:24:06 +00:00
VS_BIT_LIGHT0_COMP = 32 , // 2 bits
VS_BIT_LIGHT0_TYPE = 34 , // 2 bits
VS_BIT_LIGHT1_COMP = 36 , // 2 bits
VS_BIT_LIGHT1_TYPE = 38 , // 2 bits
VS_BIT_LIGHT2_COMP = 40 , // 2 bits
VS_BIT_LIGHT2_TYPE = 42 , // 2 bits
VS_BIT_LIGHT3_COMP = 44 , // 2 bits
VS_BIT_LIGHT3_TYPE = 46 , // 2 bits
2017-01-06 16:21:17 +00:00
VS_BIT_MATERIAL_UPDATE = 48 , // 3 bits
VS_BIT_SPLINE = 51 , // 1 bit
2015-10-24 21:24:06 +00:00
VS_BIT_LIGHT0_ENABLE = 52 ,
VS_BIT_LIGHT1_ENABLE = 53 ,
VS_BIT_LIGHT2_ENABLE = 54 ,
VS_BIT_LIGHT3_ENABLE = 55 ,
VS_BIT_LIGHTING_ENABLE = 56 ,
2018-04-10 09:22:58 +00:00
VS_BIT_WEIGHT_FMTSCALE = 57 , // only two bits
// 59 - 61 are free.
2017-01-06 16:21:17 +00:00
VS_BIT_FLATSHADE = 62 , // 1 bit
VS_BIT_BEZIER = 63 , // 1 bit
// No more free
2015-10-24 21:24:06 +00:00
} ;
2019-02-16 14:54:56 +00:00
static inline VShaderBit operator + ( VShaderBit bit , int i ) {
return VShaderBit ( ( int ) bit + i ) ;
}
2015-10-24 21:24:06 +00:00
// Local
2019-02-16 14:54:56 +00:00
enum FShaderBit : uint8_t {
2015-10-24 21:24:06 +00:00
FS_BIT_CLEARMODE = 0 ,
FS_BIT_DO_TEXTURE = 1 ,
FS_BIT_TEXFUNC = 2 , // 3 bits
2023-05-10 14:14:33 +00:00
FS_BIT_DOUBLE_COLOR = 5 , // Not used with FS_BIT_UBERSHADER
2022-09-11 12:14:18 +00:00
FS_BIT_3D_TEXTURE = 6 ,
2015-10-24 21:24:06 +00:00
FS_BIT_SHADER_TEX_CLAMP = 7 ,
FS_BIT_CLAMP_S = 8 ,
FS_BIT_CLAMP_T = 9 ,
2023-05-10 14:14:33 +00:00
FS_BIT_TEXALPHA = 10 , // Not used with FS_BIT_UBERSHADER
2023-05-09 15:50:43 +00:00
FS_BIT_LMODE = 11 ,
2015-10-24 21:24:06 +00:00
FS_BIT_ALPHA_TEST = 12 ,
FS_BIT_ALPHA_TEST_FUNC = 13 , // 3 bits
FS_BIT_ALPHA_AGAINST_ZERO = 16 ,
FS_BIT_COLOR_TEST = 17 ,
FS_BIT_COLOR_TEST_FUNC = 18 , // 2 bits
FS_BIT_COLOR_AGAINST_ZERO = 20 ,
2023-05-10 14:14:33 +00:00
FS_BIT_ENABLE_FOG = 21 , // Not used with FS_BIT_UBERSHADER
FS_BIT_DO_TEXTURE_PROJ = 22 ,
// 1 free bit
2015-10-24 21:24:06 +00:00
FS_BIT_STENCIL_TO_ALPHA = 24 , // 2 bits
2020-11-06 19:08:57 +00:00
FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE = 26 , // 4 bits (ReplaceAlphaType)
2022-09-03 21:28:03 +00:00
FS_BIT_SIMULATE_LOGIC_OP_TYPE = 30 , // 2 bits
2020-11-06 19:08:57 +00:00
FS_BIT_REPLACE_BLEND = 32 , // 3 bits (ReplaceBlendType)
2015-10-24 21:24:06 +00:00
FS_BIT_BLENDEQ = 35 , // 3 bits
FS_BIT_BLENDFUNC_A = 38 , // 4 bits
2017-12-02 16:52:21 +00:00
FS_BIT_BLENDFUNC_B = 42 , // 4 bits
2023-05-10 14:14:33 +00:00
FS_BIT_FLATSHADE = 46 ,
2015-10-24 22:34:23 +00:00
FS_BIT_BGRA_TEXTURE = 47 ,
2018-07-28 03:04:36 +00:00
FS_BIT_TEST_DISCARD_TO_ZERO = 48 ,
2018-12-23 20:19:34 +00:00
FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL = 49 ,
2020-11-08 22:17:06 +00:00
FS_BIT_COLOR_WRITEMASK = 50 ,
2022-09-11 12:14:18 +00:00
FS_BIT_REPLACE_LOGIC_OP = 51 , // 4 bits. GE_LOGIC_COPY means no-op/off.
FS_BIT_SHADER_DEPAL_MODE = 55 , // 2 bits (ShaderDepalMode)
2023-05-10 14:14:33 +00:00
FS_BIT_SAMPLE_ARRAY_TEXTURE = 57 , // For multiview, framebuffers are array textures and we need to sample the two layers correctly.
FS_BIT_STEREO = 58 ,
FS_BIT_USE_FRAMEBUFFER_FETCH = 59 ,
FS_BIT_UBERSHADER = 60 ,
2024-02-02 10:06:49 +00:00
FS_BIT_DEPTH_TEST_NEVER = 61 , // Only used on Mali. Set when depth == NEVER. We forcibly avoid writing to depth in this case, since it crashes the driver.
2015-10-24 21:24:06 +00:00
} ;
2019-02-16 14:54:56 +00:00
static inline FShaderBit operator + ( FShaderBit bit , int i ) {
return FShaderBit ( ( int ) bit + i ) ;
}
2022-10-02 03:01:23 +00:00
// Some of these bits are straight from FShaderBit, since they essentially enable attributes directly.
enum GShaderBit : uint8_t {
GS_BIT_ENABLED = 0 , // If not set, we don't use a geo shader.
GS_BIT_DO_TEXTURE = 1 , // presence of texcoords
2023-05-09 15:50:43 +00:00
GS_BIT_LMODE = 2 ,
GS_BIT_CURVE = 3 , // curve, which means don't do range culling.
2022-10-02 03:01:23 +00:00
} ;
static inline GShaderBit operator + ( GShaderBit bit , int i ) {
return GShaderBit ( ( int ) bit + i ) ;
}
2015-10-24 21:24:06 +00:00
struct ShaderID {
ShaderID ( ) {
clear ( ) ;
}
void clear ( ) {
for ( size_t i = 0 ; i < ARRAY_SIZE ( d ) ; i + + ) {
d [ i ] = 0 ;
}
}
void set_invalid ( ) {
for ( size_t i = 0 ; i < ARRAY_SIZE ( d ) ; i + + ) {
d [ i ] = 0xFFFFFFFF ;
}
}
2022-10-01 19:12:46 +00:00
bool is_invalid ( ) const {
for ( size_t i = 0 ; i < ARRAY_SIZE ( d ) ; i + + ) {
if ( d [ i ] ! = 0xFFFFFFFF )
return false ;
}
return true ;
}
2015-10-24 21:24:06 +00:00
2017-02-08 16:35:41 +00:00
uint32_t d [ 2 ] ;
2015-10-24 21:24:06 +00:00
bool operator < ( const ShaderID & other ) const {
2017-02-08 16:35:41 +00:00
for ( size_t i = 0 ; i < sizeof ( d ) / sizeof ( uint32_t ) ; i + + ) {
2015-10-24 21:24:06 +00:00
if ( d [ i ] < other . d [ i ] )
return true ;
if ( d [ i ] > other . d [ i ] )
return false ;
}
return false ;
}
bool operator = = ( const ShaderID & other ) const {
2017-02-08 16:35:41 +00:00
for ( size_t i = 0 ; i < sizeof ( d ) / sizeof ( uint32_t ) ; i + + ) {
2015-10-24 21:24:06 +00:00
if ( d [ i ] ! = other . d [ i ] )
return false ;
}
return true ;
}
2017-04-03 14:45:58 +00:00
bool operator ! = ( const ShaderID & other ) const {
return ! ( * this = = other ) ;
}
2019-02-16 14:54:56 +00:00
uint32_t Word ( int word ) const {
return d [ word ] ;
}
2022-12-18 17:05:20 +00:00
// Note: This is a binary copy to string-as-bytes, not a human-readable representation.
2019-02-16 14:54:56 +00:00
void ToString ( std : : string * dest ) const {
dest - > resize ( sizeof ( d ) ) ;
memcpy ( & ( * dest ) [ 0 ] , d , sizeof ( d ) ) ;
}
2022-12-18 17:05:20 +00:00
// Note: This is a binary copy from string-as-bytes, not a human-readable representation.
2019-02-16 14:54:56 +00:00
void FromString ( std : : string src ) {
memcpy ( d , & ( src ) [ 0 ] , sizeof ( d ) ) ;
}
protected :
2015-10-24 21:24:06 +00:00
bool Bit ( int bit ) const {
return ( d [ bit > > 5 ] > > ( bit & 31 ) ) & 1 ;
}
2017-08-15 12:21:38 +00:00
// Does not handle crossing 32-bit boundaries. count must be 30 or smaller.
2015-10-24 21:24:06 +00:00
int Bits ( int bit , int count ) const {
const int mask = ( 1 < < count ) - 1 ;
return ( d [ bit > > 5 ] > > ( bit & 31 ) ) & mask ;
}
void SetBit ( int bit , bool value = true ) {
if ( value ) {
d [ bit > > 5 ] | = 1 < < ( bit & 31 ) ;
2020-10-21 21:09:34 +00:00
} else {
d [ bit > > 5 ] & = ~ ( 1 < < ( bit & 31 ) ) ;
2015-10-24 21:24:06 +00:00
}
}
void SetBits ( int bit , int count , int value ) {
2020-10-30 09:22:51 +00:00
const int mask = ( 1 < < count ) - 1 ;
const int shifted_mask = mask < < ( bit & 31 ) ;
d [ bit > > 5 ] = ( d [ bit > > 5 ] & ~ shifted_mask ) | ( ( value & mask ) < < ( bit & 31 ) ) ;
2015-10-24 21:24:06 +00:00
}
2015-10-24 21:49:05 +00:00
} ;
2017-12-02 17:07:27 +00:00
struct VShaderID : ShaderID {
VShaderID ( ) : ShaderID ( ) {
}
explicit VShaderID ( ShaderID & src ) {
memcpy ( d , src . d , sizeof ( d ) ) ;
}
2019-02-16 14:54:56 +00:00
bool Bit ( VShaderBit bit ) const {
return ShaderID : : Bit ( ( int ) bit ) ;
}
int Bits ( VShaderBit bit , int count ) const {
return ShaderID : : Bits ( ( int ) bit , count ) ;
}
void SetBit ( VShaderBit bit , bool value = true ) {
ShaderID : : SetBit ( ( int ) bit , value ) ;
}
void SetBits ( VShaderBit bit , int count , int value ) {
ShaderID : : SetBits ( ( int ) bit , count , value ) ;
}
2017-12-02 17:07:27 +00:00
} ;
struct FShaderID : ShaderID {
FShaderID ( ) : ShaderID ( ) {
}
explicit FShaderID ( ShaderID & src ) {
memcpy ( d , src . d , sizeof ( d ) ) ;
}
2019-02-16 14:54:56 +00:00
bool Bit ( FShaderBit bit ) const {
return ShaderID : : Bit ( ( int ) bit ) ;
}
int Bits ( FShaderBit bit , int count ) const {
return ShaderID : : Bits ( ( int ) bit , count ) ;
}
void SetBit ( FShaderBit bit , bool value = true ) {
ShaderID : : SetBit ( ( int ) bit , value ) ;
}
void SetBits ( FShaderBit bit , int count , int value ) {
ShaderID : : SetBits ( ( int ) bit , count , value ) ;
}
2017-12-02 17:07:27 +00:00
} ;
2022-10-02 03:01:23 +00:00
struct GShaderID : ShaderID {
GShaderID ( ) : ShaderID ( ) {
}
explicit GShaderID ( ShaderID & src ) {
memcpy ( d , src . d , sizeof ( d ) ) ;
}
bool Bit ( GShaderBit bit ) const {
return ShaderID : : Bit ( ( int ) bit ) ;
}
int Bits ( GShaderBit bit , int count ) const {
return ShaderID : : Bits ( ( int ) bit , count ) ;
}
void SetBit ( GShaderBit bit , bool value = true ) {
ShaderID : : SetBit ( ( int ) bit , value ) ;
}
void SetBits ( GShaderBit bit , int count , int value ) {
ShaderID : : SetBits ( ( int ) bit , count , value ) ;
}
} ;
2018-12-23 20:19:34 +00:00
namespace Draw {
class Bugs ;
}
2022-12-14 21:48:17 +00:00
class VertexDecoder ;
void ComputeVertexShaderID ( VShaderID * id , VertexDecoder * vertexDecoder , bool useHWTransform , bool useHWTessellation , bool weightsAsFloat , bool useSkinInDecode ) ;
2015-10-24 21:49:05 +00:00
// Generates a compact string that describes the shader. Useful in a list to get an overview
// of the current flora of shaders.
2019-02-16 14:54:56 +00:00
std : : string VertexShaderDesc ( const VShaderID & id ) ;
2015-10-24 21:49:05 +00:00
2022-09-02 20:07:42 +00:00
struct ComputedPipelineState ;
void ComputeFragmentShaderID ( FShaderID * id , const ComputedPipelineState & pipelineState , const Draw : : Bugs & bugs ) ;
2019-02-16 14:54:56 +00:00
std : : string FragmentShaderDesc ( const FShaderID & id ) ;
2022-10-02 03:01:23 +00:00
void ComputeGeometryShaderID ( GShaderID * id , const Draw : : Bugs & bugs , int prim ) ;
std : : string GeometryShaderDesc ( const GShaderID & id ) ;
2022-10-13 20:35:23 +00:00
// For sanity checking.
bool FragmentIdNeedsFramebufferRead ( const FShaderID & id ) ;