summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/vooddefs.ipp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/video/vooddefs.ipp')
-rw-r--r--src/devices/video/vooddefs.ipp3181
1 files changed, 0 insertions, 3181 deletions
diff --git a/src/devices/video/vooddefs.ipp b/src/devices/video/vooddefs.ipp
deleted file mode 100644
index d9726edf960..00000000000
--- a/src/devices/video/vooddefs.ipp
+++ /dev/null
@@ -1,3181 +0,0 @@
- // license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-/***************************************************************************
-
- vooddefs.h
-
- 3dfx Voodoo Graphics SST-1/2 emulator.
-
-***************************************************************************/
-
-#ifndef MAME_VIDEO_VOODDEFS_IPP
-#define MAME_VIDEO_VOODDEFS_IPP
-
-#pragma once
-
-#include "voodoo.h"
-
-
-
-/*************************************
- *
- * Core types
- *
- *************************************/
-
-typedef voodoo_reg rgb_union;
-
-
-
-
-
-/*************************************
- *
- * Inline FIFO management
- *
- *************************************/
-
-inline void voodoo_device::fifo_state::add(uint32_t data)
-{
- /* compute the value of 'in' after we add this item */
- int32_t next_in = in + 1;
- if (next_in >= size)
- next_in = 0;
-
- /* as long as it's not equal to the output pointer, we can do it */
- if (next_in != out)
- {
- base[in] = data;
- in = next_in;
- }
-}
-
-
-inline uint32_t voodoo_device::fifo_state::remove()
-{
- uint32_t data = 0xffffffff;
-
- /* as long as we have data, we can do it */
- if (out != in)
- {
- int32_t next_out;
-
- /* fetch the data */
- data = base[out];
-
- /* advance the output pointer */
- next_out = out + 1;
- if (next_out >= size)
- next_out = 0;
- out = next_out;
- }
- return data;
-}
-
-
-inline int32_t voodoo_device::fifo_state::items() const
-{
- int32_t items = in - out;
- if (items < 0)
- items += size;
- return items;
-}
-
-
-
-/*************************************
- *
- * Computes a fast 16.16 reciprocal
- * of a 16.32 value; used for
- * computing 1/w in the rasterizer.
- *
- * Since it is trivial to also
- * compute log2(1/w) = -log2(w) at
- * the same time, we do that as well
- * to 16.8 precision for LOD
- * calculations.
- *
- * On a Pentium M, this routine is
- * 20% faster than a 64-bit integer
- * divide and also produces the log
- * for free.
- *
- *************************************/
-
-static inline int32_t fast_reciplog(int64_t value, int32_t *log2)
-{
- extern uint32_t voodoo_reciplog[];
- uint32_t temp, recip, rlog;
- uint32_t interp;
- uint32_t *table;
- int neg = false;
- int lz, exp = 0;
-
- /* always work with unsigned numbers */
- if (value < 0)
- {
- value = -value;
- neg = true;
- }
-
- /* if we've spilled out of 32 bits, push it down under 32 */
- if (value & 0xffff00000000U)
- {
- temp = (uint32_t)(value >> 16);
- exp -= 16;
- }
- else
- temp = (uint32_t)value;
-
- /* if the resulting value is 0, the reciprocal is infinite */
- if (UNEXPECTED(temp == 0))
- {
- *log2 = 1000 << LOG_OUTPUT_PREC;
- return neg ? 0x80000000 : 0x7fffffff;
- }
-
- /* determine how many leading zeros in the value and shift it up high */
- lz = count_leading_zeros_32(temp);
- temp <<= lz;
- exp += lz;
-
- /* compute a pointer to the table entries we want */
- /* math is a bit funny here because we shift one less than we need to in order */
- /* to account for the fact that there are two uint32_t's per table entry */
- table = &voodoo_reciplog[(temp >> (31 - RECIPLOG_LOOKUP_BITS - 1)) & ((2 << RECIPLOG_LOOKUP_BITS) - 2)];
-
- /* compute the interpolation value */
- interp = (temp >> (31 - RECIPLOG_LOOKUP_BITS - 8)) & 0xff;
-
- /* do a linear interpolatation between the two nearest table values */
- /* for both the log and the reciprocal */
- rlog = (table[1] * (0x100 - interp) + table[3] * interp) >> 8;
- recip = (table[0] * (0x100 - interp) + table[2] * interp) >> 8;
-
- /* the log result is the fractional part of the log; round it to the output precision */
- rlog = (rlog + (1 << (RECIPLOG_LOOKUP_PREC - LOG_OUTPUT_PREC - 1))) >> (RECIPLOG_LOOKUP_PREC - LOG_OUTPUT_PREC);
-
- /* the exponent is the non-fractional part of the log; normally, we would subtract it from rlog */
- /* but since we want the log(1/value) = -log(value), we subtract rlog from the exponent */
- *log2 = ((exp - (31 - RECIPLOG_INPUT_PREC)) << LOG_OUTPUT_PREC) - rlog;
-
- /* adjust the exponent to account for all the reciprocal-related parameters to arrive at a final shift amount */
- exp += (RECIP_OUTPUT_PREC - RECIPLOG_LOOKUP_PREC) - (31 - RECIPLOG_INPUT_PREC);
-
- /* shift by the exponent */
- if (exp < 0)
- recip >>= -exp;
- else
- recip <<= exp;
-
- /* on the way out, apply the original sign to the reciprocal */
- return neg ? -recip : recip;
-}
-
-
-
-/*************************************
- *
- * Float-to-int conversions
- *
- *************************************/
-
-static inline int32_t float_to_int32(uint32_t data, int fixedbits)
-{
- int exponent = ((data >> 23) & 0xff) - 127 - 23 + fixedbits;
- int32_t result = (data & 0x7fffff) | 0x800000;
- if (exponent < 0)
- {
- if (exponent > -32)
- result >>= -exponent;
- else
- result = 0;
- }
- else
- {
- if (exponent < 32)
- result <<= exponent;
- else
- result = 0x7fffffff;
- }
- if (data & 0x80000000)
- result = -result;
- return result;
-}
-
-
-static inline int64_t float_to_int64(uint32_t data, int fixedbits)
-{
- int exponent = ((data >> 23) & 0xff) - 127 - 23 + fixedbits;
- int64_t result = (data & 0x7fffff) | 0x800000;
- if (exponent < 0)
- {
- if (exponent > -64)
- result >>= -exponent;
- else
- result = 0;
- }
- else
- {
- if (exponent < 64)
- result <<= exponent;
- else
- result = 0x7fffffffffffffffU;
- }
- if (data & 0x80000000)
- result = -result;
- return result;
-}
-
-
-
-/*************************************
- *
- * Rasterizer inlines
- *
- *************************************/
-
-static inline uint32_t normalize_color_path(uint32_t eff_color_path)
-{
- /* ignore the subpixel adjust and texture enable flags */
- eff_color_path &= ~((1 << 26) | (1 << 27));
-
- return eff_color_path;
-}
-
-
-static inline uint32_t normalize_alpha_mode(uint32_t eff_alpha_mode)
-{
- /* always ignore alpha ref value */
- eff_alpha_mode &= ~(0xff << 24);
-
- /* if not doing alpha testing, ignore the alpha function and ref value */
- if (!ALPHAMODE_ALPHATEST(eff_alpha_mode))
- eff_alpha_mode &= ~(7 << 1);
-
- /* if not doing alpha blending, ignore the source and dest blending factors */
- if (!ALPHAMODE_ALPHABLEND(eff_alpha_mode))
- eff_alpha_mode &= ~((15 << 8) | (15 << 12) | (15 << 16) | (15 << 20));
-
- return eff_alpha_mode;
-}
-
-
-static inline uint32_t normalize_fog_mode(uint32_t eff_fog_mode)
-{
- /* if not doing fogging, ignore all the other fog bits */
- if (!FOGMODE_ENABLE_FOG(eff_fog_mode))
- eff_fog_mode = 0;
-
- return eff_fog_mode;
-}
-
-
-static inline uint32_t normalize_fbz_mode(uint32_t eff_fbz_mode)
-{
- /* ignore the draw buffer */
- eff_fbz_mode &= ~(3 << 14);
-
- return eff_fbz_mode;
-}
-
-
-static inline uint32_t normalize_tex_mode(uint32_t eff_tex_mode)
-{
- /* ignore the NCC table and seq_8_downld flags */
- eff_tex_mode &= ~((1 << 5) | (1 << 31));
-
- /* classify texture formats into 3 format categories */
- if (TEXMODE_FORMAT(eff_tex_mode) < 8)
- eff_tex_mode = (eff_tex_mode & ~(0xf << 8)) | (0 << 8);
- else if (TEXMODE_FORMAT(eff_tex_mode) >= 10 && TEXMODE_FORMAT(eff_tex_mode) <= 12)
- eff_tex_mode = (eff_tex_mode & ~(0xf << 8)) | (10 << 8);
- else
- eff_tex_mode = (eff_tex_mode & ~(0xf << 8)) | (8 << 8);
-
- return eff_tex_mode;
-}
-
-
-inline uint32_t voodoo_device::raster_info::compute_hash() const
-{
- uint32_t result;
-
- /* make a hash */
- result = eff_color_path;
- result = (result << 1) | (result >> 31);
- result ^= eff_fbz_mode;
- result = (result << 1) | (result >> 31);
- result ^= eff_alpha_mode;
- result = (result << 1) | (result >> 31);
- result ^= eff_fog_mode;
- result = (result << 1) | (result >> 31);
- result ^= eff_tex_mode_0;
- result = (result << 1) | (result >> 31);
- result ^= eff_tex_mode_1;
-
- return result % RASTER_HASH_SIZE;
-}
-
-
-
-/*************************************
- *
- * Dithering macros
- *
- *************************************/
-
-/* note that these equations and the dither matrixes have
- been confirmed to be exact matches to the real hardware */
-#define DITHER_RB(val,dith) ((((val) << 1) - ((val) >> 4) + ((val) >> 7) + (dith)) >> 1)
-#define DITHER_G(val,dith) ((((val) << 2) - ((val) >> 4) + ((val) >> 6) + (dith)) >> 2)
-
-#define DECLARE_DITHER_POINTERS \
- const uint8_t *dither_lookup = nullptr; \
- const uint8_t *dither4 = nullptr; \
- const uint8_t *dither = nullptr
-#define DECLARE_DITHER_POINTERS_NO_DITHER_VAR \
- const uint8_t *dither_lookup = nullptr;
-#define COMPUTE_DITHER_POINTERS(FBZMODE, YY, FOGMODE) \
-do \
-{ \
- if (FBZMODE_ENABLE_DITHERING(FBZMODE) || FOGMODE_FOG_DITHER(FOGMODE)) \
- dither4 = &dither_matrix_4x4[((YY) & 3) * 4]; \
- /* compute the dithering pointers */ \
- if (FBZMODE_ENABLE_DITHERING(FBZMODE)) \
- { \
- if (FBZMODE_DITHER_TYPE(FBZMODE) == 0) \
- { \
- dither = &dither_subtract_4x4[((YY) & 3) * 4]; \
- dither_lookup = &dither4_lookup[(YY & 3) << 11]; \
- } \
- else \
- { \
- dither = &dither_subtract_2x2[((YY) & 3) * 4]; \
- dither_lookup = &dither2_lookup[(YY & 3) << 11]; \
- } \
- } \
-} \
-while (0)
-
-#define COMPUTE_DITHER_POINTERS_NO_DITHER_VAR(FBZMODE, YY) \
-do \
-{ \
- /* compute the dithering pointers */ \
- if (FBZMODE_ENABLE_DITHERING(FBZMODE)) \
- { \
- if (FBZMODE_DITHER_TYPE(FBZMODE) == 0) \
- { \
- dither_lookup = &dither4_lookup[(YY & 3) << 11]; \
- } \
- else \
- { \
- dither_lookup = &dither2_lookup[(YY & 3) << 11]; \
- } \
- } \
-} \
-while (0)
-
-#define APPLY_DITHER(FBZMODE, XX, DITHER_LOOKUP, RR, GG, BB) \
-do \
-{ \
- /* apply dithering */ \
- if (FBZMODE_ENABLE_DITHERING(FBZMODE)) \
- { \
- /* look up the dither value from the appropriate matrix */ \
- const uint8_t *dith = &DITHER_LOOKUP[((XX) & 3) << 1]; \
- \
- /* apply dithering to R,G,B */ \
- (RR) = dith[((RR) << 3) + 0]; \
- (GG) = dith[((GG) << 3) + 1]; \
- (BB) = dith[((BB) << 3) + 0]; \
- } \
- else \
- { \
- (RR) >>= 3; \
- (GG) >>= 2; \
- (BB) >>= 3; \
- } \
-} \
-while (0)
-
-
-
-/*************************************
- *
- * Clamping macros
- *
- *************************************/
-
-#define CLAMPED_ARGB(ITERR, ITERG, ITERB, ITERA, FBZCP, RESULT) \
-do \
-{ \
- r = (int32_t)(ITERR) >> 12; \
- g = (int32_t)(ITERG) >> 12; \
- b = (int32_t)(ITERB) >> 12; \
- a = (int32_t)(ITERA) >> 12; \
- \
- if (FBZCP_RGBZW_CLAMP(FBZCP) == 0) \
- { \
- r &= 0xfff; \
- RESULT.rgb.r = r; \
- if (r == 0xfff) \
- RESULT.rgb.r = 0; \
- else if (r == 0x100) \
- RESULT.rgb.r = 0xff; \
- \
- g &= 0xfff; \
- RESULT.rgb.g = g; \
- if (g == 0xfff) \
- RESULT.rgb.g = 0; \
- else if (g == 0x100) \
- RESULT.rgb.g = 0xff; \
- \
- b &= 0xfff; \
- RESULT.rgb.b = b; \
- if (b == 0xfff) \
- RESULT.rgb.b = 0; \
- else if (b == 0x100) \
- RESULT.rgb.b = 0xff; \
- \
- a &= 0xfff; \
- RESULT.rgb.a = a; \
- if (a == 0xfff) \
- RESULT.rgb.a = 0; \
- else if (a == 0x100) \
- RESULT.rgb.a = 0xff; \
- } \
- else \
- { \
- RESULT.rgb.r = (r < 0) ? 0 : (r > 0xff) ? 0xff : r; \
- RESULT.rgb.g = (g < 0) ? 0 : (g > 0xff) ? 0xff : g; \
- RESULT.rgb.b = (b < 0) ? 0 : (b > 0xff) ? 0xff : b; \
- RESULT.rgb.a = (a < 0) ? 0 : (a > 0xff) ? 0xff : a; \
- } \
-} \
-while (0)
-
-static inline rgbaint_t ATTR_FORCE_INLINE clampARGB(const rgbaint_t &iterargb, uint32_t FBZCP)
-{
- rgbaint_t result(iterargb);
- //rgbaint_t colorint((int32_t) (itera>>12), (int32_t) (iterr>>12), (int32_t) (iterg>>12), (int32_t) (iterb>>12));
- result.shr_imm(12);
-
- if (!FBZCP_RGBZW_CLAMP(FBZCP))
- {
- //r &= 0xfff;
- result.and_imm(0xfff);
- //if (r == 0xfff)
- rgbaint_t temp(result);
- temp.cmpeq_imm(0xfff);
- // result.rgb.r = 0;
- result.andnot_reg(temp);
- //else if (r == 0x100)
- // result.rgb.r = 0xff;
- temp.set(result);
- temp.cmpeq_imm(0x100);
- result.or_reg(temp);
- // else wrap
- result.and_imm(0xff);
- }
- else
- {
- //return colorint.to_rgba_clamp();
- result.clamp_to_uint8();
- }
- return result;
-}
-
-#define CLAMPED_Z(ITERZ, FBZCP, RESULT) \
-do \
-{ \
- (RESULT) = (int32_t)(ITERZ) >> 12; \
- if (FBZCP_RGBZW_CLAMP(FBZCP) == 0) \
- { \
- (RESULT) &= 0xfffff; \
- if ((RESULT) == 0xfffff) \
- (RESULT) = 0; \
- else if ((RESULT) == 0x10000) \
- (RESULT) = 0xffff; \
- else \
- (RESULT) &= 0xffff; \
- } \
- else \
- { \
- CLAMP((RESULT), 0, 0xffff); \
- } \
-} \
-while (0)
-
-
-#define CLAMPED_W(ITERW, FBZCP, RESULT) \
-do \
-{ \
- (RESULT) = (int16_t)((ITERW) >> 32); \
- if (FBZCP_RGBZW_CLAMP(FBZCP) == 0) \
- { \
- (RESULT) &= 0xffff; \
- if ((RESULT) == 0xffff) \
- (RESULT) = 0; \
- else if ((RESULT) == 0x100) \
- (RESULT) = 0xff; \
- (RESULT) &= 0xff; \
- } \
- else \
- { \
- CLAMP((RESULT), 0, 0xff); \
- } \
-} \
-while (0)
-
-
-
-/*************************************
- *
- * Chroma keying macro
- *
- *************************************/
-
-#define APPLY_CHROMAKEY(VV, STATS, FBZMODE, COLOR) \
-do \
-{ \
- if (FBZMODE_ENABLE_CHROMAKEY(FBZMODE)) \
- { \
- /* non-range version */ \
- if (!CHROMARANGE_ENABLE((VV)->reg[chromaRange].u)) \
- { \
- if (((COLOR.u ^ (VV)->reg[chromaKey].u) & 0xffffff) == 0) \
- { \
- (STATS)->chroma_fail++; \
- goto skipdrawdepth; \
- } \
- } \
- \
- /* tricky range version */ \
- else \
- { \
- int32_t low, high, test; \
- int results = 0; \
- \
- /* check blue */ \
- low = (VV)->reg[chromaKey].rgb.b; \
- high = (VV)->reg[chromaRange].rgb.b; \
- test = COLOR.rgb.b; \
- results = (test >= low && test <= high); \
- results ^= CHROMARANGE_BLUE_EXCLUSIVE((VV)->reg[chromaRange].u); \
- results <<= 1; \
- \
- /* check green */ \
- low = (VV)->reg[chromaKey].rgb.g; \
- high = (VV)->reg[chromaRange].rgb.g; \
- test = COLOR.rgb.g; \
- results |= (test >= low && test <= high); \
- results ^= CHROMARANGE_GREEN_EXCLUSIVE((VV)->reg[chromaRange].u); \
- results <<= 1; \
- \
- /* check red */ \
- low = (VV)->reg[chromaKey].rgb.r; \
- high = (VV)->reg[chromaRange].rgb.r; \
- test = COLOR.rgb.r; \
- results |= (test >= low && test <= high); \
- results ^= CHROMARANGE_RED_EXCLUSIVE((VV)->reg[chromaRange].u); \
- \
- /* final result */ \
- if (CHROMARANGE_UNION_MODE((VV)->reg[chromaRange].u)) \
- { \
- if (results != 0) \
- { \
- (STATS)->chroma_fail++; \
- goto skipdrawdepth; \
- } \
- } \
- else \
- { \
- if (results == 7) \
- { \
- (STATS)->chroma_fail++; \
- goto skipdrawdepth; \
- } \
- } \
- } \
- } \
-} \
-while (0)
-
-inline bool ATTR_FORCE_INLINE voodoo_device::chromaKeyTest(voodoo_device *vd, stats_block *stats, uint32_t fbzModeReg, rgbaint_t rgbaIntColor)
-{
- {
- rgb_union color;
- color.u = rgbaIntColor.to_rgba();
- /* non-range version */
- if (!CHROMARANGE_ENABLE(vd->reg[chromaRange].u))
- {
- if (((color.u ^ vd->reg[chromaKey].u) & 0xffffff) == 0)
- {
- stats->chroma_fail++;
- return false;
- }
- }
-
- /* tricky range version */
- else
- {
- int32_t low, high, test;
- int results;
-
- /* check blue */
- low = vd->reg[chromaKey].rgb.b;
- high = vd->reg[chromaRange].rgb.b;
- test = color.rgb.b;
- results = (test >= low && test <= high);
- results ^= CHROMARANGE_BLUE_EXCLUSIVE(vd->reg[chromaRange].u);
- results <<= 1;
-
- /* check green */
- low = vd->reg[chromaKey].rgb.g;
- high = vd->reg[chromaRange].rgb.g;
- test = color.rgb.g;
- results |= (test >= low && test <= high);
- results ^= CHROMARANGE_GREEN_EXCLUSIVE(vd->reg[chromaRange].u);
- results <<= 1;
-
- /* check red */
- low = vd->reg[chromaKey].rgb.r;
- high = vd->reg[chromaRange].rgb.r;
- test = color.rgb.r;
- results |= (test >= low && test <= high);
- results ^= CHROMARANGE_RED_EXCLUSIVE(vd->reg[chromaRange].u);
-
- /* final result */
- if (CHROMARANGE_UNION_MODE(vd->reg[chromaRange].u))
- {
- if (results != 0)
- {
- stats->chroma_fail++;
- return false;
- }
- }
- else
- {
- if (results == 7)
- {
- stats->chroma_fail++;
- return false;
- }
- }
- }
- }
- return true;
-}
-
-
-
-/*************************************
- *
- * Alpha masking macro
- *
- *************************************/
-
-#define APPLY_ALPHAMASK(VV, STATS, FBZMODE, AA) \
-do \
-{ \
- if (FBZMODE_ENABLE_ALPHA_MASK(FBZMODE)) \
- { \
- if (((AA) & 1) == 0) \
- { \
- (STATS)->afunc_fail++; \
- goto skipdrawdepth; \
- } \
- } \
-} \
-while (0)
-
-inline bool voodoo_device::alphaMaskTest(stats_block *stats, uint32_t fbzModeReg, uint8_t alpha)
-{
- {
- if ((alpha & 1) == 0)
- {
- stats->afunc_fail++;
- return false;
- }
- }
- return true;
-}
-
-/*************************************
- *
- * Alpha testing macro
- *
- *************************************/
-
-#define APPLY_ALPHATEST(VV, STATS, ALPHAMODE, AA) \
-do \
-{ \
- if (ALPHAMODE_ALPHATEST(ALPHAMODE)) \
- { \
- uint8_t alpharef = (VV)->reg[alphaMode].rgb.a; \
- switch (ALPHAMODE_ALPHAFUNCTION(ALPHAMODE)) \
- { \
- case 0: /* alphaOP = never */ \
- (STATS)->afunc_fail++; \
- goto skipdrawdepth; \
- \
- case 1: /* alphaOP = less than */ \
- if ((AA) >= alpharef) \
- { \
- (STATS)->afunc_fail++; \
- goto skipdrawdepth; \
- } \
- break; \
- \
- case 2: /* alphaOP = equal */ \
- if ((AA) != alpharef) \
- { \
- (STATS)->afunc_fail++; \
- goto skipdrawdepth; \
- } \
- break; \
- \
- case 3: /* alphaOP = less than or equal */ \
- if ((AA) > alpharef) \
- { \
- (STATS)->afunc_fail++; \
- goto skipdrawdepth; \
- } \
- break; \
- \
- case 4: /* alphaOP = greater than */ \
- if ((AA) <= alpharef) \
- { \
- (STATS)->afunc_fail++; \
- goto skipdrawdepth; \
- } \
- break; \
- \
- case 5: /* alphaOP = not equal */ \
- if ((AA) == alpharef) \
- { \
- (STATS)->afunc_fail++; \
- goto skipdrawdepth; \
- } \
- break; \
- \
- case 6: /* alphaOP = greater than or equal */ \
- if ((AA) < alpharef) \
- { \
- (STATS)->afunc_fail++; \
- goto skipdrawdepth; \
- } \
- break; \
- \
- case 7: /* alphaOP = always */ \
- break; \
- } \
- } \
-} \
-while (0)
-
-inline bool ATTR_FORCE_INLINE voodoo_device::alphaTest(uint8_t alpharef, stats_block *stats, uint32_t alphaModeReg, uint8_t alpha)
-{
- {
- switch (ALPHAMODE_ALPHAFUNCTION(alphaModeReg))
- {
- case 0: /* alphaOP = never */
- stats->afunc_fail++;
- return false;
-
- case 1: /* alphaOP = less than */
- if (alpha >= alpharef)
- {
- stats->afunc_fail++;
- return false;
- }
- break;
-
- case 2: /* alphaOP = equal */
- if (alpha != alpharef)
- {
- stats->afunc_fail++;
- return false;
- }
- break;
-
- case 3: /* alphaOP = less than or equal */
- if (alpha > alpharef)
- {
- stats->afunc_fail++;
- return false;
- }
- break;
-
- case 4: /* alphaOP = greater than */
- if (alpha <= alpharef)
- {
- stats->afunc_fail++;
- return false;
- }
- break;
-
- case 5: /* alphaOP = not equal */
- if (alpha == alpharef)
- {
- stats->afunc_fail++;
- return false;
- }
- break;
-
- case 6: /* alphaOP = greater than or equal */
- if (alpha < alpharef)
- {
- stats->afunc_fail++;
- return false;
- }
- break;
-
- case 7: /* alphaOP = always */
- break;
- }
- }
- return true;
-}
-
-
-/*************************************
- *
- * Alpha blending macro
- *
- *************************************/
-
-#define APPLY_ALPHA_BLEND(FBZMODE, ALPHAMODE, XX, DITHER, RR, GG, BB, AA) \
-do \
-{ \
- if (ALPHAMODE_ALPHABLEND(ALPHAMODE)) \
- { \
- int dpix = dest[XX]; \
- int dr, dg, db; \
- EXTRACT_565_TO_888(dpix, dr, dg, db); \
- int da = FBZMODE_ENABLE_ALPHA_PLANES(FBZMODE) ? depth[XX] : 0xff; \
- int sr = (RR); \
- int sg = (GG); \
- int sb = (BB); \
- int sa = (AA); \
- int ta; \
- \
- /* apply dither subtraction */ \
- if (FBZMODE_ALPHA_DITHER_SUBTRACT(FBZMODE)) \
- { \
- /* look up the dither value from the appropriate matrix */ \
- int dith = DITHER[(XX) & 3]; \
- \
- /* subtract the dither value */ \
- dr = ((dr << 1) + 15 - dith) >> 1; \
- dg = ((dg << 2) + 15 - dith) >> 2; \
- db = ((db << 1) + 15 - dith) >> 1; \
- } \
- \
- /* compute source portion */ \
- switch (ALPHAMODE_SRCRGBBLEND(ALPHAMODE)) \
- { \
- default: /* reserved */ \
- case 0: /* AZERO */ \
- (RR) = (GG) = (BB) = 0; \
- break; \
- \
- case 1: /* ASRC_ALPHA */ \
- (RR) = (sr * (sa + 1)) >> 8; \
- (GG) = (sg * (sa + 1)) >> 8; \
- (BB) = (sb * (sa + 1)) >> 8; \
- break; \
- \
- case 2: /* A_COLOR */ \
- (RR) = (sr * (dr + 1)) >> 8; \
- (GG) = (sg * (dg + 1)) >> 8; \
- (BB) = (sb * (db + 1)) >> 8; \
- break; \
- \
- case 3: /* ADST_ALPHA */ \
- (RR) = (sr * (da + 1)) >> 8; \
- (GG) = (sg * (da + 1)) >> 8; \
- (BB) = (sb * (da + 1)) >> 8; \
- break; \
- \
- case 4: /* AONE */ \
- break; \
- \
- case 5: /* AOMSRC_ALPHA */ \
- (RR) = (sr * (0x100 - sa)) >> 8; \
- (GG) = (sg * (0x100 - sa)) >> 8; \
- (BB) = (sb * (0x100 - sa)) >> 8; \
- break; \
- \
- case 6: /* AOM_COLOR */ \
- (RR) = (sr * (0x100 - dr)) >> 8; \
- (GG) = (sg * (0x100 - dg)) >> 8; \
- (BB) = (sb * (0x100 - db)) >> 8; \
- break; \
- \
- case 7: /* AOMDST_ALPHA */ \
- (RR) = (sr * (0x100 - da)) >> 8; \
- (GG) = (sg * (0x100 - da)) >> 8; \
- (BB) = (sb * (0x100 - da)) >> 8; \
- break; \
- \
- case 15: /* ASATURATE */ \
- ta = (sa < (0x100 - da)) ? sa : (0x100 - da); \
- (RR) = (sr * (ta + 1)) >> 8; \
- (GG) = (sg * (ta + 1)) >> 8; \
- (BB) = (sb * (ta + 1)) >> 8; \
- break; \
- } \
- \
- /* add in dest portion */ \
- switch (ALPHAMODE_DSTRGBBLEND(ALPHAMODE)) \
- { \
- default: /* reserved */ \
- case 0: /* AZERO */ \
- break; \
- \
- case 1: /* ASRC_ALPHA */ \
- (RR) += (dr * (sa + 1)) >> 8; \
- (GG) += (dg * (sa + 1)) >> 8; \
- (BB) += (db * (sa + 1)) >> 8; \
- break; \
- \
- case 2: /* A_COLOR */ \
- (RR) += (dr * (sr + 1)) >> 8; \
- (GG) += (dg * (sg + 1)) >> 8; \
- (BB) += (db * (sb + 1)) >> 8; \
- break; \
- \
- case 3: /* ADST_ALPHA */ \
- (RR) += (dr * (da + 1)) >> 8; \
- (GG) += (dg * (da + 1)) >> 8; \
- (BB) += (db * (da + 1)) >> 8; \
- break; \
- \
- case 4: /* AONE */ \
- (RR) += dr; \
- (GG) += dg; \
- (BB) += db; \
- break; \
- \
- case 5: /* AOMSRC_ALPHA */ \
- (RR) += (dr * (0x100 - sa)) >> 8; \
- (GG) += (dg * (0x100 - sa)) >> 8; \
- (BB) += (db * (0x100 - sa)) >> 8; \
- break; \
- \
- case 6: /* AOM_COLOR */ \
- (RR) += (dr * (0x100 - sr)) >> 8; \
- (GG) += (dg * (0x100 - sg)) >> 8; \
- (BB) += (db * (0x100 - sb)) >> 8; \
- break; \
- \
- case 7: /* AOMDST_ALPHA */ \
- (RR) += (dr * (0x100 - da)) >> 8; \
- (GG) += (dg * (0x100 - da)) >> 8; \
- (BB) += (db * (0x100 - da)) >> 8; \
- break; \
- \
- case 15: /* A_COLORBEFOREFOG */ \
- (RR) += (dr * (prefogr + 1)) >> 8; \
- (GG) += (dg * (prefogg + 1)) >> 8; \
- (BB) += (db * (prefogb + 1)) >> 8; \
- break; \
- } \
- \
- /* blend the source alpha */ \
- (AA) = 0; \
- if (ALPHAMODE_SRCALPHABLEND(ALPHAMODE) == 4) \
- (AA) = sa; \
- \
- /* blend the dest alpha */ \
- if (ALPHAMODE_DSTALPHABLEND(ALPHAMODE) == 4) \
- (AA) += da; \
- \
- /* clamp */ \
- CLAMP((RR), 0x00, 0xff); \
- CLAMP((GG), 0x00, 0xff); \
- CLAMP((BB), 0x00, 0xff); \
- CLAMP((AA), 0x00, 0xff); \
- } \
-} \
-while (0)
-
-static inline void ATTR_FORCE_INLINE alphaBlend(uint32_t FBZMODE, uint32_t ALPHAMODE, int32_t x, const uint8_t *dither, int dpix, uint16_t *depth, rgbaint_t &preFog, rgbaint_t &srcColor, rgb_t *convTable)
-{
- {
- //int dpix = dest[XX];
- int dr, dg, db;
- //EXTRACT_565_TO_888(dpix, dr, dg, db);
- rgb_t drgb = convTable[dpix];
- drgb.expand_rgb(dr, dg, db);
- int da = FBZMODE_ENABLE_ALPHA_PLANES(FBZMODE) ? depth[x] : 0xff;
- //int sr = (RR);
- //int sg = (GG);
- //int sb = (BB);
- //int sa = (AA);
- int sa = srcColor.get_a();
- int ta;
- int srcAlphaScale, destAlphaScale;
- rgbaint_t srcScale, destScale;
-
- /* apply dither subtraction */
- if (FBZMODE_ALPHA_DITHER_SUBTRACT(FBZMODE))
- {
- /* look up the dither value from the appropriate matrix */
- int dith = dither[x & 3];
-
- /* subtract the dither value */
- dr += dith;
- db += dith;
- dg += dith >> 1;
- }
-
- /* blend the source alpha */
- if (ALPHAMODE_SRCALPHABLEND(ALPHAMODE) == 4)
- srcAlphaScale = 256;
- //(AA) = sa;
- else
- srcAlphaScale = 0;
-
- /* compute source portion */
- switch (ALPHAMODE_SRCRGBBLEND(ALPHAMODE))
- {
- default: /* reserved */
- case 0: /* AZERO */
- srcScale.zero();
- //(RR) = (GG) = (BB) = 0;
- break;
-
- case 1: /* ASRC_ALPHA */
- ta = sa + 1;
- srcScale.set_all(ta);
- //(RR) = (sr * (sa + 1)) >> 8;
- //(GG) = (sg * (sa + 1)) >> 8;
- //(BB) = (sb * (sa + 1)) >> 8;
- break;
-
- case 2: /* A_COLOR */
- srcScale.set(dr, dr, dg, db);
- srcScale.add_imm(1);
- //(RR) = (sr * (dr + 1)) >> 8;
- //(GG) = (sg * (dg + 1)) >> 8;
- //(BB) = (sb * (db + 1)) >> 8;
- break;
-
- case 3: /* ADST_ALPHA */
- ta = da + 1;
- srcScale.set_all(ta);
- //(RR) = (sr * (da + 1)) >> 8;
- //(GG) = (sg * (da + 1)) >> 8;
- //(BB) = (sb * (da + 1)) >> 8;
- break;
-
- case 4: /* AONE */
- srcScale.set_all(256);
- break;
-
- case 5: /* AOMSRC_ALPHA */
- ta = (0x100 - sa);
- srcScale.set_all(ta);
- //(RR) = (sr * (0x100 - sa)) >> 8;
- //(GG) = (sg * (0x100 - sa)) >> 8;
- //(BB) = (sb * (0x100 - sa)) >> 8;
- break;
-
- case 6: /* AOM_COLOR */
- srcScale.set((0x100 - dr), (0x100 - dr), (0x100 - dg), (0x100 - db));
- //(RR) = (sr * (0x100 - dr)) >> 8;
- //(GG) = (sg * (0x100 - dg)) >> 8;
- //(BB) = (sb * (0x100 - db)) >> 8;
- break;
-
- case 7: /* AOMDST_ALPHA */
- ta = (0x100 - da);
- srcScale.set_all(ta);
- //(RR) = (sr * (0x100 - da)) >> 8;
- //(GG) = (sg * (0x100 - da)) >> 8;
- //(BB) = (sb * (0x100 - da)) >> 8;
- break;
-
- case 15: /* ASATURATE */
- ta = (sa < (0x100 - da)) ? sa : (0x100 - da);
- ta++;
- srcScale.set_all(ta);
- //(RR) = (sr * (ta + 1)) >> 8;
- //(GG) = (sg * (ta + 1)) >> 8;
- //(BB) = (sb * (ta + 1)) >> 8;
- break;
- }
- // Set srcScale alpha
- srcScale.set_a16(srcAlphaScale);
-
- /* blend the dest alpha */
- if (ALPHAMODE_DSTALPHABLEND(ALPHAMODE) == 4)
- destAlphaScale = 256;
- //(AA) += da;
- else
- destAlphaScale = 0;
-
- /* add in dest portion */
- switch (ALPHAMODE_DSTRGBBLEND(ALPHAMODE))
- {
- default: /* reserved */
- case 0: /* AZERO */
- destScale.zero();
- break;
-
- case 1: /* ASRC_ALPHA */
- ta = sa + 1;
- destScale.set_all(ta);
- //(RR) += (dr * (sa + 1)) >> 8;
- //(GG) += (dg * (sa + 1)) >> 8;
- //(BB) += (db * (sa + 1)) >> 8;
- break;
-
- case 2: /* A_COLOR */
- destScale.set(srcColor);
- destScale.add_imm(1);
- //(RR) += (dr * (sr + 1)) >> 8;
- //(GG) += (dg * (sg + 1)) >> 8;
- //(BB) += (db * (sb + 1)) >> 8;
- break;
-
- case 3: /* ADST_ALPHA */
- ta = da + 1;
- destScale.set_all(ta);
- //(RR) += (dr * (da + 1)) >> 8;
- //(GG) += (dg * (da + 1)) >> 8;
- //(BB) += (db * (da + 1)) >> 8;
- break;
-
- case 4: /* AONE */
- destScale.set_all(256);
- //(RR) += dr;
- //(GG) += dg;
- //(BB) += db;
- break;
-
- case 5: /* AOMSRC_ALPHA */
- ta = (0x100 - sa);
- destScale.set_all(ta);
- //(RR) += (dr * (0x100 - sa)) >> 8;
- //(GG) += (dg * (0x100 - sa)) >> 8;
- //(BB) += (db * (0x100 - sa)) >> 8;
- break;
-
- case 6: /* AOM_COLOR */
- destScale.set_all(0x100);
- destScale.sub(srcColor);
- //destScale.set(destAlphaScale, (0x100 - color.rgb.r), (0x100 - color.rgb.g), (0x100 - color.rgb.b));
- //(RR) += (dr * (0x100 - sr)) >> 8;
- //(GG) += (dg * (0x100 - sg)) >> 8;
- //(BB) += (db * (0x100 - sb)) >> 8;
- break;
-
- case 7: /* AOMDST_ALPHA */
- ta = (0x100 - da);
- destScale.set_all(ta);
- //(RR) += (dr * (0x100 - da)) >> 8;
- //(GG) += (dg * (0x100 - da)) >> 8;
- //(BB) += (db * (0x100 - da)) >> 8;
- break;
-
- case 15: /* A_COLORBEFOREFOG */
- destScale.set(preFog);
- destScale.add_imm(1);
- //(RR) += (dr * (prefogr + 1)) >> 8;
- //(GG) += (dg * (prefogg + 1)) >> 8;
- //(BB) += (db * (prefogb + 1)) >> 8;
- break;
- }
-
- // Set destScale alpha
- destScale.set_a16(destAlphaScale);
-
- // Main blend
- rgbaint_t destColor(da, dr, dg, db);
-
- srcColor.scale2_add_and_clamp(srcScale, destColor, destScale);
- /* clamp */
- //CLAMP((RR), 0x00, 0xff);
- //CLAMP((GG), 0x00, 0xff);
- //CLAMP((BB), 0x00, 0xff);
- //CLAMP((AA), 0x00, 0xff);
- }
-}
-
-
-/*************************************
- *
- * Fogging macro
- *
- *************************************/
-
-#define APPLY_FOGGING(VV, FOGMODE, FBZCP, XX, DITHER4, RR, GG, BB, ITERZ, ITERW, ITERAXXX) \
-do \
-{ \
- if (FOGMODE_ENABLE_FOG(FOGMODE)) \
- { \
- rgb_union fogcolor = (VV)->reg[fogColor]; \
- int32_t fr, fg, fb; \
- \
- /* constant fog bypasses everything else */ \
- if (FOGMODE_FOG_CONSTANT(FOGMODE)) \
- { \
- fr = fogcolor.rgb.r; \
- fg = fogcolor.rgb.g; \
- fb = fogcolor.rgb.b; \
- } \
- \
- /* non-constant fog comes from several sources */ \
- else \
- { \
- int32_t fogblend = 0; \
- \
- /* if fog_add is zero, we start with the fog color */ \
- if (FOGMODE_FOG_ADD(FOGMODE) == 0) \
- { \
- fr = fogcolor.rgb.r; \
- fg = fogcolor.rgb.g; \
- fb = fogcolor.rgb.b; \
- } \
- else \
- fr = fg = fb = 0; \
- \
- /* if fog_mult is zero, we subtract the incoming color */ \
- if (FOGMODE_FOG_MULT(FOGMODE) == 0) \
- { \
- fr -= (RR); \
- fg -= (GG); \
- fb -= (BB); \
- } \
- \
- /* fog blending mode */ \
- switch (FOGMODE_FOG_ZALPHA(FOGMODE)) \
- { \
- case 0: /* fog table */ \
- { \
- int32_t delta = (VV)->fbi.fogdelta[fogdepth >> 10]; \
- int32_t deltaval; \
- \
- /* perform the multiply against lower 8 bits of wfloat */ \
- deltaval = (delta & (VV)->fbi.fogdelta_mask) * \
- ((fogdepth >> 2) & 0xff); \
- \
- /* fog zones allow for negating this value */ \
- if (FOGMODE_FOG_ZONES(FOGMODE) && (delta & 2)) \
- deltaval = -deltaval; \
- deltaval >>= 6; \
- \
- /* apply dither */ \
- if (FOGMODE_FOG_DITHER(FOGMODE)) \
- deltaval += DITHER4[(XX) & 3]; \
- deltaval >>= 4; \
- \
- /* add to the blending factor */ \
- fogblend = (VV)->fbi.fogblend[fogdepth >> 10] + deltaval; \
- break; \
- } \
- \
- case 1: /* iterated A */ \
- fogblend = ITERAXXX.rgb.a; \
- break; \
- \
- case 2: /* iterated Z */ \
- CLAMPED_Z((ITERZ), FBZCP, fogblend); \
- fogblend >>= 8; \
- break; \
- \
- case 3: /* iterated W - Voodoo 2 only */ \
- CLAMPED_W((ITERW), FBZCP, fogblend); \
- break; \
- } \
- \
- /* perform the blend */ \
- fogblend++; \
- fr = (fr * fogblend) >> 8; \
- fg = (fg * fogblend) >> 8; \
- fb = (fb * fogblend) >> 8; \
- } \
- \
- /* if fog_mult is 0, we add this to the original color */ \
- if (FOGMODE_FOG_MULT(FOGMODE) == 0) \
- { \
- (RR) += fr; \
- (GG) += fg; \
- (BB) += fb; \
- } \
- \
- /* otherwise this just becomes the new color */ \
- else \
- { \
- (RR) = fr; \
- (GG) = fg; \
- (BB) = fb; \
- } \
- \
- /* clamp */ \
- CLAMP((RR), 0x00, 0xff); \
- CLAMP((GG), 0x00, 0xff); \
- CLAMP((BB), 0x00, 0xff); \
- } \
-} \
-while (0)
-
-static inline void ATTR_FORCE_INLINE applyFogging(voodoo_device *vd, uint32_t fbzModeReg, uint32_t fogModeReg, uint32_t fbzCpReg, int32_t x, const uint8_t *dither4, int32_t wFloat,
- rgbaint_t &color, int32_t iterz, int64_t iterw, const rgbaint_t &iterargb)
-{
- {
- /* constant fog bypasses everything else */
- rgbaint_t fogColorLocal(vd->reg[fogColor].u);
-
- if (FOGMODE_FOG_CONSTANT(fogModeReg))
- {
- /* if fog_mult is 0, we add this to the original color */
- if (FOGMODE_FOG_MULT(fogModeReg) == 0)
- {
- fogColorLocal.add(color);
- fogColorLocal.clamp_to_uint8();
- //color += fog;
- }
-
- /* otherwise this just becomes the new color */
- else
- {
- //color = fogColorLocal;
- //color = fog;
- }
- }
- /* non-constant fog comes from several sources */
- else
- {
- int32_t fogblend = 0;
-
- /* if fog_add is zero, we start with the fog color */
- if (FOGMODE_FOG_ADD(fogModeReg))
- fogColorLocal.zero();
- //fr = fg = fb = 0;
-
- /* if fog_mult is zero, we subtract the incoming color */
- if (!FOGMODE_FOG_MULT(fogModeReg))
- {
- // Need to check this, manual states 9 bits
- fogColorLocal.sub(color);
- //fog.rgb -= color.rgb;
- //fr -= (RR);
- //fg -= (GG);
- //fb -= (BB);
- }
-
- /* fog blending mode */
- switch (FOGMODE_FOG_ZALPHA(fogModeReg))
- {
- case 0: /* fog table */
- {
- int32_t fogDepth = wFloat;
- /* add the bias for fog selection*/
- if (FBZMODE_ENABLE_DEPTH_BIAS(fbzModeReg))
- {
- fogDepth += (int16_t)vd->reg[zaColor].u;
- CLAMP(fogDepth, 0, 0xffff);
- }
- int32_t delta = vd->fbi.fogdelta[fogDepth >> 10];
- int32_t deltaval;
-
- /* perform the multiply against lower 8 bits of wfloat */
- deltaval = (delta & vd->fbi.fogdelta_mask) *
- ((fogDepth >> 2) & 0xff);
-
- /* fog zones allow for negating this value */
- if (FOGMODE_FOG_ZONES(fogModeReg) && (delta & 2))
- deltaval = -deltaval;
- deltaval >>= 6;
-
- /* apply dither */
- if (FOGMODE_FOG_DITHER(fogModeReg))
- deltaval += dither4[x&3];
- deltaval >>= 4;
-
- /* add to the blending factor */
- fogblend = vd->fbi.fogblend[fogDepth >> 10] + deltaval;
- break;
- }
-
- case 1: /* iterated A */
- fogblend = iterargb.get_a();
- break;
-
- case 2: /* iterated Z */
- CLAMPED_Z(iterz, fbzCpReg, fogblend);
- fogblend >>= 8;
- break;
-
- case 3: /* iterated W - Voodoo 2 only */
- CLAMPED_W(iterw, fbzCpReg, fogblend);
- break;
- }
-
- /* perform the blend */
- fogblend++;
-
- //fr = (fr * fogblend) >> 8;
- //fg = (fg * fogblend) >> 8;
- //fb = (fb * fogblend) >> 8;
- /* if fog_mult is 0, we add this to the original color */
- fogColorLocal.scale_imm_and_clamp((int16_t)fogblend);
- if (FOGMODE_FOG_MULT(fogModeReg) == 0)
- {
- fogColorLocal.add(color);
- fogColorLocal.clamp_to_uint8();
- //color += fog;
- //(RR) += fr;
- //(GG) += fg;
- //(BB) += fb;
- }
-
- /* otherwise this just becomes the new color */
- else
- {
- //color = fog;
- //(RR) = fr;
- //(GG) = fg;
- //(BB) = fb;
- }
- }
-
-
- /* clamp */
- //CLAMP((RR), 0x00, 0xff);
- //CLAMP((GG), 0x00, 0xff);
- //CLAMP((BB), 0x00, 0xff);
- fogColorLocal.merge_alpha16(color);
- color.set(fogColorLocal);
- }
-}
-
-
-/*************************************
- *
- * Texture pipeline macro
- *
- *************************************/
-
-#define TEXTURE_PIPELINE(TT, XX, DITHER4, TEXMODE, COTHER, LOOKUP, LODBASE, ITERS, ITERT, ITERW, RESULT) \
-do \
-{ \
- int32_t blendr, blendg, blendb, blenda; \
- int32_t tr, tg, tb, ta; \
- int32_t s, t, lod, ilod; \
- int32_t smax, tmax; \
- uint32_t texbase; \
- rgb_union c_local; \
- \
- /* determine the S/T/LOD values for this texture */ \
- if (TEXMODE_ENABLE_PERSPECTIVE(TEXMODE)) \
- { \
- if (USE_FAST_RECIP) { \
- const int32_t oow = fast_reciplog((ITERW), &lod); \
- s = ((int64_t)oow * (ITERS)) >> 29; \
- t = ((int64_t)oow * (ITERT)) >> 29; \
- } else { \
- multi_reciplog(ITERS, ITERT, ITERW, lod, s, t); \
- } \
- lod += (LODBASE); \
- } \
- else \
- { \
- s = (ITERS) >> 14; \
- t = (ITERT) >> 14; \
- lod = (LODBASE); \
- } \
- \
- /* clamp W */ \
- if (TEXMODE_CLAMP_NEG_W(TEXMODE) && (ITERW) < 0) \
- s = t = 0; \
- \
- /* clamp the LOD */ \
- lod += (TT)->lodbias; \
- if (TEXMODE_ENABLE_LOD_DITHER(TEXMODE)) \
- lod += DITHER4[(XX) & 3] << 4; \
- if (lod < (TT)->lodmin) \
- lod = (TT)->lodmin; \
- if (lod > (TT)->lodmax) \
- lod = (TT)->lodmax; \
- \
- /* now the LOD is in range; if we don't own this LOD, take the next one */ \
- ilod = lod >> 8; \
- if (!(((TT)->lodmask >> ilod) & 1)) \
- ilod++; \
- \
- /* fetch the texture base */ \
- texbase = (TT)->lodoffset[ilod]; \
- \
- /* compute the maximum s and t values at this LOD */ \
- smax = (TT)->wmask >> ilod; \
- tmax = (TT)->hmask >> ilod; \
- \
- /* determine whether we are point-sampled or bilinear */ \
- if ((lod == (TT)->lodmin && !TEXMODE_MAGNIFICATION_FILTER(TEXMODE)) || \
- (lod != (TT)->lodmin && !TEXMODE_MINIFICATION_FILTER(TEXMODE))) \
- { \
- /* point sampled */ \
- \
- uint32_t texel0; \
- \
- /* adjust S/T for the LOD and strip off the fractions */ \
- s >>= ilod + 18; \
- t >>= ilod + 18; \
- \
- /* clamp/wrap S/T if necessary */ \
- if (TEXMODE_CLAMP_S(TEXMODE)) \
- CLAMP(s, 0, smax); \
- if (TEXMODE_CLAMP_T(TEXMODE)) \
- CLAMP(t, 0, tmax); \
- s &= smax; \
- t &= tmax; \
- t *= smax + 1; \
- \
- /* fetch texel data */ \
- if (TEXMODE_FORMAT(TEXMODE) < 8) \
- { \
- texel0 = *(uint8_t *)&(TT)->ram[(texbase + t + s) & (TT)->mask]; \
- c_local.u = (LOOKUP)[texel0]; \
- } \
- else \
- { \
- texel0 = *(uint16_t *)&(TT)->ram[(texbase + 2*(t + s)) & (TT)->mask]; \
- if (TEXMODE_FORMAT(TEXMODE) >= 10 && TEXMODE_FORMAT(TEXMODE) <= 12) \
- c_local.u = (LOOKUP)[texel0]; \
- else \
- c_local.u = ((LOOKUP)[texel0 & 0xff] & 0xffffff) | \
- ((texel0 & 0xff00) << 16); \
- } \
- } \
- else \
- { \
- /* bilinear filtered */ \
- \
- uint32_t texel0, texel1, texel2, texel3; \
- uint32_t sfrac, tfrac; \
- int32_t s1, t1; \
- \
- /* adjust S/T for the LOD and strip off all but the low 8 bits of */ \
- /* the fraction */ \
- s >>= ilod + 10; \
- t >>= ilod + 10; \
- \
- /* also subtract 1/2 texel so that (0.5,0.5) = a full (0,0) texel */ \
- s -= 0x80; \
- t -= 0x80; \
- \
- /* extract the fractions */ \
- sfrac = s & (TT)->bilinear_mask; \
- tfrac = t & (TT)->bilinear_mask; \
- \
- /* now toss the rest */ \
- s >>= 8; \
- t >>= 8; \
- s1 = s + 1; \
- t1 = t + 1; \
- \
- /* clamp/wrap S/T if necessary */ \
- if (TEXMODE_CLAMP_S(TEXMODE)) \
- { \
- CLAMP(s, 0, smax); \
- CLAMP(s1, 0, smax); \
- } \
- if (TEXMODE_CLAMP_T(TEXMODE)) \
- { \
- CLAMP(t, 0, tmax); \
- CLAMP(t1, 0, tmax); \
- } \
- s &= smax; \
- s1 &= smax; \
- t &= tmax; \
- t1 &= tmax; \
- t *= smax + 1; \
- t1 *= smax + 1; \
- \
- /* fetch texel data */ \
- if (TEXMODE_FORMAT(TEXMODE) < 8) \
- { \
- texel0 = *(uint8_t *)&(TT)->ram[(texbase + t + s) & (TT)->mask]; \
- texel1 = *(uint8_t *)&(TT)->ram[(texbase + t + s1) & (TT)->mask]; \
- texel2 = *(uint8_t *)&(TT)->ram[(texbase + t1 + s) & (TT)->mask]; \
- texel3 = *(uint8_t *)&(TT)->ram[(texbase + t1 + s1) & (TT)->mask]; \
- texel0 = (LOOKUP)[texel0]; \
- texel1 = (LOOKUP)[texel1]; \
- texel2 = (LOOKUP)[texel2]; \
- texel3 = (LOOKUP)[texel3]; \
- } \
- else \
- { \
- texel0 = *(uint16_t *)&(TT)->ram[(texbase + 2*(t + s)) & (TT)->mask]; \
- texel1 = *(uint16_t *)&(TT)->ram[(texbase + 2*(t + s1)) & (TT)->mask];\
- texel2 = *(uint16_t *)&(TT)->ram[(texbase + 2*(t1 + s)) & (TT)->mask];\
- texel3 = *(uint16_t *)&(TT)->ram[(texbase + 2*(t1 + s1)) & (TT)->mask];\
- if (TEXMODE_FORMAT(TEXMODE) >= 10 && TEXMODE_FORMAT(TEXMODE) <= 12) \
- { \
- texel0 = (LOOKUP)[texel0]; \
- texel1 = (LOOKUP)[texel1]; \
- texel2 = (LOOKUP)[texel2]; \
- texel3 = (LOOKUP)[texel3]; \
- } \
- else \
- { \
- texel0 = ((LOOKUP)[texel0 & 0xff] & 0xffffff) | \
- ((texel0 & 0xff00) << 16); \
- texel1 = ((LOOKUP)[texel1 & 0xff] & 0xffffff) | \
- ((texel1 & 0xff00) << 16); \
- texel2 = ((LOOKUP)[texel2 & 0xff] & 0xffffff) | \
- ((texel2 & 0xff00) << 16); \
- texel3 = ((LOOKUP)[texel3 & 0xff] & 0xffffff) | \
- ((texel3 & 0xff00) << 16); \
- } \
- } \
- \
- /* weigh in each texel */ \
- c_local.u = rgbaint_t::bilinear_filter(texel0, texel1, texel2, texel3, sfrac, tfrac); \
- } \
- \
- /* select zero/other for RGB */ \
- if (!TEXMODE_TC_ZERO_OTHER(TEXMODE)) \
- { \
- tr = COTHER.rgb.r; \
- tg = COTHER.rgb.g; \
- tb = COTHER.rgb.b; \
- } \
- else \
- tr = tg = tb = 0; \
- \
- /* select zero/other for alpha */ \
- if (!TEXMODE_TCA_ZERO_OTHER(TEXMODE)) \
- ta = COTHER.rgb.a; \
- else \
- ta = 0; \
- \
- /* potentially subtract c_local */ \
- if (TEXMODE_TC_SUB_CLOCAL(TEXMODE)) \
- { \
- tr -= c_local.rgb.r; \
- tg -= c_local.rgb.g; \
- tb -= c_local.rgb.b; \
- } \
- if (TEXMODE_TCA_SUB_CLOCAL(TEXMODE)) \
- ta -= c_local.rgb.a; \
- \
- /* blend RGB */ \
- switch (TEXMODE_TC_MSELECT(TEXMODE)) \
- { \
- default: /* reserved */ \
- case 0: /* zero */ \
- blendr = blendg = blendb = 0; \
- break; \
- \
- case 1: /* c_local */ \
- blendr = c_local.rgb.r; \
- blendg = c_local.rgb.g; \
- blendb = c_local.rgb.b; \
- break; \
- \
- case 2: /* a_other */ \
- blendr = blendg = blendb = COTHER.rgb.a; \
- break; \
- \
- case 3: /* a_local */ \
- blendr = blendg = blendb = c_local.rgb.a; \
- break; \
- \
- case 4: /* LOD (detail factor) */ \
- if ((TT)->detailbias <= lod) \
- blendr = blendg = blendb = 0; \
- else \
- { \
- blendr = ((((TT)->detailbias - lod) << (TT)->detailscale) >> 8);\
- if (blendr > (TT)->detailmax) \
- blendr = (TT)->detailmax; \
- blendg = blendb = blendr; \
- } \
- break; \
- \
- case 5: /* LOD fraction */ \
- blendr = blendg = blendb = lod & 0xff; \
- break; \
- } \
- \
- /* blend alpha */ \
- switch (TEXMODE_TCA_MSELECT(TEXMODE)) \
- { \
- default: /* reserved */ \
- case 0: /* zero */ \
- blenda = 0; \
- break; \
- \
- case 1: /* c_local */ \
- blenda = c_local.rgb.a; \
- break; \
- \
- case 2: /* a_other */ \
- blenda = COTHER.rgb.a; \
- break; \
- \
- case 3: /* a_local */ \
- blenda = c_local.rgb.a; \
- break; \
- \
- case 4: /* LOD (detail factor) */ \
- if ((TT)->detailbias <= lod) \
- blenda = 0; \
- else \
- { \
- blenda = ((((TT)->detailbias - lod) << (TT)->detailscale) >> 8);\
- if (blenda > (TT)->detailmax) \
- blenda = (TT)->detailmax; \
- } \
- break; \
- \
- case 5: /* LOD fraction */ \
- blenda = lod & 0xff; \
- break; \
- } \
- \
- /* reverse the RGB blend */ \
- if (!TEXMODE_TC_REVERSE_BLEND(TEXMODE)) \
- { \
- blendr ^= 0xff; \
- blendg ^= 0xff; \
- blendb ^= 0xff; \
- } \
- \
- /* reverse the alpha blend */ \
- if (!TEXMODE_TCA_REVERSE_BLEND(TEXMODE)) \
- blenda ^= 0xff; \
- \
- /* do the blend */ \
- tr = (tr * (blendr + 1)) >> 8; \
- tg = (tg * (blendg + 1)) >> 8; \
- tb = (tb * (blendb + 1)) >> 8; \
- ta = (ta * (blenda + 1)) >> 8; \
- \
- /* add clocal or alocal to RGB */ \
- switch (TEXMODE_TC_ADD_ACLOCAL(TEXMODE)) \
- { \
- case 3: /* reserved */ \
- case 0: /* nothing */ \
- break; \
- \
- case 1: /* add c_local */ \
- tr += c_local.rgb.r; \
- tg += c_local.rgb.g; \
- tb += c_local.rgb.b; \
- break; \
- \
- case 2: /* add_alocal */ \
- tr += c_local.rgb.a; \
- tg += c_local.rgb.a; \
- tb += c_local.rgb.a; \
- break; \
- } \
- \
- /* add clocal or alocal to alpha */ \
- if (TEXMODE_TCA_ADD_ACLOCAL(TEXMODE)) \
- ta += c_local.rgb.a; \
- \
- /* clamp */ \
- RESULT.rgb.r = (tr < 0) ? 0 : (tr > 0xff) ? 0xff : tr; \
- RESULT.rgb.g = (tg < 0) ? 0 : (tg > 0xff) ? 0xff : tg; \
- RESULT.rgb.b = (tb < 0) ? 0 : (tb > 0xff) ? 0xff : tb; \
- RESULT.rgb.a = (ta < 0) ? 0 : (ta > 0xff) ? 0xff : ta; \
- \
- /* invert */ \
- if (TEXMODE_TC_INVERT_OUTPUT(TEXMODE)) \
- RESULT.u ^= 0x00ffffff; \
- if (TEXMODE_TCA_INVERT_OUTPUT(TEXMODE)) \
- RESULT.rgb.a ^= 0xff; \
-} \
-while (0)
-
-
-
-/*************************************
- *
- * Pixel pipeline macros
- *
- *************************************/
-
-#define PIXEL_PIPELINE_BEGIN(vd, STATS, XX, YY, FBZCOLORPATH, FBZMODE, ITERZ, ITERW) \
-do \
-{ \
- int32_t depthval, wfloat, biasdepth; \
- int32_t r, g, b; \
- \
- (STATS)->pixels_in++; \
- \
- /* apply clipping */ \
- /* note that for perf reasons, we assume the caller has done clipping */ \
- \
- /* handle stippling */ \
- if (FBZMODE_ENABLE_STIPPLE(FBZMODE)) \
- { \
- /* rotate mode */ \
- if (FBZMODE_STIPPLE_PATTERN(FBZMODE) == 0) \
- { \
- vd->reg[stipple].u = (vd->reg[stipple].u << 1) | (vd->reg[stipple].u >> 31);\
- if ((vd->reg[stipple].u & 0x80000000) == 0) \
- { \
- vd->stats.total_stippled++; \
- goto skipdrawdepth; \
- } \
- } \
- \
- /* pattern mode */ \
- else \
- { \
- int stipple_index = (((YY) & 3) << 3) | (~(XX) & 7); \
- if (((vd->reg[stipple].u >> stipple_index) & 1) == 0) \
- { \
- vd->stats.total_stippled++; \
- goto skipdrawdepth; \
- } \
- } \
- } \
- \
- /* compute "floating point" W value (used for depth and fog) */ \
- if ((ITERW) & 0xffff00000000U) \
- wfloat = 0x0000; \
- else \
- { \
- uint32_t temp = (uint32_t)(ITERW); \
- if (!(temp & 0xffff0000)) \
- wfloat = 0xffff; \
- else \
- { \
- int exp = count_leading_zeros_32(temp); \
- wfloat = ((exp << 12) | ((~temp >> (19 - exp)) & 0xfff)) + 1; \
- } \
- } \
- \
- /* compute depth value (W or Z) for this pixel */ \
- if (FBZMODE_WBUFFER_SELECT(FBZMODE)) \
- { \
- if (!FBZMODE_DEPTH_FLOAT_SELECT(FBZMODE)) \
- depthval = wfloat; \
- else \
- { \
- if ((ITERZ) & 0xf0000000) \
- depthval = 0x0000; \
- else \
- { \
- uint32_t temp = (ITERZ << 4); \
- if (!(temp & 0xffff0000)) \
- depthval = 0xffff; \
- else \
- { \
- int exp = count_leading_zeros_32(temp); \
- depthval = ((exp << 12) | ((~temp >> (19 - exp)) & 0xfff)) + 1; \
- } \
- } \
- } \
- } \
- else \
- { \
- CLAMPED_Z(ITERZ, FBZCOLORPATH, depthval); \
- } \
- /* add the bias */ \
- biasdepth = depthval; \
- if (FBZMODE_ENABLE_DEPTH_BIAS(FBZMODE)) \
- { \
- biasdepth += (int16_t)vd->reg[zaColor].u; \
- CLAMP(biasdepth, 0, 0xffff); \
- }
-
-
-#define DEPTH_TEST(vd, STATS, XX, FBZMODE) \
-do \
-{ \
- /* handle depth buffer testing */ \
- if (FBZMODE_ENABLE_DEPTHBUF(FBZMODE)) \
- { \
- int32_t depthsource; \
- \
- /* the source depth is either the iterated W/Z+bias or a */ \
- /* constant value */ \
- if (FBZMODE_DEPTH_SOURCE_COMPARE(FBZMODE) == 0) \
- depthsource = biasdepth; \
- else \
- depthsource = (uint16_t)vd->reg[zaColor].u; \
- \
- /* test against the depth buffer */ \
- switch (FBZMODE_DEPTH_FUNCTION(FBZMODE)) \
- { \
- case 0: /* depthOP = never */ \
- (STATS)->zfunc_fail++; \
- goto skipdrawdepth; \
- \
- case 1: /* depthOP = less than */ \
- if (depthsource >= depth[XX]) \
- { \
- (STATS)->zfunc_fail++; \
- goto skipdrawdepth; \
- } \
- break; \
- \
- case 2: /* depthOP = equal */ \
- if (depthsource != depth[XX]) \
- { \
- (STATS)->zfunc_fail++; \
- goto skipdrawdepth; \
- } \
- break; \
- \
- case 3: /* depthOP = less than or equal */ \
- if (depthsource > depth[XX]) \
- { \
- (STATS)->zfunc_fail++; \
- goto skipdrawdepth; \
- } \
- break; \
- \
- case 4: /* depthOP = greater than */ \
- if (depthsource <= depth[XX]) \
- { \
- (STATS)->zfunc_fail++; \
- goto skipdrawdepth; \
- } \
- break; \
- \
- case 5: /* depthOP = not equal */ \
- if (depthsource == depth[XX]) \
- { \
- (STATS)->zfunc_fail++; \
- goto skipdrawdepth; \
- } \
- break; \
- \
- case 6: /* depthOP = greater than or equal */ \
- if (depthsource < depth[XX]) \
- { \
- (STATS)->zfunc_fail++; \
- goto skipdrawdepth; \
- } \
- break; \
- \
- case 7: /* depthOP = always */ \
- break; \
- } \
- } \
-} \
-while (0)
-
-inline bool ATTR_FORCE_INLINE voodoo_device::depthTest(uint16_t zaColorReg, stats_block *stats, int32_t destDepth, uint32_t fbzModeReg, int32_t biasdepth)
-{
- /* handle depth buffer testing */
- {
- int32_t depthsource;
-
- /* the source depth is either the iterated W/Z+bias or a */
- /* constant value */
- if (FBZMODE_DEPTH_SOURCE_COMPARE(fbzModeReg) == 0)
- depthsource = biasdepth;
- else
- depthsource = zaColorReg;
-
- /* test against the depth buffer */
- switch (FBZMODE_DEPTH_FUNCTION(fbzModeReg))
- {
- case 0: /* depthOP = never */
- stats->zfunc_fail++;
- return false;
-
- case 1: /* depthOP = less than */
- if (depthsource >= destDepth)
- {
- stats->zfunc_fail++;
- return false;
- }
- break;
-
- case 2: /* depthOP = equal */
- if (depthsource != destDepth)
- {
- stats->zfunc_fail++;
- return false;
- }
- break;
-
- case 3: /* depthOP = less than or equal */
- if (depthsource > destDepth)
- {
- stats->zfunc_fail++;
- return false;
- }
- break;
-
- case 4: /* depthOP = greater than */
- if (depthsource <= destDepth)
- {
- stats->zfunc_fail++;
- return false;
- }
- break;
-
- case 5: /* depthOP = not equal */
- if (depthsource == destDepth)
- {
- stats->zfunc_fail++;
- return false;
- }
- break;
-
- case 6: /* depthOP = greater than or equal */
- if (depthsource < destDepth)
- {
- stats->zfunc_fail++;
- return false;
- }
- break;
-
- case 7: /* depthOP = always */
- break;
- }
- }
- return true;
-}
-
-#define PIXEL_PIPELINE_END(STATS, DITHER_LOOKUP, XX, dest, depth, FBZMODE) \
- \
- r = color.get_r(); g = color.get_g(); b = color.get_b(); \
- /* modify the pixel for debugging purposes */ \
- MODIFY_PIXEL(VV); \
- \
- /* write to framebuffer */ \
- if (FBZMODE_RGB_BUFFER_MASK(FBZMODE)) \
- { \
- /* apply dithering */ \
- APPLY_DITHER(FBZMODE, XX, DITHER_LOOKUP, r, g, b); \
- dest[XX] = (r << 11) | (g << 5) | b; \
- } \
- \
- /* write to aux buffer */ \
- /*if (depth && FBZMODE_AUX_BUFFER_MASK(FBZMODE))*/ \
- if (FBZMODE_AUX_BUFFER_MASK(FBZMODE)) \
- { \
- if (FBZMODE_ENABLE_ALPHA_PLANES(FBZMODE) == 0) \
- depth[XX] = biasdepth; \
- else \
- depth[XX] = color.get_a(); \
- } \
- \
- /* track pixel writes to the frame buffer regardless of mask */ \
- (STATS)->pixels_out++; \
- \
-skipdrawdepth: \
- ; \
-} \
-while (0)
-
-
-
-/*************************************
- *
- * Colorpath pipeline macro
- *
- *************************************/
-
-/*
-
- c_other_is_used:
-
- if (FBZMODE_ENABLE_CHROMAKEY(FBZMODE) ||
- FBZCP_CC_ZERO_OTHER(FBZCOLORPATH) == 0)
-
- c_local_is_used:
-
- if (FBZCP_CC_SUB_CLOCAL(FBZCOLORPATH) ||
- FBZCP_CC_MSELECT(FBZCOLORPATH) == 1 ||
- FBZCP_CC_ADD_ACLOCAL(FBZCOLORPATH) == 1)
-
- NEEDS_ITER_RGB:
-
- if ((c_other_is_used && FBZCP_CC_RGBSELECT(FBZCOLORPATH) == 0) ||
- (c_local_is_used && (FBZCP_CC_LOCALSELECT_OVERRIDE(FBZCOLORPATH) != 0 || FBZCP_CC_LOCALSELECT(FBZCOLORPATH) == 0))
-
- NEEDS_ITER_A:
-
- if ((a_other_is_used && FBZCP_CC_ASELECT(FBZCOLORPATH) == 0) ||
- (a_local_is_used && FBZCP_CCA_LOCALSELECT(FBZCOLORPATH) == 0))
-
- NEEDS_ITER_Z:
-
- if (FBZMODE_WBUFFER_SELECT(FBZMODE) == 0 ||
- FBZMODE_DEPTH_FLOAT_SELECT(FBZMODE) != 0 ||
- FBZCP_CCA_LOCALSELECT(FBZCOLORPATH) == 2)
-
-
-*/
-
-/*
- Expects the following declarations to be outside of this scope:
-
- int32_t r, g, b, a;
-*/
-#define COLORPATH_PIPELINE(VV, STATS, FBZCOLORPATH, FBZMODE, ALPHAMODE, TEXELARGB, ITERZ, ITERW, ITERARGB) \
-do \
-{ \
- int32_t blendr, blendg, blendb, blenda; \
- rgb_union c_other; \
- rgb_union c_local; \
- \
- /* compute c_other */ \
- switch (FBZCP_CC_RGBSELECT(FBZCOLORPATH)) \
- { \
- case 0: /* iterated RGB */ \
- c_other.u = ITERARGB.u; \
- break; \
- \
- case 1: /* texture RGB */ \
- c_other.u = TEXELARGB.u; \
- break; \
- \
- case 2: /* color1 RGB */ \
- c_other.u = (VV)->reg[color1].u; \
- break; \
- \
- default: /* reserved - voodoo3 framebufferRGB */ \
- c_other.u = 0; \
- break; \
- } \
- \
- /* handle chroma key */ \
- APPLY_CHROMAKEY(VV, STATS, FBZMODE, c_other); \
- \
- /* compute a_other */ \
- switch (FBZCP_CC_ASELECT(FBZCOLORPATH)) \
- { \
- case 0: /* iterated alpha */ \
- c_other.rgb.a = ITERARGB.rgb.a; \
- break; \
- \
- case 1: /* texture alpha */ \
- c_other.rgb.a = TEXELARGB.rgb.a; \
- break; \
- \
- case 2: /* color1 alpha */ \
- c_other.rgb.a = (VV)->reg[color1].rgb.a; \
- break; \
- \
- default: /* reserved */ \
- c_other.rgb.a = 0; \
- break; \
- } \
- \
- /* handle alpha mask */ \
- APPLY_ALPHAMASK(VV, STATS, FBZMODE, c_other.rgb.a); \
- \
- /* compute c_local */ \
- if (FBZCP_CC_LOCALSELECT_OVERRIDE(FBZCOLORPATH) == 0) \
- { \
- if (FBZCP_CC_LOCALSELECT(FBZCOLORPATH) == 0) /* iterated RGB */ \
- c_local.u = ITERARGB.u; \
- else /* color0 RGB */ \
- c_local.u = (VV)->reg[color0].u; \
- } \
- else \
- { \
- if (!(TEXELARGB.rgb.a & 0x80)) /* iterated RGB */ \
- c_local.u = ITERARGB.u; \
- else /* color0 RGB */ \
- c_local.u = (VV)->reg[color0].u; \
- } \
- \
- /* compute a_local */ \
- switch (FBZCP_CCA_LOCALSELECT(FBZCOLORPATH)) \
- { \
- default: \
- case 0: /* iterated alpha */ \
- c_local.rgb.a = ITERARGB.rgb.a; \
- break; \
- \
- case 1: /* color0 alpha */ \
- c_local.rgb.a = (VV)->reg[color0].rgb.a; \
- break; \
- \
- case 2: /* clamped iterated Z[27:20] */ \
- { \
- int temp; \
- CLAMPED_Z(ITERZ, FBZCOLORPATH, temp); \
- c_local.rgb.a = (uint8_t)temp; \
- break; \
- } \
- \
- case 3: /* clamped iterated W[39:32] */ \
- { \
- int temp; \
- CLAMPED_W(ITERW, FBZCOLORPATH, temp); /* Voodoo 2 only */ \
- c_local.rgb.a = (uint8_t)temp; \
- break; \
- } \
- } \
- \
- /* select zero or a_other */ \
- if (!FBZCP_CCA_ZERO_OTHER(FBZCOLORPATH)) \
- a = c_other.rgb.a; \
- else \
- a = 0; \
- \
- /* subtract a_local */ \
- if (FBZCP_CCA_SUB_CLOCAL(FBZCOLORPATH)) \
- a -= c_local.rgb.a; \
- \
- /* blend alpha */ \
- switch (FBZCP_CCA_MSELECT(FBZCOLORPATH)) \
- { \
- default: /* reserved */ \
- case 0: /* 0 */ \
- blenda = 0; \
- break; \
- \
- case 1: /* a_local */ \
- blenda = c_local.rgb.a; \
- break; \
- \
- case 2: /* a_other */ \
- blenda = c_other.rgb.a; \
- break; \
- \
- case 3: /* a_local */ \
- blenda = c_local.rgb.a; \
- break; \
- \
- case 4: /* texture alpha */ \
- blenda = TEXELARGB.rgb.a; \
- break; \
- } \
- \
- /* reverse the alpha blend */ \
- if (!FBZCP_CCA_REVERSE_BLEND(FBZCOLORPATH)) \
- blenda ^= 0xff; \
- \
- /* do the blend */ \
- a = (a * (blenda + 1)) >> 8; \
- \
- /* add clocal or alocal to alpha */ \
- if (FBZCP_CCA_ADD_ACLOCAL(FBZCOLORPATH)) \
- a += c_local.rgb.a; \
- \
- /* clamp */ \
- CLAMP(a, 0x00, 0xff); \
- \
- /* invert */ \
- if (FBZCP_CCA_INVERT_OUTPUT(FBZCOLORPATH)) \
- a ^= 0xff; \
- \
- /* handle alpha test */ \
- APPLY_ALPHATEST(VV, STATS, ALPHAMODE, a); \
- \
- \
- /* select zero or c_other */ \
- if (FBZCP_CC_ZERO_OTHER(FBZCOLORPATH) == 0) \
- { \
- r = c_other.rgb.r; \
- g = c_other.rgb.g; \
- b = c_other.rgb.b; \
- } \
- else \
- r = g = b = 0; \
- \
- /* subtract c_local */ \
- if (FBZCP_CC_SUB_CLOCAL(FBZCOLORPATH)) \
- { \
- r -= c_local.rgb.r; \
- g -= c_local.rgb.g; \
- b -= c_local.rgb.b; \
- } \
- \
- /* blend RGB */ \
- switch (FBZCP_CC_MSELECT(FBZCOLORPATH)) \
- { \
- default: /* reserved */ \
- case 0: /* 0 */ \
- blendr = blendg = blendb = 0; \
- break; \
- \
- case 1: /* c_local */ \
- blendr = c_local.rgb.r; \
- blendg = c_local.rgb.g; \
- blendb = c_local.rgb.b; \
- break; \
- \
- case 2: /* a_other */ \
- blendr = blendg = blendb = c_other.rgb.a; \
- break; \
- \
- case 3: /* a_local */ \
- blendr = blendg = blendb = c_local.rgb.a; \
- break; \
- \
- case 4: /* texture alpha */ \
- blendr = blendg = blendb = TEXELARGB.rgb.a; \
- break; \
- \
- case 5: /* texture RGB (Voodoo 2 only) */ \
- blendr = TEXELARGB.rgb.r; \
- blendg = TEXELARGB.rgb.g; \
- blendb = TEXELARGB.rgb.b; \
- break; \
- } \
- \
- /* reverse the RGB blend */ \
- if (!FBZCP_CC_REVERSE_BLEND(FBZCOLORPATH)) \
- { \
- blendr ^= 0xff; \
- blendg ^= 0xff; \
- blendb ^= 0xff; \
- } \
- \
- /* do the blend */ \
- r = (r * (blendr + 1)) >> 8; \
- g = (g * (blendg + 1)) >> 8; \
- b = (b * (blendb + 1)) >> 8; \
- \
- /* add clocal or alocal to RGB */ \
- switch (FBZCP_CC_ADD_ACLOCAL(FBZCOLORPATH)) \
- { \
- case 3: /* reserved */ \
- case 0: /* nothing */ \
- break; \
- \
- case 1: /* add c_local */ \
- r += c_local.rgb.r; \
- g += c_local.rgb.g; \
- b += c_local.rgb.b; \
- break; \
- \
- case 2: /* add_alocal */ \
- r += c_local.rgb.a; \
- g += c_local.rgb.a; \
- b += c_local.rgb.a; \
- break; \
- } \
- \
- /* clamp */ \
- CLAMP(r, 0x00, 0xff); \
- CLAMP(g, 0x00, 0xff); \
- CLAMP(b, 0x00, 0xff); \
- \
- /* invert */ \
- if (FBZCP_CC_INVERT_OUTPUT(FBZCOLORPATH)) \
- { \
- r ^= 0xff; \
- g ^= 0xff; \
- b ^= 0xff; \
- } \
-} \
-while (0)
-
-inline bool ATTR_FORCE_INLINE voodoo_device::combineColor(voodoo_device *vd, stats_block *STATS, uint32_t FBZCOLORPATH, uint32_t FBZMODE,
- rgbaint_t TEXELARGB, int32_t ITERZ, int64_t ITERW, rgbaint_t &srcColor)
-{
- rgbaint_t c_other;
- rgbaint_t c_local;
- rgbaint_t blend_color, blend_factor;
- rgbaint_t add_val;
-
- /* compute c_other */
- switch (FBZCP_CC_RGBSELECT(FBZCOLORPATH))
- {
- case 0: /* iterated RGB */
- c_other.set(srcColor);
- break;
-
- case 1: /* texture RGB */
- c_other.set(TEXELARGB);
- break;
-
- case 2: /* color1 RGB */
- c_other.set(vd->reg[color1].u);
- break;
-
- default: /* reserved - voodoo3 LFB RGB */
- c_other.zero();
- break;
- }
-
- /* handle chroma key */
- if (FBZMODE_ENABLE_CHROMAKEY(FBZMODE))
- if (!chromaKeyTest(vd, STATS, FBZMODE, c_other))
- return false;
- //APPLY_CHROMAKEY(vd->m_vds, STATS, FBZMODE, c_other);
-
- /* compute a_other */
- switch (FBZCP_CC_ASELECT(FBZCOLORPATH))
- {
- case 0: /* iterated alpha */
- c_other.merge_alpha16(srcColor);
- break;
-
- case 1: /* texture alpha */
- c_other.merge_alpha16(TEXELARGB);
- break;
-
- case 2: /* color1 alpha */
- c_other.set_a16(vd->reg[color1].rgb.a);
- break;
-
- default: /* reserved - voodoo3 LFB Alpha*/
- c_other.zero_alpha();
- break;
- }
-
- /* handle alpha mask */
- if (FBZMODE_ENABLE_ALPHA_MASK(FBZMODE))
- if (!alphaMaskTest(STATS, FBZMODE, c_other.get_a()))
- return false;
- //APPLY_ALPHAMASK(vd->m_vds, STATS, FBZMODE, c_other.rgb.a);
-
-
- /* compute c_local */
- if (FBZCP_CC_LOCALSELECT_OVERRIDE(FBZCOLORPATH) == 0)
- {
- if (FBZCP_CC_LOCALSELECT(FBZCOLORPATH) == 0) /* iterated RGB */
- c_local.set(srcColor);
- else /* color0 RGB */
- c_local.set(vd->reg[color0].u);
- }
- else
- {
- if (!(TEXELARGB.get_a() & 0x80)) /* iterated RGB */
- c_local.set(srcColor);
- else /* color0 RGB */
- c_local.set(vd->reg[color0].u);
- }
-
- /* compute a_local */
- switch (FBZCP_CCA_LOCALSELECT(FBZCOLORPATH))
- {
- default:
- case 0: /* iterated alpha */
- c_local.merge_alpha16(srcColor);
- break;
-
- case 1: /* color0 alpha */
- c_local.set_a16(vd->reg[color0].rgb.a);
- break;
-
- case 2: /* clamped iterated Z[27:20] */
- {
- int temp;
- CLAMPED_Z(ITERZ, FBZCOLORPATH, temp);
- c_local.set_a16((uint8_t) temp);
- break;
- }
-
- case 3: /* clamped iterated W[39:32] */
- {
- int temp;
- CLAMPED_W(ITERW, FBZCOLORPATH, temp); /* Voodoo 2 only */
- c_local.set_a16((uint8_t) temp);
- break;
- }
- }
-
- /* select zero or c_other */
- if (FBZCP_CC_ZERO_OTHER(FBZCOLORPATH))
- //r = g = b = 0;
- blend_color.zero();
- else
- blend_color.set(c_other);
-
- /* select zero or a_other */
- if (FBZCP_CCA_ZERO_OTHER(FBZCOLORPATH))
- blend_color.zero_alpha();
- else
- blend_color.merge_alpha16(c_other);
-
- /* subtract a/c_local */
- if (FBZCP_CC_SUB_CLOCAL(FBZCOLORPATH) || (FBZCP_CCA_SUB_CLOCAL(FBZCOLORPATH)))
- {
- rgbaint_t sub_val;
-
- if (!FBZCP_CC_SUB_CLOCAL(FBZCOLORPATH))
- sub_val.zero();
- else
- sub_val.set(c_local);
-
- if (!FBZCP_CCA_SUB_CLOCAL(FBZCOLORPATH))
- sub_val.zero_alpha();
- else
- sub_val.merge_alpha16(c_local);
-
- blend_color.sub(sub_val);
- }
-
- /* blend RGB */
- switch (FBZCP_CC_MSELECT(FBZCOLORPATH))
- {
- default: /* reserved */
- case 0: /* 0 */
- blend_factor.zero();
- break;
-
- case 1: /* c_local */
- blend_factor.set(c_local);
- break;
-
- case 2: /* a_other */
- blend_factor.set(c_other.select_alpha32());
- break;
-
- case 3: /* a_local */
- blend_factor.set(c_local.select_alpha32());
- break;
-
- case 4: /* texture alpha */
- blend_factor.set(TEXELARGB.select_alpha32());
- break;
-
- case 5: /* texture RGB (Voodoo 2 only) */
- blend_factor.set(TEXELARGB);
- break;
- }
-
- /* blend alpha */
- switch (FBZCP_CCA_MSELECT(FBZCOLORPATH))
- {
- default: /* reserved */
- case 0: /* 0 */
- blend_factor.zero_alpha();
- break;
-
- case 1: /* a_local */
- case 3: /* a_local */
- blend_factor.merge_alpha16(c_local);
- break;
-
- case 2: /* a_other */
- blend_factor.merge_alpha16(c_other);
- break;
-
- case 4: /* texture alpha */
- blend_factor.merge_alpha16(TEXELARGB);
- break;
- }
-
- /* reverse the RGB blend */
- if (!FBZCP_CC_REVERSE_BLEND(FBZCOLORPATH))
- blend_factor.xor_imm_rgba(0, 0xff, 0xff, 0xff);
-
- /* reverse the alpha blend */
- if (!FBZCP_CCA_REVERSE_BLEND(FBZCOLORPATH))
- blend_factor.xor_imm_rgba(0xff, 0, 0, 0);
-
- /* do the blend */
- //color.rgb.a = (color.rgb.a * (blenda + 1)) >> 8;
- //color.rgb.r = (color.rgb.r * (blendr + 1)) >> 8;
- //color.rgb.g = (color.rgb.g * (blendg + 1)) >> 8;
- //color.rgb.b = (color.rgb.b * (blendb + 1)) >> 8;
-
- /* add clocal or alocal to RGB */
- switch (FBZCP_CC_ADD_ACLOCAL(FBZCOLORPATH))
- {
- case 3: /* reserved */
- case 0: /* nothing */
- add_val.zero();
- break;
-
- case 1: /* add c_local */
- add_val.set(c_local);
- break;
-
- case 2: /* add_alocal */
- add_val.set(c_local.select_alpha32());
- break;
- }
-
- /* add clocal or alocal to alpha */
- if (!FBZCP_CCA_ADD_ACLOCAL(FBZCOLORPATH))
- add_val.zero_alpha();
- else
- //color.rgb.a += c_local.rgb.a;
- add_val.merge_alpha16(c_local);
-
- /* clamp */
- //CLAMP(color.rgb.a, 0x00, 0xff);
- //CLAMP(color.rgb.r, 0x00, 0xff);
- //CLAMP(color.rgb.g, 0x00, 0xff);
- //CLAMP(color.rgb.b, 0x00, 0xff);
- blend_factor.add_imm(1);
- blend_color.scale_add_and_clamp(blend_factor, add_val);
-
- /* invert */
- if (FBZCP_CCA_INVERT_OUTPUT(FBZCOLORPATH))
- blend_color.xor_imm_rgba(0xff, 0, 0, 0);
- /* invert */
- if (FBZCP_CC_INVERT_OUTPUT(FBZCOLORPATH))
- blend_color.xor_imm_rgba(0, 0xff, 0xff, 0xff);
-
- srcColor.set(blend_color);
-
- return true;
-}
-
-
-
-/*************************************
- *
- * Rasterizer generator macro
- *
- *************************************/
-
-#define RASTERIZER(name, TMUS, FBZCOLORPATH, FBZMODE, ALPHAMODE, FOGMODE, TEXMODE0, TEXMODE1) \
- \
-void voodoo_device::raster_##name(void *destbase, int32_t y, const poly_extent *extent, const void *extradata, int threadid) \
-{ \
- const poly_extra_data *extra = (const poly_extra_data *)extradata; \
- voodoo_device *vd = extra->device; \
- stats_block *stats = &vd->thread_stats[threadid]; \
- DECLARE_DITHER_POINTERS; \
- int32_t startx = extent->startx; \
- int32_t stopx = extent->stopx; \
- rgbaint_t iterargb, iterargbDelta; \
- int32_t iterz; \
- int64_t iterw; \
- tmu_state::stw_t iterstw0, iterstw1; \
- tmu_state::stw_t deltastw0, deltastw1; \
- uint16_t *depth; \
- uint16_t *dest; \
- int32_t dx, dy; \
- int32_t scry; \
- int32_t x; \
- \
- /* determine the screen Y */ \
- scry = y; \
- if (FBZMODE_Y_ORIGIN(FBZMODE)) \
- scry = (vd->fbi.yorigin - y); \
- \
- /* compute dithering */ \
- COMPUTE_DITHER_POINTERS(FBZMODE, y, FOGMODE); \
- \
- /* apply clipping */ \
- if (FBZMODE_ENABLE_CLIPPING(FBZMODE)) \
- { \
- int32_t tempclip; \
- \
- /* Y clipping buys us the whole scanline */ \
- if (scry < ((vd->reg[clipLowYHighY].u >> 16) & 0x3ff) || \
- scry >= (vd->reg[clipLowYHighY].u & 0x3ff)) \
- { \
- stats->pixels_in += stopx - startx; \
- stats->clip_fail += stopx - startx; \
- return; \
- } \
- \
- /* X clipping */ \
- tempclip = vd->reg[clipLeftRight].u & 0x3ff; \
- /* Check for start outsize of clipping boundary */ \
- if (startx >= tempclip) \
- { \
- stats->pixels_in += stopx - startx; \
- vd->stats.total_clipped += stopx - startx; \
- return; \
- } \
- if (stopx > tempclip) \
- { \
- stats->pixels_in += stopx - tempclip; \
- vd->stats.total_clipped += stopx - tempclip; \
- stopx = tempclip; \
- } \
- tempclip = (vd->reg[clipLeftRight].u >> 16) & 0x3ff; \
- if (startx < tempclip) \
- { \
- stats->pixels_in += tempclip - startx; \
- vd->stats.total_clipped += tempclip - startx; \
- startx = tempclip; \
- } \
- } \
- \
- /* get pointers to the target buffer and depth buffer */ \
- dest = (uint16_t *)destbase + scry * vd->fbi.rowpixels; \
- depth = (vd->fbi.auxoffs != ~0) ? ((uint16_t *)(vd->fbi.ram + vd->fbi.auxoffs) + scry * vd->fbi.rowpixels) : nullptr; \
- \
- /* compute the starting parameters */ \
- dx = startx - (extra->ax >> 4); \
- dy = y - (extra->ay >> 4); \
- int32_t iterr = extra->startr + dy * extra->drdy + dx * extra->drdx; \
- int32_t iterg = extra->startg + dy * extra->dgdy + dx * extra->dgdx; \
- int32_t iterb = extra->startb + dy * extra->dbdy + dx * extra->dbdx; \
- int32_t itera = extra->starta + dy * extra->dady + dx * extra->dadx; \
- iterargb.set(itera, iterr, iterg, iterb); \
- iterargbDelta.set(extra->dadx, extra->drdx, extra->dgdx, extra->dbdx); \
- iterz = extra->startz + dy * extra->dzdy + dx * extra->dzdx; \
- iterw = extra->startw + dy * extra->dwdy + dx * extra->dwdx; \
- if (TMUS >= 1) \
- { \
- iterstw0.set( \
- extra->starts0 + dy * extra->ds0dy + dx * extra->ds0dx, \
- extra->startt0 + dy * extra->dt0dy + dx * extra->dt0dx, \
- extra->startw0 + dy * extra->dw0dy + dx * extra->dw0dx); \
- deltastw0.set(extra->ds0dx, extra->dt0dx, extra->dw0dx); \
- } \
- if (TMUS >= 2) \
- { \
- iterstw1.set( \
- extra->starts1 + dy * extra->ds1dy + dx * extra->ds1dx, \
- extra->startt1 + dy * extra->dt1dy + dx * extra->dt1dx, \
- extra->startw1 + dy * extra->dw1dy + dx * extra->dw1dx); \
- deltastw1.set(extra->ds1dx, extra->dt1dx, extra->dw1dx); \
- } \
- extra->info->hits++; \
- /* loop in X */ \
- for (x = startx; x < stopx; x++) \
- { \
- rgbaint_t texel(0); \
- rgbaint_t color, preFog; \
- \
- /* pixel pipeline part 1 handles depth setup and stippling */ \
- PIXEL_PIPELINE_BEGIN(vd, stats, x, y, FBZCOLORPATH, FBZMODE, iterz, iterw); \
- /* depth testing */ \
- if (FBZMODE_ENABLE_DEPTHBUF(FBZMODE)) \
- if (!depthTest((uint16_t) vd->reg[zaColor].u, stats, depth[x], FBZMODE, biasdepth)) \
- goto skipdrawdepth; \
- \
- /* run the texture pipeline on TMU1 to produce a value in texel */ \
- /* note that they set LOD min to 8 to "disable" a TMU */ \
- if (TMUS >= 2 && vd->tmu[1].lodmin < (8 << 8)) { \
- int32_t tmp; \
- const rgbaint_t texelZero(0); \
- texel = vd->tmu[1].genTexture(x, dither4, TEXMODE1, vd->tmu[1].lookup, extra->lodbase1, \
- iterstw1, tmp); \
- texel = vd->tmu[1].combineTexture(TEXMODE1, texel, texelZero, tmp); \
- } \
- /* run the texture pipeline on TMU0 to produce a final */ \
- /* result in texel */ \
- /* note that they set LOD min to 8 to "disable" a TMU */ \
- if (TMUS >= 1 && vd->tmu[0].lodmin < (8 << 8)) \
- { \
- if (!vd->send_config) \
- { \
- int32_t lod0; \
- rgbaint_t texelT0; \
- texelT0 = vd->tmu[0].genTexture(x, dither4, TEXMODE0, vd->tmu[0].lookup, extra->lodbase0, \
- iterstw0, lod0); \
- texel = vd->tmu[0].combineTexture(TEXMODE0, texelT0, texel, lod0); \
- } \
- else \
- { \
- texel.set(vd->tmu_config); \
- } \
- } \
- \
- /* colorpath pipeline selects source colors and does blending */ \
- color = clampARGB(iterargb, FBZCOLORPATH); \
- if (!combineColor(vd, stats, FBZCOLORPATH, FBZMODE, texel, iterz, iterw, color)) \
- goto skipdrawdepth; \
- /* handle alpha test */ \
- if (ALPHAMODE_ALPHATEST(ALPHAMODE)) \
- if (!alphaTest(vd->reg[alphaMode].rgb.a, stats, ALPHAMODE, color.get_a())) \
- goto skipdrawdepth; \
- \
- /* perform fogging */ \
- preFog.set(color); \
- if (FOGMODE_ENABLE_FOG(FOGMODE)) \
- applyFogging(vd, FBZMODE, FOGMODE, FBZCOLORPATH, x, dither4, wfloat, color, iterz, iterw, iterargb); \
- \
- /* perform alpha blending */ \
- if (ALPHAMODE_ALPHABLEND(ALPHAMODE)) \
- alphaBlend(FBZMODE, ALPHAMODE, x, dither, dest[x], depth, preFog, color, vd->fbi.rgb565); \
- \
- /* pixel pipeline part 2 handles final output */ \
- PIXEL_PIPELINE_END(stats, dither_lookup, x, dest, depth, FBZMODE); \
- \
- /* update the iterated parameters */ \
- iterargb += iterargbDelta; \
- iterz += extra->dzdx; \
- iterw += extra->dwdx; \
- if (TMUS >= 1) \
- { \
- iterstw0.add(deltastw0); \
- } \
- if (TMUS >= 2) \
- { \
- iterstw1.add(deltastw1); \
- } \
- } \
-}
-
-
-// ******************************************************************************************************************************
-// Computes a log2 of a 16.32 value to 2 fractional bits of precision.
-// The return value is coded as a 24.8 value.
-// The maximum error using a 4 bit lookup from the mantissa is 0.0875, which is less than 1/2 lsb (0.125) for 2 bits of fraction.
-// An offset of +(56 << 8) is added for alignment in multi_reciplog
-// ******************************************************************************************************************************
-inline int32_t ATTR_FORCE_INLINE voodoo_device::tmu_state::new_log2(double &value, const int &offset)
-{
- static const int32_t new_log2_table[16] = {0, 22, 44, 63, 82, 100, 118, 134, 150, 165, 179, 193, 207, 220, 232, 244};
- uint64_t ival = *((uint64_t *)&value);
- // Return 0 if negative
- if (ival & ((uint64_t)1 << 63))
- return 0;
- // We zero the result if negative so don't worry about the sign bit
- int32_t exp = (ival>>52);
- exp -= 1023+32-offset;
- exp <<= 8;
- uint32_t addr = (uint64_t)(ival>>48) & 0xf;
- exp += new_log2_table[addr];
- return exp;
-}
-
-inline rgbaint_t ATTR_FORCE_INLINE voodoo_device::tmu_state::genTexture(int32_t x, const uint8_t *dither4, const uint32_t TEXMODE, rgb_t *LOOKUP, int32_t LODBASE, const stw_t &iterstw, int32_t &lod)
-{
- rgbaint_t result;
- int32_t s, t, ilod;
-
- /* determine the S/T/LOD values for this texture */
- lod = (LODBASE);
- if (TEXMODE_ENABLE_PERSPECTIVE(TEXMODE))
- {
- int32_t wLog;
- iterstw.calc_stow(s, t, wLog);
- lod += wLog;
- }
- else
- {
-#if ((!defined(MAME_DEBUG) || defined(__OPTIMIZE__)) && (defined(__SSE2__) || defined(_MSC_VER)) && defined(PTR64))
- // Extra shift by 8 due to how sse class is stored
- iterstw.get_st_shiftr(s, t, (14 + 10 + 8));
-#else
- iterstw.get_st_shiftr(s, t, (14 + 10));
-#endif
- }
-
- /* clamp W */
- if (TEXMODE_CLAMP_NEG_W(TEXMODE) && iterstw.is_w_neg())
- {
- s = t = 0;
- }
-
- /* clamp the LOD */
- lod += lodbias;
- if (TEXMODE_ENABLE_LOD_DITHER(TEXMODE))
- lod += dither4[x&3] << 4;
- CLAMP(lod, lodmin, lodmax);
-
- /* now the LOD is in range; if we don't own this LOD, take the next one */
- ilod = lod >> 8;
- if (!((lodmask >> ilod) & 1))
- ilod++;
-
- /* fetch the texture base */
- uint32_t texbase = lodoffset[ilod];
-
- /* compute the maximum s and t values at this LOD */
- int32_t smax = wmask >> ilod;
- int32_t tmax = hmask >> ilod;
-
- /* determine whether we are point-sampled or bilinear */
- if ((lod == lodmin && !TEXMODE_MAGNIFICATION_FILTER(TEXMODE)) ||
- (lod != lodmin && !TEXMODE_MINIFICATION_FILTER(TEXMODE)))
- {
- /* point sampled */
-
- uint32_t texel0;
-
- /* adjust S/T for the LOD and strip off the fractions */
- s >>= ilod + (18-10);
- t >>= ilod + (18-10);
-
- /* clamp/wrap S/T if necessary */
- if (TEXMODE_CLAMP_S(TEXMODE))
- CLAMP(s, 0, smax);
- if (TEXMODE_CLAMP_T(TEXMODE))
- CLAMP(t, 0, tmax);
- s &= smax;
- t &= tmax;
- t *= smax + 1;
-
- /* fetch texel data */
- if (TEXMODE_FORMAT(TEXMODE) < 8)
- {
- texel0 = *(uint8_t *)&ram[(texbase + t + s) & mask];
- result.set((LOOKUP)[texel0]);
- }
- else
- {
- texel0 = *(uint16_t *)&ram[(texbase + 2*(t + s)) & mask];
- if (TEXMODE_FORMAT(TEXMODE) >= 10 && TEXMODE_FORMAT(TEXMODE) <= 12)
- result.set((LOOKUP)[texel0]);
- else
- result.set(((LOOKUP)[texel0 & 0xff] & 0xffffff) | ((texel0 & 0xff00) << 16));
- }
- }
- else
- {
- /* bilinear filtered */
-
- uint32_t texel0, texel1, texel2, texel3;
- uint32_t sfrac, tfrac;
- int32_t s1, t1;
-
- /* adjust S/T for the LOD and strip off all but the low 8 bits of */
- /* the fraction */
- s >>= ilod; // + (10-10);
- t >>= ilod; // + (10-10);
-
- /* also subtract 1/2 texel so that (0.5,0.5) = a full (0,0) texel */
- s -= 0x80;
- t -= 0x80;
-
- /* extract the fractions */
- sfrac = s & bilinear_mask;
- tfrac = t & bilinear_mask;
-
- /* now toss the rest */
- s >>= 8;
- t >>= 8;
- s1 = s + 1;
- t1 = t + 1;
-
- /* clamp/wrap S/T if necessary */
- if (TEXMODE_CLAMP_S(TEXMODE))
- {
- if (s < 0) {
- s = 0;
- s1 = 0;
- } else if (s >= smax) {
- s = smax;
- s1 = smax;
- }
- //CLAMP(s, 0, smax);
- //CLAMP(s1, 0, smax);
- } else {
- s &= smax;
- s1 &= smax;
- }
-
- if (TEXMODE_CLAMP_T(TEXMODE))
- {
- if (t < 0) {
- t = 0;
- t1 = 0;
- } else if (t >= tmax) {
- t = tmax;
- t1 = tmax;
- }
- //CLAMP(t, 0, tmax);
- //CLAMP(t1, 0, tmax);
- } else {
- t &= tmax;
- t1 &= tmax;
- }
- t *= smax + 1;
- t1 *= smax + 1;
-
- /* fetch texel data */
- if (TEXMODE_FORMAT(TEXMODE) < 8)
- {
- texel0 = *(uint8_t *)&ram[(texbase + t + s) & mask];
- texel1 = *(uint8_t *)&ram[(texbase + t + s1) & mask];
- texel2 = *(uint8_t *)&ram[(texbase + t1 + s) & mask];
- texel3 = *(uint8_t *)&ram[(texbase + t1 + s1) & mask];
- texel0 = (LOOKUP)[texel0];
- texel1 = (LOOKUP)[texel1];
- texel2 = (LOOKUP)[texel2];
- texel3 = (LOOKUP)[texel3];
- }
- else
- {
- texel0 = *(uint16_t *)&ram[(texbase + 2*(t + s)) & mask];
- texel1 = *(uint16_t *)&ram[(texbase + 2*(t + s1)) & mask];
- texel2 = *(uint16_t *)&ram[(texbase + 2*(t1 + s)) & mask];
- texel3 = *(uint16_t *)&ram[(texbase + 2*(t1 + s1)) & mask];
- if (TEXMODE_FORMAT(TEXMODE) >= 10 && TEXMODE_FORMAT(TEXMODE) <= 12)
- {
- texel0 = (LOOKUP)[texel0];
- texel1 = (LOOKUP)[texel1];
- texel2 = (LOOKUP)[texel2];
- texel3 = (LOOKUP)[texel3];
- }
- else
- {
- texel0 = ((LOOKUP)[texel0 & 0xff] & 0xffffff) | ((texel0 & 0xff00) << 16);
- texel1 = ((LOOKUP)[texel1 & 0xff] & 0xffffff) | ((texel1 & 0xff00) << 16);
- texel2 = ((LOOKUP)[texel2 & 0xff] & 0xffffff) | ((texel2 & 0xff00) << 16);
- texel3 = ((LOOKUP)[texel3 & 0xff] & 0xffffff) | ((texel3 & 0xff00) << 16);
- }
- }
-
- /* weigh in each texel */
-
- result.bilinear_filter_rgbaint(texel0, texel1, texel2, texel3, sfrac, tfrac);
- }
- return result;
-}
-
-inline rgbaint_t ATTR_FORCE_INLINE voodoo_device::tmu_state::combineTexture(const uint32_t TEXMODE, const rgbaint_t& c_local, const rgbaint_t& c_other, int32_t lod)
-{
- rgbaint_t blend_color, blend_factor;
- rgbaint_t add_val;
-
- /* select zero/other for RGB */
- if (TEXMODE_TC_ZERO_OTHER(TEXMODE))
- blend_color.zero();
- else
- blend_color.set(c_other);
-
- /* select zero/other for alpha */
- if (TEXMODE_TCA_ZERO_OTHER(TEXMODE))
- blend_color.zero_alpha();
- else
- blend_color.merge_alpha16(c_other);
-
- if (TEXMODE_TC_SUB_CLOCAL(TEXMODE) || TEXMODE_TCA_SUB_CLOCAL(TEXMODE))
- {
- rgbaint_t sub_val;
-
- /* potentially subtract c_local */
- if (!TEXMODE_TC_SUB_CLOCAL(TEXMODE))
- sub_val.zero();
- else
- sub_val.set(c_local);
-
- if (!TEXMODE_TCA_SUB_CLOCAL(TEXMODE))
- sub_val.zero_alpha();
- else
- sub_val.merge_alpha16(c_local);
-
- blend_color.sub(sub_val);
- }
-
- /* blend RGB */
- switch (TEXMODE_TC_MSELECT(TEXMODE))
- {
- default: /* reserved */
- case 0: /* zero */
- blend_factor.zero();
- break;
-
- case 1: /* c_local */
- blend_factor.set(c_local);
- break;
-
- case 2: /* a_other */
- blend_factor.set(c_other.select_alpha32());
- break;
-
- case 3: /* a_local */
- blend_factor.set(c_local.select_alpha32());
- break;
-
- case 4: /* LOD (detail factor) */
- if (detailbias <= lod)
- blend_factor.zero();
- else
- {
- uint8_t tmp;
- tmp = (((detailbias - lod) << detailscale) >> 8);
- if (tmp > detailmax)
- tmp = detailmax;
- blend_factor.set_all(tmp);
- }
- break;
-
- case 5: /* LOD fraction */
- blend_factor.set_all(lod & 0xff);
- break;
- }
-
- /* blend alpha */
- switch (TEXMODE_TCA_MSELECT(TEXMODE))
- {
- default: /* reserved */
- case 0: /* zero */
- blend_factor.zero_alpha();
- break;
-
- case 1: /* c_local */
- blend_factor.merge_alpha16(c_local);
- break;
-
- case 2: /* a_other */
- blend_factor.merge_alpha16(c_other);
- break;
-
- case 3: /* a_local */
- blend_factor.merge_alpha16(c_local);
- break;
-
- case 4: /* LOD (detail factor) */
- if (detailbias <= lod)
- blend_factor.zero_alpha();
- else
- {
- uint8_t tmp;
- tmp = (((detailbias - lod) << detailscale) >> 8);
- if (tmp > detailmax)
- tmp = detailmax;
- blend_factor.set_a16(tmp);
- }
- break;
-
- case 5: /* LOD fraction */
- blend_factor.set_a16(lod & 0xff);
- break;
- }
-
- /* reverse the RGB blend */
- if (!TEXMODE_TC_REVERSE_BLEND(TEXMODE))
- blend_factor.xor_imm_rgba(0, 0xff, 0xff, 0xff);
-
- /* reverse the alpha blend */
- if (!TEXMODE_TCA_REVERSE_BLEND(TEXMODE))
- blend_factor.xor_imm_rgba(0xff, 0, 0, 0);
-
- /* do the blend */
- //tr = (tr * (blendr + 1)) >> 8;
- //tg = (tg * (blendg + 1)) >> 8;
- //tb = (tb * (blendb + 1)) >> 8;
- //ta = (ta * (blenda + 1)) >> 8;
-
- /* add clocal or alocal to RGB */
- switch (TEXMODE_TC_ADD_ACLOCAL(TEXMODE))
- {
- case 3: /* reserved */
- case 0: /* nothing */
- add_val.zero();
- break;
-
- case 1: /* add c_local */
- add_val.set(c_local);
- break;
-
- case 2: /* add_alocal */
- add_val.set(c_local.select_alpha32());
- break;
- }
-
- /* add clocal or alocal to alpha */
- if (!TEXMODE_TCA_ADD_ACLOCAL(TEXMODE))
- add_val.zero_alpha();
- else
- add_val.merge_alpha16(c_local);
-
- /* clamp */
- //result.rgb.r = (tr < 0) ? 0 : (tr > 0xff) ? 0xff : tr;
- //result.rgb.g = (tg < 0) ? 0 : (tg > 0xff) ? 0xff : tg;
- //result.rgb.b = (tb < 0) ? 0 : (tb > 0xff) ? 0xff : tb;
- //result.rgb.a = (ta < 0) ? 0 : (ta > 0xff) ? 0xff : ta;
- blend_factor.add_imm(1);
- blend_color.scale_add_and_clamp(blend_factor, add_val);
-
- /* invert */
- if (TEXMODE_TC_INVERT_OUTPUT(TEXMODE))
- blend_color.xor_imm_rgba(0, 0xff, 0xff, 0xff);
- if (TEXMODE_TCA_INVERT_OUTPUT(TEXMODE))
- blend_color.xor_imm_rgba(0xff, 0, 0, 0);
- return blend_color;
-}
-
-#endif // MAME_VIDEO_VOODDEFS_IPP