DOSBox-X
|
00001 /***************************************************************************/ 00002 /* Portion of this software comes with the following license: */ 00003 /***************************************************************************/ 00004 /* 00005 00006 Copyright Aaron Giles 00007 All rights reserved. 00008 00009 Redistribution and use in source and binary forms, with or without 00010 modification, are permitted provided that the following conditions are 00011 met: 00012 00013 * Redistributions of source code must retain the above copyright 00014 notice, this list of conditions and the following disclaimer. 00015 * Redistributions in binary form must reproduce the above copyright 00016 notice, this list of conditions and the following disclaimer in 00017 the documentation and/or other materials provided with the 00018 distribution. 00019 * Neither the name 'MAME' nor the names of its contributors may be 00020 used to endorse or promote products derived from this software 00021 without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR 00024 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00025 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00026 DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, 00027 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00028 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00029 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 00031 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00032 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00033 POSSIBILITY OF SUCH DAMAGE. 00034 00035 ***************************************************************************/ 00036 00037 /************************************************************************* 00038 00039 3dfx Voodoo Graphics SST-1/2 emulator 00040 00041 emulator by Aaron Giles 00042 00043 **************************************************************************/ 00044 00045 00046 #ifndef DOSBOX_VOODOO_DATA_H 00047 #define DOSBOX_VOODOO_DATA_H 00048 00049 00050 /************************************* 00051 * 00052 * Misc. constants 00053 * 00054 *************************************/ 00055 00056 /* enumeration specifying which model of Voodoo we are emulating */ 00057 enum 00058 { 00059 VOODOO_1, 00060 VOODOO_1_DTMU, 00061 VOODOO_2, 00062 MAX_VOODOO_TYPES 00063 }; 00064 00065 00066 /* maximum number of TMUs */ 00067 #define MAX_TMU 2 00068 00069 /* maximum number of rasterizers */ 00070 #define MAX_RASTERIZERS 1024 00071 00072 /* size of the rasterizer hash table */ 00073 #define RASTER_HASH_SIZE 97 00074 00075 /* flags for LFB writes */ 00076 #define LFB_RGB_PRESENT 1 00077 #define LFB_ALPHA_PRESENT 2 00078 #define LFB_DEPTH_PRESENT 4 00079 #define LFB_DEPTH_PRESENT_MSW 8 00080 00081 /* flags for the register access array */ 00082 #define REGISTER_READ 0x01 /* reads are allowed */ 00083 #define REGISTER_WRITE 0x02 /* writes are allowed */ 00084 #define REGISTER_PIPELINED 0x04 /* writes are pipelined */ 00085 #define REGISTER_FIFO 0x08 /* writes go to FIFO */ 00086 #define REGISTER_WRITETHRU 0x10 /* writes are valid even for CMDFIFO */ 00087 00088 /* shorter combinations to make the table smaller */ 00089 #define REG_R (REGISTER_READ) 00090 #define REG_W (REGISTER_WRITE) 00091 #define REG_WT (REGISTER_WRITE | REGISTER_WRITETHRU) 00092 #define REG_RW (REGISTER_READ | REGISTER_WRITE) 00093 #define REG_RWT (REGISTER_READ | REGISTER_WRITE | REGISTER_WRITETHRU) 00094 #define REG_RP (REGISTER_READ | REGISTER_PIPELINED) 00095 #define REG_WP (REGISTER_WRITE | REGISTER_PIPELINED) 00096 #define REG_RWP (REGISTER_READ | REGISTER_WRITE | REGISTER_PIPELINED) 00097 #define REG_RWPT (REGISTER_READ | REGISTER_WRITE | REGISTER_PIPELINED | REGISTER_WRITETHRU) 00098 #define REG_RF (REGISTER_READ | REGISTER_FIFO) 00099 #define REG_WF (REGISTER_WRITE | REGISTER_FIFO) 00100 #define REG_RWF (REGISTER_READ | REGISTER_WRITE | REGISTER_FIFO) 00101 #define REG_RPF (REGISTER_READ | REGISTER_PIPELINED | REGISTER_FIFO) 00102 #define REG_WPF (REGISTER_WRITE | REGISTER_PIPELINED | REGISTER_FIFO) 00103 #define REG_RWPF (REGISTER_READ | REGISTER_WRITE | REGISTER_PIPELINED | REGISTER_FIFO) 00104 00105 /* lookup bits is the log2 of the size of the reciprocal/log table */ 00106 #define RECIPLOG_LOOKUP_BITS 9 00107 00108 /* input precision is how many fraction bits the input value has; this is a 64-bit number */ 00109 #define RECIPLOG_INPUT_PREC 32 00110 00111 /* lookup precision is how many fraction bits each table entry contains */ 00112 #define RECIPLOG_LOOKUP_PREC 22 00113 00114 /* output precision is how many fraction bits the result should have */ 00115 #define RECIP_OUTPUT_PREC 15 00116 #define LOG_OUTPUT_PREC 8 00117 00118 00119 00120 /************************************* 00121 * 00122 * Dithering tables 00123 * 00124 *************************************/ 00125 00126 static const UINT8 dither_matrix_4x4[16] = 00127 { 00128 0, 8, 2, 10, 00129 12, 4, 14, 6, 00130 3, 11, 1, 9, 00131 15, 7, 13, 5 00132 }; 00133 00134 static const UINT8 dither_matrix_2x2[16] = 00135 { 00136 2, 10, 2, 10, 00137 14, 6, 14, 6, 00138 2, 10, 2, 10, 00139 14, 6, 14, 6 00140 }; 00141 00142 00143 00144 /************************************* 00145 * 00146 * Macros for extracting pixels 00147 * 00148 *************************************/ 00149 00150 #define EXTRACT_565_TO_888(val, a, b, c) \ 00151 (a) = (int)((((unsigned int)(val) >> 8u) & 0xf8u) | (((unsigned int)(val) >> 13u) & 0x07u)); \ 00152 (b) = (int)((((unsigned int)(val) >> 3u) & 0xfcu) | (((unsigned int)(val) >> 9u) & 0x03u)); \ 00153 (c) = (int)((((unsigned int)(val) << 3u) & 0xf8u) | (((unsigned int)(val) >> 2u) & 0x07u)); \ 00154 00155 #define EXTRACT_x555_TO_888(val, a, b, c) \ 00156 (a) = (int)((((unsigned int)(val) >> 7u) & 0xf8u) | (((unsigned int)(val) >> 12u) & 0x07u)); \ 00157 (b) = (int)((((unsigned int)(val) >> 2u) & 0xf8u) | (((unsigned int)(val) >> 7u) & 0x07u)); \ 00158 (c) = (int)((((unsigned int)(val) << 3u) & 0xf8u) | (((unsigned int)(val) >> 2u) & 0x07u)); \ 00159 00160 #define EXTRACT_555x_TO_888(val, a, b, c) \ 00161 (a) = (int)((((unsigned int)(val) >> 8u) & 0xf8u) | (((unsigned int)(val) >> 13u) & 0x07u)); \ 00162 (b) = (int)((((unsigned int)(val) >> 3u) & 0xf8u) | (((unsigned int)(val) >> 8u) & 0x07u)); \ 00163 (c) = (int)((((unsigned int)(val) << 2u) & 0xf8u) | (((unsigned int)(val) >> 3u) & 0x07u)); \ 00164 00165 #define EXTRACT_1555_TO_8888(val, a, b, c, d) \ 00166 (a) = ((INT16)(val) >> 15) & 0xff; \ 00167 EXTRACT_x555_TO_888(val, b, c, d) \ 00168 00169 #define EXTRACT_5551_TO_8888(val, a, b, c, d) \ 00170 EXTRACT_555x_TO_888(val, a, b, c) \ 00171 (d) = (int)(((unsigned int)(val) & 0x0001u) ? 0xffu : 0x00u); \ 00172 00173 #define EXTRACT_x888_TO_888(val, a, b, c) \ 00174 (a) = (int)(((unsigned int)(val) >> 16u) & 0xffu); \ 00175 (b) = (int)(((unsigned int)(val) >> 8u) & 0xffu); \ 00176 (c) = (int)(((unsigned int)(val) >> 0u) & 0xffu); \ 00177 00178 #define EXTRACT_888x_TO_888(val, a, b, c) \ 00179 (a) = (int)(((unsigned int)(val) >> 24u) & 0xffu); \ 00180 (b) = (int)(((unsigned int)(val) >> 16u) & 0xffu); \ 00181 (c) = (int)(((unsigned int)(val) >> 8u) & 0xffu); \ 00182 00183 #define EXTRACT_8888_TO_8888(val, a, b, c, d) \ 00184 (a) = (int)(((unsigned int)(val) >> 24u) & 0xffu); \ 00185 (b) = (int)(((unsigned int)(val) >> 16u) & 0xffu); \ 00186 (c) = (int)(((unsigned int)(val) >> 8u) & 0xffu); \ 00187 (d) = (int)(((unsigned int)(val) >> 0u) & 0xffu); \ 00188 00189 #define EXTRACT_4444_TO_8888(val, a, b, c, d) \ 00190 (a) = (int)((((unsigned int)(val) >> 8u) & 0xf0u) | (((unsigned int)(val) >> 12u) & 0x0fu)); \ 00191 (b) = (int)((((unsigned int)(val) >> 4u) & 0xf0u) | (((unsigned int)(val) >> 8u) & 0x0fu)); \ 00192 (c) = (int)((((unsigned int)(val) >> 0u) & 0xf0u) | (((unsigned int)(val) >> 4u) & 0x0fu)); \ 00193 (d) = (int)((((unsigned int)(val) << 4u) & 0xf0u) | (((unsigned int)(val) >> 0u) & 0x0fu)); \ 00194 00195 #define EXTRACT_332_TO_888(val, a, b, c) \ 00196 (a) = (int)((((unsigned int)(val) >> 0u) & 0xe0u) | (((unsigned int)(val) >> 3u) & 0x1cu) | (((unsigned int)(val) >> 6u) & 0x03u)); \ 00197 (b) = (int)((((unsigned int)(val) << 3u) & 0xe0u) | (((unsigned int)(val) >> 0u) & 0x1cu) | (((unsigned int)(val) >> 3u) & 0x03u)); \ 00198 (c) = (int)((((unsigned int)(val) << 6u) & 0xc0u) | (((unsigned int)(val) << 4u) & 0x30u) | (((unsigned int)(val) << 2u) & 0x0cu) | (((unsigned int)(val) << 0u) & 0x03u)); \ 00199 00200 00201 00202 /************************************* 00203 * 00204 * Misc. macros 00205 * 00206 *************************************/ 00207 00208 /* macro for clamping a value between minimum and maximum values */ 00209 #define CLAMP(val,min,max) do { if ((val) < (min)) { (val) = (min); } else if ((val) > (max)) { (val) = (max); } } while (0) 00210 00211 /* macro to compute the base 2 log for LOD calculations */ 00212 #define LOGB2(x) (log((double)(x)) / log(2.0)) 00213 00214 00215 00216 /************************************* 00217 * 00218 * Macros for extracting bitfields 00219 * 00220 *************************************/ 00221 00222 #define INITEN_ENABLE_HW_INIT(val) (((val) >> 0) & 1) 00223 #define INITEN_ENABLE_PCI_FIFO(val) (((val) >> 1) & 1) 00224 #define INITEN_REMAP_INIT_TO_DAC(val) (((val) >> 2) & 1) 00225 #define INITEN_ENABLE_SNOOP0(val) (((val) >> 4) & 1) 00226 #define INITEN_SNOOP0_MEMORY_MATCH(val) (((val) >> 5) & 1) 00227 #define INITEN_SNOOP0_READWRITE_MATCH(val) (((val) >> 6) & 1) 00228 #define INITEN_ENABLE_SNOOP1(val) (((val) >> 7) & 1) 00229 #define INITEN_SNOOP1_MEMORY_MATCH(val) (((val) >> 8) & 1) 00230 #define INITEN_SNOOP1_READWRITE_MATCH(val) (((val) >> 9) & 1) 00231 #define INITEN_SLI_BUS_OWNER(val) (((val) >> 10) & 1) 00232 #define INITEN_SLI_ODD_EVEN(val) (((val) >> 11) & 1) 00233 #define INITEN_SECONDARY_REV_ID(val) (((val) >> 12) & 0xf) /* voodoo 2 only */ 00234 #define INITEN_MFCTR_FAB_ID(val) (((val) >> 16) & 0xf) /* voodoo 2 only */ 00235 #define INITEN_ENABLE_PCI_INTERRUPT(val) (((val) >> 20) & 1) /* voodoo 2 only */ 00236 #define INITEN_PCI_INTERRUPT_TIMEOUT(val) (((val) >> 21) & 1) /* voodoo 2 only */ 00237 #define INITEN_ENABLE_NAND_TREE_TEST(val) (((val) >> 22) & 1) /* voodoo 2 only */ 00238 #define INITEN_ENABLE_SLI_ADDRESS_SNOOP(val) (((val) >> 23) & 1) /* voodoo 2 only */ 00239 #define INITEN_SLI_SNOOP_ADDRESS(val) (((val) >> 24) & 0xff) /* voodoo 2 only */ 00240 00241 #define FBZCP_CC_RGBSELECT(val) (((val) >> 0) & 3) 00242 #define FBZCP_CC_ASELECT(val) (((val) >> 2) & 3) 00243 #define FBZCP_CC_LOCALSELECT(val) (((val) >> 4) & 1) 00244 #define FBZCP_CCA_LOCALSELECT(val) (((val) >> 5) & 3) 00245 #define FBZCP_CC_LOCALSELECT_OVERRIDE(val) (((val) >> 7) & 1) 00246 #define FBZCP_CC_ZERO_OTHER(val) (((val) >> 8) & 1) 00247 #define FBZCP_CC_SUB_CLOCAL(val) (((val) >> 9) & 1) 00248 #define FBZCP_CC_MSELECT(val) (((val) >> 10) & 7) 00249 #define FBZCP_CC_REVERSE_BLEND(val) (((val) >> 13) & 1) 00250 #define FBZCP_CC_ADD_ACLOCAL(val) (((val) >> 14) & 3) 00251 #define FBZCP_CC_INVERT_OUTPUT(val) (((val) >> 16) & 1) 00252 #define FBZCP_CCA_ZERO_OTHER(val) (((val) >> 17) & 1) 00253 #define FBZCP_CCA_SUB_CLOCAL(val) (((val) >> 18) & 1) 00254 #define FBZCP_CCA_MSELECT(val) (((val) >> 19) & 7) 00255 #define FBZCP_CCA_REVERSE_BLEND(val) (((val) >> 22) & 1) 00256 #define FBZCP_CCA_ADD_ACLOCAL(val) (((val) >> 23) & 3) 00257 #define FBZCP_CCA_INVERT_OUTPUT(val) (((val) >> 25) & 1) 00258 #define FBZCP_CCA_SUBPIXEL_ADJUST(val) (((val) >> 26) & 1) 00259 #define FBZCP_TEXTURE_ENABLE(val) (((val) >> 27) & 1) 00260 #define FBZCP_RGBZW_CLAMP(val) (((val) >> 28) & 1) /* voodoo 2 only */ 00261 #define FBZCP_ANTI_ALIAS(val) (((val) >> 29) & 1) /* voodoo 2 only */ 00262 00263 #define ALPHAMODE_ALPHATEST(val) (((val) >> 0) & 1) 00264 #define ALPHAMODE_ALPHAFUNCTION(val) (((val) >> 1) & 7) 00265 #define ALPHAMODE_ALPHABLEND(val) (((val) >> 4) & 1) 00266 #define ALPHAMODE_ANTIALIAS(val) (((val) >> 5) & 1) 00267 #define ALPHAMODE_SRCRGBBLEND(val) (((val) >> 8) & 15) 00268 #define ALPHAMODE_DSTRGBBLEND(val) (((val) >> 12) & 15) 00269 #define ALPHAMODE_SRCALPHABLEND(val) (((val) >> 16) & 15) 00270 #define ALPHAMODE_DSTALPHABLEND(val) (((val) >> 20) & 15) 00271 #define ALPHAMODE_ALPHAREF(val) (((val) >> 24) & 0xff) 00272 00273 #define FOGMODE_ENABLE_FOG(val) (((val) >> 0) & 1) 00274 #define FOGMODE_FOG_ADD(val) (((val) >> 1) & 1) 00275 #define FOGMODE_FOG_MULT(val) (((val) >> 2) & 1) 00276 #define FOGMODE_FOG_ZALPHA(val) (((val) >> 3) & 3) 00277 #define FOGMODE_FOG_CONSTANT(val) (((val) >> 5) & 1) 00278 #define FOGMODE_FOG_DITHER(val) (((val) >> 6) & 1) /* voodoo 2 only */ 00279 #define FOGMODE_FOG_ZONES(val) (((val) >> 7) & 1) /* voodoo 2 only */ 00280 00281 #define FBZMODE_ENABLE_CLIPPING(val) (((val) >> 0) & 1) 00282 #define FBZMODE_ENABLE_CHROMAKEY(val) (((val) >> 1) & 1) 00283 #define FBZMODE_ENABLE_STIPPLE(val) (((val) >> 2) & 1) 00284 #define FBZMODE_WBUFFER_SELECT(val) (((val) >> 3) & 1) 00285 #define FBZMODE_ENABLE_DEPTHBUF(val) (((val) >> 4) & 1) 00286 #define FBZMODE_DEPTH_FUNCTION(val) (((val) >> 5) & 7) 00287 #define FBZMODE_ENABLE_DITHERING(val) (((val) >> 8) & 1) 00288 #define FBZMODE_RGB_BUFFER_MASK(val) (((val) >> 9) & 1) 00289 #define FBZMODE_AUX_BUFFER_MASK(val) (((val) >> 10) & 1) 00290 #define FBZMODE_DITHER_TYPE(val) (((val) >> 11) & 1) 00291 #define FBZMODE_STIPPLE_PATTERN(val) (((val) >> 12) & 1) 00292 #define FBZMODE_ENABLE_ALPHA_MASK(val) (((val) >> 13) & 1) 00293 #define FBZMODE_DRAW_BUFFER(val) (((val) >> 14) & 3) 00294 #define FBZMODE_ENABLE_DEPTH_BIAS(val) (((val) >> 16) & 1) 00295 #define FBZMODE_Y_ORIGIN(val) (((val) >> 17) & 1) 00296 #define FBZMODE_ENABLE_ALPHA_PLANES(val) (((val) >> 18) & 1) 00297 #define FBZMODE_ALPHA_DITHER_SUBTRACT(val) (((val) >> 19) & 1) 00298 #define FBZMODE_DEPTH_SOURCE_COMPARE(val) (((val) >> 20) & 1) 00299 #define FBZMODE_DEPTH_FLOAT_SELECT(val) (((val) >> 21) & 1) /* voodoo 2 only */ 00300 00301 #define LFBMODE_WRITE_FORMAT(val) (((val) >> 0) & 0xf) 00302 #define LFBMODE_WRITE_BUFFER_SELECT(val) (((val) >> 4) & 3) 00303 #define LFBMODE_READ_BUFFER_SELECT(val) (((val) >> 6) & 3) 00304 #define LFBMODE_ENABLE_PIXEL_PIPELINE(val) (((val) >> 8) & 1) 00305 #define LFBMODE_RGBA_LANES(val) (((val) >> 9) & 3) 00306 #define LFBMODE_WORD_SWAP_WRITES(val) (((val) >> 11) & 1) 00307 #define LFBMODE_BYTE_SWIZZLE_WRITES(val) (((val) >> 12) & 1) 00308 #define LFBMODE_Y_ORIGIN(val) (((val) >> 13) & 1) 00309 #define LFBMODE_WRITE_W_SELECT(val) (((val) >> 14) & 1) 00310 #define LFBMODE_WORD_SWAP_READS(val) (((val) >> 15) & 1) 00311 #define LFBMODE_BYTE_SWIZZLE_READS(val) (((val) >> 16) & 1) 00312 00313 #define CHROMARANGE_BLUE_EXCLUSIVE(val) (((val) >> 24) & 1) 00314 #define CHROMARANGE_GREEN_EXCLUSIVE(val) (((val) >> 25) & 1) 00315 #define CHROMARANGE_RED_EXCLUSIVE(val) (((val) >> 26) & 1) 00316 #define CHROMARANGE_UNION_MODE(val) (((val) >> 27) & 1) 00317 #define CHROMARANGE_ENABLE(val) (((val) >> 28) & 1) 00318 00319 #define FBIINIT0_VGA_PASSTHRU(val) (((val) >> 0) & 1) 00320 #define FBIINIT0_GRAPHICS_RESET(val) (((val) >> 1) & 1) 00321 #define FBIINIT0_FIFO_RESET(val) (((val) >> 2) & 1) 00322 #define FBIINIT0_SWIZZLE_REG_WRITES(val) (((val) >> 3) & 1) 00323 #define FBIINIT0_STALL_PCIE_FOR_HWM(val) (((val) >> 4) & 1) 00324 #define FBIINIT0_PCI_FIFO_LWM(val) (((val) >> 6) & 0x1f) 00325 #define FBIINIT0_LFB_TO_MEMORY_FIFO(val) (((val) >> 11) & 1) 00326 #define FBIINIT0_TEXMEM_TO_MEMORY_FIFO(val) (((val) >> 12) & 1) 00327 #define FBIINIT0_ENABLE_MEMORY_FIFO(val) (((val) >> 13) & 1) 00328 #define FBIINIT0_MEMORY_FIFO_HWM(val) (((val) >> 14) & 0x7ff) 00329 #define FBIINIT0_MEMORY_FIFO_BURST(val) (((val) >> 25) & 0x3f) 00330 00331 #define FBIINIT1_PCI_DEV_FUNCTION(val) (((val) >> 0) & 1) 00332 #define FBIINIT1_PCI_WRITE_WAIT_STATES(val) (((val) >> 1) & 1) 00333 #define FBIINIT1_MULTI_SST1(val) (((val) >> 2) & 1) /* not on voodoo 2 */ 00334 #define FBIINIT1_ENABLE_LFB(val) (((val) >> 3) & 1) 00335 #define FBIINIT1_X_VIDEO_TILES(val) (((val) >> 4) & 0xf) 00336 #define FBIINIT1_VIDEO_TIMING_RESET(val) (((val) >> 8) & 1) 00337 #define FBIINIT1_SOFTWARE_OVERRIDE(val) (((val) >> 9) & 1) 00338 #define FBIINIT1_SOFTWARE_HSYNC(val) (((val) >> 10) & 1) 00339 #define FBIINIT1_SOFTWARE_VSYNC(val) (((val) >> 11) & 1) 00340 #define FBIINIT1_SOFTWARE_BLANK(val) (((val) >> 12) & 1) 00341 #define FBIINIT1_DRIVE_VIDEO_TIMING(val) (((val) >> 13) & 1) 00342 #define FBIINIT1_DRIVE_VIDEO_BLANK(val) (((val) >> 14) & 1) 00343 #define FBIINIT1_DRIVE_VIDEO_SYNC(val) (((val) >> 15) & 1) 00344 #define FBIINIT1_DRIVE_VIDEO_DCLK(val) (((val) >> 16) & 1) 00345 #define FBIINIT1_VIDEO_TIMING_VCLK(val) (((val) >> 17) & 1) 00346 #define FBIINIT1_VIDEO_CLK_2X_DELAY(val) (((val) >> 18) & 3) 00347 #define FBIINIT1_VIDEO_TIMING_SOURCE(val) (((val) >> 20) & 3) 00348 #define FBIINIT1_ENABLE_24BPP_OUTPUT(val) (((val) >> 22) & 1) 00349 #define FBIINIT1_ENABLE_SLI(val) (((val) >> 23) & 1) 00350 #define FBIINIT1_X_VIDEO_TILES_BIT5(val) (((val) >> 24) & 1) /* voodoo 2 only */ 00351 #define FBIINIT1_ENABLE_EDGE_FILTER(val) (((val) >> 25) & 1) 00352 #define FBIINIT1_INVERT_VID_CLK_2X(val) (((val) >> 26) & 1) 00353 #define FBIINIT1_VID_CLK_2X_SEL_DELAY(val) (((val) >> 27) & 3) 00354 #define FBIINIT1_VID_CLK_DELAY(val) (((val) >> 29) & 3) 00355 #define FBIINIT1_DISABLE_FAST_READAHEAD(val) (((val) >> 31) & 1) 00356 00357 #define FBIINIT2_DISABLE_DITHER_SUB(val) (((val) >> 0) & 1) 00358 #define FBIINIT2_DRAM_BANKING(val) (((val) >> 1) & 1) 00359 #define FBIINIT2_ENABLE_TRIPLE_BUF(val) (((val) >> 4) & 1) 00360 #define FBIINIT2_ENABLE_FAST_RAS_READ(val) (((val) >> 5) & 1) 00361 #define FBIINIT2_ENABLE_GEN_DRAM_OE(val) (((val) >> 6) & 1) 00362 #define FBIINIT2_ENABLE_FAST_READWRITE(val) (((val) >> 7) & 1) 00363 #define FBIINIT2_ENABLE_PASSTHRU_DITHER(val) (((val) >> 8) & 1) 00364 #define FBIINIT2_SWAP_BUFFER_ALGORITHM(val) (((val) >> 9) & 3) 00365 #define FBIINIT2_VIDEO_BUFFER_OFFSET(val) (((val) >> 11) & 0x1ff) 00366 #define FBIINIT2_ENABLE_DRAM_BANKING(val) (((val) >> 20) & 1) 00367 #define FBIINIT2_ENABLE_DRAM_READ_FIFO(val) (((val) >> 21) & 1) 00368 #define FBIINIT2_ENABLE_DRAM_REFRESH(val) (((val) >> 22) & 1) 00369 #define FBIINIT2_REFRESH_LOAD_VALUE(val) (((val) >> 23) & 0x1ff) 00370 00371 #define FBIINIT3_TRI_REGISTER_REMAP(val) (((val) >> 0) & 1) 00372 #define FBIINIT3_VIDEO_FIFO_THRESH(val) (((val) >> 1) & 0x1f) 00373 #define FBIINIT3_DISABLE_TMUS(val) (((val) >> 6) & 1) 00374 #define FBIINIT3_FBI_MEMORY_TYPE(val) (((val) >> 8) & 7) 00375 #define FBIINIT3_VGA_PASS_RESET_VAL(val) (((val) >> 11) & 1) 00376 #define FBIINIT3_HARDCODE_PCI_BASE(val) (((val) >> 12) & 1) 00377 #define FBIINIT3_FBI2TREX_DELAY(val) (((val) >> 13) & 0xf) 00378 #define FBIINIT3_TREX2FBI_DELAY(val) (((val) >> 17) & 0x1f) 00379 #define FBIINIT3_YORIGIN_SUBTRACT(val) (((val) >> 22) & 0x3ff) 00380 00381 #define FBIINIT4_PCI_READ_WAITS(val) (((val) >> 0) & 1) 00382 #define FBIINIT4_ENABLE_LFB_READAHEAD(val) (((val) >> 1) & 1) 00383 #define FBIINIT4_MEMORY_FIFO_LWM(val) (((val) >> 2) & 0x3f) 00384 #define FBIINIT4_MEMORY_FIFO_START_ROW(val) (((val) >> 8) & 0x3ff) 00385 #define FBIINIT4_MEMORY_FIFO_STOP_ROW(val) (((val) >> 18) & 0x3ff) 00386 #define FBIINIT4_VIDEO_CLOCKING_DELAY(val) (((val) >> 29) & 7) /* voodoo 2 only */ 00387 00388 #define FBIINIT5_DISABLE_PCI_STOP(val) (((val) >> 0) & 1) /* voodoo 2 only */ 00389 #define FBIINIT5_PCI_SLAVE_SPEED(val) (((val) >> 1) & 1) /* voodoo 2 only */ 00390 #define FBIINIT5_DAC_DATA_OUTPUT_WIDTH(val) (((val) >> 2) & 1) /* voodoo 2 only */ 00391 #define FBIINIT5_DAC_DATA_17_OUTPUT(val) (((val) >> 3) & 1) /* voodoo 2 only */ 00392 #define FBIINIT5_DAC_DATA_18_OUTPUT(val) (((val) >> 4) & 1) /* voodoo 2 only */ 00393 #define FBIINIT5_GENERIC_STRAPPING(val) (((val) >> 5) & 0xf) /* voodoo 2 only */ 00394 #define FBIINIT5_BUFFER_ALLOCATION(val) (((val) >> 9) & 3) /* voodoo 2 only */ 00395 #define FBIINIT5_DRIVE_VID_CLK_SLAVE(val) (((val) >> 11) & 1) /* voodoo 2 only */ 00396 #define FBIINIT5_DRIVE_DAC_DATA_16(val) (((val) >> 12) & 1) /* voodoo 2 only */ 00397 #define FBIINIT5_VCLK_INPUT_SELECT(val) (((val) >> 13) & 1) /* voodoo 2 only */ 00398 #define FBIINIT5_MULTI_CVG_DETECT(val) (((val) >> 14) & 1) /* voodoo 2 only */ 00399 #define FBIINIT5_SYNC_RETRACE_READS(val) (((val) >> 15) & 1) /* voodoo 2 only */ 00400 #define FBIINIT5_ENABLE_RHBORDER_COLOR(val) (((val) >> 16) & 1) /* voodoo 2 only */ 00401 #define FBIINIT5_ENABLE_LHBORDER_COLOR(val) (((val) >> 17) & 1) /* voodoo 2 only */ 00402 #define FBIINIT5_ENABLE_BVBORDER_COLOR(val) (((val) >> 18) & 1) /* voodoo 2 only */ 00403 #define FBIINIT5_ENABLE_TVBORDER_COLOR(val) (((val) >> 19) & 1) /* voodoo 2 only */ 00404 #define FBIINIT5_DOUBLE_HORIZ(val) (((val) >> 20) & 1) /* voodoo 2 only */ 00405 #define FBIINIT5_DOUBLE_VERT(val) (((val) >> 21) & 1) /* voodoo 2 only */ 00406 #define FBIINIT5_ENABLE_16BIT_GAMMA(val) (((val) >> 22) & 1) /* voodoo 2 only */ 00407 #define FBIINIT5_INVERT_DAC_HSYNC(val) (((val) >> 23) & 1) /* voodoo 2 only */ 00408 #define FBIINIT5_INVERT_DAC_VSYNC(val) (((val) >> 24) & 1) /* voodoo 2 only */ 00409 #define FBIINIT5_ENABLE_24BIT_DACDATA(val) (((val) >> 25) & 1) /* voodoo 2 only */ 00410 #define FBIINIT5_ENABLE_INTERLACING(val) (((val) >> 26) & 1) /* voodoo 2 only */ 00411 #define FBIINIT5_DAC_DATA_18_CONTROL(val) (((val) >> 27) & 1) /* voodoo 2 only */ 00412 #define FBIINIT5_RASTERIZER_UNIT_MODE(val) (((val) >> 30) & 3) /* voodoo 2 only */ 00413 00414 #define FBIINIT6_WINDOW_ACTIVE_COUNTER(val) (((val) >> 0) & 7) /* voodoo 2 only */ 00415 #define FBIINIT6_WINDOW_DRAG_COUNTER(val) (((val) >> 3) & 0x1f) /* voodoo 2 only */ 00416 #define FBIINIT6_SLI_SYNC_MASTER(val) (((val) >> 8) & 1) /* voodoo 2 only */ 00417 #define FBIINIT6_DAC_DATA_22_OUTPUT(val) (((val) >> 9) & 3) /* voodoo 2 only */ 00418 #define FBIINIT6_DAC_DATA_23_OUTPUT(val) (((val) >> 11) & 3) /* voodoo 2 only */ 00419 #define FBIINIT6_SLI_SYNCIN_OUTPUT(val) (((val) >> 13) & 3) /* voodoo 2 only */ 00420 #define FBIINIT6_SLI_SYNCOUT_OUTPUT(val) (((val) >> 15) & 3) /* voodoo 2 only */ 00421 #define FBIINIT6_DAC_RD_OUTPUT(val) (((val) >> 17) & 3) /* voodoo 2 only */ 00422 #define FBIINIT6_DAC_WR_OUTPUT(val) (((val) >> 19) & 3) /* voodoo 2 only */ 00423 #define FBIINIT6_PCI_FIFO_LWM_RDY(val) (((val) >> 21) & 0x7f) /* voodoo 2 only */ 00424 #define FBIINIT6_VGA_PASS_N_OUTPUT(val) (((val) >> 28) & 3) /* voodoo 2 only */ 00425 #define FBIINIT6_X_VIDEO_TILES_BIT0(val) (((val) >> 30) & 1) /* voodoo 2 only */ 00426 00427 #define FBIINIT7_GENERIC_STRAPPING(val) (((val) >> 0) & 0xff) /* voodoo 2 only */ 00428 #define FBIINIT7_CMDFIFO_ENABLE(val) (((val) >> 8) & 1) /* voodoo 2 only */ 00429 #define FBIINIT7_CMDFIFO_MEMORY_STORE(val) (((val) >> 9) & 1) /* voodoo 2 only */ 00430 #define FBIINIT7_DISABLE_CMDFIFO_HOLES(val) (((val) >> 10) & 1) /* voodoo 2 only */ 00431 #define FBIINIT7_CMDFIFO_READ_THRESH(val) (((val) >> 11) & 0x1f) /* voodoo 2 only */ 00432 #define FBIINIT7_SYNC_CMDFIFO_WRITES(val) (((val) >> 16) & 1) /* voodoo 2 only */ 00433 #define FBIINIT7_SYNC_CMDFIFO_READS(val) (((val) >> 17) & 1) /* voodoo 2 only */ 00434 #define FBIINIT7_RESET_PCI_PACKER(val) (((val) >> 18) & 1) /* voodoo 2 only */ 00435 #define FBIINIT7_ENABLE_CHROMA_STUFF(val) (((val) >> 19) & 1) /* voodoo 2 only */ 00436 #define FBIINIT7_CMDFIFO_PCI_TIMEOUT(val) (((val) >> 20) & 0x7f) /* voodoo 2 only */ 00437 #define FBIINIT7_ENABLE_TEXTURE_BURST(val) (((val) >> 27) & 1) /* voodoo 2 only */ 00438 00439 #define TEXMODE_ENABLE_PERSPECTIVE(val) (((val) >> 0) & 1) 00440 #define TEXMODE_MINIFICATION_FILTER(val) (((val) >> 1) & 1) 00441 #define TEXMODE_MAGNIFICATION_FILTER(val) (((val) >> 2) & 1) 00442 #define TEXMODE_CLAMP_NEG_W(val) (((val) >> 3) & 1) 00443 #define TEXMODE_ENABLE_LOD_DITHER(val) (((val) >> 4) & 1) 00444 #define TEXMODE_NCC_TABLE_SELECT(val) (((val) >> 5) & 1) 00445 #define TEXMODE_CLAMP_S(val) (((val) >> 6) & 1) 00446 #define TEXMODE_CLAMP_T(val) (((val) >> 7) & 1) 00447 #define TEXMODE_FORMAT(val) (((val) >> 8) & 0xf) 00448 #define TEXMODE_TC_ZERO_OTHER(val) (((val) >> 12) & 1) 00449 #define TEXMODE_TC_SUB_CLOCAL(val) (((val) >> 13) & 1) 00450 #define TEXMODE_TC_MSELECT(val) (((val) >> 14) & 7) 00451 #define TEXMODE_TC_REVERSE_BLEND(val) (((val) >> 17) & 1) 00452 #define TEXMODE_TC_ADD_ACLOCAL(val) (((val) >> 18) & 3) 00453 #define TEXMODE_TC_INVERT_OUTPUT(val) (((val) >> 20) & 1) 00454 #define TEXMODE_TCA_ZERO_OTHER(val) (((val) >> 21) & 1) 00455 #define TEXMODE_TCA_SUB_CLOCAL(val) (((val) >> 22) & 1) 00456 #define TEXMODE_TCA_MSELECT(val) (((val) >> 23) & 7) 00457 #define TEXMODE_TCA_REVERSE_BLEND(val) (((val) >> 26) & 1) 00458 #define TEXMODE_TCA_ADD_ACLOCAL(val) (((val) >> 27) & 3) 00459 #define TEXMODE_TCA_INVERT_OUTPUT(val) (((val) >> 29) & 1) 00460 #define TEXMODE_TRILINEAR(val) (((val) >> 30) & 1) 00461 #define TEXMODE_SEQ_8_DOWNLD(val) (((val) >> 31) & 1) 00462 00463 #define TEXLOD_LODMIN(val) (((val) >> 0) & 0x3f) 00464 #define TEXLOD_LODMAX(val) (((val) >> 6) & 0x3f) 00465 #define TEXLOD_LODBIAS(val) (((val) >> 12) & 0x3f) 00466 #define TEXLOD_LOD_ODD(val) (((val) >> 18) & 1) 00467 #define TEXLOD_LOD_TSPLIT(val) (((val) >> 19) & 1) 00468 #define TEXLOD_LOD_S_IS_WIDER(val) (((val) >> 20) & 1) 00469 #define TEXLOD_LOD_ASPECT(val) (((val) >> 21) & 3) 00470 #define TEXLOD_LOD_ZEROFRAC(val) (((val) >> 23) & 1) 00471 #define TEXLOD_TMULTIBASEADDR(val) (((val) >> 24) & 1) 00472 #define TEXLOD_TDATA_SWIZZLE(val) (((val) >> 25) & 1) 00473 #define TEXLOD_TDATA_SWAP(val) (((val) >> 26) & 1) 00474 #define TEXLOD_TDIRECT_WRITE(val) (((val) >> 27) & 1) /* Voodoo 2 only */ 00475 00476 #define TEXDETAIL_DETAIL_MAX(val) (((val) >> 0) & 0xff) 00477 #define TEXDETAIL_DETAIL_BIAS(val) (((val) >> 8) & 0x3f) 00478 #define TEXDETAIL_DETAIL_SCALE(val) (((val) >> 14) & 7) 00479 #define TEXDETAIL_RGB_MIN_FILTER(val) (((val) >> 17) & 1) /* Voodoo 2 only */ 00480 #define TEXDETAIL_RGB_MAG_FILTER(val) (((val) >> 18) & 1) /* Voodoo 2 only */ 00481 #define TEXDETAIL_ALPHA_MIN_FILTER(val) (((val) >> 19) & 1) /* Voodoo 2 only */ 00482 #define TEXDETAIL_ALPHA_MAG_FILTER(val) (((val) >> 20) & 1) /* Voodoo 2 only */ 00483 #define TEXDETAIL_SEPARATE_RGBA_FILTER(val) (((val) >> 21) & 1) /* Voodoo 2 only */ 00484 00485 #define TREXINIT_SEND_TMU_CONFIG(val) (((val) >> 18) & 1) 00486 00487 00488 /************************************* 00489 * 00490 * Core types 00491 * 00492 *************************************/ 00493 00494 typedef struct _voodoo_state voodoo_state; 00495 typedef struct _poly_extra_data poly_extra_data; 00496 00497 typedef UINT32 rgb_t; 00498 00499 typedef struct _rgba rgba; 00500 #define LSB_FIRST 00501 struct _rgba 00502 { 00503 #ifdef LSB_FIRST 00504 UINT8 b, g, r, a; 00505 #else 00506 UINT8 a, r, g, b; 00507 #endif 00508 }; 00509 00510 00511 typedef union _voodoo_reg voodoo_reg; 00512 union _voodoo_reg 00513 { 00514 INT32 i; 00515 UINT32 u; 00516 float f; 00517 rgba rgb; 00518 }; 00519 00520 00521 typedef voodoo_reg rgb_union; 00522 00523 00524 /* note that this structure is an even 64 bytes long */ 00525 typedef struct _stats_block stats_block; 00526 struct _stats_block 00527 { 00528 INT32 pixels_in; /* pixels in statistic */ 00529 INT32 pixels_out; /* pixels out statistic */ 00530 INT32 chroma_fail; /* chroma test fail statistic */ 00531 INT32 zfunc_fail; /* z function test fail statistic */ 00532 INT32 afunc_fail; /* alpha function test fail statistic */ 00533 INT32 clip_fail; /* clipping fail statistic */ 00534 INT32 stipple_count; /* stipple statistic */ 00535 INT32 filler[64/4 - 7]; /* pad this structure to 64 bytes */ 00536 }; 00537 00538 00539 typedef struct _fifo_state fifo_state; 00540 struct _fifo_state 00541 { 00542 INT32 size; /* size of the FIFO */ 00543 }; 00544 00545 00546 typedef struct _pci_state pci_state; 00547 struct _pci_state 00548 { 00549 fifo_state fifo; /* PCI FIFO */ 00550 UINT32 init_enable; /* initEnable value */ 00551 bool op_pending; /* true if an operation is pending */ 00552 }; 00553 00554 00555 typedef struct _ncc_table ncc_table; 00556 struct _ncc_table 00557 { 00558 bool dirty; /* is the texel lookup dirty? */ 00559 voodoo_reg * reg; /* pointer to our registers */ 00560 INT32 ir[4], ig[4], ib[4]; /* I values for R,G,B */ 00561 INT32 qr[4], qg[4], qb[4]; /* Q values for R,G,B */ 00562 INT32 y[16]; /* Y values */ 00563 rgb_t * palette; /* pointer to associated RGB palette */ 00564 rgb_t * palettea; /* pointer to associated ARGB palette */ 00565 rgb_t texel[256]; /* texel lookup */ 00566 }; 00567 00568 00569 typedef struct _tmu_state tmu_state; 00570 struct _tmu_state 00571 { 00572 UINT8 * ram; /* pointer to our RAM */ 00573 UINT32 mask; /* mask to apply to pointers */ 00574 voodoo_reg * reg; /* pointer to our register base */ 00575 bool regdirty; /* true if the LOD/mode/base registers have changed */ 00576 00577 UINT32 texaddr_mask; /* mask for texture address */ 00578 UINT8 texaddr_shift; /* shift for texture address */ 00579 00580 INT64 starts, startt; /* starting S,T (14.18) */ 00581 INT64 startw; /* starting W (2.30) */ 00582 INT64 dsdx, dtdx; /* delta S,T per X */ 00583 INT64 dwdx; /* delta W per X */ 00584 INT64 dsdy, dtdy; /* delta S,T per Y */ 00585 INT64 dwdy; /* delta W per Y */ 00586 00587 INT32 lodmin, lodmax; /* min, max LOD values */ 00588 INT32 lodbias; /* LOD bias */ 00589 UINT32 lodmask; /* mask of available LODs */ 00590 UINT32 lodoffset[9]; /* offset of texture base for each LOD */ 00591 INT32 detailmax; /* detail clamp */ 00592 INT32 detailbias; /* detail bias */ 00593 UINT8 detailscale; /* detail scale */ 00594 00595 UINT32 wmask; /* mask for the current texture width */ 00596 UINT32 hmask; /* mask for the current texture height */ 00597 00598 UINT8 bilinear_mask; /* mask for bilinear resolution (0xf0 for V1, 0xff for V2) */ 00599 00600 ncc_table ncc[2]; /* two NCC tables */ 00601 00602 rgb_t * lookup; /* currently selected lookup */ 00603 rgb_t * texel[16]; /* texel lookups for each format */ 00604 00605 rgb_t palette[256]; /* palette lookup table */ 00606 rgb_t palettea[256]; /* palette+alpha lookup table */ 00607 }; 00608 00609 00610 typedef struct _tmu_shared_state tmu_shared_state; 00611 struct _tmu_shared_state 00612 { 00613 rgb_t rgb332[256]; /* RGB 3-3-2 lookup table */ 00614 rgb_t alpha8[256]; /* alpha 8-bit lookup table */ 00615 rgb_t int8[256]; /* intensity 8-bit lookup table */ 00616 rgb_t ai44[256]; /* alpha, intensity 4-4 lookup table */ 00617 00618 rgb_t rgb565[65536]; /* RGB 5-6-5 lookup table */ 00619 rgb_t argb1555[65536]; /* ARGB 1-5-5-5 lookup table */ 00620 rgb_t argb4444[65536]; /* ARGB 4-4-4-4 lookup table */ 00621 }; 00622 00623 00624 typedef struct _setup_vertex setup_vertex; 00625 struct _setup_vertex 00626 { 00627 float x, y; /* X, Y coordinates */ 00628 float a, r, g, b; /* A, R, G, B values */ 00629 float z, wb; /* Z and broadcast W values */ 00630 float w0, s0, t0; /* W, S, T for TMU 0 */ 00631 float w1, s1, t1; /* W, S, T for TMU 1 */ 00632 }; 00633 00634 00635 typedef struct _fbi_state fbi_state; 00636 struct _fbi_state 00637 { 00638 UINT8 * ram; /* pointer to frame buffer RAM */ 00639 UINT32 mask; /* mask to apply to pointers */ 00640 UINT32 rgboffs[3]; /* word offset to 3 RGB buffers */ 00641 UINT32 auxoffs; /* word offset to 1 aux buffer */ 00642 00643 UINT8 frontbuf; /* front buffer index */ 00644 UINT8 backbuf; /* back buffer index */ 00645 00646 UINT32 yorigin; /* Y origin subtract value */ 00647 00648 UINT32 width; /* width of current frame buffer */ 00649 UINT32 height; /* height of current frame buffer */ 00650 // UINT32 xoffs; /* horizontal offset (back porch) */ 00651 // UINT32 yoffs; /* vertical offset (back porch) */ 00652 // UINT32 vsyncscan; /* vertical sync scanline */ 00653 UINT32 rowpixels; /* pixels per row */ 00654 UINT32 tile_width; /* width of video tiles */ 00655 UINT32 tile_height; /* height of video tiles */ 00656 UINT32 x_tiles; /* number of tiles in the X direction */ 00657 00658 UINT8 vblank; /* VBLANK state */ 00659 bool vblank_dont_swap; /* don't actually swap when we hit this point */ 00660 bool vblank_flush_pending; 00661 00662 /* triangle setup info */ 00663 INT16 ax, ay; /* vertex A x,y (12.4) */ 00664 INT16 bx, by; /* vertex B x,y (12.4) */ 00665 INT16 cx, cy; /* vertex C x,y (12.4) */ 00666 INT32 startr, startg, startb, starta; /* starting R,G,B,A (12.12) */ 00667 INT32 startz; /* starting Z (20.12) */ 00668 INT64 startw; /* starting W (16.32) */ 00669 INT32 drdx, dgdx, dbdx, dadx; /* delta R,G,B,A per X */ 00670 INT32 dzdx; /* delta Z per X */ 00671 INT64 dwdx; /* delta W per X */ 00672 INT32 drdy, dgdy, dbdy, dady; /* delta R,G,B,A per Y */ 00673 INT32 dzdy; /* delta Z per Y */ 00674 INT64 dwdy; /* delta W per Y */ 00675 00676 stats_block lfb_stats; /* LFB-access statistics */ 00677 00678 UINT8 sverts; /* number of vertices ready */ 00679 setup_vertex svert[3]; /* 3 setup vertices */ 00680 00681 fifo_state fifo; /* framebuffer memory fifo */ 00682 00683 UINT8 fogblend[64]; /* 64-entry fog table */ 00684 UINT8 fogdelta[64]; /* 64-entry fog table */ 00685 UINT8 fogdelta_mask; /* mask for for delta (0xff for V1, 0xfc for V2) */ 00686 00687 // rgb_t clut[512]; /* clut gamma data */ 00688 }; 00689 00690 00691 typedef struct _dac_state dac_state; 00692 struct _dac_state 00693 { 00694 UINT8 reg[8]; /* 8 registers */ 00695 UINT8 read_result; /* pending read result */ 00696 }; 00697 00698 00699 typedef struct _raster_info raster_info; 00700 struct _raster_info 00701 { 00702 struct _raster_info *next; /* pointer to next entry with the same hash */ 00703 poly_draw_scanline_func callback; /* callback pointer */ 00704 bool is_generic; /* true if this is one of the generic rasterizers */ 00705 UINT8 display; /* display index */ 00706 UINT32 hits; /* how many hits (pixels) we've used this for */ 00707 UINT32 polys; /* how many polys we've used this for */ 00708 UINT32 eff_color_path; /* effective fbzColorPath value */ 00709 UINT32 eff_alpha_mode; /* effective alphaMode value */ 00710 UINT32 eff_fog_mode; /* effective fogMode value */ 00711 UINT32 eff_fbz_mode; /* effective fbzMode value */ 00712 UINT32 eff_tex_mode_0; /* effective textureMode value for TMU #0 */ 00713 UINT32 eff_tex_mode_1; /* effective textureMode value for TMU #1 */ 00714 00715 bool shader_ready; 00716 UINT32 so_shader_program; 00717 UINT32 so_vertex_shader; 00718 UINT32 so_fragment_shader; 00719 INT32* shader_ulocations; 00720 }; 00721 00722 00723 struct _poly_extra_data 00724 { 00725 voodoo_state * state; /* pointer back to the voodoo state */ 00726 raster_info * info; /* pointer to rasterizer information */ 00727 00728 INT16 ax, ay; /* vertex A x,y (12.4) */ 00729 INT32 startr, startg, startb, starta; /* starting R,G,B,A (12.12) */ 00730 INT32 startz; /* starting Z (20.12) */ 00731 INT64 startw; /* starting W (16.32) */ 00732 INT32 drdx, dgdx, dbdx, dadx; /* delta R,G,B,A per X */ 00733 INT32 dzdx; /* delta Z per X */ 00734 INT64 dwdx; /* delta W per X */ 00735 INT32 drdy, dgdy, dbdy, dady; /* delta R,G,B,A per Y */ 00736 INT32 dzdy; /* delta Z per Y */ 00737 INT64 dwdy; /* delta W per Y */ 00738 00739 INT64 starts0, startt0; /* starting S,T (14.18) */ 00740 INT64 startw0; /* starting W (2.30) */ 00741 INT64 ds0dx, dt0dx; /* delta S,T per X */ 00742 INT64 dw0dx; /* delta W per X */ 00743 INT64 ds0dy, dt0dy; /* delta S,T per Y */ 00744 INT64 dw0dy; /* delta W per Y */ 00745 INT32 lodbase0; /* used during rasterization */ 00746 00747 INT64 starts1, startt1; /* starting S,T (14.18) */ 00748 INT64 startw1; /* starting W (2.30) */ 00749 INT64 ds1dx, dt1dx; /* delta S,T per X */ 00750 INT64 dw1dx; /* delta W per X */ 00751 INT64 ds1dy, dt1dy; /* delta S,T per Y */ 00752 INT64 dw1dy; /* delta W per Y */ 00753 INT32 lodbase1; /* used during rasterization */ 00754 00755 UINT16 dither[16]; /* dither matrix, for fastfill */ 00756 00757 Bitu texcount; 00758 Bitu r_fbzColorPath; 00759 Bitu r_fbzMode; 00760 Bitu r_alphaMode; 00761 Bitu r_fogMode; 00762 INT32 r_textureMode0; 00763 INT32 r_textureMode1; 00764 }; 00765 00766 00767 /* typedef struct _voodoo_state voodoo_state; -- declared above */ 00768 struct _voodoo_state 00769 { 00770 UINT8 type; /* type of system */ 00771 UINT8 chipmask; /* mask for which chips are available */ 00772 00773 voodoo_reg reg[0x400]; /* raw registers */ 00774 const UINT8 * regaccess; /* register access array */ 00775 const char *const * regnames; /* register names array */ 00776 bool alt_regmap; /* enable alternate register map? */ 00777 00778 pci_state pci; /* PCI state */ 00779 dac_state dac; /* DAC state */ 00780 00781 fbi_state fbi; /* FBI states */ 00782 tmu_state tmu[MAX_TMU]; /* TMU states */ 00783 tmu_shared_state tmushare; /* TMU shared state */ 00784 00785 stats_block * thread_stats; /* per-thread statistics */ 00786 00787 int next_rasterizer; /* next rasterizer index */ 00788 raster_info rasterizer[MAX_RASTERIZERS]; /* array of rasterizers */ 00789 raster_info * raster_hash[RASTER_HASH_SIZE]; /* hash table of rasterizers */ 00790 00791 bool send_config; 00792 UINT32 tmu_config; 00793 00794 bool ogl; 00795 bool ogl_dimchange; 00796 bool clock_enabled; 00797 bool output_on; 00798 bool active; 00799 }; 00800 00801 00802 00803 /************************************* 00804 * 00805 * Inline FIFO management 00806 * 00807 *************************************/ 00808 00809 INLINE INT32 fifo_space(fifo_state *f) 00810 { 00811 INT32 items = 0; 00812 if (items < 0) 00813 items += f->size; 00814 return f->size - 1 - items; 00815 } 00816 00817 00818 INLINE UINT8 count_leading_zeros(UINT32 value) 00819 { 00820 INT32 result; 00821 00822 #if defined(_MSC_VER) && defined(_M_IX86) 00823 __asm 00824 { 00825 bsr eax,value 00826 jnz skip 00827 mov eax,63 00828 skip: 00829 xor eax,31 00830 mov result,eax 00831 } 00832 #else 00833 result = 32; 00834 while(value > 0) { 00835 result--; 00836 value >>= 1; 00837 } 00838 #endif 00839 00840 return (UINT8)result; 00841 } 00842 00843 /************************************* 00844 * 00845 * Computes a fast 16.16 reciprocal 00846 * of a 16.32 value; used for 00847 * computing 1/w in the rasterizer. 00848 * 00849 * Since it is trivial to also 00850 * compute log2(1/w) = -log2(w) at 00851 * the same time, we do that as well 00852 * to 16.8 precision for LOD 00853 * calculations. 00854 * 00855 * On a Pentium M, this routine is 00856 * 20% faster than a 64-bit integer 00857 * divide and also produces the log 00858 * for free. 00859 * 00860 *************************************/ 00861 00862 INLINE INT64 fast_reciplog(INT64 value, INT32 *log2) 00863 { 00864 extern UINT32 voodoo_reciplog[]; 00865 UINT32 temp, rlog; 00866 UINT32 interp; 00867 UINT32 *table; 00868 UINT64 recip; 00869 bool neg = false; 00870 int lz, exp = 0; 00871 00872 /* always work with unsigned numbers */ 00873 if (value < 0) 00874 { 00875 value = -value; 00876 neg = true; 00877 } 00878 00879 /* if we've spilled out of 32 bits, push it down under 32 */ 00880 if (value & LONGTYPE(0xffff00000000)) 00881 { 00882 temp = (UINT32)(value >> 16); 00883 exp -= 16; 00884 } 00885 else 00886 temp = (UINT32)value; 00887 00888 /* if the resulting value is 0, the reciprocal is infinite */ 00889 if (GCC_UNLIKELY(temp == 0)) 00890 { 00891 *log2 = 1000 << LOG_OUTPUT_PREC; 00892 return neg ? 0x80000000 : 0x7fffffff; 00893 } 00894 00895 /* determine how many leading zeros in the value and shift it up high */ 00896 lz = count_leading_zeros(temp); 00897 temp <<= lz; 00898 exp += lz; 00899 00900 /* compute a pointer to the table entries we want */ 00901 /* math is a bit funny here because we shift one less than we need to in order */ 00902 /* to account for the fact that there are two UINT32's per table entry */ 00903 table = &voodoo_reciplog[(temp >> (31 - RECIPLOG_LOOKUP_BITS - 1)) & ((2 << RECIPLOG_LOOKUP_BITS) - 2)]; 00904 00905 /* compute the interpolation value */ 00906 interp = (temp >> (31 - RECIPLOG_LOOKUP_BITS - 8)) & 0xff; 00907 00908 /* do a linear interpolatation between the two nearest table values */ 00909 /* for both the log and the reciprocal */ 00910 rlog = (table[1] * (0x100 - interp) + table[3] * interp) >> 8; 00911 recip = (table[0] * (0x100 - interp) + table[2] * interp) >> 8; 00912 00913 /* the log result is the fractional part of the log; round it to the output precision */ 00914 rlog = (rlog + (1 << (RECIPLOG_LOOKUP_PREC - LOG_OUTPUT_PREC - 1))) >> (RECIPLOG_LOOKUP_PREC - LOG_OUTPUT_PREC); 00915 00916 /* the exponent is the non-fractional part of the log; normally, we would subtract it from rlog */ 00917 /* but since we want the log(1/value) = -log(value), we subtract rlog from the exponent */ 00918 *log2 = (INT32)((((int)exp - ((int)31 - (int)RECIPLOG_INPUT_PREC)) << (int)LOG_OUTPUT_PREC) - (int)rlog); 00919 00920 /* adjust the exponent to account for all the reciprocal-related parameters to arrive at a final shift amount */ 00921 exp += (RECIP_OUTPUT_PREC - RECIPLOG_LOOKUP_PREC) - (31 - RECIPLOG_INPUT_PREC); 00922 00923 /* shift by the exponent */ 00924 if (exp < 0) 00925 recip >>= -exp; 00926 else 00927 recip <<= exp; 00928 00929 /* on the way out, apply the original sign to the reciprocal */ 00930 return neg ? -(INT64)recip : (INT64)recip; 00931 } 00932 00933 00934 00935 /************************************* 00936 * 00937 * Float-to-int conversions 00938 * 00939 *************************************/ 00940 00941 INLINE INT32 float_to_int32(UINT32 data, int fixedbits) 00942 { 00943 int exponent = ((int)((data >> 23u) & 0xffu) - 127 - 23 + fixedbits); 00944 INT32 result = (INT32)(data & 0x7fffff) | 0x800000; 00945 if (exponent < 0) 00946 { 00947 if (exponent > -32) 00948 result >>= -exponent; 00949 else 00950 result = 0; 00951 } 00952 else 00953 { 00954 if (exponent < 32) 00955 result <<= exponent; 00956 else 00957 result = 0x7fffffff; 00958 } 00959 if (data & 0x80000000) 00960 result = -result; 00961 return result; 00962 } 00963 00964 00965 INLINE INT64 float_to_int64(UINT32 data, int fixedbits) 00966 { 00967 int exponent = (int)((data >> 23) & 0xff) - 127 - 23 + fixedbits; 00968 INT64 result = (INT64)(data & 0x7fffff) | 0x800000; 00969 if (exponent < 0) 00970 { 00971 if (exponent > -64) 00972 result >>= -exponent; 00973 else 00974 result = 0; 00975 } 00976 else 00977 { 00978 if (exponent < 64) 00979 result <<= exponent; 00980 else 00981 result = LONGTYPE(0x7fffffffffffffff); 00982 } 00983 if (data & 0x80000000) 00984 result = -result; 00985 return result; 00986 } 00987 00988 00989 00990 /************************************* 00991 * 00992 * Rasterizer inlines 00993 * 00994 *************************************/ 00995 00996 INLINE UINT32 normalize_color_path(UINT32 eff_color_path) 00997 { 00998 /* ignore the subpixel adjust and texture enable flags */ 00999 eff_color_path &= ~((1u << 26u) | (1u << 27u)); 01000 01001 return eff_color_path; 01002 } 01003 01004 01005 INLINE UINT32 normalize_alpha_mode(UINT32 eff_alpha_mode) 01006 { 01007 /* always ignore alpha ref value */ 01008 eff_alpha_mode &= ~(0xffu << 24u); 01009 01010 /* if not doing alpha testing, ignore the alpha function and ref value */ 01011 if (!ALPHAMODE_ALPHATEST(eff_alpha_mode)) 01012 eff_alpha_mode &= ~(7u << 1u); 01013 01014 /* if not doing alpha blending, ignore the source and dest blending factors */ 01015 if (!ALPHAMODE_ALPHABLEND(eff_alpha_mode)) 01016 eff_alpha_mode &= ~((15u << 8u) | (15u << 12u) | (15u << 16u) | (15u << 20u)); 01017 01018 return eff_alpha_mode; 01019 } 01020 01021 01022 INLINE UINT32 normalize_fog_mode(UINT32 eff_fog_mode) 01023 { 01024 /* if not doing fogging, ignore all the other fog bits */ 01025 if (!FOGMODE_ENABLE_FOG(eff_fog_mode)) 01026 eff_fog_mode = 0; 01027 01028 return eff_fog_mode; 01029 } 01030 01031 01032 INLINE UINT32 normalize_fbz_mode(UINT32 eff_fbz_mode) 01033 { 01034 /* ignore the draw buffer */ 01035 eff_fbz_mode &= ~(3u << 14u); 01036 01037 return eff_fbz_mode; 01038 } 01039 01040 01041 INLINE UINT32 normalize_tex_mode(UINT32 eff_tex_mode) 01042 { 01043 /* ignore the NCC table and seq_8_downld flags */ 01044 eff_tex_mode &= ~((1u << 5u) | (1u << 31u)); 01045 01046 /* classify texture formats into 3 format categories */ 01047 if (TEXMODE_FORMAT(eff_tex_mode) < 8) 01048 eff_tex_mode = (eff_tex_mode & ~(0xfu << 8u)) | (0u << 8u); 01049 else if (TEXMODE_FORMAT(eff_tex_mode) >= 10 && TEXMODE_FORMAT(eff_tex_mode) <= 12) 01050 eff_tex_mode = (eff_tex_mode & ~(0xfu << 8u)) | (10u << 8u); 01051 else 01052 eff_tex_mode = (eff_tex_mode & ~(0xfu << 8u)) | (8u << 8u); 01053 01054 return eff_tex_mode; 01055 } 01056 01057 01058 INLINE UINT32 compute_raster_hash(const raster_info *info) 01059 { 01060 UINT32 hash; 01061 01062 /* make a hash */ 01063 hash = info->eff_color_path; 01064 hash = (hash << 1u) | (hash >> 31u); 01065 hash ^= info->eff_fbz_mode; 01066 hash = (hash << 1u) | (hash >> 31u); 01067 hash ^= info->eff_alpha_mode; 01068 hash = (hash << 1u) | (hash >> 31u); 01069 hash ^= info->eff_fog_mode; 01070 hash = (hash << 1u) | (hash >> 31u); 01071 hash ^= info->eff_tex_mode_0; 01072 hash = (hash << 1u) | (hash >> 31u); 01073 hash ^= info->eff_tex_mode_1; 01074 01075 return hash % RASTER_HASH_SIZE; 01076 } 01077 01078 01079 01080 /************************************* 01081 * 01082 * Dithering macros 01083 * 01084 *************************************/ 01085 01086 /* note that these equations and the dither matrixes have 01087 been confirmed to be exact matches to the real hardware */ 01088 #define DITHER_RB(val,dith) ((((val) << 1) - ((val) >> 4) + ((val) >> 7) + (dith)) >> 1) 01089 #define DITHER_G(val,dith) ((((val) << 2) - ((val) >> 4) + ((val) >> 6) + (dith)) >> 2) 01090 01091 #define DECLARE_DITHER_POINTERS \ 01092 const UINT8 *dither_lookup = NULL; \ 01093 const UINT8 *dither4 = NULL; \ 01094 const UINT8 *dither = NULL \ 01095 01096 #define DECLARE_DITHER_POINTERS_NO_DITHER_VAR \ 01097 const UINT8 *dither_lookup = NULL; \ 01098 01099 #define COMPUTE_DITHER_POINTERS(FBZMODE, YY) \ 01100 do \ 01101 { \ 01102 /* compute the dithering pointers */ \ 01103 if (FBZMODE_ENABLE_DITHERING(FBZMODE)) \ 01104 { \ 01105 dither4 = &dither_matrix_4x4[((YY) & 3) * 4]; \ 01106 if (FBZMODE_DITHER_TYPE(FBZMODE) == 0) \ 01107 { \ 01108 dither = dither4; \ 01109 dither_lookup = &dither4_lookup[(YY & 3) << 11]; \ 01110 } \ 01111 else \ 01112 { \ 01113 dither = &dither_matrix_2x2[((YY) & 3) * 4]; \ 01114 dither_lookup = &dither2_lookup[(YY & 3) << 11]; \ 01115 } \ 01116 } \ 01117 } \ 01118 while (0) 01119 01120 #define COMPUTE_DITHER_POINTERS_NO_DITHER_VAR(FBZMODE, YY) \ 01121 do \ 01122 { \ 01123 /* compute the dithering pointers */ \ 01124 if (FBZMODE_ENABLE_DITHERING(FBZMODE)) \ 01125 { \ 01126 if (FBZMODE_DITHER_TYPE(FBZMODE) == 0) \ 01127 { \ 01128 dither_lookup = &dither4_lookup[(YY & 3) << 11]; \ 01129 } \ 01130 else \ 01131 { \ 01132 dither_lookup = &dither2_lookup[(YY & 3) << 11]; \ 01133 } \ 01134 } \ 01135 } \ 01136 while (0) 01137 01138 #define APPLY_DITHER(FBZMODE, XX, DITHER_LOOKUP, RR, GG, BB) \ 01139 do \ 01140 { \ 01141 /* apply dithering */ \ 01142 if (FBZMODE_ENABLE_DITHERING(FBZMODE)) \ 01143 { \ 01144 /* look up the dither value from the appropriate matrix */ \ 01145 const UINT8 *dith = &DITHER_LOOKUP[((XX) & 3) << 1]; \ 01146 \ 01147 /* apply dithering to R,G,B */ \ 01148 (RR) = dith[((RR) << 3) + 0]; \ 01149 (GG) = dith[((GG) << 3) + 1]; \ 01150 (BB) = dith[((BB) << 3) + 0]; \ 01151 } \ 01152 else \ 01153 { \ 01154 (RR) >>= 3; \ 01155 (GG) >>= 2; \ 01156 (BB) >>= 3; \ 01157 } \ 01158 } \ 01159 while (0) 01160 01161 01162 01163 /************************************* 01164 * 01165 * Clamping macros 01166 * 01167 *************************************/ 01168 01169 #define CLAMPED_ARGB(ITERR, ITERG, ITERB, ITERA, FBZCP, RESULT) \ 01170 do \ 01171 { \ 01172 r = (INT32)(ITERR) >> 12; \ 01173 g = (INT32)(ITERG) >> 12; \ 01174 b = (INT32)(ITERB) >> 12; \ 01175 a = (INT32)(ITERA) >> 12; \ 01176 \ 01177 if (FBZCP_RGBZW_CLAMP(FBZCP) == 0) \ 01178 { \ 01179 r &= 0xfff; \ 01180 RESULT.rgb.r = r; \ 01181 if (r == 0xfff) \ 01182 RESULT.rgb.r = 0; \ 01183 else if (r == 0x100) \ 01184 RESULT.rgb.r = 0xff; \ 01185 \ 01186 g &= 0xfff; \ 01187 RESULT.rgb.g = g; \ 01188 if (g == 0xfff) \ 01189 RESULT.rgb.g = 0; \ 01190 else if (g == 0x100) \ 01191 RESULT.rgb.g = 0xff; \ 01192 \ 01193 b &= 0xfff; \ 01194 RESULT.rgb.b = b; \ 01195 if (b == 0xfff) \ 01196 RESULT.rgb.b = 0; \ 01197 else if (b == 0x100) \ 01198 RESULT.rgb.b = 0xff; \ 01199 \ 01200 a &= 0xfff; \ 01201 RESULT.rgb.a = a; \ 01202 if (a == 0xfff) \ 01203 RESULT.rgb.a = 0; \ 01204 else if (a == 0x100) \ 01205 RESULT.rgb.a = 0xff; \ 01206 } \ 01207 else \ 01208 { \ 01209 RESULT.rgb.r = (r < 0) ? 0 : (r > 0xff) ? 0xff : (UINT8)r; \ 01210 RESULT.rgb.g = (g < 0) ? 0 : (g > 0xff) ? 0xff : (UINT8)g; \ 01211 RESULT.rgb.b = (b < 0) ? 0 : (b > 0xff) ? 0xff : (UINT8)b; \ 01212 RESULT.rgb.a = (a < 0) ? 0 : (a > 0xff) ? 0xff : (UINT8)a; \ 01213 } \ 01214 } \ 01215 while (0) 01216 01217 01218 #define CLAMPED_Z(ITERZ, FBZCP, RESULT) \ 01219 do \ 01220 { \ 01221 (RESULT) = (INT32)(ITERZ) >> 12; \ 01222 if (FBZCP_RGBZW_CLAMP(FBZCP) == 0) \ 01223 { \ 01224 (RESULT) &= 0xfffff; \ 01225 if ((RESULT) == 0xfffff) \ 01226 (RESULT) = 0; \ 01227 else if ((RESULT) == 0x10000) \ 01228 (RESULT) = 0xffff; \ 01229 else \ 01230 (RESULT) &= 0xffff; \ 01231 } \ 01232 else \ 01233 { \ 01234 CLAMP((RESULT), 0, 0xffff); \ 01235 } \ 01236 } \ 01237 while (0) 01238 01239 01240 #define CLAMPED_W(ITERW, FBZCP, RESULT) \ 01241 do \ 01242 { \ 01243 (RESULT) = (INT16)((ITERW) >> 32); \ 01244 if (FBZCP_RGBZW_CLAMP(FBZCP) == 0) \ 01245 { \ 01246 (RESULT) &= 0xffff; \ 01247 if ((RESULT) == 0xffff) \ 01248 (RESULT) = 0; \ 01249 else if ((RESULT) == 0x100) \ 01250 (RESULT) = 0xff; \ 01251 (RESULT) &= 0xff; \ 01252 } \ 01253 else \ 01254 { \ 01255 CLAMP((RESULT), 0, 0xff); \ 01256 } \ 01257 } \ 01258 while (0) 01259 01260 01261 01262 /************************************* 01263 * 01264 * Chroma keying macro 01265 * 01266 *************************************/ 01267 01268 #define APPLY_CHROMAKEY(VV, STATS, FBZMODE, COLOR) \ 01269 do \ 01270 { \ 01271 if (FBZMODE_ENABLE_CHROMAKEY(FBZMODE)) \ 01272 { \ 01273 /* non-range version */ \ 01274 if (!CHROMARANGE_ENABLE((VV)->reg[chromaRange].u)) \ 01275 { \ 01276 if (((COLOR.u ^ (VV)->reg[chromaKey].u) & 0xffffff) == 0) \ 01277 { \ 01278 (STATS)->chroma_fail++; \ 01279 goto skipdrawdepth; \ 01280 } \ 01281 } \ 01282 \ 01283 /* tricky range version */ \ 01284 else \ 01285 { \ 01286 INT32 low, high, test; \ 01287 int results = 0; \ 01288 \ 01289 /* check blue */ \ 01290 low = (VV)->reg[chromaKey].rgb.b; \ 01291 high = (VV)->reg[chromaRange].rgb.b; \ 01292 test = COLOR.rgb.b; \ 01293 results = (test >= low && test <= high); \ 01294 results ^= (int)(CHROMARANGE_BLUE_EXCLUSIVE((VV)->reg[chromaRange].u)); \ 01295 results <<= 1; \ 01296 \ 01297 /* check green */ \ 01298 low = (VV)->reg[chromaKey].rgb.g; \ 01299 high = (VV)->reg[chromaRange].rgb.g; \ 01300 test = COLOR.rgb.g; \ 01301 results |= (test >= low && test <= high); \ 01302 results ^= (int)(CHROMARANGE_GREEN_EXCLUSIVE((VV)->reg[chromaRange].u)); \ 01303 results <<= 1; \ 01304 \ 01305 /* check red */ \ 01306 low = (VV)->reg[chromaKey].rgb.r; \ 01307 high = (VV)->reg[chromaRange].rgb.r; \ 01308 test = COLOR.rgb.r; \ 01309 results |= (test >= low && test <= high); \ 01310 results ^= (int)(CHROMARANGE_RED_EXCLUSIVE((VV)->reg[chromaRange].u)); \ 01311 \ 01312 /* final result */ \ 01313 if (CHROMARANGE_UNION_MODE((VV)->reg[chromaRange].u)) \ 01314 { \ 01315 if (results != 0) \ 01316 { \ 01317 (STATS)->chroma_fail++; \ 01318 goto skipdrawdepth; \ 01319 } \ 01320 } \ 01321 else \ 01322 { \ 01323 if (results == 7) \ 01324 { \ 01325 (STATS)->chroma_fail++; \ 01326 goto skipdrawdepth; \ 01327 } \ 01328 } \ 01329 } \ 01330 } \ 01331 } \ 01332 while (0) 01333 01334 01335 01336 /************************************* 01337 * 01338 * Alpha masking macro 01339 * 01340 *************************************/ 01341 01342 #define APPLY_ALPHAMASK(VV, STATS, FBZMODE, AA) \ 01343 do \ 01344 { \ 01345 if (FBZMODE_ENABLE_ALPHA_MASK(FBZMODE)) \ 01346 { \ 01347 if (((AA) & 1) == 0) \ 01348 { \ 01349 (STATS)->afunc_fail++; \ 01350 goto skipdrawdepth; \ 01351 } \ 01352 } \ 01353 } \ 01354 while (0) 01355 01356 01357 01358 /************************************* 01359 * 01360 * Alpha testing macro 01361 * 01362 *************************************/ 01363 01364 #define APPLY_ALPHATEST(VV, STATS, ALPHAMODE, AA) \ 01365 do \ 01366 { \ 01367 if (ALPHAMODE_ALPHATEST(ALPHAMODE)) \ 01368 { \ 01369 UINT8 alpharef = (VV)->reg[alphaMode].rgb.a; \ 01370 switch (ALPHAMODE_ALPHAFUNCTION(ALPHAMODE)) \ 01371 { \ 01372 case 0: /* alphaOP = never */ \ 01373 (STATS)->afunc_fail++; \ 01374 goto skipdrawdepth; \ 01375 \ 01376 case 1: /* alphaOP = less than */ \ 01377 if ((AA) >= alpharef) \ 01378 { \ 01379 (STATS)->afunc_fail++; \ 01380 goto skipdrawdepth; \ 01381 } \ 01382 break; \ 01383 \ 01384 case 2: /* alphaOP = equal */ \ 01385 if ((AA) != alpharef) \ 01386 { \ 01387 (STATS)->afunc_fail++; \ 01388 goto skipdrawdepth; \ 01389 } \ 01390 break; \ 01391 \ 01392 case 3: /* alphaOP = less than or equal */ \ 01393 if ((AA) > alpharef) \ 01394 { \ 01395 (STATS)->afunc_fail++; \ 01396 goto skipdrawdepth; \ 01397 } \ 01398 break; \ 01399 \ 01400 case 4: /* alphaOP = greater than */ \ 01401 if ((AA) <= alpharef) \ 01402 { \ 01403 (STATS)->afunc_fail++; \ 01404 goto skipdrawdepth; \ 01405 } \ 01406 break; \ 01407 \ 01408 case 5: /* alphaOP = not equal */ \ 01409 if ((AA) == alpharef) \ 01410 { \ 01411 (STATS)->afunc_fail++; \ 01412 goto skipdrawdepth; \ 01413 } \ 01414 break; \ 01415 \ 01416 case 6: /* alphaOP = greater than or equal */ \ 01417 if ((AA) < alpharef) \ 01418 { \ 01419 (STATS)->afunc_fail++; \ 01420 goto skipdrawdepth; \ 01421 } \ 01422 break; \ 01423 \ 01424 case 7: /* alphaOP = always */ \ 01425 break; \ 01426 } \ 01427 } \ 01428 } \ 01429 while (0) 01430 01431 01432 01433 /************************************* 01434 * 01435 * Alpha blending macro 01436 * 01437 *************************************/ 01438 01439 #define APPLY_ALPHA_BLEND(FBZMODE, ALPHAMODE, XX, DITHER, RR, GG, BB, AA) \ 01440 do \ 01441 { \ 01442 if (ALPHAMODE_ALPHABLEND(ALPHAMODE)) \ 01443 { \ 01444 int dpix = dest[XX]; \ 01445 int dr, dg, db; \ 01446 EXTRACT_565_TO_888(dpix, dr, dg, db); \ 01447 int da = (FBZMODE_ENABLE_ALPHA_PLANES(FBZMODE) && depth) ? depth[XX] : 0xff; \ 01448 int sr = (RR); \ 01449 int sg = (GG); \ 01450 int sb = (BB); \ 01451 int sa = (AA); \ 01452 int ta; \ 01453 \ 01454 /* apply dither subtraction */ \ 01455 if ((FBZMODE_ALPHA_DITHER_SUBTRACT(FBZMODE)) && DITHER) \ 01456 { \ 01457 /* look up the dither value from the appropriate matrix */ \ 01458 int dith = DITHER[(XX) & 3]; \ 01459 \ 01460 /* subtract the dither value */ \ 01461 dr = ((dr << 1) + 15 - dith) >> 1; \ 01462 dg = ((dg << 2) + 15 - dith) >> 2; \ 01463 db = ((db << 1) + 15 - dith) >> 1; \ 01464 } \ 01465 \ 01466 /* compute source portion */ \ 01467 switch (ALPHAMODE_SRCRGBBLEND(ALPHAMODE)) \ 01468 { \ 01469 default: /* reserved */ \ 01470 case 0: /* AZERO */ \ 01471 (RR) = (GG) = (BB) = 0; \ 01472 break; \ 01473 \ 01474 case 1: /* ASRC_ALPHA */ \ 01475 (RR) = (sr * (sa + 1)) >> 8; \ 01476 (GG) = (sg * (sa + 1)) >> 8; \ 01477 (BB) = (sb * (sa + 1)) >> 8; \ 01478 break; \ 01479 \ 01480 case 2: /* A_COLOR */ \ 01481 (RR) = (sr * (dr + 1)) >> 8; \ 01482 (GG) = (sg * (dg + 1)) >> 8; \ 01483 (BB) = (sb * (db + 1)) >> 8; \ 01484 break; \ 01485 \ 01486 case 3: /* ADST_ALPHA */ \ 01487 (RR) = (sr * (da + 1)) >> 8; \ 01488 (GG) = (sg * (da + 1)) >> 8; \ 01489 (BB) = (sb * (da + 1)) >> 8; \ 01490 break; \ 01491 \ 01492 case 4: /* AONE */ \ 01493 break; \ 01494 \ 01495 case 5: /* AOMSRC_ALPHA */ \ 01496 (RR) = (sr * (0x100 - sa)) >> 8; \ 01497 (GG) = (sg * (0x100 - sa)) >> 8; \ 01498 (BB) = (sb * (0x100 - sa)) >> 8; \ 01499 break; \ 01500 \ 01501 case 6: /* AOM_COLOR */ \ 01502 (RR) = (sr * (0x100 - dr)) >> 8; \ 01503 (GG) = (sg * (0x100 - dg)) >> 8; \ 01504 (BB) = (sb * (0x100 - db)) >> 8; \ 01505 break; \ 01506 \ 01507 case 7: /* AOMDST_ALPHA */ \ 01508 (RR) = (sr * (0x100 - da)) >> 8; \ 01509 (GG) = (sg * (0x100 - da)) >> 8; \ 01510 (BB) = (sb * (0x100 - da)) >> 8; \ 01511 break; \ 01512 \ 01513 case 15: /* ASATURATE */ \ 01514 ta = (sa < (0x100 - da)) ? sa : (0x100 - da); \ 01515 (RR) = (sr * (ta + 1)) >> 8; \ 01516 (GG) = (sg * (ta + 1)) >> 8; \ 01517 (BB) = (sb * (ta + 1)) >> 8; \ 01518 break; \ 01519 } \ 01520 \ 01521 /* add in dest portion */ \ 01522 switch (ALPHAMODE_DSTRGBBLEND(ALPHAMODE)) \ 01523 { \ 01524 default: /* reserved */ \ 01525 case 0: /* AZERO */ \ 01526 break; \ 01527 \ 01528 case 1: /* ASRC_ALPHA */ \ 01529 (RR) += (dr * (sa + 1)) >> 8; \ 01530 (GG) += (dg * (sa + 1)) >> 8; \ 01531 (BB) += (db * (sa + 1)) >> 8; \ 01532 break; \ 01533 \ 01534 case 2: /* A_COLOR */ \ 01535 (RR) += (dr * (sr + 1)) >> 8; \ 01536 (GG) += (dg * (sg + 1)) >> 8; \ 01537 (BB) += (db * (sb + 1)) >> 8; \ 01538 break; \ 01539 \ 01540 case 3: /* ADST_ALPHA */ \ 01541 (RR) += (dr * (da + 1)) >> 8; \ 01542 (GG) += (dg * (da + 1)) >> 8; \ 01543 (BB) += (db * (da + 1)) >> 8; \ 01544 break; \ 01545 \ 01546 case 4: /* AONE */ \ 01547 (RR) += dr; \ 01548 (GG) += dg; \ 01549 (BB) += db; \ 01550 break; \ 01551 \ 01552 case 5: /* AOMSRC_ALPHA */ \ 01553 (RR) += (dr * (0x100 - sa)) >> 8; \ 01554 (GG) += (dg * (0x100 - sa)) >> 8; \ 01555 (BB) += (db * (0x100 - sa)) >> 8; \ 01556 break; \ 01557 \ 01558 case 6: /* AOM_COLOR */ \ 01559 (RR) += (dr * (0x100 - sr)) >> 8; \ 01560 (GG) += (dg * (0x100 - sg)) >> 8; \ 01561 (BB) += (db * (0x100 - sb)) >> 8; \ 01562 break; \ 01563 \ 01564 case 7: /* AOMDST_ALPHA */ \ 01565 (RR) += (dr * (0x100 - da)) >> 8; \ 01566 (GG) += (dg * (0x100 - da)) >> 8; \ 01567 (BB) += (db * (0x100 - da)) >> 8; \ 01568 break; \ 01569 \ 01570 case 15: /* A_COLORBEFOREFOG */ \ 01571 (RR) += (dr * (prefogr + 1)) >> 8; \ 01572 (GG) += (dg * (prefogg + 1)) >> 8; \ 01573 (BB) += (db * (prefogb + 1)) >> 8; \ 01574 break; \ 01575 } \ 01576 \ 01577 /* blend the source alpha */ \ 01578 (AA) = 0; \ 01579 if (ALPHAMODE_SRCALPHABLEND(ALPHAMODE) == 4) \ 01580 (AA) = sa; \ 01581 \ 01582 /* blend the dest alpha */ \ 01583 if (ALPHAMODE_DSTALPHABLEND(ALPHAMODE) == 4) \ 01584 (AA) += da; \ 01585 \ 01586 /* clamp */ \ 01587 CLAMP((RR), 0x00, 0xff); \ 01588 CLAMP((GG), 0x00, 0xff); \ 01589 CLAMP((BB), 0x00, 0xff); \ 01590 CLAMP((AA), 0x00, 0xff); \ 01591 } \ 01592 } \ 01593 while (0) 01594 01595 01596 01597 /************************************* 01598 * 01599 * Fogging macro 01600 * 01601 *************************************/ 01602 01603 #define APPLY_FOGGING(VV, FOGMODE, FBZCP, XX, DITHER4, RR, GG, BB, ITERZ, ITERW, ITERAXXX) \ 01604 do \ 01605 { \ 01606 if (FOGMODE_ENABLE_FOG(FOGMODE)) \ 01607 { \ 01608 rgb_union fogcolor = (VV)->reg[fogColor]; \ 01609 INT32 fr, fg, fb; \ 01610 \ 01611 /* constant fog bypasses everything else */ \ 01612 if (FOGMODE_FOG_CONSTANT(FOGMODE)) \ 01613 { \ 01614 fr = fogcolor.rgb.r; \ 01615 fg = fogcolor.rgb.g; \ 01616 fb = fogcolor.rgb.b; \ 01617 } \ 01618 \ 01619 /* non-constant fog comes from several sources */ \ 01620 else \ 01621 { \ 01622 INT32 fogblend = 0; \ 01623 \ 01624 /* if fog_add is zero, we start with the fog color */ \ 01625 if (FOGMODE_FOG_ADD(FOGMODE) == 0) \ 01626 { \ 01627 fr = fogcolor.rgb.r; \ 01628 fg = fogcolor.rgb.g; \ 01629 fb = fogcolor.rgb.b; \ 01630 } \ 01631 else \ 01632 fr = fg = fb = 0; \ 01633 \ 01634 /* if fog_mult is zero, we subtract the incoming color */ \ 01635 if (FOGMODE_FOG_MULT(FOGMODE) == 0) \ 01636 { \ 01637 fr -= (RR); \ 01638 fg -= (GG); \ 01639 fb -= (BB); \ 01640 } \ 01641 \ 01642 /* fog blending mode */ \ 01643 switch (FOGMODE_FOG_ZALPHA(FOGMODE)) \ 01644 { \ 01645 case 0: /* fog table */ \ 01646 { \ 01647 INT32 delta = (VV)->fbi.fogdelta[fogdepth >> 10]; \ 01648 INT32 deltaval; \ 01649 \ 01650 /* perform the multiply against lower 8 bits of wfloat */ \ 01651 deltaval = (delta & (VV)->fbi.fogdelta_mask) * \ 01652 ((fogdepth >> 2) & 0xff); \ 01653 \ 01654 /* fog zones allow for negating this value */ \ 01655 if (FOGMODE_FOG_ZONES(FOGMODE) && (delta & 2)) \ 01656 deltaval = -deltaval; \ 01657 deltaval >>= 6; \ 01658 \ 01659 /* apply dither */ \ 01660 if (FOGMODE_FOG_DITHER(FOGMODE)) \ 01661 if (DITHER4) \ 01662 deltaval += DITHER4[(XX) & 3]; \ 01663 deltaval >>= 4; \ 01664 \ 01665 /* add to the blending factor */ \ 01666 fogblend = (VV)->fbi.fogblend[fogdepth >> 10] + deltaval; \ 01667 break; \ 01668 } \ 01669 \ 01670 case 1: /* iterated A */ \ 01671 fogblend = ITERAXXX.rgb.a; \ 01672 break; \ 01673 \ 01674 case 2: /* iterated Z */ \ 01675 CLAMPED_Z((ITERZ), FBZCP, fogblend); \ 01676 fogblend >>= 8; \ 01677 break; \ 01678 \ 01679 case 3: /* iterated W - Voodoo 2 only */ \ 01680 CLAMPED_W((ITERW), FBZCP, fogblend); \ 01681 break; \ 01682 } \ 01683 \ 01684 /* perform the blend */ \ 01685 fogblend++; \ 01686 fr = (fr * fogblend) >> 8; \ 01687 fg = (fg * fogblend) >> 8; \ 01688 fb = (fb * fogblend) >> 8; \ 01689 } \ 01690 \ 01691 /* if fog_mult is 0, we add this to the original color */ \ 01692 if (FOGMODE_FOG_MULT(FOGMODE) == 0) \ 01693 { \ 01694 (RR) += fr; \ 01695 (GG) += fg; \ 01696 (BB) += fb; \ 01697 } \ 01698 \ 01699 /* otherwise this just becomes the new color */ \ 01700 else \ 01701 { \ 01702 (RR) = fr; \ 01703 (GG) = fg; \ 01704 (BB) = fb; \ 01705 } \ 01706 \ 01707 /* clamp */ \ 01708 CLAMP((RR), 0x00, 0xff); \ 01709 CLAMP((GG), 0x00, 0xff); \ 01710 CLAMP((BB), 0x00, 0xff); \ 01711 } \ 01712 } \ 01713 while (0) 01714 01715 01716 01717 /************************************* 01718 * 01719 * Texture pipeline macro 01720 * 01721 *************************************/ 01722 01723 #define TEXTURE_PIPELINE(TT, XX, DITHER4, TEXMODE, COTHER, LOOKUP, LODBASE, ITERS, ITERT, ITERW, RESULT) \ 01724 do \ 01725 { \ 01726 INT32 blendr, blendg, blendb, blenda; \ 01727 INT32 tr, tg, tb, ta; \ 01728 INT32 s, t, lod, ilod; \ 01729 INT64 oow; \ 01730 INT32 smax, tmax; \ 01731 UINT32 texbase; \ 01732 rgb_union c_local; \ 01733 \ 01734 /* determine the S/T/LOD values for this texture */ \ 01735 if (TEXMODE_ENABLE_PERSPECTIVE(TEXMODE)) \ 01736 { \ 01737 oow = fast_reciplog((ITERW), &lod); \ 01738 s = (INT32)((oow * (ITERS)) >> 29); \ 01739 t = (INT32)((oow * (ITERT)) >> 29); \ 01740 lod = (LODBASE); \ 01741 } \ 01742 else \ 01743 { \ 01744 s = (INT32)((ITERS) >> 14); \ 01745 t = (INT32)((ITERT) >> 14); \ 01746 lod = (LODBASE); \ 01747 } \ 01748 \ 01749 /* clamp W */ \ 01750 if (TEXMODE_CLAMP_NEG_W(TEXMODE) && (ITERW) < 0) \ 01751 s = t = 0; \ 01752 \ 01753 /* clamp the LOD */ \ 01754 lod += (TT)->lodbias; \ 01755 if (TEXMODE_ENABLE_LOD_DITHER(TEXMODE)) \ 01756 if (DITHER4) \ 01757 lod += DITHER4[(XX) & 3] << 4; \ 01758 if (lod < (TT)->lodmin) \ 01759 lod = (TT)->lodmin; \ 01760 if (lod > (TT)->lodmax) \ 01761 lod = (TT)->lodmax; \ 01762 \ 01763 /* now the LOD is in range; if we don't own this LOD, take the next one */ \ 01764 ilod = lod >> 8; \ 01765 if (!(((TT)->lodmask >> ilod) & 1)) \ 01766 ilod++; \ 01767 \ 01768 /* fetch the texture base */ \ 01769 texbase = (TT)->lodoffset[ilod]; \ 01770 \ 01771 /* compute the maximum s and t values at this LOD */ \ 01772 smax = (INT32)((TT)->wmask >> ilod); \ 01773 tmax = (INT32)((TT)->hmask >> ilod); \ 01774 \ 01775 /* determine whether we are point-sampled or bilinear */ \ 01776 if ((lod == (TT)->lodmin && !TEXMODE_MAGNIFICATION_FILTER(TEXMODE)) || \ 01777 (lod != (TT)->lodmin && !TEXMODE_MINIFICATION_FILTER(TEXMODE))) \ 01778 { \ 01779 /* point sampled */ \ 01780 \ 01781 UINT32 texel0; \ 01782 \ 01783 /* adjust S/T for the LOD and strip off the fractions */ \ 01784 s >>= ilod + 18; \ 01785 t >>= ilod + 18; \ 01786 \ 01787 /* clamp/wrap S/T if necessary */ \ 01788 if (TEXMODE_CLAMP_S(TEXMODE)) \ 01789 CLAMP(s, 0, smax); \ 01790 if (TEXMODE_CLAMP_T(TEXMODE)) \ 01791 CLAMP(t, 0, tmax); \ 01792 s &= smax; \ 01793 t &= tmax; \ 01794 t *= smax + 1; \ 01795 \ 01796 /* fetch texel data */ \ 01797 if (TEXMODE_FORMAT(TEXMODE) < 8) \ 01798 { \ 01799 texel0 = *(UINT8 *)&(TT)->ram[(unsigned long)((unsigned long)texbase + (unsigned long)t + (unsigned long)s) & (TT)->mask]; \ 01800 c_local.u = (LOOKUP)[texel0]; \ 01801 } \ 01802 else \ 01803 { \ 01804 texel0 = *(UINT16 *)&(TT)->ram[(unsigned long)((unsigned long)texbase + 2ul*((unsigned long)t + (unsigned long)s)) & (TT)->mask]; \ 01805 if (TEXMODE_FORMAT(TEXMODE) >= 10 && TEXMODE_FORMAT(TEXMODE) <= 12) \ 01806 c_local.u = (LOOKUP)[texel0]; \ 01807 else \ 01808 c_local.u = ((LOOKUP)[texel0 & 0xff] & 0xffffff) | \ 01809 ((texel0 & 0xff00) << 16); \ 01810 } \ 01811 } \ 01812 else \ 01813 { \ 01814 /* bilinear filtered */ \ 01815 \ 01816 UINT32 texel0, texel1, texel2, texel3; \ 01817 UINT8 sfrac, tfrac; \ 01818 INT32 s1, t1; \ 01819 \ 01820 /* adjust S/T for the LOD and strip off all but the low 8 bits of */ \ 01821 /* the fraction */ \ 01822 s >>= ilod + 10; \ 01823 t >>= ilod + 10; \ 01824 \ 01825 /* also subtract 1/2 texel so that (0.5,0.5) = a full (0,0) texel */ \ 01826 s -= 0x80; \ 01827 t -= 0x80; \ 01828 \ 01829 /* extract the fractions */ \ 01830 sfrac = (UINT8)(s & (TT)->bilinear_mask); \ 01831 tfrac = (UINT8)(t & (TT)->bilinear_mask); \ 01832 \ 01833 /* now toss the rest */ \ 01834 s >>= 8; \ 01835 t >>= 8; \ 01836 s1 = s + 1; \ 01837 t1 = t + 1; \ 01838 \ 01839 /* clamp/wrap S/T if necessary */ \ 01840 if (TEXMODE_CLAMP_S(TEXMODE)) \ 01841 { \ 01842 CLAMP(s, 0, smax); \ 01843 CLAMP(s1, 0, smax); \ 01844 } \ 01845 if (TEXMODE_CLAMP_T(TEXMODE)) \ 01846 { \ 01847 CLAMP(t, 0, tmax); \ 01848 CLAMP(t1, 0, tmax); \ 01849 } \ 01850 s &= smax; \ 01851 s1 &= smax; \ 01852 t &= tmax; \ 01853 t1 &= tmax; \ 01854 t *= smax + 1; \ 01855 t1 *= smax + 1; \ 01856 \ 01857 /* fetch texel data */ \ 01858 if (TEXMODE_FORMAT(TEXMODE) < 8) \ 01859 { \ 01860 texel0 = *(UINT8 *)&(TT)->ram[((unsigned long)texbase + (unsigned long)t + (unsigned long)s) & (TT)->mask]; \ 01861 texel1 = *(UINT8 *)&(TT)->ram[((unsigned long)texbase + (unsigned long)t + (unsigned long)s1) & (TT)->mask]; \ 01862 texel2 = *(UINT8 *)&(TT)->ram[((unsigned long)texbase + (unsigned long)t1 + (unsigned long)s) & (TT)->mask]; \ 01863 texel3 = *(UINT8 *)&(TT)->ram[((unsigned long)texbase + (unsigned long)t1 + (unsigned long)s1) & (TT)->mask]; \ 01864 texel0 = (LOOKUP)[texel0]; \ 01865 texel1 = (LOOKUP)[texel1]; \ 01866 texel2 = (LOOKUP)[texel2]; \ 01867 texel3 = (LOOKUP)[texel3]; \ 01868 } \ 01869 else \ 01870 { \ 01871 texel0 = *(UINT16 *)&(TT)->ram[((unsigned long)texbase + 2ul*((unsigned long)t + (unsigned long)s)) & (TT)->mask]; \ 01872 texel1 = *(UINT16 *)&(TT)->ram[((unsigned long)texbase + 2ul*((unsigned long)t + (unsigned long)s1)) & (TT)->mask];\ 01873 texel2 = *(UINT16 *)&(TT)->ram[((unsigned long)texbase + 2ul*((unsigned long)t1 + (unsigned long)s)) & (TT)->mask];\ 01874 texel3 = *(UINT16 *)&(TT)->ram[((unsigned long)texbase + 2ul*((unsigned long)t1 + (unsigned long)s1)) & (TT)->mask];\ 01875 if (TEXMODE_FORMAT(TEXMODE) >= 10 && TEXMODE_FORMAT(TEXMODE) <= 12) \ 01876 { \ 01877 texel0 = (LOOKUP)[texel0]; \ 01878 texel1 = (LOOKUP)[texel1]; \ 01879 texel2 = (LOOKUP)[texel2]; \ 01880 texel3 = (LOOKUP)[texel3]; \ 01881 } \ 01882 else \ 01883 { \ 01884 texel0 = ((LOOKUP)[texel0 & 0xff] & 0xffffff) | \ 01885 ((texel0 & 0xff00) << 16); \ 01886 texel1 = ((LOOKUP)[texel1 & 0xff] & 0xffffff) | \ 01887 ((texel1 & 0xff00) << 16); \ 01888 texel2 = ((LOOKUP)[texel2 & 0xff] & 0xffffff) | \ 01889 ((texel2 & 0xff00) << 16); \ 01890 texel3 = ((LOOKUP)[texel3 & 0xff] & 0xffffff) | \ 01891 ((texel3 & 0xff00) << 16); \ 01892 } \ 01893 } \ 01894 \ 01895 /* weigh in each texel */ \ 01896 c_local.u = rgba_bilinear_filter(texel0, texel1, texel2, texel3, sfrac, tfrac);\ 01897 } \ 01898 \ 01899 /* select zero/other for RGB */ \ 01900 if (!TEXMODE_TC_ZERO_OTHER(TEXMODE)) \ 01901 { \ 01902 tr = COTHER.rgb.r; \ 01903 tg = COTHER.rgb.g; \ 01904 tb = COTHER.rgb.b; \ 01905 } \ 01906 else \ 01907 tr = tg = tb = 0; \ 01908 \ 01909 /* select zero/other for alpha */ \ 01910 if (!TEXMODE_TCA_ZERO_OTHER(TEXMODE)) \ 01911 ta = COTHER.rgb.a; \ 01912 else \ 01913 ta = 0; \ 01914 \ 01915 /* potentially subtract c_local */ \ 01916 if (TEXMODE_TC_SUB_CLOCAL(TEXMODE)) \ 01917 { \ 01918 tr -= c_local.rgb.r; \ 01919 tg -= c_local.rgb.g; \ 01920 tb -= c_local.rgb.b; \ 01921 } \ 01922 if (TEXMODE_TCA_SUB_CLOCAL(TEXMODE)) \ 01923 ta -= c_local.rgb.a; \ 01924 \ 01925 /* blend RGB */ \ 01926 switch (TEXMODE_TC_MSELECT(TEXMODE)) \ 01927 { \ 01928 default: /* reserved */ \ 01929 case 0: /* zero */ \ 01930 blendr = blendg = blendb = 0; \ 01931 break; \ 01932 \ 01933 case 1: /* c_local */ \ 01934 blendr = c_local.rgb.r; \ 01935 blendg = c_local.rgb.g; \ 01936 blendb = c_local.rgb.b; \ 01937 break; \ 01938 \ 01939 case 2: /* a_other */ \ 01940 blendr = blendg = blendb = COTHER.rgb.a; \ 01941 break; \ 01942 \ 01943 case 3: /* a_local */ \ 01944 blendr = blendg = blendb = c_local.rgb.a; \ 01945 break; \ 01946 \ 01947 case 4: /* LOD (detail factor) */ \ 01948 if ((TT)->detailbias <= lod) \ 01949 blendr = blendg = blendb = 0; \ 01950 else \ 01951 { \ 01952 blendr = ((((TT)->detailbias - lod) << (TT)->detailscale) >> 8);\ 01953 if (blendr > (TT)->detailmax) \ 01954 blendr = (TT)->detailmax; \ 01955 blendg = blendb = blendr; \ 01956 } \ 01957 break; \ 01958 \ 01959 case 5: /* LOD fraction */ \ 01960 blendr = blendg = blendb = lod & 0xff; \ 01961 break; \ 01962 } \ 01963 \ 01964 /* blend alpha */ \ 01965 switch (TEXMODE_TCA_MSELECT(TEXMODE)) \ 01966 { \ 01967 default: /* reserved */ \ 01968 case 0: /* zero */ \ 01969 blenda = 0; \ 01970 break; \ 01971 \ 01972 case 1: /* c_local */ \ 01973 blenda = c_local.rgb.a; \ 01974 break; \ 01975 \ 01976 case 2: /* a_other */ \ 01977 blenda = COTHER.rgb.a; \ 01978 break; \ 01979 \ 01980 case 3: /* a_local */ \ 01981 blenda = c_local.rgb.a; \ 01982 break; \ 01983 \ 01984 case 4: /* LOD (detail factor) */ \ 01985 if ((TT)->detailbias <= lod) \ 01986 blenda = 0; \ 01987 else \ 01988 { \ 01989 blenda = ((((TT)->detailbias - lod) << (TT)->detailscale) >> 8);\ 01990 if (blenda > (TT)->detailmax) \ 01991 blenda = (TT)->detailmax; \ 01992 } \ 01993 break; \ 01994 \ 01995 case 5: /* LOD fraction */ \ 01996 blenda = lod & 0xff; \ 01997 break; \ 01998 } \ 01999 \ 02000 /* reverse the RGB blend */ \ 02001 if (!TEXMODE_TC_REVERSE_BLEND(TEXMODE)) \ 02002 { \ 02003 blendr ^= 0xff; \ 02004 blendg ^= 0xff; \ 02005 blendb ^= 0xff; \ 02006 } \ 02007 \ 02008 /* reverse the alpha blend */ \ 02009 if (!TEXMODE_TCA_REVERSE_BLEND(TEXMODE)) \ 02010 blenda ^= 0xff; \ 02011 \ 02012 /* do the blend */ \ 02013 tr = (tr * (blendr + 1)) >> 8; \ 02014 tg = (tg * (blendg + 1)) >> 8; \ 02015 tb = (tb * (blendb + 1)) >> 8; \ 02016 ta = (ta * (blenda + 1)) >> 8; \ 02017 \ 02018 /* add clocal or alocal to RGB */ \ 02019 switch (TEXMODE_TC_ADD_ACLOCAL(TEXMODE)) \ 02020 { \ 02021 case 3: /* reserved */ \ 02022 case 0: /* nothing */ \ 02023 break; \ 02024 \ 02025 case 1: /* add c_local */ \ 02026 tr += c_local.rgb.r; \ 02027 tg += c_local.rgb.g; \ 02028 tb += c_local.rgb.b; \ 02029 break; \ 02030 \ 02031 case 2: /* add_alocal */ \ 02032 tr += c_local.rgb.a; \ 02033 tg += c_local.rgb.a; \ 02034 tb += c_local.rgb.a; \ 02035 break; \ 02036 } \ 02037 \ 02038 /* add clocal or alocal to alpha */ \ 02039 if (TEXMODE_TCA_ADD_ACLOCAL(TEXMODE)) \ 02040 ta += c_local.rgb.a; \ 02041 \ 02042 /* clamp */ \ 02043 RESULT.rgb.r = (tr < 0) ? 0 : (tr > 0xff) ? 0xff : (UINT8)tr; \ 02044 RESULT.rgb.g = (tg < 0) ? 0 : (tg > 0xff) ? 0xff : (UINT8)tg; \ 02045 RESULT.rgb.b = (tb < 0) ? 0 : (tb > 0xff) ? 0xff : (UINT8)tb; \ 02046 RESULT.rgb.a = (ta < 0) ? 0 : (ta > 0xff) ? 0xff : (UINT8)ta; \ 02047 \ 02048 /* invert */ \ 02049 if (TEXMODE_TC_INVERT_OUTPUT(TEXMODE)) \ 02050 RESULT.u ^= 0x00ffffff; \ 02051 if (TEXMODE_TCA_INVERT_OUTPUT(TEXMODE)) \ 02052 RESULT.rgb.a ^= 0xff; \ 02053 } \ 02054 while (0) 02055 02056 02057 02058 /************************************* 02059 * 02060 * Pixel pipeline macros 02061 * 02062 *************************************/ 02063 02064 #define PIXEL_PIPELINE_BEGIN(VV, XX, YY, FBZCOLORPATH, FBZMODE, ITERZ, ITERW) \ 02065 do \ 02066 { \ 02067 INT32 depthval, wfloat, fogdepth, biasdepth; \ 02068 INT32 prefogr, prefogg, prefogb; \ 02069 INT32 r, g, b, a; \ 02070 \ 02071 /* apply clipping */ \ 02072 /* note that for perf reasons, we assume the caller has done clipping */ \ 02073 \ 02074 /* handle stippling */ \ 02075 if (FBZMODE_ENABLE_STIPPLE(FBZMODE)) \ 02076 { \ 02077 /* rotate mode */ \ 02078 if (FBZMODE_STIPPLE_PATTERN(FBZMODE) == 0) \ 02079 { \ 02080 (VV)->reg[stipple].u = ((VV)->reg[stipple].u << 1) | ((VV)->reg[stipple].u >> 31);\ 02081 if (((VV)->reg[stipple].u & 0x80000000) == 0) \ 02082 { \ 02083 goto skipdrawdepth; \ 02084 } \ 02085 } \ 02086 \ 02087 /* pattern mode */ \ 02088 else \ 02089 { \ 02090 int stipple_index = (((YY) & 3) << 3) | (~(XX) & 7); \ 02091 if ((((VV)->reg[stipple].u >> stipple_index) & 1) == 0) \ 02092 { \ 02093 goto skipdrawdepth; \ 02094 } \ 02095 } \ 02096 } \ 02097 \ 02098 /* compute "floating point" W value (used for depth and fog) */ \ 02099 if ((ITERW) & LONGTYPE(0xffff00000000)) \ 02100 wfloat = 0x0000; \ 02101 else \ 02102 { \ 02103 UINT32 temp = (UINT32)(ITERW); \ 02104 if ((temp & 0xffff0000) == 0) \ 02105 wfloat = 0xffff; \ 02106 else \ 02107 { \ 02108 int exp = count_leading_zeros(temp); \ 02109 wfloat = (INT32)(((unsigned int)exp << 12) | ((~temp >> (19 - exp)) & 0xfff)) + 1; \ 02110 } \ 02111 } \ 02112 fogdepth = wfloat; \ 02113 /* add the bias for fog selection*/ \ 02114 if (FBZMODE_ENABLE_DEPTH_BIAS(FBZMODE)) \ 02115 { \ 02116 fogdepth += (INT16)(VV)->reg[zaColor].u; \ 02117 CLAMP(fogdepth, 0, 0xffff); \ 02118 } \ 02119 \ 02120 /* compute depth value (W or Z) for this pixel */ \ 02121 if (FBZMODE_WBUFFER_SELECT(FBZMODE) == 0) \ 02122 { \ 02123 CLAMPED_Z(ITERZ, FBZCOLORPATH, depthval); \ 02124 } \ 02125 else if (FBZMODE_DEPTH_FLOAT_SELECT(FBZMODE) == 0) \ 02126 depthval = wfloat; \ 02127 else \ 02128 { \ 02129 if ((unsigned int)(ITERZ) & 0xf0000000l) \ 02130 depthval = 0x0000; \ 02131 else \ 02132 { \ 02133 UINT32 temp = (UINT32)(ITERZ << 4); \ 02134 if (!(temp & 0xffff0000u)) \ 02135 depthval = 0xffff; \ 02136 else \ 02137 { \ 02138 int exp = count_leading_zeros(temp); \ 02139 depthval = (INT32)(((unsigned int)exp << 12) | ((~temp >> (19 - exp)) & 0xfff)) + 1; \ 02140 } \ 02141 } \ 02142 } \ 02143 /* add the bias */ \ 02144 biasdepth = depthval; \ 02145 if (FBZMODE_ENABLE_DEPTH_BIAS(FBZMODE)) \ 02146 { \ 02147 biasdepth += (INT16)(VV)->reg[zaColor].u; \ 02148 CLAMP(biasdepth, 0, 0xffff); \ 02149 } \ 02150 02151 02152 #define DEPTH_TEST(VV, STATS, XX, FBZMODE) \ 02153 do \ 02154 { \ 02155 /* handle depth buffer testing */ \ 02156 if (FBZMODE_ENABLE_DEPTHBUF(FBZMODE)) \ 02157 { \ 02158 INT32 depthsource; \ 02159 \ 02160 /* the source depth is either the iterated W/Z+bias or a */ \ 02161 /* constant value */ \ 02162 if (FBZMODE_DEPTH_SOURCE_COMPARE(FBZMODE) == 0) \ 02163 depthsource = biasdepth; \ 02164 else \ 02165 depthsource = (UINT16)(VV)->reg[zaColor].u; \ 02166 \ 02167 /* test against the depth buffer */ \ 02168 switch (FBZMODE_DEPTH_FUNCTION(FBZMODE)) \ 02169 { \ 02170 case 0: /* depthOP = never */ \ 02171 (STATS)->zfunc_fail++; \ 02172 goto skipdrawdepth; \ 02173 \ 02174 case 1: /* depthOP = less than */ \ 02175 if (depthsource >= depth[XX]) \ 02176 { \ 02177 (STATS)->zfunc_fail++; \ 02178 goto skipdrawdepth; \ 02179 } \ 02180 break; \ 02181 \ 02182 case 2: /* depthOP = equal */ \ 02183 if (depthsource != depth[XX]) \ 02184 { \ 02185 (STATS)->zfunc_fail++; \ 02186 goto skipdrawdepth; \ 02187 } \ 02188 break; \ 02189 \ 02190 case 3: /* depthOP = less than or equal */ \ 02191 if (depthsource > depth[XX]) \ 02192 { \ 02193 (STATS)->zfunc_fail++; \ 02194 goto skipdrawdepth; \ 02195 } \ 02196 break; \ 02197 \ 02198 case 4: /* depthOP = greater than */ \ 02199 if (depthsource <= depth[XX]) \ 02200 { \ 02201 (STATS)->zfunc_fail++; \ 02202 goto skipdrawdepth; \ 02203 } \ 02204 break; \ 02205 \ 02206 case 5: /* depthOP = not equal */ \ 02207 if (depthsource == depth[XX]) \ 02208 { \ 02209 (STATS)->zfunc_fail++; \ 02210 goto skipdrawdepth; \ 02211 } \ 02212 break; \ 02213 \ 02214 case 6: /* depthOP = greater than or equal */ \ 02215 if (depthsource < depth[XX]) \ 02216 { \ 02217 (STATS)->zfunc_fail++; \ 02218 goto skipdrawdepth; \ 02219 } \ 02220 break; \ 02221 \ 02222 case 7: /* depthOP = always */ \ 02223 break; \ 02224 } \ 02225 } \ 02226 } \ 02227 while (0) 02228 02229 02230 #define PIXEL_PIPELINE_MODIFY(VV, DITHER, DITHER4, XX, FBZMODE, FBZCOLORPATH, ALPHAMODE, FOGMODE, ITERZ, ITERW, ITERAXXX) \ 02231 \ 02232 /* perform fogging */ \ 02233 prefogr = r; \ 02234 prefogg = g; \ 02235 prefogb = b; \ 02236 APPLY_FOGGING(VV, FOGMODE, FBZCOLORPATH, XX, DITHER4, r, g, b, \ 02237 ITERZ, ITERW, ITERAXXX); \ 02238 \ 02239 /* perform alpha blending */ \ 02240 APPLY_ALPHA_BLEND(FBZMODE, ALPHAMODE, XX, DITHER, r, g, b, a); 02241 02242 02243 #define PIXEL_PIPELINE_FINISH(VV, DITHER_LOOKUP, XX, dest, depth, FBZMODE) \ 02244 \ 02245 /* write to framebuffer */ \ 02246 if (FBZMODE_RGB_BUFFER_MASK(FBZMODE)) \ 02247 { \ 02248 /* apply dithering */ \ 02249 APPLY_DITHER(FBZMODE, XX, DITHER_LOOKUP, r, g, b); \ 02250 dest[XX] = (UINT16)((r << 11) | (g << 5) | b); \ 02251 } \ 02252 \ 02253 /* write to aux buffer */ \ 02254 if (depth && FBZMODE_AUX_BUFFER_MASK(FBZMODE)) \ 02255 { \ 02256 if (FBZMODE_ENABLE_ALPHA_PLANES(FBZMODE) == 0) \ 02257 depth[XX] = (UINT16)biasdepth; \ 02258 else \ 02259 depth[XX] = (UINT16)a; \ 02260 } 02261 02262 #define PIXEL_PIPELINE_END(STATS) \ 02263 \ 02264 /* track pixel writes to the frame buffer regardless of mask */ \ 02265 (STATS)->pixels_out++; \ 02266 \ 02267 skipdrawdepth: \ 02268 ; \ 02269 } \ 02270 while (0) 02271 02272 #endif