added optimized array mode to draw()

This commit is contained in:
h4570
2020-12-26 13:29:37 +01:00
parent aeb25ad398
commit 8406dcee72
6 changed files with 324 additions and 101 deletions
+24 -9
View File
@@ -13,6 +13,8 @@
#include <draw_buffers.h> #include <draw_buffers.h>
#include <draw_primitives.h> #include <draw_primitives.h>
#include <gs_privileged.h>
#include <draw.h>
#include <packet2.h> #include <packet2.h>
#include "gif_sender.hpp" #include "gif_sender.hpp"
#include "vif_sender.hpp" #include "vif_sender.hpp"
@@ -38,12 +40,20 @@ public:
void enableVSync() { isVSyncEnabled = true; } void enableVSync() { isVSyncEnabled = true; }
void disableVSync() { isVSyncEnabled = false; } 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 /// --- Draw: PATH3
void draw(Sprite &t_sprite);
/** /**
* WARNING: THIS FUNC CAUSE VISUAL ARTIFACTS!
* Draw many meshes with lighting information. * Draw many meshes with lighting information.
* Slowest way of rendering (PATH 3, using EE and GIF). * Slowest way of rendering (PATH 3, using EE and GIF).
* NOTICE: Animation supported, lighting supported * NOTICE: Animation supported, lighting supported
@@ -51,6 +61,7 @@ public:
void drawByPath3(Mesh *t_meshes, u16 t_amount, LightBulb *t_bulbs, u16 t_bulbsCount); 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. * Draw mesh with lighting information.
* Slowest way of rendering (PATH 3, using EE and GIF). * Slowest way of rendering (PATH 3, using EE and GIF).
* NOTICE: Animation supported, lighting supported * NOTICE: Animation supported, lighting supported
@@ -58,6 +69,7 @@ public:
void drawByPath3(Mesh &t_mesh, LightBulb *t_bulbs, u16 t_bulbsCount); void drawByPath3(Mesh &t_mesh, LightBulb *t_bulbs, u16 t_bulbsCount);
/** /**
* WARNING: THIS FUNC CAUSE VISUAL ARTIFACTS!
* Draw many meshes without lighting information. * Draw many meshes without lighting information.
* Slowest way of rendering (PATH 3, using EE and GIF). * Slowest way of rendering (PATH 3, using EE and GIF).
* NOTICE: Animation supported, lighting supported * NOTICE: Animation supported, lighting supported
@@ -65,6 +77,7 @@ public:
void drawByPath3(Mesh *t_meshes, u16 t_amount); void drawByPath3(Mesh *t_meshes, u16 t_amount);
/** /**
* WARNING: THIS FUNC CAUSE VISUAL ARTIFACTS!
* Draw mesh without lighting information. * Draw mesh without lighting information.
* Slowest way of rendering (PATH 3, using EE and GIF). * Slowest way of rendering (PATH 3, using EE and GIF).
* NOTICE: Animation supported, lighting supported * NOTICE: Animation supported, lighting supported
@@ -74,25 +87,27 @@ public:
/// --- Draw: PATH1 /// --- 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). * Fastest way of rendering (PATH 1, using VU1).
* NOTICE: Animation supported, lighting NOT supported (at this moment) * 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. * Draw mesh with lighting information.
* Fastest way of rendering (PATH 1, using VU1). * Fastest way of rendering (PATH 1, using VU1).
* NOTICE: Animation supported, lighting NOT supported (at this moment) * NOTICE: Animation supported, lighting NOT supported (at this moment)
*/ */
void draw(Mesh &t_mesh, LightBulb *t_bulbs, u16 t_bulbsCount); void draw(Mesh &t_mesh, LightBulb *t_bulbs, u16 t_bulbsCount);
/** /**
* Draw many meshes without lighting information. * Draw many meshes without lighting information.
* Fastest way of rendering (PATH 1, using VU1). * 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) * 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. * Draw mesh without lighting information.
+7 -2
View File
@@ -31,12 +31,17 @@ public:
// TODO refactor // 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 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 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: private:
u32 lastVertCount; // needed for drawTheSameWithOtherMatrices()
u8 isDrawWaitEnabled;
Light *light; Light *light;
void uploadMicroProgram(); void uploadMicroProgram();
void setDoubleBuffer(); 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 *textureBuffer); 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 *packets[2] __attribute__((aligned(64)));
packet2_t *currPacket; packet2_t *currPacket;
/** /**
+27 -6
View File
@@ -13,8 +13,6 @@
#include <dma.h> #include <dma.h>
#include <graph.h> #include <graph.h>
#include <packet.h> #include <packet.h>
#include <draw.h>
#include <gs_psm.h>
#include "../include/utils/debug.hpp" #include "../include/utils/debug.hpp"
#include "../include/utils/math.hpp" #include "../include/utils/math.hpp"
@@ -268,10 +266,33 @@ void Renderer::drawByPath3(Mesh &t_mesh) { drawByPath3(t_mesh, NULL, 0); }
/// --- Draw: PATH1 /// --- 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++) beginFrameIfNeeded();
draw(t_meshes[i], t_bulbs, t_bulbsCount); 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) 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); } void Renderer::draw(Mesh &t_mesh) { draw(t_mesh, NULL, 0); }
+92 -12
View File
@@ -19,6 +19,8 @@
const u32 VU1_PACKAGE_VERTS_PER_BUFF = 96; // Remember to modify buffer size in vu1 also 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_PACKAGES_PER_PACKET = 9;
const u32 VU1_PACKET_SIZE = 256; // should be 128, but 256 is more safe for future 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 // Constructors/Destructors
@@ -31,16 +33,18 @@ extern u32 VU1Draw3D_CodeEnd __attribute__((section(".vudata")));
VifSender::VifSender(Light *t_light) VifSender::VifSender(Light *t_light)
{ {
light = t_light;
PRINT_LOG("Initializing VifSender"); 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_initialize(DMA_CHANNEL_VIF1, NULL, 0);
dma_channel_fast_waits(DMA_CHANNEL_VIF1); dma_channel_fast_waits(DMA_CHANNEL_VIF1);
uploadMicroProgram(); uploadMicroProgram();
packets[0] = packet2_create(VU1_PACKET_SIZE, P2_TYPE_NORMAL, P2_MODE_CHAIN, true); 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); packets[1] = packet2_create(VU1_PACKET_SIZE, P2_TYPE_NORMAL, P2_MODE_CHAIN, true);
context = 0; context = 0;
setDoubleBuffer(); setDoubleBufferAddStaticData();
PRINT_LOG("VifSender initialized!");
} }
VifSender::~VifSender() VifSender::~VifSender()
@@ -93,7 +97,7 @@ void VifSender::drawMesh(RenderData *t_renderData, Matrix t_perspective, u32 ver
i -= 3; i -= 3;
const u32 endI = i + (VU1_PACKAGE_VERTS_PER_BUFF - 1) > vertCount2 ? vertCount2 : i + (VU1_PACKAGE_VERTS_PER_BUFF - 1); 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 if (endI == vertCount2) // if there are no more vertices to draw, break
{ {
i = vertCount2; 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_double_buffer(settings, 10, 498);
packet2_utils_vu_add_end_tag(settings); packet2_utils_vu_add_end_tag(settings);
dma_channel_send_packet2(settings, DMA_CHANNEL_VIF1, true); dma_channel_send_packet2(settings, DMA_CHANNEL_VIF1, true);
@@ -120,28 +130,98 @@ void VifSender::setDoubleBuffer()
} }
/** Draw using PATH1 */ /** 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; const u32 vertCount = t_end - t_start;
u32 vif_added_bytes = 0; lastVertCount = vertCount;
packet2_utils_vu_open_unpack(currPacket, 0, true); packet2_utils_vu_open_unpack(currPacket, 0, true);
packet2_add_data(currPacket, modelViewProj.data, 4); 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); // Vertex count
packet2_add_u32(currPacket, vertCount / 3); // Triangles count packet2_add_u32(currPacket, vertCount / 3); // Triangles count
packet2_add_u32(currPacket, 0); // Free 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_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_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.r);
packet2_add_u32(currPacket, t_mesh.color.g); packet2_add_u32(currPacket, t_mesh.color.g);
packet2_add_u32(currPacket, t_mesh.color.b); packet2_add_u32(currPacket, t_mesh.color.b);
packet2_add_u32(currPacket, t_mesh.color.a); 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); packet2_utils_vu_add_unpack_data(currPacket, vif_added_bytes, t_vertices + t_start, vertCount, true);
vif_added_bytes += vertCount; vif_added_bytes += vertCount;
packet2_utils_vu_add_unpack_data(currPacket, vif_added_bytes, t_coordinates + t_start, vertCount, true); packet2_utils_vu_add_unpack_data(currPacket, vif_added_bytes, t_coordinates + t_start, vertCount, true);
vif_added_bytes += vertCount; vif_added_bytes += vertCount;
packet2_utils_vu_add_start_program(currPacket, 0); 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);
}
+17 -7
View File
@@ -39,19 +39,24 @@
--enter --enter
--endenter --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 xtop double_buffer
;//////// LOAD CURRENT BUFFER DATA ////////// ;//////// LOAD CURRENT BUFFER DATA //////////
MatrixLoad{ matrix, 0, double_buffer } 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 ilw.y vertex_count, 4(double_buffer) ; Vertex count
lq gif_set_tag, 5(double_buffer) ; GIF tag - set ilw.z triangles_count, 4(double_buffer) ; Triangles count
lq tex_gif_tag_1, 6(double_buffer) ; GIF tag - texture LOD lq tex_gif_tag_1, 5(double_buffer) ; GIF tag - texture LOD
lq tex_gif_tag_2, 7(double_buffer) ; GIF tag - texture buffer & CLUT lq tex_gif_tag_2, 6(double_buffer) ; GIF tag - texture buffer & CLUT
lq prim_tag, 8(double_buffer) ; GIF tag - tell GS how many data we will send lq prim_tag, 7(double_buffer) ; GIF tag - tell GS how many data we will send
lq rgba, 9(double_buffer) ; Mesh RGBA 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 stq_data, vertex_data, vertex_count ; pointer to stq
iadd kick_address, stq_data, vertex_count ; pointer for XGKICK iadd kick_address, stq_data, vertex_count ; pointer for XGKICK
iadd dest_address, stq_data, vertex_count ; helper pointer for data inserting 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 tex_gif_tag_1, (dest_address++) ; texture LOD tag
sqi gif_set_tag, (dest_address++) ; sqi gif_set_tag, (dest_address++) ;
sqi tex_gif_tag_2, (dest_address++) ; texture buffer & CLUT tag 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 sqi prim_tag, (dest_address++) ; prim + tell gs how many data will be
;//////////////////////////////////////////// ;////////////////////////////////////////////
@@ -135,6 +144,7 @@ triangle_loop: --LoopCS 1,3
--barrier --barrier
xgkick kick_address ; dispatch to the GS rasterizer. xgkick kick_address ; dispatch to the GS rasterizer.
--exit --exit
+157 -65
View File
@@ -3,6 +3,10 @@
;-----VCL CODE------------ ;-----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: ; flowMon::Emit() vcl 1.4beta7 produced this code:
.vu .vu
@@ -11,83 +15,171 @@
.global VU1Draw3D_CodeEnd .global VU1Draw3D_CodeEnd
VU1Draw3D_CodeStart: VU1Draw3D_CodeStart:
__v_draw3D_vcl_4: __v_draw3D_vcl_4:
; _LNOPT_w=[ normal2 ] 27 [27 0] 27 [__v_draw3D_vcl_4] ; _LNOPT_w=[ normal2 ] 26 [26 0] 26 [__v_draw3D_vcl_4]
NOP xtop VI07 NOP xtop VI05
NOP lq VF01,0(VI07) NOP lq VF02,1(VI00)
NOP ilw.y VI05,4(VI07) NOP lq VF01,0(VI00)
NOP lq VF05,5(VI07) NOP ilw.x VI01,4(VI05)
NOP lq VF09,6(VI07) NOP ilw.y VI07,4(VI05)
NOP lq VF08,7(VI07) NOP lq VF03,0(VI05)
NOP lq VF07,8(VI07) NOP lq VF08,5(VI05)
NOP lq VF02,1(VI07) NOP lq VF10,6(VI05)
NOP iaddiu VI03,VI07,0x0000000a NOP lq VF04,1(VI05)
NOP iadd VI04,VI03,VI05 NOP lq VF05,2(VI05)
NOP lq VF03,2(VI07) NOP iaddiu VI03,VI05,0x00000009
NOP iadd VI06,VI04,VI05 NOP iadd VI04,VI03,VI07
NOP lq VF06,3(VI05)
NOP iadd VI06,VI04,VI07
NOP loi 0x44fff000 NOP loi 0x44fff000
NOP lq VF04,3(VI07) NOP ilw.z VI02,4(VI05)
NOP ilw.z VI02,4(VI07) NOP lq VF07,7(VI05)
NOP sqi VF05,(VI06++) NOP sqi VF02,(VI06++)
NOP sqi VF09,(VI06++)
NOP sqi VF05,(VI06++)
NOP sqi VF08,(VI06++) NOP sqi VF08,(VI06++)
NOP lq VF05,9(VI07) NOP sqi VF02,(VI06++)
NOP iaddiu VI07,VI00,0x00007fff NOP lq VF08,8(VI05)
NOP iadd VI05,VI04,VI05 NOP iadd VI05,VI04,VI07
addi.xy VF06,VF00,I loi 0x492aaaaa addi.xy VF09,VF00,I loi 0x492aaaaa
NOP fcset 0 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 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) NOP lq VF07,0(VI03)
mulax ACC,VF01,VF07x iaddiu VI08,VI08,0x00000001 ; STALL_LATENCY ?3 mulax ACC,VF03,VF07x lq VF14,1(VI03) ; STALL_LATENCY ?3
madday ACC,VF02,VF07y NOP madday ACC,VF04,VF07y sq VF08,1(VI06)
maddaz ACC,VF03,VF07z NOP maddaz ACC,VF05,VF07z sq VF08,7(VI06)
maddw VF10,VF04,VF07w lq VF08,2(VI03) maddw VF11,VF06,VF07w NOP
mulax ACC,VF01,VF08x div Q,VF00w,VF10w ; STALL_LATENCY ?3 mulax ACC,VF03,VF14x lq VF07,2(VI03)
madday ACC,VF02,VF08y NOP madday ACC,VF04,VF14y NOP
maddaz ACC,VF03,VF08z lq VF07,1(VI03) maddaz ACC,VF05,VF14z NOP
maddw VF08,VF04,VF08w NOP maddw VF14,VF06,VF14w div Q,VF00w,VF11w
clipw.xyz VF10xyz,VF10w NOP mulax ACC,VF03,VF07x NOP
mulax ACC,VF01,VF07x NOP ; STALL_LATENCY ?1 madday ACC,VF04,VF07y iaddiu VI07,VI00,0x00007fff
madday ACC,VF02,VF07y div Q,VF00w,VF08w maddaz ACC,VF05,VF07z iaddiu VI07,VI07,0x00000001
maddaz ACC,VF03,VF07z lq VF09,0(VI04) maddw VF07,VF06,VF07w iaddiu VI08,VI00,0
maddw VF07,VF04,VF07w NOP clipw.xyz VF11xyz,VF11w iaddiu VI04,VI04,0
mulaw.xyz ACC,VF06,VF00w NOP clipw.xyz VF14xyz,VF14w div Q,VF00w,VF14w ; STALL_THRUPUT ?1
mulq.xyz VF10,VF10,Q NOP clipw.xyz VF07xyz,VF07w lq VF15,0(VI04)
mulq VF09,VF09,Q sq VF05,1(VI06) mulq.xyz VF02,VF11,Q sq VF08,4(VI06)
clipw.xyz VF07xyz,VF07w lq VF11,2(VI04) mulaw.xyz ACC,VF09,VF00w iaddiu VI03,VI03,0
clipw.xyz VF08xyz,VF08w div Q,VF00w,VF07w mulq VF11,VF15,Q iaddiu VI06,VI06,0 ; STALL_LATENCY ?1
mulq.xyz VF08,VF08,Q sq VF05,4(VI06) madd.xyz VF01,VF02,VF09 lq VF02,1(VI04)
madd.xyz VF09,VF10,VF06 sq VF09,0(VI06) NOP div Q,VF00w,VF07w
mulq VF10,VF11,Q sq VF05,7(VI06) mulq.xyz VF15,VF14,Q iaddiu VI08,VI08,0x00000001
mulaw.xyz ACC,VF06,VF00w mfir.w VF09,VI07 mulaw.xyz ACC,VF09,VF00w sq VF11,0(VI06)
madd.xyz VF08,VF08,VF06 fcand VI01,262143 mulq VF14,VF02,Q mfir.w VF11,VI07
NOP iaddiu VI01,VI01,0x00007fff ftoi4.xyz VF11,VF01 ibeq VI08,VI02,EXPL_draw3D_vcl_triangle_loop__EPI1
mulq.xyz VF10,VF07,Q sq VF10,6(VI06) madd.xyz VF02,VF15,VF09 lq VF15,2(VI04)
ftoi4.xyz VF09,VF09 mfir.w VF07,VI01 ; _LNOPT_w=[ ] 31 [29 0] 31 [EXPL_draw3D_vcl_triangle_loop__PRO1]
ftoi4.xyz VF07,VF08 lq VF11,1(VI04) NOP lq VF12,3(VI03)
mulaw.xyz ACC,VF06,VF00w iaddiu VI03,VI03,0x00000003 NOP NOP
madd.xyz VF08,VF10,VF06 iaddiu VI04,VI04,0x00000003 mulq.xyz VF01,VF07,Q NOP
NOP sq VF09,2(VI06) mulq VF11,VF15,Q sq VF11,2(VI06)
mulq VF09,VF11,Q sq VF07,8(VI06) mulax ACC,VF03,VF12x lq VF10,4(VI03)
NOP mfir.w VF07,VI07 madday ACC,VF04,VF12y NOP
ftoi4.xyz VF07,VF08 iaddiu VI06,VI06,0x00000009 maddaz ACC,VF05,VF12z NOP
NOP sq VF09,-6(VI06) ; STALL_LATENCY ?1 maddw VF11,VF06,VF12w sq VF11,6(VI06)
NOP ibne VI08,VI02,triangle_loop mulax ACC,VF03,VF10x lq VF07,5(VI03)
NOP sq VF07,-4(VI06) madday ACC,VF04,VF10y sq VF14,3(VI06)
; _LNOPT_w=[ normal2 ] 3 [1 0] 3 [__v_draw3D_vcl_7] 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 xgkick VI05
NOP[E] NOP NOP[E] NOP
NOP NOP NOP NOP
.align 4 .align 4
VU1Draw3D_CodeEnd: VU1Draw3D_CodeEnd:
; iCount=67 ; iCount=145
; register stats: ; register stats:
; 9 VU User integer ; 9 VU User integer
; 12 VU User floating point ; 16 VU User floating point
;------------------------- ;-------------------------
;------------------------- ;-------------------------
;------------------------- ;-------------------------