1 // Copyright 2009 Dolphin Emulator Project 2 // Licensed under GPLv2+ 3 // Refer to the license.txt file included. 4 5 #pragma once 6 7 #include <array> 8 #include <string> 9 10 #include "Common/BitField.h" 11 #include "Common/CommonTypes.h" 12 #include "Common/Inline.h" 13 14 enum class EFBCopyFormat; 15 16 #pragma pack(4) 17 18 enum 19 { 20 BPMEM_GENMODE = 0x00, 21 BPMEM_DISPLAYCOPYFILTER = 0x01, // 0x01 + 4 22 BPMEM_IND_MTXA = 0x06, // 0x06 + (3 * 3) 23 BPMEM_IND_MTXB = 0x07, // 0x07 + (3 * 3) 24 BPMEM_IND_MTXC = 0x08, // 0x08 + (3 * 3) 25 BPMEM_IND_IMASK = 0x0F, 26 BPMEM_IND_CMD = 0x10, // 0x10 + 16 27 BPMEM_SCISSORTL = 0x20, 28 BPMEM_SCISSORBR = 0x21, 29 BPMEM_LINEPTWIDTH = 0x22, 30 BPMEM_PERF0_TRI = 0x23, 31 BPMEM_PERF0_QUAD = 0x24, 32 BPMEM_RAS1_SS0 = 0x25, 33 BPMEM_RAS1_SS1 = 0x26, 34 BPMEM_IREF = 0x27, 35 BPMEM_TREF = 0x28, // 0x28 + 8 36 BPMEM_SU_SSIZE = 0x30, // 0x30 + (2 * 8) 37 BPMEM_SU_TSIZE = 0x31, // 0x31 + (2 * 8) 38 BPMEM_ZMODE = 0x40, 39 BPMEM_BLENDMODE = 0x41, 40 BPMEM_CONSTANTALPHA = 0x42, 41 BPMEM_ZCOMPARE = 0x43, 42 BPMEM_FIELDMASK = 0x44, 43 BPMEM_SETDRAWDONE = 0x45, 44 BPMEM_BUSCLOCK0 = 0x46, 45 BPMEM_PE_TOKEN_ID = 0x47, 46 BPMEM_PE_TOKEN_INT_ID = 0x48, 47 BPMEM_EFB_TL = 0x49, 48 BPMEM_EFB_BR = 0x4A, 49 BPMEM_EFB_ADDR = 0x4B, 50 BPMEM_MIPMAP_STRIDE = 0x4D, 51 BPMEM_COPYYSCALE = 0x4E, 52 BPMEM_CLEAR_AR = 0x4F, 53 BPMEM_CLEAR_GB = 0x50, 54 BPMEM_CLEAR_Z = 0x51, 55 BPMEM_TRIGGER_EFB_COPY = 0x52, 56 BPMEM_COPYFILTER0 = 0x53, 57 BPMEM_COPYFILTER1 = 0x54, 58 BPMEM_CLEARBBOX1 = 0x55, 59 BPMEM_CLEARBBOX2 = 0x56, 60 BPMEM_CLEAR_PIXEL_PERF = 0x57, 61 BPMEM_REVBITS = 0x58, 62 BPMEM_SCISSOROFFSET = 0x59, 63 BPMEM_PRELOAD_ADDR = 0x60, 64 BPMEM_PRELOAD_TMEMEVEN = 0x61, 65 BPMEM_PRELOAD_TMEMODD = 0x62, 66 BPMEM_PRELOAD_MODE = 0x63, 67 BPMEM_LOADTLUT0 = 0x64, 68 BPMEM_LOADTLUT1 = 0x65, 69 BPMEM_TEXINVALIDATE = 0x66, 70 BPMEM_PERF1 = 0x67, 71 BPMEM_FIELDMODE = 0x68, 72 BPMEM_BUSCLOCK1 = 0x69, 73 BPMEM_TX_SETMODE0 = 0x80, // 0x80 + 4 74 BPMEM_TX_SETMODE1 = 0x84, // 0x84 + 4 75 BPMEM_TX_SETIMAGE0 = 0x88, // 0x88 + 4 76 BPMEM_TX_SETIMAGE1 = 0x8C, // 0x8C + 4 77 BPMEM_TX_SETIMAGE2 = 0x90, // 0x90 + 4 78 BPMEM_TX_SETIMAGE3 = 0x94, // 0x94 + 4 79 BPMEM_TX_SETTLUT = 0x98, // 0x98 + 4 80 BPMEM_TX_SETMODE0_4 = 0xA0, // 0xA0 + 4 81 BPMEM_TX_SETMODE1_4 = 0xA4, // 0xA4 + 4 82 BPMEM_TX_SETIMAGE0_4 = 0xA8, // 0xA8 + 4 83 BPMEM_TX_SETIMAGE1_4 = 0xAC, // 0xA4 + 4 84 BPMEM_TX_SETIMAGE2_4 = 0xB0, // 0xB0 + 4 85 BPMEM_TX_SETIMAGE3_4 = 0xB4, // 0xB4 + 4 86 BPMEM_TX_SETTLUT_4 = 0xB8, // 0xB8 + 4 87 BPMEM_TEV_COLOR_ENV = 0xC0, // 0xC0 + (2 * 16) 88 BPMEM_TEV_ALPHA_ENV = 0xC1, // 0xC1 + (2 * 16) 89 BPMEM_TEV_COLOR_RA = 0xE0, // 0xE0 + (2 * 4) 90 BPMEM_TEV_COLOR_BG = 0xE1, // 0xE1 + (2 * 4) 91 BPMEM_FOGRANGE = 0xE8, // 0xE8 + 6 92 BPMEM_FOGPARAM0 = 0xEE, 93 BPMEM_FOGBMAGNITUDE = 0xEF, 94 BPMEM_FOGBEXPONENT = 0xF0, 95 BPMEM_FOGPARAM3 = 0xF1, 96 BPMEM_FOGCOLOR = 0xF2, 97 BPMEM_ALPHACOMPARE = 0xF3, 98 BPMEM_BIAS = 0xF4, 99 BPMEM_ZTEX2 = 0xF5, 100 BPMEM_TEV_KSEL = 0xF6, // 0xF6 + 8 101 BPMEM_BP_MASK = 0xFE, 102 }; 103 104 // Tev/combiner things 105 106 // TEV scaling type 107 enum : u32 108 { 109 TEVSCALE_1 = 0, 110 TEVSCALE_2 = 1, 111 TEVSCALE_4 = 2, 112 TEVDIVIDE_2 = 3 113 }; 114 115 enum : u32 116 { 117 TEVCMP_R8 = 0, 118 TEVCMP_GR16 = 1, 119 TEVCMP_BGR24 = 2, 120 TEVCMP_RGB8 = 3 121 }; 122 123 // TEV combiner operator 124 enum : u32 125 { 126 TEVOP_ADD = 0, 127 TEVOP_SUB = 1, 128 TEVCMP_R8_GT = 8, 129 TEVCMP_R8_EQ = 9, 130 TEVCMP_GR16_GT = 10, 131 TEVCMP_GR16_EQ = 11, 132 TEVCMP_BGR24_GT = 12, 133 TEVCMP_BGR24_EQ = 13, 134 TEVCMP_RGB8_GT = 14, 135 TEVCMP_RGB8_EQ = 15, 136 TEVCMP_A8_GT = TEVCMP_RGB8_GT, 137 TEVCMP_A8_EQ = TEVCMP_RGB8_EQ 138 }; 139 140 // TEV color combiner input 141 enum : u32 142 { 143 TEVCOLORARG_CPREV = 0, 144 TEVCOLORARG_APREV = 1, 145 TEVCOLORARG_C0 = 2, 146 TEVCOLORARG_A0 = 3, 147 TEVCOLORARG_C1 = 4, 148 TEVCOLORARG_A1 = 5, 149 TEVCOLORARG_C2 = 6, 150 TEVCOLORARG_A2 = 7, 151 TEVCOLORARG_TEXC = 8, 152 TEVCOLORARG_TEXA = 9, 153 TEVCOLORARG_RASC = 10, 154 TEVCOLORARG_RASA = 11, 155 TEVCOLORARG_ONE = 12, 156 TEVCOLORARG_HALF = 13, 157 TEVCOLORARG_KONST = 14, 158 TEVCOLORARG_ZERO = 15 159 }; 160 161 // TEV alpha combiner input 162 enum : u32 163 { 164 TEVALPHAARG_APREV = 0, 165 TEVALPHAARG_A0 = 1, 166 TEVALPHAARG_A1 = 2, 167 TEVALPHAARG_A2 = 3, 168 TEVALPHAARG_TEXA = 4, 169 TEVALPHAARG_RASA = 5, 170 TEVALPHAARG_KONST = 6, 171 TEVALPHAARG_ZERO = 7 172 }; 173 174 // TEV output registers 175 enum : u32 176 { 177 GX_TEVPREV = 0, 178 GX_TEVREG0 = 1, 179 GX_TEVREG1 = 2, 180 GX_TEVREG2 = 3 181 }; 182 183 // Z-texture formats 184 enum : u32 185 { 186 TEV_ZTEX_TYPE_U8 = 0, 187 TEV_ZTEX_TYPE_U16 = 1, 188 TEV_ZTEX_TYPE_U24 = 2 189 }; 190 191 // Z texture operator 192 enum : u32 193 { 194 ZTEXTURE_DISABLE = 0, 195 ZTEXTURE_ADD = 1, 196 ZTEXTURE_REPLACE = 2 197 }; 198 199 // TEV bias value 200 enum : u32 201 { 202 TEVBIAS_ZERO = 0, 203 TEVBIAS_ADDHALF = 1, 204 TEVBIAS_SUBHALF = 2, 205 TEVBIAS_COMPARE = 3 206 }; 207 208 // Indirect texture format 209 enum : u32 210 { 211 ITF_8 = 0, 212 ITF_5 = 1, 213 ITF_4 = 2, 214 ITF_3 = 3 215 }; 216 217 // Indirect texture bias 218 enum : u32 219 { 220 ITB_NONE = 0, 221 ITB_S = 1, 222 ITB_T = 2, 223 ITB_ST = 3, 224 ITB_U = 4, 225 ITB_SU = 5, 226 ITB_TU = 6, 227 ITB_STU = 7 228 }; 229 230 // Indirect texture bump alpha 231 enum : u32 232 { 233 ITBA_OFF = 0, 234 ITBA_S = 1, 235 ITBA_T = 2, 236 ITBA_U = 3 237 }; 238 239 // Indirect texture wrap value 240 enum : u32 241 { 242 ITW_OFF = 0, 243 ITW_256 = 1, 244 ITW_128 = 2, 245 ITW_64 = 3, 246 ITW_32 = 4, 247 ITW_16 = 5, 248 ITW_0 = 6 249 }; 250 251 union IND_MTXA 252 { 253 struct 254 { 255 s32 ma : 11; 256 s32 mb : 11; 257 u32 s0 : 2; // bits 0-1 of scale factor 258 u32 rid : 8; 259 }; 260 u32 hex; 261 }; 262 263 union IND_MTXB 264 { 265 struct 266 { 267 s32 mc : 11; 268 s32 md : 11; 269 u32 s1 : 2; // bits 2-3 of scale factor 270 u32 rid : 8; 271 }; 272 u32 hex; 273 }; 274 275 union IND_MTXC 276 { 277 struct 278 { 279 s32 me : 11; 280 s32 mf : 11; 281 u32 s2 : 2; // bits 4-5 of scale factor 282 u32 rid : 8; 283 }; 284 u32 hex; 285 }; 286 287 struct IND_MTX 288 { 289 IND_MTXA col0; 290 IND_MTXB col1; 291 IND_MTXC col2; 292 }; 293 294 union IND_IMASK 295 { 296 struct 297 { 298 u32 mask : 24; 299 u32 rid : 8; 300 }; 301 u32 hex; 302 }; 303 304 struct TevStageCombiner 305 { 306 union ColorCombiner 307 { 308 // abc=8bit,d=10bit 309 BitField<0, 4, u32> d; // TEVSELCC_X 310 BitField<4, 4, u32> c; // TEVSELCC_X 311 BitField<8, 4, u32> b; // TEVSELCC_X 312 BitField<12, 4, u32> a; // TEVSELCC_X 313 314 BitField<16, 2, u32> bias; 315 BitField<18, 1, u32> op; 316 BitField<19, 1, u32> clamp; 317 318 BitField<20, 2, u32> shift; 319 BitField<22, 2, u32> dest; // 1,2,3 320 321 u32 hex; 322 }; 323 union AlphaCombiner 324 { 325 BitField<0, 2, u32> rswap; 326 BitField<2, 2, u32> tswap; 327 BitField<4, 3, u32> d; // TEVSELCA_ 328 BitField<7, 3, u32> c; // TEVSELCA_ 329 BitField<10, 3, u32> b; // TEVSELCA_ 330 BitField<13, 3, u32> a; // TEVSELCA_ 331 332 BitField<16, 2, u32> bias; // GXTevBias 333 BitField<18, 1, u32> op; 334 BitField<19, 1, u32> clamp; 335 336 BitField<20, 2, u32> shift; 337 BitField<22, 2, u32> dest; // 1,2,3 338 339 u32 hex; 340 }; 341 342 ColorCombiner colorC; 343 AlphaCombiner alphaC; 344 }; 345 346 // several discoveries: 347 // GXSetTevIndBumpST(tevstage, indstage, matrixind) 348 // if ( matrix == 2 ) realmat = 6; // 10 349 // else if ( matrix == 3 ) realmat = 7; // 11 350 // else if ( matrix == 1 ) realmat = 5; // 9 351 // GXSetTevIndirect(tevstage, indstage, 0, 3, realmat, 6, 6, 0, 0, 0) 352 // GXSetTevIndirect(tevstage+1, indstage, 0, 3, realmat+4, 6, 6, 1, 0, 0) 353 // GXSetTevIndirect(tevstage+2, indstage, 0, 0, 0, 0, 0, 1, 0, 0) 354 355 union TevStageIndirect 356 { 357 BitField<0, 2, u32> bt; // Indirect tex stage ID 358 BitField<2, 2, u32> fmt; // Format: ITF_X 359 BitField<4, 3, u32> bias; // ITB_X 360 BitField<7, 2, u32> bs; // ITBA_X, indicates which coordinate will become the 'bump alpha' 361 BitField<9, 4, u32> mid; // Matrix ID to multiply offsets with 362 BitField<13, 3, u32> sw; // ITW_X, wrapping factor for S of regular coord 363 BitField<16, 3, u32> tw; // ITW_X, wrapping factor for T of regular coord 364 BitField<19, 1, u32> lb_utclod; // Use modified or unmodified texture 365 // coordinates for LOD computation 366 BitField<20, 1, u32> fb_addprev; // 1 if the texture coordinate results from the previous TEV 367 // stage should be added 368 369 struct 370 { 371 u32 hex : 21; 372 u32 unused : 11; 373 }; 374 375 // If bs and mid are zero, the result of the stage is independent of 376 // the texture sample data, so we can skip sampling the texture. IsActive()377 bool IsActive() const { return bs != ITBA_OFF || mid != 0; } 378 }; 379 380 union TwoTevStageOrders 381 { 382 BitField<0, 3, u32> texmap0; // Indirect tex stage texmap 383 BitField<3, 3, u32> texcoord0; 384 BitField<6, 1, u32> enable0; // 1 if should read from texture 385 BitField<7, 3, u32> colorchan0; // RAS1_CC_X 386 387 BitField<12, 3, u32> texmap1; 388 BitField<15, 3, u32> texcoord1; 389 BitField<18, 1, u32> enable1; // 1 if should read from texture 390 BitField<19, 3, u32> colorchan1; // RAS1_CC_X 391 392 BitField<24, 8, u32> rid; 393 394 u32 hex; getTexMap(int i)395 u32 getTexMap(int i) const { return i ? texmap1.Value() : texmap0.Value(); } getTexCoord(int i)396 u32 getTexCoord(int i) const { return i ? texcoord1.Value() : texcoord0.Value(); } getEnable(int i)397 u32 getEnable(int i) const { return i ? enable1.Value() : enable0.Value(); } getColorChan(int i)398 u32 getColorChan(int i) const { return i ? colorchan1.Value() : colorchan0.Value(); } 399 }; 400 401 union TEXSCALE 402 { 403 struct 404 { 405 u32 ss0 : 4; // Indirect tex stage 0, 2^(-ss0) 406 u32 ts0 : 4; // Indirect tex stage 0 407 u32 ss1 : 4; // Indirect tex stage 1 408 u32 ts1 : 4; // Indirect tex stage 1 409 u32 pad : 8; 410 u32 rid : 8; 411 }; 412 u32 hex; 413 }; 414 415 union RAS1_IREF 416 { 417 struct 418 { 419 u32 bi0 : 3; // Indirect tex stage 0 ntexmap 420 u32 bc0 : 3; // Indirect tex stage 0 ntexcoord 421 u32 bi1 : 3; 422 u32 bc1 : 3; 423 u32 bi2 : 3; 424 u32 bc3 : 3; 425 u32 bi4 : 3; 426 u32 bc4 : 3; 427 u32 rid : 8; 428 }; 429 u32 hex; 430 getTexCoord(int i)431 u32 getTexCoord(int i) const { return (hex >> (6 * i + 3)) & 7; } getTexMap(int i)432 u32 getTexMap(int i) const { return (hex >> (6 * i)) & 7; } 433 }; 434 435 // Texture structs 436 437 union TexMode0 438 { 439 enum TextureFilter : u32 440 { 441 TEXF_NONE = 0, 442 TEXF_POINT = 1, 443 TEXF_LINEAR = 2 444 }; 445 446 struct 447 { 448 u32 wrap_s : 2; 449 u32 wrap_t : 2; 450 u32 mag_filter : 1; 451 u32 min_filter : 3; 452 u32 diag_lod : 1; 453 s32 lod_bias : 8; 454 u32 pad0 : 2; 455 u32 max_aniso : 2; 456 u32 lod_clamp : 1; 457 }; 458 u32 hex; 459 }; 460 union TexMode1 461 { 462 struct 463 { 464 u32 min_lod : 8; 465 u32 max_lod : 8; 466 }; 467 u32 hex; 468 }; 469 union TexImage0 470 { 471 struct 472 { 473 u32 width : 10; // Actually w-1 474 u32 height : 10; // Actually h-1 475 u32 format : 4; 476 }; 477 u32 hex; 478 }; 479 union TexImage1 480 { 481 struct 482 { 483 u32 tmem_even : 15; // TMEM line index for even LODs 484 u32 cache_width : 3; 485 u32 cache_height : 3; 486 u32 image_type : 1; // 1 if this texture is managed manually (0 means we'll autofetch the 487 // texture data whenever it changes) 488 }; 489 u32 hex; 490 }; 491 492 union TexImage2 493 { 494 struct 495 { 496 u32 tmem_odd : 15; // tmem line index for odd LODs 497 u32 cache_width : 3; 498 u32 cache_height : 3; 499 }; 500 u32 hex; 501 }; 502 503 union TexImage3 504 { 505 struct 506 { 507 u32 image_base : 24; // address in memory >> 5 (was 20 for GC) 508 }; 509 u32 hex; 510 }; 511 union TexTLUT 512 { 513 struct 514 { 515 u32 tmem_offset : 10; 516 u32 tlut_format : 2; 517 }; 518 u32 hex; 519 }; 520 521 union ZTex1 522 { 523 BitField<0, 24, u32> bias; 524 u32 hex; 525 }; 526 527 union ZTex2 528 { 529 BitField<0, 2, u32> type; // TEV_Z_TYPE_X 530 BitField<2, 2, u32> op; // GXZTexOp 531 u32 hex; 532 }; 533 534 struct FourTexUnits 535 { 536 TexMode0 texMode0[4]; 537 TexMode1 texMode1[4]; 538 TexImage0 texImage0[4]; 539 TexImage1 texImage1[4]; 540 TexImage2 texImage2[4]; 541 TexImage3 texImage3[4]; 542 TexTLUT texTlut[4]; 543 u32 unknown[4]; 544 }; 545 546 // Geometry/other structs 547 548 union GenMode 549 { 550 enum CullMode : u32 551 { 552 CULL_NONE = 0, 553 CULL_BACK = 1, // cull back-facing primitives 554 CULL_FRONT = 2, // cull front-facing primitives 555 CULL_ALL = 3, // cull all primitives 556 }; 557 558 BitField<0, 4, u32> numtexgens; 559 BitField<4, 3, u32> numcolchans; 560 // 1 bit unused? 561 BitField<8, 1, u32> flat_shading; // unconfirmed 562 BitField<9, 1, u32> multisampling; 563 BitField<10, 4, u32> numtevstages; 564 BitField<14, 2, CullMode> cullmode; 565 BitField<16, 3, u32> numindstages; 566 BitField<19, 1, u32> zfreeze; 567 568 u32 hex; 569 }; 570 571 union LPSize 572 { 573 struct 574 { 575 u32 linesize : 8; // in 1/6th pixels 576 u32 pointsize : 8; // in 1/6th pixels 577 u32 lineoff : 3; 578 u32 pointoff : 3; 579 u32 lineaspect : 1; // interlacing: adjust for pixels having AR of 1/2 580 u32 padding : 1; 581 }; 582 u32 hex; 583 }; 584 585 union X12Y12 586 { 587 struct 588 { 589 u32 y : 12; 590 u32 x : 12; 591 }; 592 u32 hex; 593 }; 594 union X10Y10 595 { 596 struct 597 { 598 u32 x : 10; 599 u32 y : 10; 600 }; 601 u32 hex; 602 }; 603 604 // Framebuffer/pixel stuff (incl fog) 605 606 union BlendMode 607 { 608 enum BlendFactor : u32 609 { 610 ZERO = 0, 611 ONE = 1, 612 SRCCLR = 2, // for dst factor 613 INVSRCCLR = 3, // for dst factor 614 DSTCLR = SRCCLR, // for src factor 615 INVDSTCLR = INVSRCCLR, // for src factor 616 SRCALPHA = 4, 617 INVSRCALPHA = 5, 618 DSTALPHA = 6, 619 INVDSTALPHA = 7 620 }; 621 622 enum LogicOp : u32 623 { 624 CLEAR = 0, 625 AND = 1, 626 AND_REVERSE = 2, 627 COPY = 3, 628 AND_INVERTED = 4, 629 NOOP = 5, 630 XOR = 6, 631 OR = 7, 632 NOR = 8, 633 EQUIV = 9, 634 INVERT = 10, 635 OR_REVERSE = 11, 636 COPY_INVERTED = 12, 637 OR_INVERTED = 13, 638 NAND = 14, 639 SET = 15 640 }; 641 642 BitField<0, 1, u32> blendenable; 643 BitField<1, 1, u32> logicopenable; 644 BitField<2, 1, u32> dither; 645 BitField<3, 1, u32> colorupdate; 646 BitField<4, 1, u32> alphaupdate; 647 BitField<5, 3, BlendFactor> dstfactor; 648 BitField<8, 3, BlendFactor> srcfactor; 649 BitField<11, 1, u32> subtract; 650 BitField<12, 4, LogicOp> logicmode; 651 652 u32 hex; 653 654 bool UseLogicOp() const; 655 }; 656 657 union FogParam0 658 { 659 BitField<0, 11, u32> mant; 660 BitField<11, 8, u32> exp; 661 BitField<19, 1, u32> sign; 662 663 u32 hex; 664 }; 665 666 union FogParam3 667 { 668 BitField<0, 11, u32> c_mant; 669 BitField<11, 8, u32> c_exp; 670 BitField<19, 1, u32> c_sign; 671 BitField<20, 1, u32> proj; // 0 - perspective, 1 - orthographic 672 BitField<21, 3, u32> fsel; // 0 - off, 2 - linear, 4 - exp, 5 - exp2, 6 - 673 // backward exp, 7 - backward exp2 674 675 u32 hex; 676 }; 677 678 union FogRangeKElement 679 { 680 BitField<0, 12, u32> HI; 681 BitField<12, 12, u32> LO; 682 BitField<24, 8, u32> regid; 683 684 // TODO: Which scaling coefficient should we use here? This is just a guess! GetValue(int i)685 float GetValue(int i) const { return (i ? HI.Value() : LO.Value()) / 256.f; } 686 u32 HEX; 687 }; 688 689 struct FogRangeParams 690 { 691 union RangeBase 692 { 693 BitField<0, 10, u32> Center; // viewport center + 342 694 BitField<10, 1, u32> Enabled; 695 BitField<24, 8, u32> regid; 696 u32 hex; 697 }; 698 RangeBase Base; 699 FogRangeKElement K[5]; 700 }; 701 // final eq: ze = A/(B_MAG - (Zs>>B_SHF)); 702 struct FogParams 703 { 704 FogParam0 a; 705 u32 b_magnitude; 706 u32 b_shift; // b's exp + 1? 707 FogParam3 c_proj_fsel; 708 709 union FogColor 710 { 711 BitField<0, 8, u32> b; 712 BitField<8, 8, u32> g; 713 BitField<16, 8, u32> r; 714 u32 hex; 715 }; 716 717 FogColor color; // 0:b 8:g 16:r - nice! 718 719 // Special case where a and c are infinite and the sign matches, resulting in a result of NaN. 720 bool IsNaNCase() const; 721 float GetA() const; 722 723 // amount to subtract from eyespacez after range adjustment 724 float GetC() const; 725 }; 726 727 union ZMode 728 { 729 enum CompareMode : u32 730 { 731 NEVER = 0, 732 LESS = 1, 733 EQUAL = 2, 734 LEQUAL = 3, 735 GREATER = 4, 736 NEQUAL = 5, 737 GEQUAL = 6, 738 ALWAYS = 7 739 }; 740 741 BitField<0, 1, u32> testenable; 742 BitField<1, 3, CompareMode> func; 743 BitField<4, 1, u32> updateenable; 744 745 u32 hex; 746 }; 747 748 union ConstantAlpha 749 { 750 BitField<0, 8, u32> alpha; 751 BitField<8, 1, u32> enable; 752 u32 hex; 753 }; 754 755 union FieldMode 756 { 757 struct 758 { 759 u32 texLOD : 1; // adjust vert tex LOD computation to account for interlacing 760 }; 761 u32 hex; 762 }; 763 764 union FieldMask 765 { 766 struct 767 { 768 // If bit is not set, do not write field to EFB 769 u32 odd : 1; 770 u32 even : 1; 771 }; 772 u32 hex; 773 }; 774 775 union PEControl 776 { 777 enum PixelFormat : u32 778 { 779 RGB8_Z24 = 0, 780 RGBA6_Z24 = 1, 781 RGB565_Z16 = 2, 782 Z24 = 3, 783 Y8 = 4, 784 U8 = 5, 785 V8 = 6, 786 YUV420 = 7, 787 INVALID_FMT = 0xffffffff, // Used by Dolphin to represent a missing value. 788 }; 789 790 enum DepthFormat : u32 791 { 792 ZLINEAR = 0, 793 ZNEAR = 1, 794 ZMID = 2, 795 ZFAR = 3, 796 797 // It seems these Z formats aren't supported/were removed ? 798 ZINV_LINEAR = 4, 799 ZINV_NEAR = 5, 800 ZINV_MID = 6, 801 ZINV_FAR = 7 802 }; 803 804 BitField<0, 3, PixelFormat> pixel_format; 805 BitField<3, 3, DepthFormat> zformat; 806 BitField<6, 1, u32> early_ztest; 807 808 u32 hex; 809 }; 810 811 // Texture coordinate stuff 812 813 union TCInfo 814 { 815 struct 816 { 817 u32 scale_minus_1 : 16; 818 u32 range_bias : 1; 819 u32 cylindric_wrap : 1; 820 // These bits only have effect in the s field of TCoordInfo 821 u32 line_offset : 1; 822 u32 point_offset : 1; 823 }; 824 u32 hex; 825 }; 826 struct TCoordInfo 827 { 828 TCInfo s; 829 TCInfo t; 830 }; 831 832 union TevReg 833 { 834 u64 hex; 835 836 // Access to individual registers 837 BitField<0, 32, u64> low; 838 BitField<32, 32, u64> high; 839 840 // TODO: Check if Konst uses all 11 bits or just 8 841 842 // Low register 843 BitField<0, 11, s64> red; 844 845 BitField<12, 11, s64> alpha; 846 BitField<23, 1, u64> type_ra; 847 848 // High register 849 BitField<32, 11, s64> blue; 850 851 BitField<44, 11, s64> green; 852 BitField<55, 1, u64> type_bg; 853 }; 854 855 union TevKSel 856 { 857 BitField<0, 2, u32> swap1; 858 BitField<2, 2, u32> swap2; 859 BitField<4, 5, u32> kcsel0; 860 BitField<9, 5, u32> kasel0; 861 BitField<14, 5, u32> kcsel1; 862 BitField<19, 5, u32> kasel1; 863 u32 hex; 864 getKC(int i)865 u32 getKC(int i) const { return i ? kcsel1.Value() : kcsel0.Value(); } getKA(int i)866 u32 getKA(int i) const { return i ? kasel1.Value() : kasel0.Value(); } 867 }; 868 869 union AlphaTest 870 { 871 enum CompareMode : u32 872 { 873 NEVER = 0, 874 LESS = 1, 875 EQUAL = 2, 876 LEQUAL = 3, 877 GREATER = 4, 878 NEQUAL = 5, 879 GEQUAL = 6, 880 ALWAYS = 7 881 }; 882 883 enum Op : u32 884 { 885 AND = 0, 886 OR = 1, 887 XOR = 2, 888 XNOR = 3 889 }; 890 891 BitField<0, 8, u32> ref0; 892 BitField<8, 8, u32> ref1; 893 BitField<16, 3, CompareMode> comp0; 894 BitField<19, 3, CompareMode> comp1; 895 BitField<22, 2, Op> logic; 896 897 u32 hex; 898 899 enum TEST_RESULT 900 { 901 UNDETERMINED = 0, 902 FAIL = 1, 903 PASS = 2, 904 }; 905 TestResult()906 DOLPHIN_FORCE_INLINE TEST_RESULT TestResult() const 907 { 908 switch (logic) 909 { 910 case AND: 911 if (comp0 == ALWAYS && comp1 == ALWAYS) 912 return PASS; 913 if (comp0 == NEVER || comp1 == NEVER) 914 return FAIL; 915 break; 916 917 case OR: 918 if (comp0 == ALWAYS || comp1 == ALWAYS) 919 return PASS; 920 if (comp0 == NEVER && comp1 == NEVER) 921 return FAIL; 922 break; 923 924 case XOR: 925 if ((comp0 == ALWAYS && comp1 == NEVER) || (comp0 == NEVER && comp1 == ALWAYS)) 926 return PASS; 927 if ((comp0 == ALWAYS && comp1 == ALWAYS) || (comp0 == NEVER && comp1 == NEVER)) 928 return FAIL; 929 break; 930 931 case XNOR: 932 if ((comp0 == ALWAYS && comp1 == NEVER) || (comp0 == NEVER && comp1 == ALWAYS)) 933 return FAIL; 934 if ((comp0 == ALWAYS && comp1 == ALWAYS) || (comp0 == NEVER && comp1 == NEVER)) 935 return PASS; 936 break; 937 938 default: 939 return UNDETERMINED; 940 } 941 return UNDETERMINED; 942 } 943 }; 944 945 union UPE_Copy 946 { 947 u32 Hex; 948 949 BitField<0, 1, u32> clamp_top; // if set clamp top 950 BitField<1, 1, u32> clamp_bottom; // if set clamp bottom 951 BitField<2, 1, u32> yuv; // if set, color conversion from RGB to YUV 952 BitField<3, 4, u32> target_pixel_format; // realformat is (fmt/2)+((fmt&1)*8).... for some reason 953 // the msb is the lsb (pattern: cycling right shift) 954 BitField<7, 2, u32> gamma; // gamma correction.. 0 = 1.0 ; 1 = 1.7 ; 2 = 2.2 ; 3 is reserved 955 BitField<9, 1, u32> 956 half_scale; // "mipmap" filter... 0 = no filter (scale 1:1) ; 1 = box filter (scale 2:1) 957 BitField<10, 1, u32> scale_invert; // if set vertical scaling is on 958 BitField<11, 1, u32> clear; 959 BitField<12, 2, u32> frame_to_field; // 0 progressive ; 1 is reserved ; 2 = interlaced (even 960 // lines) ; 3 = interlaced 1 (odd lines) 961 BitField<14, 1, u32> copy_to_xfb; 962 BitField<15, 1, u32> intensity_fmt; // if set, is an intensity format (I4,I8,IA4,IA8) 963 BitField<16, 1, u32> 964 auto_conv; // if 0 automatic color conversion by texture format and pixel type 965 tp_realFormat()966 EFBCopyFormat tp_realFormat() const 967 { 968 return static_cast<EFBCopyFormat>(target_pixel_format / 2 + (target_pixel_format & 1) * 8); 969 } 970 }; 971 972 union CopyFilterCoefficients 973 { 974 using Values = std::array<u8, 7>; 975 976 u64 Hex; 977 978 BitField<0, 6, u64> w0; 979 BitField<6, 6, u64> w1; 980 BitField<12, 6, u64> w2; 981 BitField<18, 6, u64> w3; 982 BitField<32, 6, u64> w4; 983 BitField<38, 6, u64> w5; 984 BitField<44, 6, u64> w6; 985 GetCoefficients()986 Values GetCoefficients() const 987 { 988 return {{ 989 static_cast<u8>(w0), 990 static_cast<u8>(w1), 991 static_cast<u8>(w2), 992 static_cast<u8>(w3), 993 static_cast<u8>(w4), 994 static_cast<u8>(w5), 995 static_cast<u8>(w6), 996 }}; 997 } 998 }; 999 1000 union BPU_PreloadTileInfo 1001 { 1002 u32 hex; 1003 struct 1004 { 1005 u32 count : 15; 1006 u32 type : 2; 1007 }; 1008 }; 1009 1010 struct BPS_TmemConfig 1011 { 1012 u32 preload_addr; 1013 u32 preload_tmem_even; 1014 u32 preload_tmem_odd; 1015 BPU_PreloadTileInfo preload_tile_info; 1016 u32 tlut_src; 1017 u32 tlut_dest; 1018 u32 texinvalidate; 1019 }; 1020 1021 // All of BP memory 1022 1023 struct BPCmd 1024 { 1025 int address; 1026 int changes; 1027 int newvalue; 1028 }; 1029 1030 struct BPMemory 1031 { 1032 GenMode genMode; 1033 u32 display_copy_filter[4]; // 01-04 1034 u32 unknown; // 05 1035 // indirect matrices (set by GXSetIndTexMtx, selected by TevStageIndirect::mid) 1036 // abc form a 2x3 offset matrix, there's 3 such matrices 1037 // the 3 offset matrices can either be indirect type, S-type, or T-type 1038 // 6bit scale factor s is distributed across IND_MTXA/B/C. 1039 // before using matrices scale by 2^-(s-17) 1040 IND_MTX indmtx[3]; // 06-0e GXSetIndTexMtx, 2x3 matrices 1041 IND_IMASK imask; // 0f 1042 TevStageIndirect tevind[16]; // 10 GXSetTevIndirect 1043 X12Y12 scissorTL; // 20 1044 X12Y12 scissorBR; // 21 1045 LPSize lineptwidth; // 22 line and point width 1046 u32 sucounter; // 23 1047 u32 rascounter; // 24 1048 TEXSCALE texscale[2]; // 25-26 GXSetIndTexCoordScale 1049 RAS1_IREF tevindref; // 27 GXSetIndTexOrder 1050 TwoTevStageOrders tevorders[8]; // 28-2F 1051 TCoordInfo texcoords[8]; // 0x30 s,t,s,t,s,t,s,t... 1052 ZMode zmode; // 40 1053 BlendMode blendmode; // 41 1054 ConstantAlpha dstalpha; // 42 1055 PEControl zcontrol; // 43 GXSetZCompLoc, GXPixModeSync 1056 FieldMask fieldmask; // 44 1057 u32 drawdone; // 45, bit1=1 if end of list 1058 u32 unknown5; // 46 clock? 1059 u32 petoken; // 47 1060 u32 petokenint; // 48 1061 X10Y10 copyTexSrcXY; // 49 1062 X10Y10 copyTexSrcWH; // 4a 1063 u32 copyTexDest; // 4b// 4b == CopyAddress (GXDispCopy and GXTexCopy use it) 1064 u32 unknown6; // 4c 1065 u32 copyMipMapStrideChannels; // 4d usually set to 4 when dest is single channel, 8 when dest is 1066 // 2 channel, 16 when dest is RGBA 1067 // also, doubles whenever mipmap box filter option is set (excent on RGBA). Probably to do with 1068 // number of bytes to look at when smoothing 1069 u32 dispcopyyscale; // 4e 1070 u32 clearcolorAR; // 4f 1071 u32 clearcolorGB; // 50 1072 u32 clearZValue; // 51 1073 UPE_Copy triggerEFBCopy; // 52 1074 CopyFilterCoefficients copyfilter; // 53,54 1075 u32 boundbox0; // 55 1076 u32 boundbox1; // 56 1077 u32 unknown7[2]; // 57,58 1078 X10Y10 scissorOffset; // 59 1079 u32 unknown8[6]; // 5a,5b,5c,5d, 5e,5f 1080 BPS_TmemConfig tmem_config; // 60-66 1081 u32 metric; // 67 1082 FieldMode fieldmode; // 68 1083 u32 unknown10[7]; // 69-6F 1084 u32 unknown11[16]; // 70-7F 1085 FourTexUnits tex[2]; // 80-bf 1086 TevStageCombiner combiners[16]; // 0xC0-0xDF 1087 TevReg tevregs[4]; // 0xE0 1088 FogRangeParams fogRange; // 0xE8 1089 FogParams fog; // 0xEE,0xEF,0xF0,0xF1,0xF2 1090 AlphaTest alpha_test; // 0xF3 1091 ZTex1 ztex1; // 0xf4,0xf5 1092 ZTex2 ztex2; 1093 TevKSel tevksel[8]; // 0xf6,0xf7,f8,f9,fa,fb,fc,fd 1094 u32 bpMask; // 0xFE 1095 u32 unknown18; // ff 1096 UseEarlyDepthTestBPMemory1097 bool UseEarlyDepthTest() const { return zcontrol.early_ztest && zmode.testenable; } UseLateDepthTestBPMemory1098 bool UseLateDepthTest() const { return !zcontrol.early_ztest && zmode.testenable; } 1099 }; 1100 1101 #pragma pack() 1102 1103 extern BPMemory bpmem; 1104 1105 void LoadBPReg(u32 value0); 1106 void LoadBPRegPreprocess(u32 value0); 1107 1108 void GetBPRegInfo(const u8* data, std::string* name, std::string* desc); 1109