CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/GPU/Common/ShaderId.h
Views: 1401
#pragma once12#include <string>3#include <cstring>4#include <cstdint>56#include "Common/CommonFuncs.h"78// VS_BIT_LIGHT_UBERSHADER indicates that some groups of these will be9// sent to the shader and processed there. This cuts down the number of shaders ("ubershader approach").10enum VShaderBit : uint8_t {11VS_BIT_LMODE = 0,12VS_BIT_IS_THROUGH = 1,13// bit 2 is free.14VS_BIT_HAS_COLOR = 3,15// bit 4 is free.16VS_BIT_VERTEX_RANGE_CULLING = 5,17VS_BIT_SIMPLE_STEREO = 6,18// 7 is free.19VS_BIT_USE_HW_TRANSFORM = 8,20VS_BIT_HAS_NORMAL = 9, // conditioned on hw transform21VS_BIT_NORM_REVERSE = 10,22VS_BIT_HAS_TEXCOORD = 11,23VS_BIT_HAS_COLOR_TESS = 12, // 1 bit24VS_BIT_HAS_TEXCOORD_TESS = 13, // 1 bit25VS_BIT_NORM_REVERSE_TESS = 14, // 1 bit26VS_BIT_HAS_NORMAL_TESS = 15, // 1 bit27VS_BIT_UVGEN_MODE = 16,28VS_BIT_UVPROJ_MODE = 18, // 2, can overlap with LS029VS_BIT_LS0 = 18, // 230VS_BIT_LS1 = 20, // 231VS_BIT_BONES = 22, // 3 should be enough, not 832// 25 - 29 are free.33VS_BIT_ENABLE_BONES = 30,3435// If this is set along with LIGHTING_ENABLE, all other lighting bits below36// are passed to the shader directly instead.37VS_BIT_LIGHT_UBERSHADER = 31,3839VS_BIT_LIGHT0_COMP = 32, // 2 bits40VS_BIT_LIGHT0_TYPE = 34, // 2 bits41VS_BIT_LIGHT1_COMP = 36, // 2 bits42VS_BIT_LIGHT1_TYPE = 38, // 2 bits43VS_BIT_LIGHT2_COMP = 40, // 2 bits44VS_BIT_LIGHT2_TYPE = 42, // 2 bits45VS_BIT_LIGHT3_COMP = 44, // 2 bits46VS_BIT_LIGHT3_TYPE = 46, // 2 bits47VS_BIT_MATERIAL_UPDATE = 48, // 3 bits48VS_BIT_SPLINE = 51, // 1 bit49VS_BIT_LIGHT0_ENABLE = 52,50VS_BIT_LIGHT1_ENABLE = 53,51VS_BIT_LIGHT2_ENABLE = 54,52VS_BIT_LIGHT3_ENABLE = 55,53VS_BIT_LIGHTING_ENABLE = 56,54VS_BIT_WEIGHT_FMTSCALE = 57, // only two bits55// 59 - 61 are free.56VS_BIT_FLATSHADE = 62, // 1 bit57VS_BIT_BEZIER = 63, // 1 bit58// No more free59};6061static inline VShaderBit operator +(VShaderBit bit, int i) {62return VShaderBit((int)bit + i);63}6465// Local66enum FShaderBit : uint8_t {67FS_BIT_CLEARMODE = 0,68FS_BIT_DO_TEXTURE = 1,69FS_BIT_TEXFUNC = 2, // 3 bits70FS_BIT_DOUBLE_COLOR = 5, // Not used with FS_BIT_UBERSHADER71FS_BIT_3D_TEXTURE = 6,72FS_BIT_SHADER_TEX_CLAMP = 7,73FS_BIT_CLAMP_S = 8,74FS_BIT_CLAMP_T = 9,75FS_BIT_TEXALPHA = 10, // Not used with FS_BIT_UBERSHADER76FS_BIT_LMODE = 11,77FS_BIT_ALPHA_TEST = 12,78FS_BIT_ALPHA_TEST_FUNC = 13, // 3 bits79FS_BIT_ALPHA_AGAINST_ZERO = 16,80FS_BIT_COLOR_TEST = 17,81FS_BIT_COLOR_TEST_FUNC = 18, // 2 bits82FS_BIT_COLOR_AGAINST_ZERO = 20,83FS_BIT_ENABLE_FOG = 21, // Not used with FS_BIT_UBERSHADER84FS_BIT_DO_TEXTURE_PROJ = 22,85// 1 free bit86FS_BIT_STENCIL_TO_ALPHA = 24, // 2 bits87FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE = 26, // 4 bits (ReplaceAlphaType)88FS_BIT_SIMULATE_LOGIC_OP_TYPE = 30, // 2 bits89FS_BIT_REPLACE_BLEND = 32, // 3 bits (ReplaceBlendType)90FS_BIT_BLENDEQ = 35, // 3 bits91FS_BIT_BLENDFUNC_A = 38, // 4 bits92FS_BIT_BLENDFUNC_B = 42, // 4 bits93FS_BIT_FLATSHADE = 46,94FS_BIT_BGRA_TEXTURE = 47,95FS_BIT_TEST_DISCARD_TO_ZERO = 48,96FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL = 49,97FS_BIT_COLOR_WRITEMASK = 50,98FS_BIT_REPLACE_LOGIC_OP = 51, // 4 bits. GE_LOGIC_COPY means no-op/off.99FS_BIT_SHADER_DEPAL_MODE = 55, // 2 bits (ShaderDepalMode)100FS_BIT_SAMPLE_ARRAY_TEXTURE = 57, // For multiview, framebuffers are array textures and we need to sample the two layers correctly.101FS_BIT_STEREO = 58,102FS_BIT_USE_FRAMEBUFFER_FETCH = 59,103FS_BIT_UBERSHADER = 60,104FS_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.105};106107static inline FShaderBit operator +(FShaderBit bit, int i) {108return FShaderBit((int)bit + i);109}110111// Some of these bits are straight from FShaderBit, since they essentially enable attributes directly.112enum GShaderBit : uint8_t {113GS_BIT_ENABLED = 0, // If not set, we don't use a geo shader.114GS_BIT_DO_TEXTURE = 1, // presence of texcoords115GS_BIT_LMODE = 2,116GS_BIT_CURVE = 3, // curve, which means don't do range culling.117};118119static inline GShaderBit operator +(GShaderBit bit, int i) {120return GShaderBit((int)bit + i);121}122123struct ShaderID {124ShaderID() {125clear();126}127void clear() {128for (size_t i = 0; i < ARRAY_SIZE(d); i++) {129d[i] = 0;130}131}132void set_invalid() {133for (size_t i = 0; i < ARRAY_SIZE(d); i++) {134d[i] = 0xFFFFFFFF;135}136}137bool is_invalid() const {138for (size_t i = 0; i < ARRAY_SIZE(d); i++) {139if (d[i] != 0xFFFFFFFF)140return false;141}142return true;143}144145uint32_t d[2];146bool operator < (const ShaderID &other) const {147for (size_t i = 0; i < sizeof(d) / sizeof(uint32_t); i++) {148if (d[i] < other.d[i])149return true;150if (d[i] > other.d[i])151return false;152}153return false;154}155bool operator == (const ShaderID &other) const {156for (size_t i = 0; i < sizeof(d) / sizeof(uint32_t); i++) {157if (d[i] != other.d[i])158return false;159}160return true;161}162bool operator != (const ShaderID &other) const {163return !(*this == other);164}165166uint32_t Word(int word) const {167return d[word];168}169170// Note: This is a binary copy to string-as-bytes, not a human-readable representation.171void ToString(std::string *dest) const {172dest->resize(sizeof(d));173memcpy(&(*dest)[0], d, sizeof(d));174}175// Note: This is a binary copy from string-as-bytes, not a human-readable representation.176void FromString(std::string src) {177memcpy(d, &(src)[0], sizeof(d));178}179180protected:181bool Bit(int bit) const {182return (d[bit >> 5] >> (bit & 31)) & 1;183}184// Does not handle crossing 32-bit boundaries. count must be 30 or smaller.185int Bits(int bit, int count) const {186const int mask = (1 << count) - 1;187return (d[bit >> 5] >> (bit & 31)) & mask;188}189void SetBit(int bit, bool value = true) {190if (value) {191d[bit >> 5] |= 1 << (bit & 31);192} else {193d[bit >> 5] &= ~(1 << (bit & 31));194}195}196void SetBits(int bit, int count, int value) {197const int mask = (1 << count) - 1;198const int shifted_mask = mask << (bit & 31);199d[bit >> 5] = (d[bit >> 5] & ~shifted_mask) | ((value & mask) << (bit & 31));200}201};202203struct VShaderID : ShaderID {204VShaderID() : ShaderID() {205}206207explicit VShaderID(ShaderID &src) {208memcpy(d, src.d, sizeof(d));209}210211bool Bit(VShaderBit bit) const {212return ShaderID::Bit((int)bit);213}214215int Bits(VShaderBit bit, int count) const {216return ShaderID::Bits((int)bit, count);217}218219void SetBit(VShaderBit bit, bool value = true) {220ShaderID::SetBit((int)bit, value);221}222223void SetBits(VShaderBit bit, int count, int value) {224ShaderID::SetBits((int)bit, count, value);225}226};227228struct FShaderID : ShaderID {229FShaderID() : ShaderID() {230}231232explicit FShaderID(ShaderID &src) {233memcpy(d, src.d, sizeof(d));234}235236bool Bit(FShaderBit bit) const {237return ShaderID::Bit((int)bit);238}239240int Bits(FShaderBit bit, int count) const {241return ShaderID::Bits((int)bit, count);242}243244void SetBit(FShaderBit bit, bool value = true) {245ShaderID::SetBit((int)bit, value);246}247248void SetBits(FShaderBit bit, int count, int value) {249ShaderID::SetBits((int)bit, count, value);250}251};252253struct GShaderID : ShaderID {254GShaderID() : ShaderID() {255}256257explicit GShaderID(ShaderID &src) {258memcpy(d, src.d, sizeof(d));259}260261bool Bit(GShaderBit bit) const {262return ShaderID::Bit((int)bit);263}264265int Bits(GShaderBit bit, int count) const {266return ShaderID::Bits((int)bit, count);267}268269void SetBit(GShaderBit bit, bool value = true) {270ShaderID::SetBit((int)bit, value);271}272273void SetBits(GShaderBit bit, int count, int value) {274ShaderID::SetBits((int)bit, count, value);275}276};277278namespace Draw {279class Bugs;280}281282class VertexDecoder;283284void ComputeVertexShaderID(VShaderID *id, VertexDecoder *vertexDecoder, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat, bool useSkinInDecode);285// Generates a compact string that describes the shader. Useful in a list to get an overview286// of the current flora of shaders.287std::string VertexShaderDesc(const VShaderID &id);288289struct ComputedPipelineState;290void ComputeFragmentShaderID(FShaderID *id, const ComputedPipelineState &pipelineState, const Draw::Bugs &bugs);291std::string FragmentShaderDesc(const FShaderID &id);292293void ComputeGeometryShaderID(GShaderID *id, const Draw::Bugs &bugs, int prim);294std::string GeometryShaderDesc(const GShaderID &id);295296// For sanity checking.297bool FragmentIdNeedsFramebufferRead(const FShaderID &id);298299300