summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame
diff options
context:
space:
mode:
author yz70s <yz70s@users.noreply.github.com>2016-02-01 23:28:56 +0100
committer yz70s <yz70s@users.noreply.github.com>2016-02-01 23:28:56 +0100
commit5e8d6c57bd99293eeee8328b4b392b97c1756438 (patch)
tree7e02f97a096154739dd641137f5af6c1a95c9c95 /src/mame
parent4ba9de3b750206e601de667450b8d254074e6850 (diff)
chihiro.cpp: add backface culling to 3d accelerator (nw)
Diffstat (limited to 'src/mame')
-rw-r--r--src/mame/includes/chihiro.h16
-rw-r--r--src/mame/video/chihiro.cpp68
2 files changed, 67 insertions, 17 deletions
diff --git a/src/mame/includes/chihiro.h b/src/mame/includes/chihiro.h
index 0f68747059a..0a1915157c6 100644
--- a/src/mame/includes/chihiro.h
+++ b/src/mame/includes/chihiro.h
@@ -346,6 +346,15 @@ public:
B8 = 9,
G8B8 = 10
};
+ enum class NV2A_GL_FRONT_FACE {
+ CW = 0x0900,
+ CCW = 0x0901
+ };
+ enum class NV2A_GL_CULL_FACE {
+ FRONT = 0x0404,
+ BACK = 0x0405,
+ FRONT_AND_BACK = 0x0408
+ };
nv2a_renderer(running_machine &machine) : poly_manager<float, nvidia_object_data, 13, 8192>(machine)
{
@@ -363,6 +372,9 @@ public:
indexesleft_count = 0;
vertex_pipeline = 4;
color_mask = 0xffffffff;
+ backface_culling_enabled = false;
+ backface_culling_winding = NV2A_GL_FRONT_FACE::CCW;
+ backface_culling_culled = NV2A_GL_CULL_FACE::BACK;
alpha_test_enabled = false;
alpha_reference = 0;
alpha_func = NV2A_COMPARISON_OP::ALWAYS;
@@ -464,6 +476,7 @@ public:
int read_vertices_0x1810(address_space & space, vertex_nv *destination, int offset, int limit);
int read_vertices_0x1818(address_space & space, vertex_nv *destination, UINT32 address, int limit);
void convert_vertices_poly(vertex_nv *source, vertex_t *destination, int count);
+ UINT32 render_triangle_culling(const rectangle &cliprect, render_delegate callback, int paramcount, const vertex_t &_v1, const vertex_t &_v2, const vertex_t &_v3);
void clear_render_target(int what, UINT32 value);
void clear_depth_buffer(int what, UINT32 value);
inline UINT8 *direct_access_ptr(offs_t address);
@@ -630,6 +643,9 @@ public:
std::mutex lock;
} combiner;
UINT32 color_mask;
+ bool backface_culling_enabled;
+ NV2A_GL_FRONT_FACE backface_culling_winding;
+ NV2A_GL_CULL_FACE backface_culling_culled;
bool alpha_test_enabled;
NV2A_COMPARISON_OP alpha_func;
int alpha_reference;
diff --git a/src/mame/video/chihiro.cpp b/src/mame/video/chihiro.cpp
index e6c8e578bb6..845110e59b4 100644
--- a/src/mame/video/chihiro.cpp
+++ b/src/mame/video/chihiro.cpp
@@ -2549,6 +2549,25 @@ void nv2a_renderer::clear_depth_buffer(int what, UINT32 value)
}
}
+UINT32 nv2a_renderer::render_triangle_culling(const rectangle &cliprect, render_delegate callback, int paramcount, const vertex_t &_v1, const vertex_t &_v2, const vertex_t &_v3)
+{
+ float areax2;
+
+ if (backface_culling_enabled == false)
+ return render_triangle(cliprect, callback, paramcount, _v1, _v2, _v3);
+ if (backface_culling_culled == NV2A_GL_CULL_FACE::FRONT_AND_BACK)
+ return 0;
+ areax2 = _v1.x*(_v2.y - _v3.y) + _v2.x*(_v3.y - _v1.y) + _v3.x*(_v1.y - _v2.y);
+ if (backface_culling_winding == NV2A_GL_FRONT_FACE::CCW)
+ areax2 = -areax2;
+ // if areax2 >= 0 then front faced else back faced
+ if ((backface_culling_culled == NV2A_GL_CULL_FACE::FRONT) && (areax2 >= 0))
+ return 0;
+ if ((backface_culling_culled == NV2A_GL_CULL_FACE::BACK) && (areax2 < 0))
+ return 0;
+ return render_triangle(cliprect, callback, paramcount, _v1, _v2, _v3);
+}
+
int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UINT32 subchannel, UINT32 method, UINT32 address, int &countlen)
{
UINT32 maddress;
@@ -2592,7 +2611,9 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
for (n = 0; n <= count; n += 4) {
read_vertices_0x1810(space, vertex_software + vertex_first, n + offset, 4);
convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 4);
- render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy + vertex_first); // 4 rgba, 4 texture units 2 uv
+ //render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy + vertex_first); // 4 rgba, 4 texture units 2 uv
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[vertex_first + 1], vertex_xy[vertex_first + 2]);
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[vertex_first + 2], vertex_xy[vertex_first + 3]);
vertex_first = (vertex_first + 4) & 1023;
vertex_count = vertex_count + 4;
wait();
@@ -2602,7 +2623,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
for (n = 0; n <= count; n += 3) {
read_vertices_0x1810(space, vertex_software + vertex_first, n + offset, 3);
convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 3);
- render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[(vertex_first + 1) & 1023], vertex_xy[(vertex_first + 2) & 1023]); // 4 rgba, 4 texture units 2 uv
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[(vertex_first + 1) & 1023], vertex_xy[(vertex_first + 2) & 1023]); // 4 rgba, 4 texture units 2 uv
vertex_first = (vertex_first + 3) & 1023;
vertex_count = vertex_count + 3;
wait();
@@ -2624,7 +2645,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
for (n = 0; n <= count; n++) {
read_vertices_0x1810(space, vertex_software + vertex_first, offset + n, 1);
convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 1);
- render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[1024], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]);
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[1024], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]);
vertex_first = (vertex_first + 1) & 1023;
vertex_count = vertex_count + 1;
wait();
@@ -2645,9 +2666,9 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
read_vertices_0x1810(space, vertex_software + vertex_first, offset + n, 1);
convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 1);
if ((vertex_count & 1) == 0)
- render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]);
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]);
else
- render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[vertex_first], vertex_xy[(vertex_first - 1) & 1023]);
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[vertex_first], vertex_xy[(vertex_first - 1) & 1023]);
vertex_first = (vertex_first + 1) & 1023;
vertex_count = vertex_count + 1;
wait();
@@ -2691,7 +2712,9 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
address = address + c * 4;
countlen = countlen - c;
convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 4);
- render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy + vertex_first); // 4 rgba, 4 texture units 2 uv
+ //render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy + vertex_first); // 4 rgba, 4 texture units 2 uv
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[vertex_first + 1], vertex_xy[vertex_first + 2]);
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[vertex_first + 2], vertex_xy[vertex_first + 3]);
vertex_first = (vertex_first + 4) & 1023;
vertex_count = vertex_count + 4;
wait();
@@ -2733,7 +2756,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 1);
address = address + c * 4;
countlen = countlen - c;
- render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[1024], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]);
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[1024], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]);
vertex_first = (vertex_first + 1) & 1023;
vertex_count = vertex_count + 1;
wait();
@@ -2753,7 +2776,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
address = address + c * 4;
countlen = countlen - c;
convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 3);
- render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[(vertex_first + 1) & 1023], vertex_xy[(vertex_first + 2) & 1023]); // 4 rgba, 4 texture units 2 uv
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[(vertex_first + 1) & 1023], vertex_xy[(vertex_first + 2) & 1023]); // 4 rgba, 4 texture units 2 uv
vertex_first = (vertex_first + 3) & 1023;
vertex_count = vertex_count + 3;
wait();
@@ -2789,9 +2812,9 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
countlen = countlen - c;
convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 1);
if ((vertex_count & 1) == 0)
- render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]);
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]);
else
- render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[vertex_first], vertex_xy[(vertex_first - 1) & 1023]);
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[vertex_first], vertex_xy[(vertex_first - 1) & 1023]);
vertex_first = (vertex_first + 1) & 1023;
vertex_count = vertex_count + 1;
wait();
@@ -2849,7 +2872,9 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
break;
}
address = address + c * 4;
- render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy); // 4 rgba, 4 texture units 2 uv
+ //render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy); // 4 rgba, 4 texture units 2 uv
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[vertex_first + 1], vertex_xy[vertex_first + 2]);
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[vertex_first + 2], vertex_xy[vertex_first + 3]);
vertex_first = (vertex_first + 4) & 1023;
vertex_count = vertex_count + 4;
wait();
@@ -2877,8 +2902,8 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
return 0;
}
address = address + c * 4;
- render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[n & 3], vertex_xy[(n + 1) & 3], vertex_xy[(n + 2) & 3]);
- render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(n + 2) & 3], vertex_xy[(n + 1) & 3], vertex_xy[(n + 3) & 3]);
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[n & 3], vertex_xy[(n + 1) & 3], vertex_xy[(n + 2) & 3]);
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(n + 2) & 3], vertex_xy[(n + 1) & 3], vertex_xy[(n + 3) & 3]);
wait();
}
}
@@ -2914,7 +2939,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
}
address = address + c * 4;
convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 1);
- render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[1024], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]);
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[1024], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]);
vertex_first = (vertex_first + 1) & 1023;
vertex_count = vertex_count + 1;
wait();
@@ -2933,7 +2958,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
break;
}
address = address + c * 4;
- render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[(vertex_first + 1) & 1023], vertex_xy[(vertex_first + 2) & 1023]); // 4 rgba, 4 texture units 2 uv
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[(vertex_first + 1) & 1023], vertex_xy[(vertex_first + 2) & 1023]); // 4 rgba, 4 texture units 2 uv
vertex_first = (vertex_first + 3) & 1023;
vertex_count = vertex_count + 3;
wait();
@@ -2968,9 +2993,9 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
}
address = address + c * 4;
if ((vertex_count & 1) == 0)
- render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]);
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]);
else
- render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[vertex_first], vertex_xy[(vertex_first - 1) & 1023]);
+ render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[vertex_first], vertex_xy[(vertex_first - 1) & 1023]);
vertex_first = (vertex_first + 1) & 1023;
vertex_count = vertex_count + 1;
wait();
@@ -3028,6 +3053,15 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
}
if ((maddress == 0x1d6c) || (maddress == 0x1d70) || (maddress == 0x1a4))
countlen--;
+ if (maddress == 0x0308) {
+ backface_culling_enabled = data != 0 ? true : false;
+ }
+ if (maddress == 0x03a0) {
+ backface_culling_winding = (NV2A_GL_FRONT_FACE)data;
+ }
+ if (maddress == 0x039c) {
+ backface_culling_culled = (NV2A_GL_CULL_FACE)data;
+ }
if (maddress == 0x019c) {
geforce_read_dma_object(data, dma_offset[0], dma_size[0]);
}