From af69a613b6d55af21c6990c8cf28edd2d75c2034 Mon Sep 17 00:00:00 2001 From: snickerbockers Date: Fri, 7 Sep 2018 01:35:00 -0700 Subject: powervr2.cpp: make opaque polygons opaque Previously, MAME's pvr2 implementation treated all polygons as transparent. This resolves missing graphics in certain games which were rendering opaque polygons with alpha values which would make them transparent if they weren't on the opaque list. In the future, Punch-through polygons will also require special consideration. These are polygons which support transparency but not blending (every pixel is either entirely transparent or entirely opaque). For now, they're still treated the same as transparent polygons. --- src/mame/video/powervr2.cpp | 67 +++++++++++++++++++++++++-------------------- src/mame/video/powervr2.h | 14 ++++++---- 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/src/mame/video/powervr2.cpp b/src/mame/video/powervr2.cpp index 0eeed1caa75..1cbb9409d05 100644 --- a/src/mame/video/powervr2.cpp +++ b/src/mame/video/powervr2.cpp @@ -2361,7 +2361,7 @@ inline uint32_t powervr2_device::sample_textured(texinfo *ti, float u, float v, return c; } -template +template inline void powervr2_device::render_hline(bitmap_rgb32 &bitmap, texinfo *ti, int y, float xl, float xr, float ul, float ur, float vl, float vr, float wl, float wr, float const bl_in[4], float const br_in[4], float const offl_in[4], float const offr_in[4]) { int idx; @@ -2431,9 +2431,14 @@ inline void powervr2_device::render_hline(bitmap_rgb32 &bitmap, texinfo *ti, int uint32_t offset_color = float_argb_to_packed_argb(offl); uint32_t base_color = float_argb_to_packed_argb(bl); c = (this->*sample_fn)(ti, u, v, offset_color, base_color); - if(c & 0xff000000) { + if (group_no == DISPLAY_LIST_OPAQUE) { + *tdata = c; *wbufline = wl; - *tdata = ti->blend(c, *tdata); + } else { + if(c & 0xff000000) { + *wbufline = wl; + *tdata = ti->blend(c, *tdata); + } } } wbufline++; @@ -2450,7 +2455,7 @@ inline void powervr2_device::render_hline(bitmap_rgb32 &bitmap, texinfo *ti, int } } -template +template inline void powervr2_device::render_span(bitmap_rgb32 &bitmap, texinfo *ti, float y0, float y1, float xl, float xr, @@ -2529,7 +2534,7 @@ inline void powervr2_device::render_span(bitmap_rgb32 &bitmap, texinfo *ti, } while(yy0 < yy1) { - render_hline(bitmap, ti, yy0, xl, xr, ul, ur, vl, vr, wl, wr, bl, br, offl, offr); + render_hline(bitmap, ti, yy0, xl, xr, ul, ur, vl, vr, wl, wr, bl, br, offl, offr); xl += dxldy; xr += dxrdy; @@ -2581,7 +2586,7 @@ void powervr2_device::sort_vertices(const vert *v, int *i0, int *i1, int *i2) } -template +template inline void powervr2_device::render_tri_sorted(bitmap_rgb32 &bitmap, texinfo *ti, const vert *v0, const vert *v1, const vert *v2) { float dy01, dy02, dy12; @@ -2700,15 +2705,15 @@ inline void powervr2_device::render_tri_sorted(bitmap_rgb32 &bitmap, texinfo *ti return; if(v1->x > v0->x) - render_span(bitmap, ti, v1->y, v2->y, v0->x, v1->x, v0->u, v1->u, v0->v, v1->v, v0->w, v1->w, v0->b, v1->b, v0->o, v1->o, dx02dy, dx12dy, du02dy, du12dy, dv02dy, dv12dy, dw02dy, dw12dy, db02dy, db12dy, do02dy, do12dy); + render_span(bitmap, ti, v1->y, v2->y, v0->x, v1->x, v0->u, v1->u, v0->v, v1->v, v0->w, v1->w, v0->b, v1->b, v0->o, v1->o, dx02dy, dx12dy, du02dy, du12dy, dv02dy, dv12dy, dw02dy, dw12dy, db02dy, db12dy, do02dy, do12dy); else - render_span(bitmap, ti, v1->y, v2->y, v1->x, v0->x, v1->u, v0->u, v1->v, v0->v, v1->w, v0->w, v1->b, v0->b, v1->o, v0->o, dx12dy, dx02dy, du12dy, du02dy, dv12dy, dv02dy, dw12dy, dw02dy, db12dy, db02dy, do12dy, do02dy); + render_span(bitmap, ti, v1->y, v2->y, v1->x, v0->x, v1->u, v0->u, v1->v, v0->v, v1->w, v0->w, v1->b, v0->b, v1->o, v0->o, dx12dy, dx02dy, du12dy, du02dy, dv12dy, dv02dy, dw12dy, dw02dy, db12dy, db02dy, do12dy, do02dy); } else if(!dy12) { if(v2->x > v1->x) - render_span(bitmap, ti, v0->y, v1->y, v0->x, v0->x, v0->u, v0->u, v0->v, v0->v, v0->w, v0->w, v0->b, v0->b, v0->o, v0->o, dx01dy, dx02dy, du01dy, du02dy, dv01dy, dv02dy, dw01dy, dw02dy, db01dy, db02dy, do01dy, do02dy); + render_span(bitmap, ti, v0->y, v1->y, v0->x, v0->x, v0->u, v0->u, v0->v, v0->v, v0->w, v0->w, v0->b, v0->b, v0->o, v0->o, dx01dy, dx02dy, du01dy, du02dy, dv01dy, dv02dy, dw01dy, dw02dy, db01dy, db02dy, do01dy, do02dy); else - render_span(bitmap, ti, v0->y, v1->y, v0->x, v0->x, v0->u, v0->u, v0->v, v0->v, v0->w, v0->w, v0->b, v0->b, v0->o, v0->o, dx02dy, dx01dy, du02dy, du01dy, dv02dy, dv01dy, dw02dy, dw01dy, db02dy, db01dy, do02dy, do01dy); + render_span(bitmap, ti, v0->y, v1->y, v0->x, v0->x, v0->u, v0->u, v0->v, v0->v, v0->w, v0->w, v0->b, v0->b, v0->o, v0->o, dx02dy, dx01dy, du02dy, du01dy, dv02dy, dv01dy, dw02dy, dw01dy, db02dy, db01dy, do02dy, do01dy); } else { float idk_b[4] = { @@ -2724,23 +2729,24 @@ inline void powervr2_device::render_tri_sorted(bitmap_rgb32 &bitmap, texinfo *ti v0->o[3] + do02dy[3] * dy01 }; if(dx01dy < dx02dy) { - render_span(bitmap, ti, v0->y, v1->y, + render_span(bitmap, ti, v0->y, v1->y, v0->x, v0->x, v0->u, v0->u, v0->v, v0->v, v0->w, v0->w, v0->b, v0->b, v0->o, v0->o, dx01dy, dx02dy, du01dy, du02dy, dv01dy, dv02dy, dw01dy, dw02dy, db01dy, db02dy, do01dy, do02dy); - render_span(bitmap, ti, v1->y, v2->y, + render_span(bitmap, ti, v1->y, v2->y, v1->x, v0->x + dx02dy*dy01, v1->u, v0->u + du02dy*dy01, v1->v, v0->v + dv02dy*dy01, v1->w, v0->w + dw02dy*dy01, v1->b, idk_b, v1->o, idk_o, dx12dy, dx02dy, du12dy, du02dy, dv12dy, dv02dy, dw12dy, dw02dy, db12dy, db02dy, do12dy, do02dy); } else { - render_span(bitmap, ti, v0->y, v1->y, + render_span(bitmap, ti, v0->y, v1->y, v0->x, v0->x, v0->u, v0->u, v0->v, v0->v, v0->w, v0->w, v0->b, v0->b, v0->o, v0->o, dx02dy, dx01dy, du02dy, du01dy, dv02dy, dv01dy, dw02dy, dw01dy, db02dy, db01dy, do02dy, do01dy); - render_span(bitmap, ti, v1->y, v2->y, + render_span(bitmap, ti, v1->y, v2->y, v0->x + dx02dy*dy01, v1->x, v0->u + du02dy*dy01, v1->u, v0->v + dv02dy*dy01, v1->v, v0->w + dw02dy*dy01, v1->w, idk_b, v1->b, idk_o, v1->o, dx02dy, dx12dy, du02dy, du12dy, dv02dy, dv12dy, dw02dy, dw12dy, db02dy, db12dy, do02dy, do12dy); } } } +template void powervr2_device::render_tri(bitmap_rgb32 &bitmap, texinfo *ti, const vert *v) { int i0, i1, i2; @@ -2754,16 +2760,16 @@ void powervr2_device::render_tri(bitmap_rgb32 &bitmap, texinfo *ti, const vert * if (bilinear) { switch (ti->tsinstruction) { case 0: - render_tri_sorted<&powervr2_device::sample_textured<0,true>>(bitmap, ti, v+i0, v+i1, v+i2); + render_tri_sorted<&powervr2_device::sample_textured<0,true>, group_no>(bitmap, ti, v+i0, v+i1, v+i2); break; case 1: - render_tri_sorted<&powervr2_device::sample_textured<1,true>>(bitmap, ti, v+i0, v+i1, v+i2); + render_tri_sorted<&powervr2_device::sample_textured<1,true>, group_no>(bitmap, ti, v+i0, v+i1, v+i2); break; case 2: - render_tri_sorted<&powervr2_device::sample_textured<2,true>>(bitmap, ti, v+i0, v+i1, v+i2); + render_tri_sorted<&powervr2_device::sample_textured<2,true>, group_no>(bitmap, ti, v+i0, v+i1, v+i2); break; case 3: - render_tri_sorted<&powervr2_device::sample_textured<3,true>>(bitmap, ti, v+i0, v+i1, v+i2); + render_tri_sorted<&powervr2_device::sample_textured<3,true>, group_no>(bitmap, ti, v+i0, v+i1, v+i2); break; default: /* @@ -2771,21 +2777,21 @@ void powervr2_device::render_tri(bitmap_rgb32 &bitmap, texinfo *ti, const vert * * AND'd with 3 */ logerror("%s - tsinstruction is 0x%08x\n", (unsigned)ti->tsinstruction); - render_tri_sorted<&powervr2_device::sample_nontextured>(bitmap, ti, v+i0, v+i1, v+i2); + render_tri_sorted<&powervr2_device::sample_nontextured, group_no>(bitmap, ti, v+i0, v+i1, v+i2); } } else { switch (ti->tsinstruction) { case 0: - render_tri_sorted<&powervr2_device::sample_textured<0,false>>(bitmap, ti, v+i0, v+i1, v+i2); + render_tri_sorted<&powervr2_device::sample_textured<0,false>, group_no>(bitmap, ti, v+i0, v+i1, v+i2); break; case 1: - render_tri_sorted<&powervr2_device::sample_textured<1,false>>(bitmap, ti, v+i0, v+i1, v+i2); + render_tri_sorted<&powervr2_device::sample_textured<1,false>, group_no>(bitmap, ti, v+i0, v+i1, v+i2); break; case 2: - render_tri_sorted<&powervr2_device::sample_textured<2,false>>(bitmap, ti, v+i0, v+i1, v+i2); + render_tri_sorted<&powervr2_device::sample_textured<2,false>, group_no>(bitmap, ti, v+i0, v+i1, v+i2); break; case 3: - render_tri_sorted<&powervr2_device::sample_textured<3,false>>(bitmap, ti, v+i0, v+i1, v+i2); + render_tri_sorted<&powervr2_device::sample_textured<3,false>, group_no>(bitmap, ti, v+i0, v+i1, v+i2); break; default: /* @@ -2793,15 +2799,16 @@ void powervr2_device::render_tri(bitmap_rgb32 &bitmap, texinfo *ti, const vert * * AND'd with 3 */ logerror("%s - tsinstruction is 0x%08x\n", (unsigned)ti->tsinstruction); - render_tri_sorted<&powervr2_device::sample_nontextured>(bitmap, ti, v+i0, v+i1, v+i2); + render_tri_sorted<&powervr2_device::sample_nontextured, group_no>(bitmap, ti, v+i0, v+i1, v+i2); } } } else { - render_tri_sorted<&powervr2_device::sample_nontextured>(bitmap, ti, v+i0, v+i1, v+i2); + render_tri_sorted<&powervr2_device::sample_nontextured, group_no>(bitmap, ti, v+i0, v+i1, v+i2); } } -void powervr2_device::render_group_to_accumulation_buffer(bitmap_rgb32 &bitmap,const rectangle &cliprect, int group_no) +template +void powervr2_device::render_group_to_accumulation_buffer(bitmap_rgb32 &bitmap,const rectangle &cliprect) { #if 0 int stride; @@ -2840,7 +2847,7 @@ void powervr2_device::render_group_to_accumulation_buffer(bitmap_rgb32 &bitmap,c for(i=sv; i <= ev-2; i++) { if (!(debug_dip_status&0x2)) - render_tri(bitmap, &ts->ti, grab[rs].verts + i); + render_tri(bitmap, &ts->ti, grab[rs].verts + i); } } @@ -2858,9 +2865,9 @@ void powervr2_device::render_to_accumulation_buffer(bitmap_rgb32 &bitmap, const bitmap.fill(c, cliprect); // TODO: modifier volumes - render_group_to_accumulation_buffer(bitmap, cliprect, DISPLAY_LIST_OPAQUE); - render_group_to_accumulation_buffer(bitmap, cliprect, DISPLAY_LIST_TRANS); - render_group_to_accumulation_buffer(bitmap, cliprect, DISPLAY_LIST_PUNCH_THROUGH); + render_group_to_accumulation_buffer(bitmap, cliprect); + render_group_to_accumulation_buffer(bitmap, cliprect); + render_group_to_accumulation_buffer(bitmap, cliprect); grab[renderselect].busy=0; } diff --git a/src/mame/video/powervr2.h b/src/mame/video/powervr2.h index 702f2233934..ce402e07302 100644 --- a/src/mame/video/powervr2.h +++ b/src/mame/video/powervr2.h @@ -501,7 +501,7 @@ private: uint32_t tex_r_default(texinfo *t, float x, float y); void tex_get_info(texinfo *t); - template + template inline void render_hline(bitmap_rgb32 &bitmap, texinfo *ti, int y, float xl, float xr, float ul, float ur, float vl, float vr, @@ -509,7 +509,7 @@ private: float const bl[4], float const br[4], float const offl[4], float const offr[4]); - template + template inline void render_span(bitmap_rgb32 &bitmap, texinfo *ti, float y0, float y1, float xl, float xr, @@ -525,14 +525,18 @@ private: float const dbldy[4], float const dbrdy[4], float const doldy[4], float const dordy[4]); - template + template inline void render_tri_sorted(bitmap_rgb32 &bitmap, texinfo *ti, const vert *v0, const vert *v1, const vert *v2); + template + void render_tri(bitmap_rgb32 &bitmap, texinfo *ti, const vert *v); + + template + void render_group_to_accumulation_buffer(bitmap_rgb32 &bitmap, const rectangle &cliprect); + void sort_vertices(const vert *v, int *i0, int *i1, int *i2); - void render_tri(bitmap_rgb32 &bitmap, texinfo *ti, const vert *v); - void render_group_to_accumulation_buffer(bitmap_rgb32 &bitmap, const rectangle &cliprect, int group_no); void render_to_accumulation_buffer(bitmap_rgb32 &bitmap, const rectangle &cliprect); void pvr_accumulationbuffer_to_framebuffer(address_space &space, int x, int y); void pvr_drawframebuffer(bitmap_rgb32 &bitmap,const rectangle &cliprect); -- cgit v1.2.3