diff options
author | yz70s <yz70s@users.noreply.github.com> | 2015-05-11 23:52:10 +0200 |
---|---|---|
committer | yz70s <yz70s@users.noreply.github.com> | 2015-05-12 00:00:14 +0200 |
commit | 9bdeedb52bd39163d4e93832a9f509b3d00e3dd8 (patch) | |
tree | 44dae619d630cb3d46c283cb068ee390404aa89b /src/mame | |
parent | 88c04136c83e43d6e441704f7ad1e78dc898738a (diff) |
chihiro.c: add 3d method 1808 puls a few misc. changes (nw)
Diffstat (limited to 'src/mame')
-rw-r--r-- | src/mame/drivers/chihiro.c | 2 | ||||
-rw-r--r-- | src/mame/includes/chihiro.h | 63 | ||||
-rw-r--r-- | src/mame/video/chihiro.c | 183 |
3 files changed, 180 insertions, 68 deletions
diff --git a/src/mame/drivers/chihiro.c b/src/mame/drivers/chihiro.c index a385f0b7be2..ce5ea0b9cf2 100644 --- a/src/mame/drivers/chihiro.c +++ b/src/mame/drivers/chihiro.c @@ -1803,7 +1803,7 @@ void chihiro_state::machine_start() save_item(NAME(smbusst.words)); save_item(NAME(pic16lc_buffer)); save_item(NAME(usbhack_counter)); - nvidia_nv2a->start(); + nvidia_nv2a->start(&m_maincpu->space()); nvidia_nv2a->savestate_items(); } diff --git a/src/mame/includes/chihiro.h b/src/mame/includes/chihiro.h index 73acd6ae920..896b7985f0a 100644 --- a/src/mame/includes/chihiro.h +++ b/src/mame/includes/chihiro.h @@ -70,6 +70,32 @@ struct vertex_nv { */ class vertex_program_simulator { public: + enum VectorialOperation { + VecNOP=0, + VecMOV, + VecMUL, + VecADD, + VecMAD, + VecDP3, + VecDPH, + VecDP4, + VecDST, + VecMIN, + VecMAX, + VecSLT, + VecSGE, + VecARL + }; + enum ScalarOperation { + ScaNOP=0, + ScaIMV, + ScaRCP, + ScaRCC, + ScaRSQ, + ScaEXP, + ScaLOG, + ScaLIT + }; vertex_program_simulator(); // input vertex vertex_nv *input; @@ -92,7 +118,8 @@ public: int SwizzleA[4], SignA, ParameterTypeA, TempIndexA; int SwizzleB[4], SignB, ParameterTypeB, TempIndexB; int SwizzleC[4], SignC, ParameterTypeC, TempIndexC; - int VecOperation, ScaOperation; + VectorialOperation VecOperation; + ScalarOperation ScaOperation; int OutputWriteMask, MultiplexerControl; int VecTempWriteMask, ScaTempWriteMask; int VecTempIndex, OutputIndex; @@ -190,6 +217,12 @@ public: limits_rendertarget.set(0, 0, 640, 480); pitch_rendertarget = 0; pitch_depthbuffer = 0; + height_rendertarget=0; + width_rendertarget=0; + antialiasing_rendertarget=0; + type_rendertarget=nv2a_renderer::LINEAR; + depth_rendertarget=nv2a_renderer::NV2A_RT_DEPTH_FORMAT_Z24S8; + color_rendertarget=nv2a_renderer::NV2A_COLOR_FORMAT_A8R8G8B8; rendertarget = NULL; depthbuffer = NULL; displayedtarget = NULL; @@ -247,13 +280,15 @@ public: int toggle_wait_vblank_support(); void debug_grab_texture(int type, const char *filename); void debug_grab_vertex_program_slot(int slot, UINT32 *instruction); - void start(); + void start(address_space *cpu_space); void savestate_items(); void read_vertex(address_space & space, offs_t address, vertex_nv &vertex, int attrib); - int read_vertices_0x1810(address_space & space, vertex_nv *destination, int offset, int limit); int read_vertices_0x1800(address_space & space, vertex_nv *destination, UINT32 address, int limit); + int read_vertices_0x1808(address_space & space, vertex_nv *destination, UINT32 address, int limit); + 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); + inline UINT8 *direct_access_ptr(offs_t address); TIMER_CALLBACK_MEMBER(puller_timer_work); struct { @@ -270,9 +305,16 @@ public: UINT32 ramin[0x100000 / 4]; UINT32 dma_offset[2]; UINT32 dma_size[2]; + UINT8 *basemempointer; rectangle limits_rendertarget; UINT32 pitch_rendertarget; UINT32 pitch_depthbuffer; + int height_rendertarget; + int width_rendertarget; + int antialiasing_rendertarget; + int type_rendertarget; + int depth_rendertarget; + int color_rendertarget; UINT32 *rendertarget; UINT32 *depthbuffer; UINT32 *displayedtarget; @@ -595,4 +637,19 @@ public: INCR_WRAP = 0x8507, DECR_WRAP = 0x8508 }; + enum NV2A_RT_TYPE { + LINEAR = 1, + SWIZZLED = 2 + }; + enum NV2A_RT_DEPTH_FORMAT { + NV2A_RT_DEPTH_FORMAT_Z16 = 0x0001, + NV2A_RT_DEPTH_FORMAT_Z24S8 = 0x0002 + }; + + enum NV2A_COLOR_FORMAT { + NV2A_COLOR_FORMAT_R5G6B5 = 0x0003, + NV2A_COLOR_FORMAT_X8R8G8B8 = 0x0005, + NV2A_COLOR_FORMAT_A8R8G8B8 = 0x0008, + NV2A_COLOR_FORMAT_B8 = 0x0009 + }; }; diff --git a/src/mame/video/chihiro.c b/src/mame/video/chihiro.c index ede19297dea..ac74dc2ac24 100644 --- a/src/mame/video/chihiro.c +++ b/src/mame/video/chihiro.c @@ -477,8 +477,8 @@ void vertex_program_simulator::decode_instruction(int address) i->d.SwizzleC[1] = (i->i[2] >> 6) & 3; i->d.SwizzleC[2] = (i->i[2] >> 4) & 3; i->d.SwizzleC[3] = (i->i[2] >> 2) & 3; - i->d.VecOperation = (i->i[1] >> 21) & 15; - i->d.ScaOperation = (i->i[1] >> 25) & 15; + i->d.VecOperation = (VectorialOperation)((i->i[1] >> 21) & 15); + i->d.ScaOperation = (ScalarOperation)((i->i[1] >> 25) & 15); i->d.OutputWriteMask = ((i->i[3] >> 12) & 15); i->d.MultiplexerControl = i->i[3] & 4; // 0 : output Rn from vectorial operation 4 : output Rn from scalar operation i->d.VecTempIndex = (i->i[3] >> 20) & 15; @@ -910,6 +910,11 @@ void nv2a_renderer::computedilated(void) dilatechose[(b << 4) + a] = (a < b ? a : b); } +inline UINT8 *nv2a_renderer::direct_access_ptr(offs_t address) +{ + return basemempointer + address; +} + int nv2a_renderer::geforce_commandkind(UINT32 word) { if ((word & 0x00000003) == 0x00000002) @@ -2059,29 +2064,42 @@ void nv2a_renderer::read_vertex(address_space & space, offs_t address, vertex_nv } } -/* Read vertices data from system memory. Method 0x1810 */ -int nv2a_renderer::read_vertices_0x1810(address_space & space, vertex_nv *destination, int offset, int limit) +/* Read vertices data from system memory. Method 0x1800 */ +int nv2a_renderer::read_vertices_0x1800(address_space & space, vertex_nv *destination, UINT32 address, int limit) { - UINT32 m; + UINT32 data; + UINT32 m, i, c; int a, b; #ifdef MAME_DEBUG memset(destination, 0, sizeof(vertex_nv)*limit); #endif + c = 0; for (m = 0; m < limit; m++) { + if (indexesleft_count == 0) { + data = space.read_dword(address); + i = (indexesleft_first + indexesleft_count) & 7; + indexesleft[i] = data & 0xffff; + indexesleft[(i + 1) & 7] = (data >> 16) & 0xffff; + indexesleft_count = indexesleft_count + 2; + address += 4; + c++; + } b = enabled_vertex_attributes; for (a = 0; a < 16; a++) { if (b & 1) { - read_vertex(space, vertexbuffer_address[a] + (m + offset)*vertexbuffer_stride[a], destination[m], a); + read_vertex(space, vertexbuffer_address[a] + indexesleft[indexesleft_first] * vertexbuffer_stride[a], destination[m], a); } b = b >> 1; } + indexesleft_first = (indexesleft_first + 1) & 7; + indexesleft_count--; } - return m; + return (int)c; } -/* Read vertices data from system memory. Method 0x1800 */ -int nv2a_renderer::read_vertices_0x1800(address_space & space, vertex_nv *destination, UINT32 address, int limit) +/* Read vertices data from system memory. Method 0x1808 */ +int nv2a_renderer::read_vertices_0x1808(address_space & space, vertex_nv *destination, UINT32 address, int limit) { UINT32 data; UINT32 m, i, c; @@ -2095,9 +2113,8 @@ int nv2a_renderer::read_vertices_0x1800(address_space & space, vertex_nv *destin if (indexesleft_count == 0) { data = space.read_dword(address); i = (indexesleft_first + indexesleft_count) & 7; - indexesleft[i] = data & 0xffff; - indexesleft[(i + 1) & 7] = (data >> 16) & 0xffff; - indexesleft_count = indexesleft_count + 2; + indexesleft[i] = data; + indexesleft_count = indexesleft_count + 1; address += 4; c++; } @@ -2114,6 +2131,27 @@ int nv2a_renderer::read_vertices_0x1800(address_space & space, vertex_nv *destin return (int)c; } +/* Read vertices data from system memory. Method 0x1810 */ +int nv2a_renderer::read_vertices_0x1810(address_space & space, vertex_nv *destination, int offset, int limit) +{ + UINT32 m; + int a, b; + +#ifdef MAME_DEBUG + memset(destination, 0, sizeof(vertex_nv)*limit); +#endif + for (m = 0; m < limit; m++) { + b = enabled_vertex_attributes; + for (a = 0; a < 16; a++) { + if (b & 1) { + read_vertex(space, vertexbuffer_address[a] + (m + offset)*vertexbuffer_stride[a], destination[m], a); + } + b = b >> 1; + } + } + return m; +} + /* Read vertices data from system memory. Method 0x1818 */ int nv2a_renderer::read_vertices_0x1818(address_space & space, vertex_nv *destination, UINT32 address, int limit) { @@ -2243,9 +2281,10 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN } countlen--; } - if (maddress == 0x1800) { + if ((maddress == 0x1800) || (maddress == 0x1808)) { UINT32 type, n; render_delegate renderspans; + int mult; if (((channel[chanel][subchannel].object.method[0x1e60 / 4] & 7) > 0) && (combiner.used != 0)) { renderspans = render_delegate(FUNC(nv2a_renderer::render_register_combiners), this); @@ -2255,8 +2294,13 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN } else renderspans = render_delegate(FUNC(nv2a_renderer::render_color), this); + if (maddress == 0x1800) + mult = 2; + else + mult = 1; // vertices are selected from the vertex buffer using an array of indexes // each dword after 1800 contains two 16 bit index values to select the vartices + // each dword after 1808 contains a 32 bit index value to select the vartices type = channel[chanel][subchannel].object.method[0x17fc / 4]; #ifdef LOG_NV2A printf("vertex %d %d %d\n\r", type, offset, count); @@ -2267,24 +2311,17 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN vertex_t xy[4]; int c; - if ((countlen * 2 + indexesleft_count) < 4) + if ((countlen * mult + indexesleft_count) < 4) break; - c = read_vertices_0x1800(space, vert, address, 4); + if (mult == 1) + c = read_vertices_0x1808(space, vert, address, 4); + else + c = read_vertices_0x1800(space, vert, address, 4); address = address + c * 4; countlen = countlen - c; convert_vertices_poly(vert, xy, 4); render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv } - while (countlen > 0) { - data = space.read_dword(address); - n = (indexesleft_first + indexesleft_count) & 7; - indexesleft[n] = data & 0xffff; - indexesleft[(n + 1) & 7] = (data >> 16) & 0xffff; - indexesleft_count = indexesleft_count + 2; - address += 4; - countlen--; - } - wait(); } else if (type == nv2a_renderer::TRIANGLES) { while (1) { @@ -2292,38 +2329,37 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN vertex_t xy[3]; int c; - if ((countlen * 2 + indexesleft_count) < 3) + if ((countlen * mult + indexesleft_count) < 3) break; - c = read_vertices_0x1800(space, vert, address, 3); + if (mult == 1) + c = read_vertices_0x1808(space, vert, address, 3); + else + c = read_vertices_0x1800(space, vert, address, 3); address = address + c * 4; countlen = countlen - c; convert_vertices_poly(vert, xy, 3); render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[1], xy[2]); // 4 rgba, 4 texture units 2 uv } - while (countlen > 0) { - data = space.read_dword(address); - n = (indexesleft_first + indexesleft_count) & 7; - indexesleft[n] = data & 0xffff; - indexesleft[(n + 1) & 7] = (data >> 16) & 0xffff; - indexesleft_count = indexesleft_count + 2; - address += 4; - countlen--; - } - wait(); } else if (type == nv2a_renderer::TRIANGLE_STRIP) { - if ((countlen * 2 + indexesleft_count) >= 3) { + if ((countlen * mult + indexesleft_count) >= 3) { vertex_nv vert[4]; vertex_t xy[4]; int c, count; - c = read_vertices_0x1800(space, vert, address, 2); + if (mult == 1) + c = read_vertices_0x1808(space, vert, address, 2); + else + c = read_vertices_0x1800(space, vert, address, 2); convert_vertices_poly(vert, xy, 2); address = address + c * 4; countlen = countlen - c; - count = countlen * 2 + indexesleft_count; - for (n = 0; n < count; n++) { // <= - c = read_vertices_0x1800(space, vert + ((n + 2) & 3), address, 1); + count = countlen * mult + indexesleft_count; + for (n = 0; n < count; n++) { + if (mult == 1) + c = read_vertices_0x1808(space, vert + ((n + 2) & 3), address, 1); + else + c = read_vertices_0x1800(space, vert + ((n + 2) & 3), address, 1); address = address + c * 4; countlen = countlen - c; convert_vertices_poly(vert + ((n + 2) & 3), xy + ((n + 2) & 3), 1); @@ -2332,21 +2368,27 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]); } } - while (countlen > 0) { - data = space.read_dword(address); - n = (indexesleft_first + indexesleft_count) & 7; + } + else { + logerror("Unsupported primitive %d for method 0x1800/8\n", type); + countlen = 0; + } + while (countlen > 0) { + data = space.read_dword(address); + n = (indexesleft_first + indexesleft_count) & 7; + if (mult == 2) { indexesleft[n] = data & 0xffff; indexesleft[(n + 1) & 7] = (data >> 16) & 0xffff; indexesleft_count = indexesleft_count + 2; - address += 4; - countlen--; } - wait(); - } - else { - logerror("Unsupported primitive %d for method 0x1800\n", type); - countlen = 0; + else { + indexesleft[n] = data; + indexesleft_count = indexesleft_count + 1; + } + address += 4; + countlen--; } + wait(); } if (maddress == 0x1818) { int n; @@ -2575,14 +2617,26 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN countlen--; } if (maddress == 0x0200) { - //x = data & 0xffff; - //w = (data >> 16) & 0xffff; - limits_rendertarget.setx(0,((data >> 16) & 0xffff)-1); + int x, w; + + x = data & 0xffff; + w = (data >> 16) & 0xffff; + limits_rendertarget.setx(x,x+w-1); } if (maddress == 0x0204) { - //y = data & 0xffff; - //h = (data >> 16) & 0xffff; - limits_rendertarget.sety(0,((data >> 16) & 0xffff)-1); + int y, h; + + y = data & 0xffff; + h = (data >> 16) & 0xffff; + limits_rendertarget.sety(y,y+h-1); + } + if (maddress == 0x0208) { + height_rendertarget=(data >> 24) & 255; + width_rendertarget=(data >> 16) & 255; + antialiasing_rendertarget=(data >> 12) & 15; + type_rendertarget=(data >> 8) & 15; + depth_rendertarget=(data >> 4) & 15; + color_rendertarget=(data >> 0) & 15; } if (maddress == 0x020c) { // line size ? @@ -2596,7 +2650,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN if ((data & 0x1f) == 1) { data = data >> 5; data = data & 0x0ffffff0; - displayedtarget = (UINT32 *)space.get_write_ptr(data); + displayedtarget = (UINT32 *)direct_access_ptr(data); } } if (maddress == 0x0130) { @@ -2608,13 +2662,13 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN } if (maddress == 0x0210) { // framebuffer offset ? - rendertarget = (UINT32 *)space.get_write_ptr(data); + rendertarget = (UINT32 *)direct_access_ptr(data); //printf("Render target at %08X\n\r",data); countlen--; } if (maddress == 0x0214) { // zbuffer offset ? - depthbuffer = (UINT32 *)space.get_write_ptr(data); + depthbuffer = (UINT32 *)direct_access_ptr(data); //printf("Depth buffer at %08X\n\r",data); if ((data == 0) || (data > 0x7ffffffc)) depth_write_enabled = false; @@ -2708,7 +2762,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN //UINT32 dmahand,dmaoff,dmasiz; offset = data; - texture[unit].buffer = space.get_read_ptr(offset); + texture[unit].buffer = direct_access_ptr(offset); /*if (dma0 != 0) { dmahand=channel[channel][subchannel].object.method[0x184/4]; geforce_read_dma_object(dmahand,dmaoff,smasiz); @@ -3839,7 +3893,7 @@ WRITE32_MEMBER(nv2a_renderer::geforce_w) return; COMBINE_DATA(pcrtc + e); if (e == 0x800 / 4) { - displayedtarget = (UINT32 *)space.get_read_ptr(data); + displayedtarget = (UINT32 *)direct_access_ptr(data); //printf("crtc buffer %08X\n\r", data); } //logerror("NV_2A: write PCRTC[%06X]=%08X\n",offset*4-0x00600000,data & mem_mask); @@ -3898,8 +3952,9 @@ void nv2a_renderer::savestate_items() { } -void nv2a_renderer::start() +void nv2a_renderer::start(address_space *cpu_space) { + basemempointer = (UINT8 *)cpu_space->get_read_ptr(0); puller_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nv2a_renderer::puller_timer_work), this), (void *)"NV2A Puller Timer"); puller_timer->enable(false); } |