Previous 199869 Revisions Next

r25449 Saturday 28th September, 2013 at 05:13:54 UTC by Ryan Holtz
-Refactored N64 RDP blender to use function arrays in order to [MooglyGuy]
flatten inner-loop branch structures for potential performance.

-Broke blender steps into individual #defines in order to make the [MooglyGuy]
functional differences between RDP modes more apparent.
[src/emu/cpu/rsp]rsp.h rspdrc.c
[src/mame/video]rdpblend.c rdpblend.h rdpspn16.c

trunk/src/emu/cpu/rsp/rsp.h
r25448r25449
1616#ifndef __RSP_H__
1717#define __RSP_H__
1818
19#define USE_SIMD        (0)
19#define USE_SIMD        (1)
2020
2121#if USE_SIMD
2222#include <tmmintrin.h>
trunk/src/emu/cpu/rsp/rspdrc.c
r25448r25449
30893089
30903090    __m128i shuffled = _mm_shuffle_epi8(rsp->xv[VS2REG], vec_shuf_inverse[EL]);
30913091   __m128i carry = _mm_and_si128(rsp->xvflag[CARRY], vec_flagmask);
3092    __m128i unsat = _mm_add_epi16(_mm_add_epi16(rsp->xv[VS1REG], shuffled), carry);
3092    rsp->accum_l = _mm_add_epi16(_mm_add_epi16(rsp->xv[VS1REG], shuffled), carry);
30933093
30943094    __m128i addvec = _mm_adds_epi16(rsp->xv[VS1REG], shuffled);
30953095
r25448r25449
30983098
30993099    rsp->xv[VDREG] = _mm_add_epi16(addvec, carry);
31003100
3101    rsp->accum_l = unsat;
3102
31033101   rsp->xvflag[ZERO] = _mm_setzero_si128();
31043102   rsp->xvflag[CARRY] = _mm_setzero_si128();
31053103#else
trunk/src/mame/video/rdpblend.c
r25448r25449
22#include "includes/n64.h"
33#include "video/n64.h"
44
5bool N64BlenderT::Blend1Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object)
5N64BlenderT::N64BlenderT()
66{
7   INT32 r, g, b;
7   blend1[0] = &N64BlenderT::Blend1CycleNoBlendNoACVGNoDither;
8   blend1[1] = &N64BlenderT::Blend1CycleNoBlendNoACVGDither;
9   blend1[2] = &N64BlenderT::Blend1CycleNoBlendACVGNoDither;
10   blend1[3] = &N64BlenderT::Blend1CycleNoBlendACVGDither;
11   blend1[4] = &N64BlenderT::Blend1CycleBlendNoACVGNoDither;
12   blend1[5] = &N64BlenderT::Blend1CycleBlendNoACVGDither;
13   blend1[6] = &N64BlenderT::Blend1CycleBlendACVGNoDither;
14   blend1[7] = &N64BlenderT::Blend1CycleBlendACVGDither;
815
9   if (!object.OtherModes.alpha_cvg_select)
10   {
11      DitherA(&userdata->PixelColor.i.a, adseed);
12   }
16   blend2[0] = &N64BlenderT::Blend2CycleNoBlendNoACVGNoDither;
17   blend2[1] = &N64BlenderT::Blend2CycleNoBlendNoACVGDither;
18   blend2[2] = &N64BlenderT::Blend2CycleNoBlendACVGNoDither;
19   blend2[3] = &N64BlenderT::Blend2CycleNoBlendACVGDither;
20   blend2[4] = &N64BlenderT::Blend2CycleBlendNoACVGNoDither;
21   blend2[5] = &N64BlenderT::Blend2CycleBlendNoACVGDither;
22   blend2[6] = &N64BlenderT::Blend2CycleBlendACVGNoDither;
23   blend2[7] = &N64BlenderT::Blend2CycleBlendACVGDither;
1324
14   DitherA(&userdata->ShadeColor.i.a, adseed);
25   cycle0[0] = &N64BlenderT::BlendEquationCycle0NoForceNoSpecial;
26   cycle0[1] = &N64BlenderT::BlendEquationCycle0NoForceSpecial;
27   cycle0[2] = &N64BlenderT::BlendEquationCycle0ForceNoSpecial;
28   cycle0[3] = &N64BlenderT::BlendEquationCycle0ForceSpecial;
1529
16   if (!AlphaCompare(userdata->PixelColor.i.a, userdata, object))
17   {
18      return false;
30   cycle1[0] = &N64BlenderT::BlendEquationCycle1NoForceNoSpecial;
31   cycle1[1] = &N64BlenderT::BlendEquationCycle1NoForceSpecial;
32   cycle1[2] = &N64BlenderT::BlendEquationCycle1ForceNoSpecial;
33   cycle1[3] = &N64BlenderT::BlendEquationCycle1ForceSpecial;
34}
35
36#define ALPHA_COMPARE()   \
37   if (!AlphaCompare(userdata->PixelColor.i.a, userdata, object))   \
38   {                                                \
39      return false;                                    \
1940   }
2041
21   if (object.OtherModes.antialias_en ? (!userdata->CurrentPixCvg) : (!userdata->CurrentCvgBit))
22   {
23      return false;
42#define CVG_COMPARE() \
43   if (object.OtherModes.antialias_en ? (!userdata->CurrentPixCvg) : (!userdata->CurrentCvgBit))   \
44   {                                                \
45      return false;                                    \
2446   }
2547
26   bool dontblend = (partialreject && userdata->PixelColor.i.a >= 0xff);
27   if (!userdata->BlendEnable || dontblend)
28   {
29      r = *userdata->ColorInputs.blender1a_r[0];
30      g = *userdata->ColorInputs.blender1a_g[0];
31      b = *userdata->ColorInputs.blender1a_b[0];
48#define TEST_REJECT() \
49   ALPHA_COMPARE() \
50   CVG_COMPARE()
51
52#define WRITE_OUT_NB_ND(cycle) \
53   *fr = *userdata->ColorInputs.blender1a_r[cycle];   \
54   *fg = *userdata->ColorInputs.blender1a_g[cycle];   \
55   *fb = *userdata->ColorInputs.blender1a_b[cycle];
56
57#define WRITE_OUT() \
58   *fr = r;   \
59   *fg = g;   \
60   *fb = b;
61
62#define WRITE_BLENDED_COLOR() \
63   userdata->BlendedPixelColor.i.r = r;   \
64   userdata->BlendedPixelColor.i.g = g;   \
65   userdata->BlendedPixelColor.i.b = b;   \
66   userdata->BlendedPixelColor.i.a = userdata->PixelColor.i.a;
67
68#define BLEND_CYCLE(cyc) \
69   if (partialreject && userdata->PixelColor.i.a >= 0xff)   \
70   {                                          \
71      ASSIGN_OUT(cyc);                           \
72   }                                          \
73   else                                       \
74   {                                          \
75      userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[cyc];   \
76      ((this)->*(cycle##cyc[((object.OtherModes.force_blend & 1) << 1) | (special_bsel##cyc & 1)]))(&r, &g, &b, userdata, object);   \
3277   }
33   else
34   {
35      userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
36      BlendEquationCycle0(&r, &g, &b, special_bsel, userdata, object);
37   }
3878
39   if (object.OtherModes.rgb_dither_sel < 3)
40   {
41      DitherRGB(&r, &g, &b, dith);
79#define BLEND_FACTORS(cycle) \
80   UINT8 blend1a = *userdata->ColorInputs.blender1b_a[cycle] >> 3;   \
81   UINT8 blend2a = *userdata->ColorInputs.blender2b_a[cycle] >> 3;
82
83#define BLEND_FACTORS_SUM(cycle) \
84   UINT8 blend1a = *userdata->ColorInputs.blender1b_a[cycle] >> 3;   \
85   UINT8 blend2a = *userdata->ColorInputs.blender2b_a[cycle] >> 3;   \
86   UINT32 sum = ((blend1a >> 2) + (blend2a >> 2) + 1) & 0xf;
87
88#define BLEND_FACTORS_SPECIAL(cycle) \
89   UINT8 blend1a = (*userdata->ColorInputs.blender1b_a[cycle] >> (3 + userdata->ShiftA)) & 0x1c;   \
90   UINT8 blend2a = (*userdata->ColorInputs.blender2b_a[cycle] >> (3 + userdata->ShiftB)) & 0x1c;
91
92#define BLEND_FACTORS_SPECIAL_SUM(cycle) \
93   UINT8 blend1a = (*userdata->ColorInputs.blender1b_a[cycle] >> (3 + userdata->ShiftA)) & 0x1c;   \
94   UINT8 blend2a = (*userdata->ColorInputs.blender2b_a[cycle] >> (3 + userdata->ShiftB)) & 0x1c;   \
95   UINT32 sum = ((blend1a >> 2) + (blend2a >> 2) + 1) & 0xf;
96
97#define BLEND_MUL(cycle) \
98   *r = (((int)(*userdata->ColorInputs.blender1a_r[cycle]) * (int)(blend1a))) +   \
99      (((int)(*userdata->ColorInputs.blender2a_r[cycle]) * (int)(blend2a)));      \
100   *g = (((int)(*userdata->ColorInputs.blender1a_g[cycle]) * (int)(blend1a))) +   \
101      (((int)(*userdata->ColorInputs.blender2a_g[cycle]) * (int)(blend2a)));      \
102   *b = (((int)(*userdata->ColorInputs.blender1a_b[cycle]) * (int)(blend1a))) +   \
103      (((int)(*userdata->ColorInputs.blender2a_b[cycle]) * (int)(blend2a)));
104
105#define BLEND_ADD_SPECIAL(cycle) \
106   *r += (((int)*userdata->ColorInputs.blender2a_r[cycle]) << 2);   \
107   *g += (((int)*userdata->ColorInputs.blender2a_g[cycle]) << 2);   \
108   *b += (((int)*userdata->ColorInputs.blender2a_b[cycle]) << 2);
109
110#define BLEND_ADD(cycle) \
111   *r += (int)*userdata->ColorInputs.blender2a_r[cycle];   \
112   *g += (int)*userdata->ColorInputs.blender2a_g[cycle];   \
113   *b += (int)*userdata->ColorInputs.blender2a_b[cycle];
114
115#define BLEND_SHIFT(shift)   \
116   *r >>= shift;         \
117   *g >>= shift;         \
118   *b >>= shift;
119
120#define BLEND_CLAMP()      \
121   if (*r > 255) *r = 255;   \
122   if (*g > 255) *g = 255;   \
123   if (*b > 255) *b = 255;
124
125#define BLEND_SCALE()         \
126   if (sum)               \
127   {                     \
128      *r /= sum;            \
129      *g /= sum;            \
130      *b /= sum;            \
131   }                     \
132   else                  \
133   {                     \
134      *r = *g = *b = 0xff;   \
42135   }
43136
44   *fr = r;
45   *fg = g;
46   *fb = b;
47137
138#define ASSIGN_OUT(cycle) \
139   r = *userdata->ColorInputs.blender1a_r[cycle];   \
140   g = *userdata->ColorInputs.blender1a_g[cycle];   \
141   b = *userdata->ColorInputs.blender1a_b[cycle];
142
143bool N64BlenderT::Blend1CycleNoBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object)
144{
145   DitherA(&userdata->PixelColor.i.a, adseed);
146   DitherA(&userdata->ShadeColor.i.a, adseed);
147
148   TEST_REJECT();
149   WRITE_OUT_NB_ND(0);
150
48151   return true;
49152}
50153
51bool N64BlenderT::Blend2Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object)
154bool N64BlenderT::Blend1CycleNoBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object)
52155{
53   if (!object.OtherModes.alpha_cvg_select)
54   {
55      DitherA(&userdata->PixelColor.i.a, adseed);
56   }
156   INT32 r, g, b;
57157
158   DitherA(&userdata->PixelColor.i.a, adseed);
58159   DitherA(&userdata->ShadeColor.i.a, adseed);
59160
60   if (!AlphaCompare(userdata->PixelColor.i.a, userdata, object))
61   {
62      return false;
63   }
161   TEST_REJECT();
162   ASSIGN_OUT(0);
163   DitherRGB(&r, &g, &b, dith);
164   WRITE_OUT();
64165
65   if (object.OtherModes.antialias_en ? (!userdata->CurrentPixCvg) : (!userdata->CurrentCvgBit))
66   {
67      return false;
68   }
166   return true;
167}
69168
169bool N64BlenderT::Blend1CycleNoBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object)
170{
171   DitherA(&userdata->ShadeColor.i.a, adseed);
172
173   TEST_REJECT();
174   WRITE_OUT_NB_ND(0);
175
176   return true;
177}
178
179bool N64BlenderT::Blend1CycleNoBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object)
180{
181   INT32 r, g, b;
182
183   DitherA(&userdata->ShadeColor.i.a, adseed);
184
185   TEST_REJECT();
186   ASSIGN_OUT(0);
187   DitherRGB(&r, &g, &b, dith);
188   WRITE_OUT();
189
190   return true;
191}
192
193bool N64BlenderT::Blend1CycleBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object)
194{
195   INT32 r, g, b;
196
197   DitherA(&userdata->PixelColor.i.a, adseed);
198   DitherA(&userdata->ShadeColor.i.a, adseed);
199
200   TEST_REJECT();
201   BLEND_CYCLE(0);
202   WRITE_OUT();
203
204   return true;
205}
206
207bool N64BlenderT::Blend1CycleBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object)
208{
209   INT32 r, g, b;
210
211   DitherA(&userdata->PixelColor.i.a, adseed);
212   DitherA(&userdata->ShadeColor.i.a, adseed);
213
214   TEST_REJECT();
215   BLEND_CYCLE(0);
216   DitherRGB(&r, &g, &b, dith);
217   WRITE_OUT();
218
219   return true;
220}
221
222bool N64BlenderT::Blend1CycleBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object)
223{
224   INT32 r, g, b;
225
226   DitherA(&userdata->ShadeColor.i.a, adseed);
227
228   TEST_REJECT();
229   BLEND_CYCLE(0);
230   WRITE_OUT();
231
232   return true;
233}
234
235bool N64BlenderT::Blend1CycleBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object)
236{
237   INT32 r, g, b;
238
239   DitherA(&userdata->ShadeColor.i.a, adseed);
240
241   TEST_REJECT();
242   BLEND_CYCLE(0);
243   DitherRGB(&r, &g, &b, dith);
244   WRITE_OUT();
245
246   return true;
247}
248
249bool N64BlenderT::Blend2CycleNoBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object)
250{
251   INT32 r, g, b;
252
253   DitherA(&userdata->PixelColor.i.a, adseed);
254   DitherA(&userdata->ShadeColor.i.a, adseed);
255
256   TEST_REJECT();
70257   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
258   ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object);
259   WRITE_BLENDED_COLOR();
260   WRITE_OUT_NB_ND(1);
71261
262   return true;
263}
264
265bool N64BlenderT::Blend2CycleNoBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object)
266{
72267   INT32 r, g, b;
73   BlendEquationCycle0(&r, &g, &b, special_bsel0, userdata, object);
74268
75   userdata->BlendedPixelColor.i.r = r;
76   userdata->BlendedPixelColor.i.g = g;
77   userdata->BlendedPixelColor.i.b = b;
78   userdata->BlendedPixelColor.i.a = userdata->PixelColor.i.a;
269   DitherA(&userdata->PixelColor.i.a, adseed);
270   DitherA(&userdata->ShadeColor.i.a, adseed);
79271
80   bool dontblend = (partialreject && userdata->PixelColor.i.a >= 0xff);
81   if (!userdata->BlendEnable || dontblend)
82   {
83      r = *userdata->ColorInputs.blender1a_r[1];
84      g = *userdata->ColorInputs.blender1a_g[1];
85      b = *userdata->ColorInputs.blender1a_b[1];
86   }
87   else
88   {
89      userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[1];
90      BlendEquationCycle1(&r, &g, &b, special_bsel1, userdata, object);
91   }
272   TEST_REJECT();
273   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
274   ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object);
275   WRITE_BLENDED_COLOR();
276   ASSIGN_OUT(1);
277   DitherRGB(&r, &g, &b, dith);
278   WRITE_OUT();
92279
93   if (object.OtherModes.rgb_dither_sel < 3)
94   {
95      DitherRGB(&r, &g, &b, dith);
96   }
280   return true;
281}
97282
98   *fr = r;
99   *fg = g;
100   *fb = b;
283bool N64BlenderT::Blend2CycleNoBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object)
284{
285   INT32 r, g, b;
101286
287   DitherA(&userdata->ShadeColor.i.a, adseed);
288
289   TEST_REJECT();
290   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
291   ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object);
292   WRITE_BLENDED_COLOR();
293   WRITE_OUT_NB_ND(1);
294
102295   return true;
103296}
104297
105void N64BlenderT::BlendEquationCycle0(int* r, int* g, int* b, int bsel_special, rdp_span_aux *userdata, const rdp_poly_state& object)
298bool N64BlenderT::Blend2CycleNoBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object)
106299{
107   UINT8 blend1a = *userdata->ColorInputs.blender1b_a[0] >> 3;
108   UINT8 blend2a = *userdata->ColorInputs.blender2b_a[0] >> 3;
300   INT32 r, g, b;
109301
110   if (bsel_special)
111   {
112      blend1a = (blend1a >> userdata->ShiftA) & 0x1C;
113      blend2a = (blend2a >> userdata->ShiftB) & 0x1C;
114   }
302   DitherA(&userdata->ShadeColor.i.a, adseed);
115303
116   UINT32 sum = ((blend1a >> 2) + (blend2a >> 2) + 1) & 0xf;
304   TEST_REJECT();
305   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
306   ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object);
307   WRITE_BLENDED_COLOR();
308   ASSIGN_OUT(1);
309   DitherRGB(&r, &g, &b, dith);
310   WRITE_OUT();
117311
118   *r = (((int)(*userdata->ColorInputs.blender1a_r[0]) * (int)(blend1a))) +
119      (((int)(*userdata->ColorInputs.blender2a_r[0]) * (int)(blend2a)));
312   return true;
313}
120314
121   *g = (((int)(*userdata->ColorInputs.blender1a_g[0]) * (int)(blend1a))) +
122      (((int)(*userdata->ColorInputs.blender2a_g[0]) * (int)(blend2a)));
315bool N64BlenderT::Blend2CycleBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object)
316{
317   INT32 r, g, b;
123318
124   *b = (((int)(*userdata->ColorInputs.blender1a_b[0]) * (int)(blend1a))) +
125      (((int)(*userdata->ColorInputs.blender2a_b[0]) * (int)(blend2a)));
319   DitherA(&userdata->PixelColor.i.a, adseed);
320   DitherA(&userdata->ShadeColor.i.a, adseed);
126321
127   if (bsel_special)
128   {
129      *r += (((int)*userdata->ColorInputs.blender2a_r[0]) << 2);
130      *g += (((int)*userdata->ColorInputs.blender2a_g[0]) << 2);
131      *b += (((int)*userdata->ColorInputs.blender2a_b[0]) << 2);
132   }
133   else
134   {
135      *r += (int)*userdata->ColorInputs.blender2a_r[0];
136      *g += (int)*userdata->ColorInputs.blender2a_g[0];
137      *b += (int)*userdata->ColorInputs.blender2a_b[0];
138   }
322   TEST_REJECT();
323   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
324   ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object);
325   WRITE_BLENDED_COLOR();
326   BLEND_CYCLE(1);
327   WRITE_OUT();
139328
140   *r >>= 2;
141   *g >>= 2;
142   *b >>= 2;
329   return true;
330}
143331
144   if (object.OtherModes.force_blend)
145   {
146      *r >>= 3;
147      *g >>= 3;
148      *b >>= 3;
149   }
150   else
151   {
152      if (sum)
153      {
154         *r /= sum;
155         *g /= sum;
156         *b /= sum;
157      }
158      else
159      {
160         *r = *g = *b = 0xff;
161      }
162   }
332bool N64BlenderT::Blend2CycleBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object)
333{
334   INT32 r, g, b;
163335
164   if (*r > 255) *r = 255;
165   if (*g > 255) *g = 255;
166   if (*b > 255) *b = 255;
336   DitherA(&userdata->PixelColor.i.a, adseed);
337   DitherA(&userdata->ShadeColor.i.a, adseed);
338
339   TEST_REJECT();
340   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
341   ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object);
342   WRITE_BLENDED_COLOR();
343   BLEND_CYCLE(1);
344   DitherRGB(&r, &g, &b, dith);
345   WRITE_OUT();
346
347   return true;
167348}
168349
169void N64BlenderT::BlendEquationCycle1(INT32* r, INT32* g, INT32* b, int bsel_special, rdp_span_aux *userdata, const rdp_poly_state& object)
350bool N64BlenderT::Blend2CycleBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object)
170351{
171   UINT8 blend1a = *userdata->ColorInputs.blender1b_a[1] >> 3;
172   UINT8 blend2a = *userdata->ColorInputs.blender2b_a[1] >> 3;
352   INT32 r, g, b;
173353
174   if (bsel_special)
175   {
176      blend1a = (blend1a >> userdata->ShiftA) & 0x1C;
177      blend2a = (blend2a >> userdata->ShiftB) & 0x1C;
178   }
354   DitherA(&userdata->ShadeColor.i.a, adseed);
179355
180   UINT32 sum = ((blend1a >> 2) + (blend2a >> 2) + 1) & 0xf;
356   TEST_REJECT();
357   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
358   ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object);
359   WRITE_BLENDED_COLOR();
360   BLEND_CYCLE(1);
361   WRITE_OUT();
181362
182   *r = (((int)(*userdata->ColorInputs.blender1a_r[1]) * (int)(blend1a))) +
183      (((int)(*userdata->ColorInputs.blender2a_r[1]) * (int)(blend2a)));
363   return true;
364}
184365
185   *g = (((int)(*userdata->ColorInputs.blender1a_g[1]) * (int)(blend1a))) +
186      (((int)(*userdata->ColorInputs.blender2a_g[1]) * (int)(blend2a)));
366bool N64BlenderT::Blend2CycleBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object)
367{
368   INT32 r, g, b;
187369
188   *b = (((int)(*userdata->ColorInputs.blender1a_b[1]) * (int)(blend1a))) +
189      (((int)(*userdata->ColorInputs.blender2a_b[1]) * (int)(blend2a)));
370   DitherA(&userdata->ShadeColor.i.a, adseed);
190371
191   if (bsel_special)
192   {
193      *r += (((int)*userdata->ColorInputs.blender2a_r[1]) << 2);
194      *g += (((int)*userdata->ColorInputs.blender2a_g[1]) << 2);
195      *b += (((int)*userdata->ColorInputs.blender2a_b[1]) << 2);
196   }
197   else
198   {
199      *r += (int)*userdata->ColorInputs.blender2a_r[1];
200      *g += (int)*userdata->ColorInputs.blender2a_g[1];
201      *b += (int)*userdata->ColorInputs.blender2a_b[1];
202   }
372   TEST_REJECT();
373   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
374   ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object);
375   WRITE_BLENDED_COLOR();
376   BLEND_CYCLE(1);
377   DitherRGB(&r, &g, &b, dith);
378   WRITE_OUT();
203379
204   *r >>= 2;
205   *g >>= 2;
206   *b >>= 2;
380   return true;
381}
207382
208   if (object.OtherModes.force_blend)
209   {
210      *r >>= 3;
211      *g >>= 3;
212      *b >>= 3;
213   }
214   else
215   {
216      if (sum)
217      {
218         *r /= sum;
219         *g /= sum;
220         *b /= sum;
221      }
222      else
223      {
224         *r = *g = *b = 0xff;
225      }
226   }
383void N64BlenderT::BlendEquationCycle0NoForceNoSpecial(int* r, int* g, int* b, rdp_span_aux *userdata, const rdp_poly_state& object)
384{
385   BLEND_FACTORS_SUM(0);
386   BLEND_MUL(0);
387   BLEND_ADD(0);
388   BLEND_SHIFT(2);
389   BLEND_SCALE();
390   BLEND_CLAMP();
391}
227392
228   if (*r > 255) *r = 255;
229   if (*g > 255) *g = 255;
230   if (*b > 255) *b = 255;
393void N64BlenderT::BlendEquationCycle0NoForceSpecial(int* r, int* g, int* b, rdp_span_aux *userdata, const rdp_poly_state& object)
394{
395   BLEND_FACTORS_SPECIAL_SUM(0);
396   BLEND_MUL(0);
397   BLEND_ADD_SPECIAL(0);
398   BLEND_SHIFT(2);
399   BLEND_SCALE();
400   BLEND_CLAMP();
231401}
232402
403void N64BlenderT::BlendEquationCycle0ForceNoSpecial(int* r, int* g, int* b, rdp_span_aux *userdata, const rdp_poly_state& object)
404{
405   BLEND_FACTORS(0);
406   BLEND_MUL(0);
407   BLEND_ADD(0);
408   BLEND_SHIFT(5);
409   BLEND_CLAMP();
410}
411
412void N64BlenderT::BlendEquationCycle0ForceSpecial(int* r, int* g, int* b, rdp_span_aux *userdata, const rdp_poly_state& object)
413{
414   BLEND_FACTORS_SPECIAL(0);
415   BLEND_MUL(0);
416   BLEND_ADD_SPECIAL(0);
417   BLEND_SHIFT(5);
418   BLEND_CLAMP();
419}
420
421void N64BlenderT::BlendEquationCycle1NoForceNoSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object)
422{
423   BLEND_FACTORS_SUM(1);
424   BLEND_MUL(1);
425   BLEND_ADD(1);
426   BLEND_SHIFT(2);
427   BLEND_SCALE();
428   BLEND_CLAMP();
429}
430
431void N64BlenderT::BlendEquationCycle1NoForceSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object)
432{
433   BLEND_FACTORS_SPECIAL_SUM(1);
434   BLEND_MUL(1);
435   BLEND_ADD_SPECIAL(1);
436   BLEND_SHIFT(2);
437   BLEND_SCALE();
438   BLEND_CLAMP();
439}
440
441void N64BlenderT::BlendEquationCycle1ForceNoSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object)
442{
443   BLEND_FACTORS(1);
444   BLEND_MUL(1);
445   BLEND_ADD(1);
446   BLEND_SHIFT(5);
447   BLEND_CLAMP();
448}
449
450void N64BlenderT::BlendEquationCycle1ForceSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object)
451{
452   BLEND_FACTORS_SPECIAL(1);
453   BLEND_MUL(1);
454   BLEND_ADD_SPECIAL(1);
455   BLEND_SHIFT(5);
456   BLEND_CLAMP();
457}
458
233459bool N64BlenderT::AlphaCompare(UINT8 alpha, const rdp_span_aux *userdata, const rdp_poly_state& object)
234460{
235461   INT32 threshold;
trunk/src/mame/video/rdpblend.h
r25448r25449
1313class N64BlenderT
1414{
1515   public:
16      N64BlenderT()
17      {
18      }
16      typedef bool (N64BlenderT::*Blender1)(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
17      typedef bool (N64BlenderT::*Blender2)(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object);
18      typedef void (N64BlenderT::*BlendEquation)(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object);
19      N64BlenderT();
1920
20      bool                Blend2Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object);
21      bool                Blend1Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
21      Blender1         blend1[8];
22      Blender2         blend2[8];
2223
2324      void                SetMachine(running_machine& machine) { m_machine = &machine; }
2425      void                SetProcessor(n64_rdp* rdp) { m_rdp = rdp; }
r25448r25449
2930      running_machine*    m_machine;
3031      n64_rdp*            m_rdp;
3132
32      void                BlendEquationCycle0(INT32* r, INT32* g, INT32* b, int bsel_special, rdp_span_aux *userdata, const rdp_poly_state& object);
33      void                BlendEquationCycle1(INT32* r, INT32* g, INT32* b, int bsel_special, rdp_span_aux *userdata, const rdp_poly_state& object);
33      bool            Blend1CycleNoBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
34      bool            Blend1CycleNoBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
35      bool            Blend1CycleNoBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
36      bool            Blend1CycleNoBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
37      bool            Blend1CycleBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
38      bool            Blend1CycleBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
39      bool            Blend1CycleBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
40      bool            Blend1CycleBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
3441
42      bool            Blend2CycleNoBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object);
43      bool            Blend2CycleNoBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object);
44      bool            Blend2CycleNoBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object);
45      bool            Blend2CycleNoBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object);
46      bool            Blend2CycleBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object);
47      bool            Blend2CycleBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object);
48      bool            Blend2CycleBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object);
49      bool            Blend2CycleBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object);
50
51      void                BlendEquationCycle0NoForceNoSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object);
52      void                BlendEquationCycle0NoForceSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object);
53      void                BlendEquationCycle0ForceNoSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object);
54      void                BlendEquationCycle0ForceSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object);
55
56      void                BlendEquationCycle1NoForceNoSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object);
57      void                BlendEquationCycle1NoForceSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object);
58      void                BlendEquationCycle1ForceNoSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object);
59      void                BlendEquationCycle1ForceSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object);
60
61      BlendEquation      cycle0[4];
62      BlendEquation      cycle1[4];
63
3564      bool                AlphaCompare(UINT8 alpha, const rdp_span_aux *userdata, const rdp_poly_state& object);
3665
3766      void                DitherRGB(INT32* r, INT32* g, INT32* b, int dith);
trunk/src/mame/video/rdpspn16.c
r25448r25449
5050      case CYCLE_TYPE_1:
5151         render_triangle_custom(visarea, render_delegate(FUNC(n64_rdp::SpanDraw1Cycle), this), start, (end - start) + 1, Spans + offset);
5252         break;
53
5354      case CYCLE_TYPE_2:
5455         render_triangle_custom(visarea, render_delegate(FUNC(n64_rdp::SpanDraw2Cycle), this), start, (end - start) + 1, Spans + offset);
5556         break;
r25448r25449
148149   bool partialreject = (userdata->ColorInputs.blender2b_a[0] == &userdata->InvPixelColor.i.a && userdata->ColorInputs.blender1b_a[0] == &userdata->PixelColor.i.a);
149150   bool bsel0 = (userdata->ColorInputs.blender2b_a[0] == &userdata->MemoryColor.i.a);
150151
151   int drinc = flip ? (object.SpanBase.m_span_dr) : -object.SpanBase.m_span_dr;
152   int dginc = flip ? (object.SpanBase.m_span_dg) : -object.SpanBase.m_span_dg;
153   int dbinc = flip ? (object.SpanBase.m_span_db) : -object.SpanBase.m_span_db;
154   int dainc = flip ? (object.SpanBase.m_span_da) : -object.SpanBase.m_span_da;
155   int dzinc = flip ? (object.SpanBase.m_span_dz) : -object.SpanBase.m_span_dz;
156   int dsinc = flip ? (object.SpanBase.m_span_ds) : -object.SpanBase.m_span_ds;
157   int dtinc = flip ? (object.SpanBase.m_span_dt) : -object.SpanBase.m_span_dt;
158   int dwinc = flip ? (object.SpanBase.m_span_dw) : -object.SpanBase.m_span_dw;
152   int drinc = object.SpanBase.m_span_dr;
153   int dginc = object.SpanBase.m_span_dg;
154   int dbinc = object.SpanBase.m_span_db;
155   int dainc = object.SpanBase.m_span_da;
156   int dzinc = object.SpanBase.m_span_dz;
157   int dsinc = object.SpanBase.m_span_ds;
158   int dtinc = object.SpanBase.m_span_dt;
159   int dwinc = object.SpanBase.m_span_dw;
160   int xinc = 1;
161   if (!flip)
162   {
163      drinc = -drinc;
164      dginc = -dginc;
165      dbinc = -dbinc;
166      dainc = -dainc;
167      dzinc = -dzinc;
168      dsinc = -dsinc;
169      dtinc = -dtinc;
170      dwinc = -dwinc;
171      xinc = -xinc;
172   }
159173   int dzpix = object.SpanBase.m_span_dzpix;
160   int xinc = flip ? 1 : -1;
161174
162175   int fb_index = object.MiscState.FBWidth * scanline;
163176
r25448r25449
180193      dzinc = 0;
181194   }
182195
196   int blend_index = (object.OtherModes.alpha_cvg_select ? 2 : 0) | ((object.OtherModes.rgb_dither_sel < 3) ? 1 : 0);
197   int read_index = ((object.MiscState.FBSize - 2) << 1) | object.OtherModes.image_read_en;
198   int write_index = ((object.MiscState.FBSize - 2) << 3) | (object.OtherModes.cvg_dest << 1);
183199   userdata->m_start_span = true;
184200   for (int j = 0; j <= length; j++)
185201   {
r25448r25449
233249         UINT32 zbcur = zb + curpixel;
234250         UINT32 zhbcur = zhb + curpixel;
235251
236         ((this)->*(_Read[((object.MiscState.FBSize - 2) << 1) | object.OtherModes.image_read_en]))(curpixel, userdata, object);
252         ((this)->*(_Read[read_index]))(curpixel, userdata, object);
237253
238254         if(m_rdp->ZCompare(zbcur, zhbcur, sz, dzpix, userdata, object))
239255         {
240256            m_rdp->GetDitherValues(scanline, j, &cdith, &adith, object);
241257
242            bool rendered = m_rdp->Blender.Blend1Cycle(&fir, &fig, &fib, cdith, adith, partialreject, bsel0, userdata, object);
258            bool rendered = ((&m_rdp->Blender)->*(m_rdp->Blender.blend1[(userdata->BlendEnable << 2) | blend_index]))(&fir, &fig, &fib, cdith, adith, partialreject, bsel0, userdata, object);
243259
244260            if (rendered)
245261            {
246               ((this)->*(_Write[((object.MiscState.FBSize - 2) << 3) | (object.OtherModes.cvg_dest << 1) | userdata->BlendEnable]))(curpixel, fir, fig, fib, userdata, object);
262               ((this)->*(_Write[write_index | userdata->BlendEnable]))(curpixel, fir, fig, fib, userdata, object);
247263
248264               if (object.OtherModes.z_update_en)
249265               {
r25448r25449
337353      dzinc = 0;
338354   }
339355
356   int blend_index = (object.OtherModes.alpha_cvg_select ? 2 : 0) | ((object.OtherModes.rgb_dither_sel < 3) ? 1 : 0);
357   int read_index = ((object.MiscState.FBSize - 2) << 1) | object.OtherModes.image_read_en;
358   int write_index = ((object.MiscState.FBSize - 2) << 3) | (object.OtherModes.cvg_dest << 1);
340359   userdata->m_start_span = true;
341360   for (int j = 0; j <= length; j++)
342361   {
r25448r25449
399418         UINT32 zbcur = zb + curpixel;
400419         UINT32 zhbcur = zhb + curpixel;
401420
402         ((this)->*(_Read[((object.MiscState.FBSize - 2) << 1) | object.OtherModes.image_read_en]))(curpixel, userdata, object);
421         ((this)->*(_Read[read_index]))(curpixel, userdata, object);
403422
404423         if(m_rdp->ZCompare(zbcur, zhbcur, sz, dzpix, userdata, object))
405424         {
406425            m_rdp->GetDitherValues(scanline, j, &cdith, &adith, object);
407426
408            bool rendered = m_rdp->Blender.Blend2Cycle(&fir, &fig, &fib, cdith, adith, partialreject, bsel0, bsel1, userdata, object);
427            bool rendered = ((&m_rdp->Blender)->*(m_rdp->Blender.blend2[(userdata->BlendEnable << 2) | blend_index]))(&fir, &fig, &fib, cdith, adith, partialreject, bsel0, bsel1, userdata, object);
409428
410429            if (rendered)
411430            {
412               ((this)->*(_Write[((object.MiscState.FBSize - 2) << 3) | (object.OtherModes.cvg_dest << 1) | userdata->BlendEnable]))(curpixel, fir, fig, fib, userdata, object);
431               ((this)->*(_Write[write_index | userdata->BlendEnable]))(curpixel, fir, fig, fib, userdata, object);
413432               if (object.OtherModes.z_update_en)
414433               {
415434                  m_rdp->ZStore(zbcur, zhbcur, sz, userdata->m_dzpix_enc);

Previous 199869 Revisions Next


© 1997-2024 The MAME Team