From 8406dcee72d096b4e6daf96543a2a5689bc47d2d Mon Sep 17 00:00:00 2001 From: h4570 Date: Sat, 26 Dec 2020 13:29:37 +0100 Subject: [PATCH] added optimized array mode to draw() --- src/engine/include/modules/renderer.hpp | 33 +++- src/engine/include/modules/vif_sender.hpp | 9 +- src/engine/modules/renderer.cpp | 33 +++- src/engine/modules/vif_sender.cpp | 104 ++++++++-- src/engine/vu1_progs/draw3D.vclpp | 24 ++- src/engine/vu1_progs/draw3D.vsm | 222 +++++++++++++++------- 6 files changed, 324 insertions(+), 101 deletions(-) diff --git a/src/engine/include/modules/renderer.hpp b/src/engine/include/modules/renderer.hpp index be874d9..913770d 100644 --- a/src/engine/include/modules/renderer.hpp +++ b/src/engine/include/modules/renderer.hpp @@ -13,6 +13,8 @@ #include #include +#include +#include #include #include "gif_sender.hpp" #include "vif_sender.hpp" @@ -38,12 +40,20 @@ public: void enableVSync() { isVSyncEnabled = true; } void disableVSync() { isVSyncEnabled = false; } + void clearAndWaitForRender() + { + *GS_REG_CSR |= 2; // Reset wait flag + draw_wait_finish(); + } + void waitForRender() { draw_wait_finish(); } + + /** 2D draw. */ + void draw(Sprite &t_sprite); /// --- Draw: PATH3 - void draw(Sprite &t_sprite); - /** + * WARNING: THIS FUNC CAUSE VISUAL ARTIFACTS! * Draw many meshes with lighting information. * Slowest way of rendering (PATH 3, using EE and GIF). * NOTICE: Animation supported, lighting supported @@ -51,6 +61,7 @@ public: void drawByPath3(Mesh *t_meshes, u16 t_amount, LightBulb *t_bulbs, u16 t_bulbsCount); /** + * WARNING: THIS FUNC CAUSE VISUAL ARTIFACTS! * Draw mesh with lighting information. * Slowest way of rendering (PATH 3, using EE and GIF). * NOTICE: Animation supported, lighting supported @@ -58,6 +69,7 @@ public: void drawByPath3(Mesh &t_mesh, LightBulb *t_bulbs, u16 t_bulbsCount); /** + * WARNING: THIS FUNC CAUSE VISUAL ARTIFACTS! * Draw many meshes without lighting information. * Slowest way of rendering (PATH 3, using EE and GIF). * NOTICE: Animation supported, lighting supported @@ -65,6 +77,7 @@ public: void drawByPath3(Mesh *t_meshes, u16 t_amount); /** + * WARNING: THIS FUNC CAUSE VISUAL ARTIFACTS! * Draw mesh without lighting information. * Slowest way of rendering (PATH 3, using EE and GIF). * NOTICE: Animation supported, lighting supported @@ -74,25 +87,27 @@ public: /// --- Draw: PATH1 /** - * Draw many meshes with lighting information. + * Draw many meshes with lighting information. + * Draw in array mode, can be A LOT faster than for looping! * Fastest way of rendering (PATH 1, using VU1). * NOTICE: Animation supported, lighting NOT supported (at this moment) */ - void draw(Mesh *t_meshes, u16 t_amount, LightBulb *t_bulbs, u16 t_bulbsCount); + void draw(Mesh **t_meshes, u16 t_amount, LightBulb *t_bulbs, u16 t_bulbsCount); /** - * Draw mesh with lighting information. - * Fastest way of rendering (PATH 1, using VU1). + * Draw mesh with lighting information. + * Fastest way of rendering (PATH 1, using VU1). * NOTICE: Animation supported, lighting NOT supported (at this moment) */ void draw(Mesh &t_mesh, LightBulb *t_bulbs, u16 t_bulbsCount); /** - * Draw many meshes without lighting information. - * Fastest way of rendering (PATH 1, using VU1). + * Draw many meshes without lighting information. + * Draw in array mode, can be A LOT faster than for looping! + * Fastest way of rendering (PATH 1, using VU1). * NOTICE: Animation supported, lighting NOT supported (at this moment) */ - void draw(Mesh *t_meshes, u16 t_amount); + void draw(Mesh **t_meshes, u16 t_amount); /** * Draw mesh without lighting information. diff --git a/src/engine/include/modules/vif_sender.hpp b/src/engine/include/modules/vif_sender.hpp index 43c2d7e..c1fdbc6 100644 --- a/src/engine/include/modules/vif_sender.hpp +++ b/src/engine/include/modules/vif_sender.hpp @@ -31,12 +31,17 @@ public: // TODO refactor void drawMesh(RenderData *t_renderData, Matrix t_perspective, u32 vertCount2, VECTOR *vertices, VECTOR *normals, VECTOR *coordinates, Mesh &t_mesh, LightBulb *t_bulbs, u16 t_bulbsCount, texbuffer_t *textureBuffer); void calcMatrix(const RenderData &t_renderData, const Vector3 &t_position, const Vector3 &t_rotation); + void drawTheSameWithOtherMatrices(const RenderData &t_renderData, Mesh **t_meshes, const u32 &t_skip, const u32 &t_count); + void enableWait() { isDrawWaitEnabled = true; } + void disableWait() { isDrawWaitEnabled = false; } private: + u32 lastVertCount; // needed for drawTheSameWithOtherMatrices() + u8 isDrawWaitEnabled; Light *light; void uploadMicroProgram(); - void setDoubleBuffer(); - void drawVertices(Mesh &t_mesh, u32 t_start, u32 t_end, VECTOR *t_vertices, VECTOR *t_coordinates, prim_t *t_prim, texbuffer_t *textureBuffer); + void setDoubleBufferAddStaticData(); + void drawVertices(Mesh &t_mesh, u32 t_start, u32 t_end, VECTOR *t_vertices, VECTOR *t_coordinates, prim_t *t_prim, texbuffer_t *t_textureBuffer, u8 t_addDrawWait); packet2_t *packets[2] __attribute__((aligned(64))); packet2_t *currPacket; /** diff --git a/src/engine/modules/renderer.cpp b/src/engine/modules/renderer.cpp index 425fb0d..35961b3 100644 --- a/src/engine/modules/renderer.cpp +++ b/src/engine/modules/renderer.cpp @@ -13,8 +13,6 @@ #include #include #include -#include -#include #include "../include/utils/debug.hpp" #include "../include/utils/math.hpp" @@ -268,10 +266,33 @@ void Renderer::drawByPath3(Mesh &t_mesh) { drawByPath3(t_mesh, NULL, 0); } /// --- Draw: PATH1 -void Renderer::draw(Mesh *t_meshes, u16 t_amount, LightBulb *t_bulbs, u16 t_bulbsCount) +void Renderer::draw(Mesh **t_meshes, u16 t_amount, LightBulb *t_bulbs, u16 t_bulbsCount) { - for (u16 i = 0; i < t_amount; i++) - draw(t_meshes[i], t_bulbs, t_bulbsCount); + beginFrameIfNeeded(); + if (!t_meshes[0]->isDataLoaded()) + PRINT_ERR("Can't draw, because no mesh data was loaded!"); + else if ( + t_amount >= 3 && + !t_meshes[0]->shouldBeBackfaceCulled && + t_meshes[0]->getFramesCount() == 1 && + t_meshes[0]->getMaterialsCount() == 1 && + t_meshes[0]->getFrame(0).getVertexCount() <= 96) + { + vifSender->disableWait(); + Mesh **meshesInFrustum = new Mesh *[t_amount]; + u16 addedMeshes = 0; + for (u16 i = 0; i < t_amount; i++) + if (t_meshes[i]->getMaterial(0).isInFrustum(renderData.frustumPlanes, t_meshes[i]->position)) + meshesInFrustum[addedMeshes++] = t_meshes[i]; + draw(*meshesInFrustum[0], t_bulbs, t_bulbsCount); + draw(*meshesInFrustum[1], t_bulbs, t_bulbsCount); + vifSender->enableWait(); + vifSender->drawTheSameWithOtherMatrices(renderData, meshesInFrustum, 2, addedMeshes); + delete[] meshesInFrustum; + } + else + for (u16 i = 0; i < t_amount; i++) + draw(*t_meshes[i], t_bulbs, t_bulbsCount); } void Renderer::draw(Mesh &t_mesh, LightBulb *t_bulbs, u16 t_bulbsCount) @@ -302,7 +323,7 @@ void Renderer::draw(Mesh &t_mesh, LightBulb *t_bulbs, u16 t_bulbsCount) } } -void Renderer::draw(Mesh *t_meshes, u16 t_amount) { draw(t_meshes, t_amount, NULL, 0); } +void Renderer::draw(Mesh **t_meshes, u16 t_amount) { draw(t_meshes, t_amount, NULL, 0); } void Renderer::draw(Mesh &t_mesh) { draw(t_mesh, NULL, 0); } diff --git a/src/engine/modules/vif_sender.cpp b/src/engine/modules/vif_sender.cpp index 78dd0ce..a72c50a 100644 --- a/src/engine/modules/vif_sender.cpp +++ b/src/engine/modules/vif_sender.cpp @@ -19,6 +19,8 @@ const u32 VU1_PACKAGE_VERTS_PER_BUFF = 96; // Remember to modify buffer size in vu1 also const u32 VU1_PACKAGES_PER_PACKET = 9; const u32 VU1_PACKET_SIZE = 256; // should be 128, but 256 is more safe for future +const u8 VU1_PARAMS_ADDRESS = 4; +const u8 VU1_RGBA_ADDRESS = 8; // ---- // Constructors/Destructors @@ -31,16 +33,18 @@ extern u32 VU1Draw3D_CodeEnd __attribute__((section(".vudata"))); VifSender::VifSender(Light *t_light) { - light = t_light; PRINT_LOG("Initializing VifSender"); - PRINT_LOG("VifSender initialized!"); + light = t_light; + lastVertCount = 0; + isDrawWaitEnabled = true; dma_channel_initialize(DMA_CHANNEL_VIF1, NULL, 0); dma_channel_fast_waits(DMA_CHANNEL_VIF1); uploadMicroProgram(); packets[0] = packet2_create(VU1_PACKET_SIZE, P2_TYPE_NORMAL, P2_MODE_CHAIN, true); packets[1] = packet2_create(VU1_PACKET_SIZE, P2_TYPE_NORMAL, P2_MODE_CHAIN, true); context = 0; - setDoubleBuffer(); + setDoubleBufferAddStaticData(); + PRINT_LOG("VifSender initialized!"); } VifSender::~VifSender() @@ -93,7 +97,7 @@ void VifSender::drawMesh(RenderData *t_renderData, Matrix t_perspective, u32 ver i -= 3; const u32 endI = i + (VU1_PACKAGE_VERTS_PER_BUFF - 1) > vertCount2 ? vertCount2 : i + (VU1_PACKAGE_VERTS_PER_BUFF - 1); - drawVertices(t_mesh, i, endI, vertices, coordinates, t_renderData->prim, textureBuffer); + drawVertices(t_mesh, i, endI, vertices, coordinates, t_renderData->prim, textureBuffer, isDrawWaitEnabled ? endI == vertCount2 : false); if (endI == vertCount2) // if there are no more vertices to draw, break { i = vertCount2; @@ -109,9 +113,15 @@ void VifSender::drawMesh(RenderData *t_renderData, Matrix t_perspective, u32 ver } } -void VifSender::setDoubleBuffer() +void VifSender::setDoubleBufferAddStaticData() { - packet2_t *settings = packet2_create(2, P2_TYPE_NORMAL, P2_MODE_CHAIN, true); + packet2_t *settings = packet2_create(10, P2_TYPE_NORMAL, P2_MODE_CHAIN, true); + packet2_utils_vu_open_unpack(settings, 0, false); + { + packet2_utils_gs_add_draw_finish_giftag(settings); + packet2_utils_gif_add_set(settings, 1); + } + packet2_utils_vu_close_unpack(settings); packet2_utils_vu_add_double_buffer(settings, 10, 498); packet2_utils_vu_add_end_tag(settings); dma_channel_send_packet2(settings, DMA_CHANNEL_VIF1, true); @@ -120,28 +130,98 @@ void VifSender::setDoubleBuffer() } /** Draw using PATH1 */ -void VifSender::drawVertices(Mesh &t_mesh, u32 t_start, u32 t_end, VECTOR *t_vertices, VECTOR *t_coordinates, prim_t *t_prim, texbuffer_t *textureBuffer) +void VifSender::drawVertices(Mesh &t_mesh, u32 t_start, u32 t_end, VECTOR *t_vertices, VECTOR *t_coordinates, prim_t *t_prim, texbuffer_t *t_texBuff, u8 t_addDrawWait) { const u32 vertCount = t_end - t_start; - u32 vif_added_bytes = 0; + lastVertCount = vertCount; packet2_utils_vu_open_unpack(currPacket, 0, true); packet2_add_data(currPacket, modelViewProj.data, 4); - packet2_add_u32(currPacket, 0); // Free + packet2_add_u32(currPacket, t_addDrawWait); // Draw finish? packet2_add_u32(currPacket, vertCount); // Vertex count packet2_add_u32(currPacket, vertCount / 3); // Triangles count packet2_add_u32(currPacket, 0); // Free - packet2_utils_gif_add_set(currPacket, 1); packet2_utils_gs_add_lod(currPacket, &t_mesh.lod); - packet2_utils_gs_add_texbuff_clut(currPacket, textureBuffer, &t_mesh.clut); + packet2_utils_gs_add_texbuff_clut(currPacket, t_texBuff, &t_mesh.clut); packet2_utils_gs_add_prim_giftag(currPacket, t_prim, vertCount, DRAW_STQ2_REGLIST, 3, 0); packet2_add_u32(currPacket, t_mesh.color.r); packet2_add_u32(currPacket, t_mesh.color.g); packet2_add_u32(currPacket, t_mesh.color.b); packet2_add_u32(currPacket, t_mesh.color.a); - vif_added_bytes += packet2_utils_vu_close_unpack(currPacket); + u32 vif_added_bytes = packet2_utils_vu_close_unpack(currPacket); packet2_utils_vu_add_unpack_data(currPacket, vif_added_bytes, t_vertices + t_start, vertCount, true); vif_added_bytes += vertCount; packet2_utils_vu_add_unpack_data(currPacket, vif_added_bytes, t_coordinates + t_start, vertCount, true); vif_added_bytes += vertCount; packet2_utils_vu_add_start_program(currPacket, 0); } + +void VifSender::drawTheSameWithOtherMatrices(const RenderData &t_renderData, Mesh **t_meshes, const u32 &t_skip, const u32 &t_count) +{ + packet2_t *packet2 = packet2_create(300, P2_TYPE_NORMAL, P2_MODE_CHAIN, true); + u8 switchCounter = 0; + u32 i; + for (i = t_skip; i < t_count; i++) + { + model.identity(); + model.rotate(t_meshes[i]->rotation); + model.translate(t_meshes[i]->position); + + modelViewProj.identity(); + modelViewProj = model * modelViewProj; + modelViewProj = *t_renderData.view * modelViewProj; + modelViewProj = *t_renderData.projection * modelViewProj; + + packet2_utils_vu_open_unpack(packet2, 0, true); + { + packet2_add_data(packet2, modelViewProj.data, 4); + } + packet2_utils_vu_close_unpack(packet2); + packet2_utils_vu_open_unpack(packet2, VU1_RGBA_ADDRESS, true); + { + packet2_add_u32(packet2, t_meshes[i]->color.r); + packet2_add_u32(packet2, t_meshes[i]->color.g); + packet2_add_u32(packet2, t_meshes[i]->color.b); + packet2_add_u32(packet2, t_meshes[i]->color.a); + } + packet2_utils_vu_close_unpack(packet2); + if (i != t_count - 1) + packet2_utils_vu_add_start_program(packet2, 0); + + if (switchCounter++ >= 32) + { + switchCounter = 0; + if (i == t_count - 1) // is last + { + packet2_utils_vu_open_unpack(packet2, VU1_PARAMS_ADDRESS, true); + { + packet2_add_u32(packet2, true); // Draw wait finish? + packet2_add_u32(packet2, lastVertCount); // Vertex count + packet2_add_u32(packet2, lastVertCount / 3); // Triangles count + packet2_add_u32(packet2, 0); // Free + } + packet2_utils_vu_close_unpack(packet2); + packet2_utils_vu_add_start_program(packet2, 0); + } + packet2_utils_vu_add_end_tag(packet2); + dma_channel_wait(DMA_CHANNEL_VIF1, 0); + dma_channel_send_packet2(packet2, DMA_CHANNEL_VIF1, 1); + packet2_reset(packet2, false); + } + } + if (switchCounter != 0) + { + packet2_utils_vu_open_unpack(packet2, VU1_PARAMS_ADDRESS, true); + { + packet2_add_u32(packet2, true); // Draw wait finish? + packet2_add_u32(packet2, lastVertCount); // Vertex count + packet2_add_u32(packet2, lastVertCount / 3); // Triangles count + packet2_add_u32(packet2, 0); // Free + } + packet2_utils_vu_close_unpack(packet2); + packet2_utils_vu_add_start_program(packet2, 0); + packet2_utils_vu_add_end_tag(packet2); + dma_channel_wait(DMA_CHANNEL_VIF1, 0); + dma_channel_send_packet2(packet2, DMA_CHANNEL_VIF1, 1); + } + packet2_free(packet2); +} diff --git a/src/engine/vu1_progs/draw3D.vclpp b/src/engine/vu1_progs/draw3D.vclpp index f38fc42..f50a7be 100644 --- a/src/engine/vu1_progs/draw3D.vclpp +++ b/src/engine/vu1_progs/draw3D.vclpp @@ -39,19 +39,24 @@ --enter --endenter +;///////////// LOAD STATIC DATA ///////////// +lq gif_draw_finish_tag, 0(vi00) ; GIF tag - wait +lq gif_set_tag, 1(vi00) ; GIF tag - set +;//////////////////////////////////////////// + xtop double_buffer ;//////// LOAD CURRENT BUFFER DATA ////////// MatrixLoad{ matrix, 0, double_buffer } -ilw.z triangles_count, 4(double_buffer) ; Triangles count +ilw.x do_draw_finish, 4(double_buffer) ; Add draw finish tag? (sync) ilw.y vertex_count, 4(double_buffer) ; Vertex count -lq gif_set_tag, 5(double_buffer) ; GIF tag - set -lq tex_gif_tag_1, 6(double_buffer) ; GIF tag - texture LOD -lq tex_gif_tag_2, 7(double_buffer) ; GIF tag - texture buffer & CLUT -lq prim_tag, 8(double_buffer) ; GIF tag - tell GS how many data we will send -lq rgba, 9(double_buffer) ; Mesh RGBA +ilw.z triangles_count, 4(double_buffer) ; Triangles count +lq tex_gif_tag_1, 5(double_buffer) ; GIF tag - texture LOD +lq tex_gif_tag_2, 6(double_buffer) ; GIF tag - texture buffer & CLUT +lq prim_tag, 7(double_buffer) ; GIF tag - tell GS how many data we will send +lq rgba, 8(double_buffer) ; Mesh RGBA -iaddiu vertex_data, double_buffer, 10 ; pointer to vertex data +iaddiu vertex_data, double_buffer, 9 ; pointer to vertex data iadd stq_data, vertex_data, vertex_count ; pointer to stq iadd kick_address, stq_data, vertex_count ; pointer for XGKICK iadd dest_address, stq_data, vertex_count ; helper pointer for data inserting @@ -65,6 +70,10 @@ sqi gif_set_tag, (dest_address++) ; sqi tex_gif_tag_1, (dest_address++) ; texture LOD tag sqi gif_set_tag, (dest_address++) ; sqi tex_gif_tag_2, (dest_address++) ; texture buffer & CLUT tag +iblez do_draw_finish, kick +sqi gif_set_tag, (dest_address++) ; +sqi gif_draw_finish_tag, (dest_address++) ; do draw_finish is needed +kick: sqi prim_tag, (dest_address++) ; prim + tell gs how many data will be ;//////////////////////////////////////////// @@ -135,6 +144,7 @@ triangle_loop: --LoopCS 1,3 --barrier + xgkick kick_address ; dispatch to the GS rasterizer. --exit diff --git a/src/engine/vu1_progs/draw3D.vsm b/src/engine/vu1_progs/draw3D.vsm index f557b72..e312e7e 100644 --- a/src/engine/vu1_progs/draw3D.vsm +++ b/src/engine/vu1_progs/draw3D.vsm @@ -3,6 +3,10 @@ ;-----VCL CODE------------ ;------------------------- ;------------------------- +; === __LP__ EXPL_draw3D_vcl_triangle_loop__MAIN_LOOP: +; === hDown : optimal=30 clid=0 mlid=2 size=(31) +; === dUp : optimal=30 clid=0 mlid=2 size=(31) +; === another : optimal=30 clid=0 mlid=2 size=(31) ; ================================================= ; flowMon::Emit() vcl 1.4beta7 produced this code: .vu @@ -11,83 +15,171 @@ .global VU1Draw3D_CodeEnd VU1Draw3D_CodeStart: __v_draw3D_vcl_4: -; _LNOPT_w=[ normal2 ] 27 [27 0] 27 [__v_draw3D_vcl_4] - NOP xtop VI07 - NOP lq VF01,0(VI07) - NOP ilw.y VI05,4(VI07) - NOP lq VF05,5(VI07) - NOP lq VF09,6(VI07) - NOP lq VF08,7(VI07) - NOP lq VF07,8(VI07) - NOP lq VF02,1(VI07) - NOP iaddiu VI03,VI07,0x0000000a - NOP iadd VI04,VI03,VI05 - NOP lq VF03,2(VI07) - NOP iadd VI06,VI04,VI05 +; _LNOPT_w=[ normal2 ] 26 [26 0] 26 [__v_draw3D_vcl_4] + NOP xtop VI05 + NOP lq VF02,1(VI00) + NOP lq VF01,0(VI00) + NOP ilw.x VI01,4(VI05) + NOP ilw.y VI07,4(VI05) + NOP lq VF03,0(VI05) + NOP lq VF08,5(VI05) + NOP lq VF10,6(VI05) + NOP lq VF04,1(VI05) + NOP lq VF05,2(VI05) + NOP iaddiu VI03,VI05,0x00000009 + NOP iadd VI04,VI03,VI07 + NOP lq VF06,3(VI05) + NOP iadd VI06,VI04,VI07 NOP loi 0x44fff000 - NOP lq VF04,3(VI07) - NOP ilw.z VI02,4(VI07) - NOP sqi VF05,(VI06++) - NOP sqi VF09,(VI06++) - NOP sqi VF05,(VI06++) + NOP ilw.z VI02,4(VI05) + NOP lq VF07,7(VI05) + NOP sqi VF02,(VI06++) NOP sqi VF08,(VI06++) - NOP lq VF05,9(VI07) - NOP iaddiu VI07,VI00,0x00007fff - NOP iadd VI05,VI04,VI05 - addi.xy VF06,VF00,I loi 0x492aaaaa + NOP sqi VF02,(VI06++) + NOP lq VF08,8(VI05) + NOP iadd VI05,VI04,VI07 + addi.xy VF09,VF00,I loi 0x492aaaaa NOP fcset 0 + NOP iblez VI01,kick + addi.z VF09,VF00,I sqi VF10,(VI06++) +; _LNOPT_w=[ normal2 ] 2 [2 0] 2 [__v_draw3D_vcl_5] + NOP sqi VF02,(VI06++) + NOP sqi VF01,(VI06++) +kick: +; _LNOPT_w=[ normal2 ] 27 [27 0] 32 [kick] NOP sqi VF07,(VI06++) - NOP iaddiu VI07,VI07,0x00000001 - addi.z VF06,VF00,I iaddiu VI08,VI00,0 -triangle_loop: -; _LNOPT_w=[ normal ] 37 [31 30] 45 [triangle_loop] NOP lq VF07,0(VI03) - mulax ACC,VF01,VF07x iaddiu VI08,VI08,0x00000001 ; STALL_LATENCY ?3 - madday ACC,VF02,VF07y NOP - maddaz ACC,VF03,VF07z NOP - maddw VF10,VF04,VF07w lq VF08,2(VI03) - mulax ACC,VF01,VF08x div Q,VF00w,VF10w ; STALL_LATENCY ?3 - madday ACC,VF02,VF08y NOP - maddaz ACC,VF03,VF08z lq VF07,1(VI03) - maddw VF08,VF04,VF08w NOP - clipw.xyz VF10xyz,VF10w NOP - mulax ACC,VF01,VF07x NOP ; STALL_LATENCY ?1 - madday ACC,VF02,VF07y div Q,VF00w,VF08w - maddaz ACC,VF03,VF07z lq VF09,0(VI04) - maddw VF07,VF04,VF07w NOP - mulaw.xyz ACC,VF06,VF00w NOP - mulq.xyz VF10,VF10,Q NOP - mulq VF09,VF09,Q sq VF05,1(VI06) - clipw.xyz VF07xyz,VF07w lq VF11,2(VI04) - clipw.xyz VF08xyz,VF08w div Q,VF00w,VF07w - mulq.xyz VF08,VF08,Q sq VF05,4(VI06) - madd.xyz VF09,VF10,VF06 sq VF09,0(VI06) - mulq VF10,VF11,Q sq VF05,7(VI06) - mulaw.xyz ACC,VF06,VF00w mfir.w VF09,VI07 - madd.xyz VF08,VF08,VF06 fcand VI01,262143 - NOP iaddiu VI01,VI01,0x00007fff - mulq.xyz VF10,VF07,Q sq VF10,6(VI06) - ftoi4.xyz VF09,VF09 mfir.w VF07,VI01 - ftoi4.xyz VF07,VF08 lq VF11,1(VI04) - mulaw.xyz ACC,VF06,VF00w iaddiu VI03,VI03,0x00000003 - madd.xyz VF08,VF10,VF06 iaddiu VI04,VI04,0x00000003 - NOP sq VF09,2(VI06) - mulq VF09,VF11,Q sq VF07,8(VI06) - NOP mfir.w VF07,VI07 - ftoi4.xyz VF07,VF08 iaddiu VI06,VI06,0x00000009 - NOP sq VF09,-6(VI06) ; STALL_LATENCY ?1 - NOP ibne VI08,VI02,triangle_loop - NOP sq VF07,-4(VI06) -; _LNOPT_w=[ normal2 ] 3 [1 0] 3 [__v_draw3D_vcl_7] + mulax ACC,VF03,VF07x lq VF14,1(VI03) ; STALL_LATENCY ?3 + madday ACC,VF04,VF07y sq VF08,1(VI06) + maddaz ACC,VF05,VF07z sq VF08,7(VI06) + maddw VF11,VF06,VF07w NOP + mulax ACC,VF03,VF14x lq VF07,2(VI03) + madday ACC,VF04,VF14y NOP + maddaz ACC,VF05,VF14z NOP + maddw VF14,VF06,VF14w div Q,VF00w,VF11w + mulax ACC,VF03,VF07x NOP + madday ACC,VF04,VF07y iaddiu VI07,VI00,0x00007fff + maddaz ACC,VF05,VF07z iaddiu VI07,VI07,0x00000001 + maddw VF07,VF06,VF07w iaddiu VI08,VI00,0 + clipw.xyz VF11xyz,VF11w iaddiu VI04,VI04,0 + clipw.xyz VF14xyz,VF14w div Q,VF00w,VF14w ; STALL_THRUPUT ?1 + clipw.xyz VF07xyz,VF07w lq VF15,0(VI04) + mulq.xyz VF02,VF11,Q sq VF08,4(VI06) + mulaw.xyz ACC,VF09,VF00w iaddiu VI03,VI03,0 + mulq VF11,VF15,Q iaddiu VI06,VI06,0 ; STALL_LATENCY ?1 + madd.xyz VF01,VF02,VF09 lq VF02,1(VI04) + NOP div Q,VF00w,VF07w + mulq.xyz VF15,VF14,Q iaddiu VI08,VI08,0x00000001 + mulaw.xyz ACC,VF09,VF00w sq VF11,0(VI06) + mulq VF14,VF02,Q mfir.w VF11,VI07 + ftoi4.xyz VF11,VF01 ibeq VI08,VI02,EXPL_draw3D_vcl_triangle_loop__EPI1 + madd.xyz VF02,VF15,VF09 lq VF15,2(VI04) +; _LNOPT_w=[ ] 31 [29 0] 31 [EXPL_draw3D_vcl_triangle_loop__PRO1] + NOP lq VF12,3(VI03) + NOP NOP + mulq.xyz VF01,VF07,Q NOP + mulq VF11,VF15,Q sq VF11,2(VI06) + mulax ACC,VF03,VF12x lq VF10,4(VI03) + madday ACC,VF04,VF12y NOP + maddaz ACC,VF05,VF12z NOP + maddw VF11,VF06,VF12w sq VF11,6(VI06) + mulax ACC,VF03,VF10x lq VF07,5(VI03) + madday ACC,VF04,VF10y sq VF14,3(VI06) + maddaz ACC,VF05,VF10z sq VF08,10(VI06) + maddw VF10,VF06,VF10w div Q,VF00w,VF11w + mulax ACC,VF03,VF07x sq VF08,13(VI06) + madday ACC,VF04,VF07y sq VF08,16(VI06) + maddaz ACC,VF05,VF07z iaddiu VI03,VI03,0x00000006 + maddw VF07,VF06,VF07w iaddiu VI04,VI04,0x00000006 + clipw.xyz VF11xyz,VF11w lq VF12,-3(VI04) + clipw.xyz VF10xyz,VF10w iaddiu VI06,VI06,0x00000012 + mulq.xyz VF14,VF11,Q div Q,VF00w,VF10w + clipw.xyz VF07xyz,VF07w fcand VI01,262143 + mulq VF12,VF12,Q iaddiu VI08,VI08,0x00000001 + ftoi4.xyz VF11,VF02 iaddiu VI01,VI01,0x00007fff + mulaw.xyz ACC,VF09,VF00w mfir.w VF11,VI07 + madd.xyz VF14,VF14,VF09 mfir.w VF10,VI01 + mulaw.xyz ACC,VF09,VF00w lq VF02,-2(VI04) + madd.xyz VF01,VF01,VF09 div Q,VF00w,VF07w + mulq.xyz VF10,VF10,Q lq VF15,-1(VI04) + ftoi4.xyz VF11,VF14 sq VF11,-13(VI06) + mulq VF14,VF02,Q sq VF12,-9(VI06) + mulaw.xyz ACC,VF09,VF00w ibeq VI08,VI02,EXPL_draw3D_vcl_triangle_loop__EPI0 + madd.xyz VF02,VF10,VF09 mfir.w VF11,VI07 +EXPL_draw3D_vcl_triangle_loop__MAIN_LOOP: +; _LPOPT_w=[ hDown ] 31 [30 30] 31 [EXPL_draw3D_vcl_triangle_loop__MAIN_LOOP] + ftoi4.xyz VF10,VF01 lq VF13,0(VI03) + NOP lq VF12,1(VI03) + mulq.xyz VF01,VF07,Q sq VF14,-6(VI06) + mulq VF11,VF15,Q sq VF11,-7(VI06) + mulax ACC,VF03,VF13x sq VF10,-10(VI06) + madday ACC,VF04,VF13y sq VF08,1(VI06) + maddaz ACC,VF05,VF13z NOP + maddw VF11,VF06,VF13w sq VF11,-3(VI06) + mulax ACC,VF03,VF12x lq VF07,2(VI03) + madday ACC,VF04,VF12y sq VF08,4(VI06) + maddaz ACC,VF05,VF12z sq VF08,7(VI06) + maddw VF10,VF06,VF12w div Q,VF00w,VF11w + mulax ACC,VF03,VF07x NOP + madday ACC,VF04,VF07y iaddiu VI03,VI03,0x00000003 + maddaz ACC,VF05,VF07z NOP + maddw VF07,VF06,VF07w iaddiu VI04,VI04,0x00000003 + clipw.xyz VF11xyz,VF11w lq VF12,-3(VI04) + clipw.xyz VF10xyz,VF10w iaddiu VI06,VI06,0x00000009 + mulq.xyz VF13,VF11,Q fcand VI01,262143 + clipw.xyz VF07xyz,VF07w div Q,VF00w,VF10w + mulq VF12,VF12,Q iaddiu VI08,VI08,0x00000001 + ftoi4.xyz VF11,VF02 iaddiu VI01,VI01,0x00007fff + mulaw.xyz ACC,VF09,VF00w mfir.w VF10,VI01 + madd.xyz VF13,VF13,VF09 mfir.w VF11,VI07 + mulaw.xyz ACC,VF09,VF00w lq VF02,-2(VI04) + madd.xyz VF01,VF01,VF09 sq VF12,-9(VI06) + mulq.xyz VF10,VF10,Q div Q,VF00w,VF07w + ftoi4.xyz VF11,VF13 sq VF11,-13(VI06) + mulq VF14,VF02,Q mfir.w VF11,VI07 + mulaw.xyz ACC,VF09,VF00w ibne VI08,VI02,EXPL_draw3D_vcl_triangle_loop__MAIN_LOOP + madd.xyz VF02,VF10,VF09 lq VF15,-1(VI04) +EXPL_draw3D_vcl_triangle_loop__EPI0: +; _LNOPT_w=[ ] 13 [13 0] 15 [EXPL_draw3D_vcl_triangle_loop__EPI0] + NOP NOP + ftoi4.xyz VF10,VF01 fcand VI01,262143 + mulq.xyz VF01,VF07,Q sq VF14,-6(VI06) + mulq VF11,VF15,Q sq VF11,-7(VI06) + mulaw.xyz ACC,VF09,VF00w iaddiu VI01,VI01,0x00007fff + madd.xyz VF01,VF01,VF09 sq VF10,-10(VI06) ; STALL_LATENCY ?1 + ftoi4.xyz VF11,VF02 sq VF11,-3(VI06) + NOP mfir.w VF11,VI07 + NOP mfir.w VF10,VI01 + ftoi4.xyz VF10,VF01 NOP + NOP sq VF11,-4(VI06) ; STALL_LATENCY ?1 + NOP b EXPL_draw3D_vcl_triangle_loop__EXIT_POINT + NOP sq VF10,-1(VI06) +EXPL_draw3D_vcl_triangle_loop__EPI1: +; _LNOPT_w=[ ] 12 [13 0] 14 [EXPL_draw3D_vcl_triangle_loop__EPI1] + NOP NOP + mulq.xyz VF14,VF07,Q sq VF14,3(VI06) + NOP NOP + mulq VF11,VF15,Q sq VF11,2(VI06) + mulaw.xyz ACC,VF09,VF00w fcand VI01,262143 + madd.xyz VF14,VF14,VF09 iaddiu VI01,VI01,0x00007fff + NOP mfir.w VF14,VI01 + ftoi4.xyz VF11,VF02 sq VF11,6(VI06) + NOP mfir.w VF11,VI07 + ftoi4.xyz VF14,VF14 NOP + NOP sq VF11,5(VI06) ; STALL_LATENCY ?2 + NOP sq VF14,8(VI06) +EXPL_draw3D_vcl_triangle_loop__EXIT_POINT: +; _LNOPT_w=[ ] 0 [0 0] 0 [EXPL_draw3D_vcl_triangle_loop__EXIT_POINT] +; _LNOPT_w=[ normal2 ] 3 [1 0] 3 [__v_draw3D_vcl_9] NOP xgkick VI05 NOP[E] NOP NOP NOP .align 4 VU1Draw3D_CodeEnd: -; iCount=67 +; iCount=145 ; register stats: ; 9 VU User integer -; 12 VU User floating point +; 16 VU User floating point ;------------------------- ;------------------------- ;-------------------------