From c0ece7206c4de180509f2730c653fca6339d6e81 Mon Sep 17 00:00:00 2001 From: h4570 Date: Thu, 24 Dec 2020 13:08:03 +0100 Subject: [PATCH 1/3] tweaked vu1 packets a bit --- src/engine/include/modules/renderer.hpp | 4 +-- src/engine/modules/renderer.cpp | 44 ++++++++++++++----------- src/engine/modules/vif_sender.cpp | 4 +-- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/engine/include/modules/renderer.hpp b/src/engine/include/modules/renderer.hpp index 1ad7acb..be874d9 100644 --- a/src/engine/include/modules/renderer.hpp +++ b/src/engine/include/modules/renderer.hpp @@ -134,8 +134,8 @@ private: VifSender *vifSender; packet2_t *flipPacket; color_t worldColor; - void allocateBuffers(float t_screenW, float t_screenH); - void initDrawingEnv(float t_screenW, float t_screenH); + void allocateBuffers(int t_screenW, int t_screenH); + void initDrawingEnv(); void setPrim(); }; diff --git a/src/engine/modules/renderer.cpp b/src/engine/modules/renderer.cpp index 5ed1027..2287b88 100644 --- a/src/engine/modules/renderer.cpp +++ b/src/engine/modules/renderer.cpp @@ -22,6 +22,9 @@ // Constructors/Destructors // ---- +static const float GS_CENTER = 4096.0F; +static const float SCREEN_CENTER = GS_CENTER / 2.0F; + /** Initialize DMA<->GIF channel * Allocate buffers * Initialize screen @@ -35,19 +38,19 @@ Renderer::Renderer(u32 t_packetSize, ScreenSettings *t_screen) PRINT_LOG("Initializing renderer"); dma_channel_initialize(DMA_CHANNEL_GIF, NULL, 0); // Initialize DMA to enable data transfer dma_channel_fast_waits(DMA_CHANNEL_GIF); + screen = t_screen; context = 0; isTextureVRAMAllocated = false; isVSyncEnabled = true; isFrameEmpty = false; lastTextureId = 0; flipPacket = packet2_create(4, P2_TYPE_UNCACHED_ACCL, P2_MODE_NORMAL, 0); - allocateBuffers(t_screen->width, t_screen->height); - initDrawingEnv(t_screen->width, t_screen->height); + allocateBuffers((int)t_screen->width, (int)t_screen->height); + initDrawingEnv(); setPrim(); worldColor.r = 0x10; worldColor.g = 0x10; worldColor.b = 0x10; - screen = t_screen; gifSender = new GifSender(t_packetSize, t_screen, &light); vifSender = new VifSender(&light); perspective.setPerspective(*t_screen); @@ -142,7 +145,7 @@ void Renderer::draw(Sprite &t_sprite) beginFrameIfNeeded(); changeTexture(texture); packet2_t *packet2 = packet2_create(12, P2_TYPE_NORMAL, P2_MODE_NORMAL, 0); - packet2_update(packet2, draw_primitive_xyoffset(packet2->next, 0, 2048, 2048)); + packet2_update(packet2, draw_primitive_xyoffset(packet2->next, 0, SCREEN_CENTER, SCREEN_CENTER)); packet2_utils_gif_add_set(packet2, 1); packet2_utils_gs_add_texbuff_clut(packet2, &textureBuffer, &t_sprite.clut); draw_enable_blending(); @@ -151,7 +154,8 @@ void Renderer::draw(Sprite &t_sprite) draw_primitive_xyoffset( packet2->next, 0, - (2048 - (screen->width / 2)), (2048 - (screen->height / 2)))); + SCREEN_CENTER - (screen->width / 2.0F), + SCREEN_CENTER - (screen->height / 2.0F))); draw_disable_blending(); packet2_update(packet2, draw_finish(packet2->next)); dma_channel_wait(DMA_CHANNEL_GIF, 0); @@ -160,14 +164,14 @@ void Renderer::draw(Sprite &t_sprite) } /** Initializes drawing environment (1st app packet) */ -void Renderer::initDrawingEnv(float t_screenW, float t_screenH) +void Renderer::initDrawingEnv() { PRINT_LOG("Initializing drawing environment"); - u16 halfW = (u16)t_screenW / 2; - u16 halfH = (u16)t_screenH / 2; packet2_t *packet2 = packet2_create(20, P2_TYPE_NORMAL, P2_MODE_NORMAL, 0); packet2_update(packet2, draw_setup_environment(packet2->base, 0, frameBuffers, &(zBuffer))); - packet2_update(packet2, draw_primitive_xyoffset(packet2->next, 0, (2048 - halfW), (2048 - halfH))); + packet2_update(packet2, draw_primitive_xyoffset(packet2->next, 0, + SCREEN_CENTER - (screen->width / 2.0F), + SCREEN_CENTER - (screen->height / 2.0F))); packet2_update(packet2, draw_finish(packet2->next)); dma_channel_send_packet2(packet2, DMA_CHANNEL_GIF, true); dma_channel_wait(DMA_CHANNEL_GIF, 0); @@ -198,29 +202,29 @@ void Renderer::setWorldColor(const color_t &t_rgb) } /** Defines and allocates framebuffers and zbuffer */ -void Renderer::allocateBuffers(float t_screenW, float t_screenH) +void Renderer::allocateBuffers(int t_screenW, int t_screenH) { - frameBuffers[0].width = (u16)t_screenW; - frameBuffers[0].height = (u16)t_screenH; + frameBuffers[0].width = (unsigned int)t_screenW; + frameBuffers[0].height = (unsigned int)t_screenH; frameBuffers[0].mask = 0; - frameBuffers[0].psm = GS_PSM_24; - frameBuffers[0].address = graph_vram_allocate((u16)t_screenW, (u16)t_screenH, frameBuffers[0].psm, GRAPH_ALIGN_PAGE); + frameBuffers[0].psm = GS_PSM_32; + frameBuffers[0].address = graph_vram_allocate(t_screenW, t_screenH, frameBuffers[0].psm, GRAPH_ALIGN_PAGE); - frameBuffers[1].width = (u16)t_screenW; - frameBuffers[1].height = (u16)t_screenH; + frameBuffers[1].width = (unsigned int)t_screenW; + frameBuffers[1].height = (unsigned int)t_screenH; frameBuffers[1].mask = 0; - frameBuffers[1].psm = GS_PSM_24; - frameBuffers[1].address = graph_vram_allocate((u16)t_screenW, (u16)t_screenH, frameBuffers[1].psm, GRAPH_ALIGN_PAGE); + frameBuffers[1].psm = GS_PSM_32; + frameBuffers[1].address = graph_vram_allocate(t_screenW, t_screenH, frameBuffers[1].psm, GRAPH_ALIGN_PAGE); zBuffer.enable = DRAW_ENABLE; zBuffer.mask = 0; zBuffer.method = ZTEST_METHOD_GREATER_EQUAL; zBuffer.zsm = GS_ZBUF_24; - zBuffer.address = graph_vram_allocate((u16)t_screenW, (u16)t_screenH, zBuffer.zsm, GRAPH_ALIGN_PAGE); + zBuffer.address = graph_vram_allocate(t_screenW, t_screenH, zBuffer.zsm, GRAPH_ALIGN_PAGE); PRINT_LOG("Framebuffers, zBuffer set and allocated!"); // Initialize the screen and tie the first framebuffer to the read circuits. - graph_initialize(frameBuffers[1].address, frameBuffers[1].width, frameBuffers[1].height, frameBuffers[1].psm, 0, 0); + graph_initialize(frameBuffers[0].address, frameBuffers[0].width, frameBuffers[0].height, frameBuffers[0].psm, 0, 0); } /// --- Draw: PATH3 diff --git a/src/engine/modules/vif_sender.cpp b/src/engine/modules/vif_sender.cpp index 2b7f20c..b318a37 100644 --- a/src/engine/modules/vif_sender.cpp +++ b/src/engine/modules/vif_sender.cpp @@ -17,8 +17,8 @@ #include "../include/utils/debug.hpp" const u32 VU1_PACKAGE_VERTS_PER_BUFF = 96; // Remember to modify buffer size in vu1 also -const u32 VU1_PACKAGES_PER_PACKET = 6; -const u32 VU1_PACKET_SIZE = 128; +const u32 VU1_PACKAGES_PER_PACKET = 9; +const u32 VU1_PACKET_SIZE = 256; // should be 128, but 256 is more safe for future // ---- // Constructors/Destructors From d60d42cac6c156dcf2a6d0c3436df86a685dedbd Mon Sep 17 00:00:00 2001 From: h4570 Date: Thu, 24 Dec 2020 13:09:13 +0100 Subject: [PATCH 2/3] removed unecessary include --- src/engine/modules/vif_sender.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/modules/vif_sender.cpp b/src/engine/modules/vif_sender.cpp index b318a37..647650c 100644 --- a/src/engine/modules/vif_sender.cpp +++ b/src/engine/modules/vif_sender.cpp @@ -68,7 +68,7 @@ void VifSender::uploadMicroProgram() dma_channel_send_packet2(packet2, DMA_CHANNEL_VIF1, 1); packet2_free(packet2); } -#include + void VifSender::sendMatrices(const RenderData &t_renderData, const Vector3 &t_position, const Vector3 &t_rotation) { From aeb25ad398c2978fdcc80eb5176db0e699ef98b5 Mon Sep 17 00:00:00 2001 From: h4570 Date: Thu, 24 Dec 2020 14:35:13 +0100 Subject: [PATCH 3/3] new vu1 renderer, added vcl preprocessor --- src/engine/Makefile | 6 +- src/engine/Makefile.pref | 1 + src/engine/include/modules/vif_sender.hpp | 3 +- src/engine/modules/renderer.cpp | 2 +- src/engine/modules/vif_sender.cpp | 75 ++--------- src/engine/vu1_progs/draw3D.vcl | 154 ---------------------- src/engine/vu1_progs/draw3D.vclpp | 143 ++++++++++++++++++++ src/engine/vu1_progs/draw3D.vsm | 110 +++++++++------- src/engine/vu1_progs/geometry.inc | 7 + src/engine/vu1_progs/matrix.inc | 13 ++ src/engine/vu1_progs/vector.inc | 27 ++++ 11 files changed, 273 insertions(+), 268 deletions(-) delete mode 100644 src/engine/vu1_progs/draw3D.vcl create mode 100644 src/engine/vu1_progs/draw3D.vclpp create mode 100644 src/engine/vu1_progs/geometry.inc create mode 100644 src/engine/vu1_progs/matrix.inc create mode 100644 src/engine/vu1_progs/vector.inc diff --git a/src/engine/Makefile b/src/engine/Makefile index 78c621f..949c572 100644 --- a/src/engine/Makefile +++ b/src/engine/Makefile @@ -35,8 +35,10 @@ all: $(EE_OBJS) ar rcs $(LIB_NAME) $(EE_OBJS) rm -f $(EE_OBJS) -# https://github.com/microsoft/wsl/issues/2468#issuecomment-374904520 -#%.vsm: %.vcl # sudo service binfmt-support start +#%.vcl: %.vclpp +# $(EE_VCLPP) $< $@ + +#%.vsm: %.vcl # $(EE_VCL) $< >> $@ %.o: %.vsm diff --git a/src/engine/Makefile.pref b/src/engine/Makefile.pref index 389166e..574715b 100644 --- a/src/engine/Makefile.pref +++ b/src/engine/Makefile.pref @@ -5,6 +5,7 @@ EE_CFLAGS := -DHAVE_LIBPNG -DHAVE_ZLIB $(EE_CFLAGS) EE_CXXFLAGS := -DHAVE_LIBPNG -DHAVE_ZLIB $(EE_CXXFLAGS) EE_DVP = dvp-as EE_VCL = vcl +EE_VCLPP = vclpp LIB_NAME = libtyra.a include $(PS2SDK)/samples/Makefile.pref diff --git a/src/engine/include/modules/vif_sender.hpp b/src/engine/include/modules/vif_sender.hpp index 53153c5..43c2d7e 100644 --- a/src/engine/include/modules/vif_sender.hpp +++ b/src/engine/include/modules/vif_sender.hpp @@ -30,7 +30,7 @@ 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 sendMatrices(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); private: Light *light; @@ -50,7 +50,6 @@ private: */ Matrix modelViewProj; u8 context; - packet2_t *matricesPacket __attribute__((aligned(64))); VECTOR position, rotation; u32 vertCount; }; diff --git a/src/engine/modules/renderer.cpp b/src/engine/modules/renderer.cpp index 2287b88..425fb0d 100644 --- a/src/engine/modules/renderer.cpp +++ b/src/engine/modules/renderer.cpp @@ -277,7 +277,7 @@ void Renderer::draw(Mesh *t_meshes, u16 t_amount, LightBulb *t_bulbs, u16 t_bulb void Renderer::draw(Mesh &t_mesh, LightBulb *t_bulbs, u16 t_bulbsCount) { beginFrameIfNeeded(); - vifSender->sendMatrices(renderData, t_mesh.position, t_mesh.rotation); + vifSender->calcMatrix(renderData, t_mesh.position, t_mesh.rotation); if (!t_mesh.isDataLoaded()) PRINT_ERR("Can't draw, because no mesh data was loaded!"); diff --git a/src/engine/modules/vif_sender.cpp b/src/engine/modules/vif_sender.cpp index 647650c..78dd0ce 100644 --- a/src/engine/modules/vif_sender.cpp +++ b/src/engine/modules/vif_sender.cpp @@ -39,7 +39,6 @@ VifSender::VifSender(Light *t_light) 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); - matricesPacket = packet2_create(4, P2_TYPE_NORMAL, P2_MODE_CHAIN, true); context = 0; setDoubleBuffer(); } @@ -48,7 +47,6 @@ VifSender::~VifSender() { packet2_free(packets[0]); packet2_free(packets[1]); - packet2_free(matricesPacket); } // ---- @@ -69,10 +67,8 @@ void VifSender::uploadMicroProgram() packet2_free(packet2); } -void VifSender::sendMatrices(const RenderData &t_renderData, const Vector3 &t_position, const Vector3 &t_rotation) +void VifSender::calcMatrix(const RenderData &t_renderData, const Vector3 &t_position, const Vector3 &t_rotation) { - - Matrix model; model.identity(); model.rotate(t_rotation); model.translate(t_position); @@ -81,12 +77,6 @@ void VifSender::sendMatrices(const RenderData &t_renderData, const Vector3 &t_po modelViewProj = model * modelViewProj; modelViewProj = *t_renderData.view * modelViewProj; modelViewProj = *t_renderData.projection * modelViewProj; - - packet2_reset(matricesPacket, false); - packet2_utils_vu_add_unpack_data(matricesPacket, 0, &modelViewProj.data, 8, 0); - packet2_utils_vu_add_end_tag(matricesPacket); - dma_channel_wait(DMA_CHANNEL_VIF1, 0); - dma_channel_send_packet2(matricesPacket, DMA_CHANNEL_VIF1, 1); } void VifSender::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) @@ -122,9 +112,9 @@ void VifSender::drawMesh(RenderData *t_renderData, Matrix t_perspective, u32 ver void VifSender::setDoubleBuffer() { packet2_t *settings = packet2_create(2, P2_TYPE_NORMAL, P2_MODE_CHAIN, true); - packet2_utils_vu_add_double_buffer(settings, 8, 496); + packet2_utils_vu_add_double_buffer(settings, 10, 498); packet2_utils_vu_add_end_tag(settings); - dma_channel_send_packet2(settings, DMA_CHANNEL_VIF1, 1); + dma_channel_send_packet2(settings, DMA_CHANNEL_VIF1, true); dma_channel_wait(DMA_CHANNEL_VIF1, 0); packet2_free(settings); } @@ -134,67 +124,24 @@ void VifSender::drawVertices(Mesh &t_mesh, u32 t_start, u32 t_end, VECTOR *t_ver { const u32 vertCount = t_end - t_start; u32 vif_added_bytes = 0; - packet2_utils_vu_open_unpack(currPacket, 0, 1); - // TODO get this via screensettings - packet2_add_float(currPacket, 2048.0F); // scale - packet2_add_float(currPacket, 2048.0F); // scale - packet2_add_float(currPacket, ((float)0xFFFFFF) / 32.0F); // scale - packet2_add_u32(currPacket, vertCount); // vertex count + 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, 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_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); - - // Clipping tests start - - // // const float minZ = 1; - // // const float maxZ = 65535; - // // const int iGuardDimXY = 2048; - - // // vu1.addFloat(1.0F); // f_TODO clipping maybe there is problem? - // // vu1.addFloat(1.0F); - // // vu1.addFloat(1.0F); - // // vu1.addFloat(1.0F); - // // float xClip = (float)2048.0f/(drawContext.GetFBWidth() * 0.5f * 2.0f); - // // packet += Math::Max( xClip, 1.0f ); - // // float yClip = (float)2048.0f/(drawContext.GetFBHeight() * 0.5f * 2.0f); - // // packet += Math::Max( yClip, 1.0f ); - // // float depthClip = 2048.0f / depthClipToGs; - // // // F_FIXME: maybe these 2048's should be 2047.5s... - // // depthClip *= 1.003f; // round up a bit for fp error (????) - // // packet += depthClip; - // // // enable/disable clipping - // // packet += (drawContext.GetDoClipping()) ? 1 : 0; - - // u32 depthBits = 24; // or 28(fog) or 16 - // float depthClipToGs = (float)((1 << depthBits) - 1) / 2.0f; - // vu1.addFloat(2048.0f / (640.0F * 0.5f * 2.0f)); - // vu1.addFloat(2048.0f / (480.0F * 0.5f * 2.0f)); - // vu1.addFloat((2048.0f / depthClipToGs) * 1.003F); - // // vu1.addFloat(2048.0F); // scale - // // vu1.addFloat(2048.0F); // scale - // // vu1.addFloat(((float)0xFFFFFF) / 32.0F); // scale - // vu1.addFloat(0.0F); - // // vu1.addFloat(0.5f * iGuardDimXY); - // // vu1.addFloat(-0.5f * iGuardDimXY); - // // vu1.addFloat(1.0F); - // // vu1.addFloat(500.0F); // far - - packet2_add_float(currPacket, 0.0F); - packet2_add_float(currPacket, 0.0F); - packet2_add_float(currPacket, 0.0F); - packet2_add_float(currPacket, 0.0F); - - //// Clipping tests end vif_added_bytes += packet2_utils_vu_close_unpack(currPacket); - packet2_utils_vu_add_unpack_data(currPacket, vif_added_bytes, t_vertices + t_start, vertCount, 1); + 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, 1); + 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); } diff --git a/src/engine/vu1_progs/draw3D.vcl b/src/engine/vu1_progs/draw3D.vcl deleted file mode 100644 index 777d84f..0000000 --- a/src/engine/vu1_progs/draw3D.vcl +++ /dev/null @@ -1,154 +0,0 @@ -; ______ ____ ___ -; | \/ ____| |___| -; | | | \ | | -;--------------------------- -; Copyright 2020, tyra - https://github.com/h4570/tyra -; Sandro Sobczyński -; -;--------------------------------------------------------------- -; draw3D.vcl | -;--------------------------------------------------------------- -; A VU1 microprogram to draw 3D object using XYZ2, RGBAQ and ST| -; This program uses double buffering (xtop) | -; | -; Many thanks to: | -; - Dr Henry Fortuna | -; - Jesper Svennevid, Daniel Collin | -; - Guilherme Lampert | -;--------------------------------------------------------------- - -; TODO -; - Fix vertex clipping (is clipping visible triangles :/) -; - Move lerp() from EE to VU1 (performance) -; - Add dynamic lighting (feature) -; - Add --cont + MSCNT instead of alltime MSCAL (performance) - -.syntax new -.name VU1Draw3D -.vu -.init_vf_all -.init_vi_all - ---enter ---endenter - - ;//////////// --- Load data 1 --- ///////////// - ; Updated once per frame - lq matrixRow0, 0(vi00) ; load view-projection matrix - lq matrixRow1, 1(vi00) - lq matrixRow2, 2(vi00) - lq matrixRow3, 3(vi00) - ;///////////////////////////////////////////// - - fcset 0x000000 ; VCL won't let us use CLIP without first zeroing - ; the clip flags - - ;//////////// --- Load data 2 --- ///////////// - ; Updated dynamically - xtop iBase - - lq.xyz scale, 0(iBase) ; load program params - ; float : X, Y, Z - scale vector that we will use to scale the verts after projecting them. - ; float : W - vert count. - lq gifSetTag, 1(iBase) ; GIF tag - set - lq texGifTag1, 2(iBase) ; GIF tag - texture LOD - lq texGifTag2, 3(iBase) ; GIF tag - texture buffer & CLUT - lq primTag, 4(iBase) ; GIF tag - tell GS how many data we will send - lq rgba, 5(iBase) ; RGBA - ;lq clipScale, 6(iBase) ; TODO clipping tests - ; u32 : R, G, B, A (0-128) - iaddiu vertexData, iBase, 7 ; pointer to vertex data - ilw.w vertCount, 0(iBase) ; load vert count from scale vector - iadd stqData, vertexData, vertCount ; pointer to stq - iadd kickAddress, stqData, vertCount ; pointer for XGKICK - iadd destAddress, stqData, vertCount ; helper pointer for data inserting - ;//////////////////////////////////////////// - - ;/////////// --- Store tags --- ///////////// - sqi gifSetTag, (destAddress++) ; - sqi texGifTag1, (destAddress++) ; texture LOD tag - sqi gifSetTag, (destAddress++) ; - sqi texGifTag2, (destAddress++) ; texture buffer & CLUT tag - sqi primTag, (destAddress++) ; prim + tell gs how many data will be - ;//////////////////////////////////////////// - - ;/////////////// --- Loop --- /////////////// - iadd vertexCounter, iBase, vertCount ; loop vertCount times - vertexLoop: - - ;////////// --- Load loop data --- ////////// - lq vertex, 0(vertexData) ; load xyz - ; float : X, Y, Z - ; any32 : _ = 0 - lq stq, 0(stqData) ; load stq - ; float : S, T - ; any32 : Q = 1 ; 1, because we will mul this by 1/vert[w] and this - ; will be our q for texture perspective correction - ; any32 : _ = 0 - ;//////////////////////////////////////////// - - - ;////////////// --- Vertex --- ////////////// - mul acc, matrixRow0, vertex[x] ; transform each vertex by the matrix - madd acc, matrixRow1, vertex[y] - madd acc, matrixRow2, vertex[z] - madd vertex, matrixRow3, vertex[w] - - ;add.z acc, vf0, clipScale[w] ; TODO clipping maybe this? - ;madd.z clipVec, clipScale, vertex - ;mul.xy clipVec, clipScale, vertex - ;mul.w clipVec, vf0, vertex[z] - - ;mul.xyz clipVec, vertex, clipScale ; TODO clipping maybe this? - - clipw.xyz vertex, vertex ; Dr. Fortuna: This instruction checks if the vertex is outside - ; the viewing frustum. If it is, then the appropriate - ; clipping flags are set - fcand VI01, 0x3FFFF ; Bitwise AND the clipping flags with 0x3FFFF, this makes - ; sure that we get the clipping judgement for the last three - ; verts (i.e. that make up the triangle we are about to draw) - iaddiu iADC, VI01, 0x7FFF ; Add 0x7FFF. If any of the clipping flags were set this will - ; cause the triangle not to be drawn (any values above 0x8000 - ; that are stored in the w component of XYZ2 will set the ADC - ; bit, which tells the GS not to perform a drawing kick on this - ; triangle. - - ;ilw.w iNoDraw, UVStart(Counter) ; Load the iNoDraw flag. If true we should set the ADC bit so the vert isn't drawn - ;iadd iADC, iADC, iNoDraw ; TODO clipping maybe this? - - isw.w iADC, 2(destAddress) - - div q, vf00[w], vertex[w] ; perspective divide (1/vert[w]): - mul.xyz vertex, vertex, q - mula.xyz acc, scale, vf00[w] ; scale to GS screen space - madd.xyz vertex, vertex, scale ; multiply and add the scales -> vert = vert * scale + scale - ftoi4.xyz vertex, vertex ; convert vertex to 12:4 fixed point format - ;//////////////////////////////////////////// - - - ;//////////////// --- ST --- //////////////// - mulq modStq, stq, q - ;//////////////////////////////////////////// - - - ;//////////// --- Store data --- //////////// - sq modStq, 0(destAddress) ; STQ - sq rgba, 1(destAddress) ; RGBA ; q is grabbed from stq - sq.xyz vertex, 2(destAddress) ; XYZ2 - ;//////////////////////////////////////////// - - iaddiu vertexData, vertexData, 1 - iaddiu stqData, stqData, 1 - iaddiu destAddress, destAddress, 3 - - iaddi vertexCounter, vertexCounter, -1 ; decrement the loop counter - ibne vertexCounter, iBase, vertexLoop ; and repeat if needed - - ;//////////////////////////////////////////// - - --barrier - - xgkick kickAddress ; dispatch to the GS rasterizer. - ---exit ---endexit diff --git a/src/engine/vu1_progs/draw3D.vclpp b/src/engine/vu1_progs/draw3D.vclpp new file mode 100644 index 0000000..f38fc42 --- /dev/null +++ b/src/engine/vu1_progs/draw3D.vclpp @@ -0,0 +1,143 @@ +; ______ ____ ___ +; | \/ ____| |___| +; | | | \ | | +;--------------------------- +; Copyright 2020, tyra - https://github.com/h4570/tyra +; Sandro Sobczyński +; +;--------------------------------------------------------------- +; draw3D.vcl | +;--------------------------------------------------------------- +; First tyra VU1 microprogram. | +; Features: | +; - Draw triangles (no strip) with STQ (textures) and 1 RGBA. | +; This program uses double buffering (xtop) | +; | +; I want to say thank you to: | +; - Dr Henry Fortuna - for teaching how things work | +; - Jesper Svennevid, Daniel Collin - for openvcl samples | +; - Guilherme Lampert - for VU1 idea for PS2 Quake and vclpp | +; - Tyler Daniel - for PS2GL source code for PS2 Linux | +;--------------------------------------------------------------- + +; TODO +; - Add dynamic lighting (feature) +; - Add --cont + MSCNT instead of alltime MSCAL + +#include "/repos/tyra/src/engine/vu1_progs/geometry.inc" +#include "/repos/tyra/src/engine/vu1_progs/matrix.inc" +#include "/repos/tyra/src/engine/vu1_progs/vector.inc" + +#vuprog draw3D + +.syntax new +.name VU1Draw3D +.vu +.init_vf_all +.init_vi_all + +--enter +--endenter + +xtop double_buffer + +;//////// LOAD CURRENT BUFFER DATA ////////// +MatrixLoad{ matrix, 0, double_buffer } +ilw.z triangles_count, 4(double_buffer) ; Triangles count +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 + +iaddiu vertex_data, double_buffer, 10 ; 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 +;//////////////////////////////////////////// + +LoadScaleConstant{ gs_scale } +fcset 0x000000 ; VCL won't let us use CLIP without first zeroing the clip flags + +;/////////////// STORE TAGS ///////////////// +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 +sqi prim_tag, (dest_address++) ; prim + tell gs how many data will be +;//////////////////////////////////////////// + +;//////// FIX ADC BIT FOR CLIPPING ////////// +iaddiu adc_bit, vi00, 0x7FFF +iaddiu adc_bit, adc_bit, 1 +;//////////////////////////////////////////// + +;/////////// START TRIANGLE LOOP //////////// +iaddiu triangle_counter, vi00, 0 ; Reset counter +triangle_loop: --LoopCS 1,3 + + ;//////////////// VERTEX 1 ////////////////// + VectorLoad{ vertex, vertex_data, 0 } + VectorLoad{ stq1, stq_data, 0 } + MatrixXForm{ xformed_vertex, matrix, vertex } + VectorClip{ gs_vertex, xformed_vertex } + VectorPerspectiveDivide{ xformed_vertex } + VectorAddGSScales{ gs_vertex, xformed_vertex, gs_scale } + VectorTexturePerspectiveCorrection{ pers_stq, stq1 } + VectorStore{ pers_stq, dest_address, 0 } + VectorStore{ rgba, dest_address, 1 } + VectorStore{ gs_vertex, dest_address, 2 } + ;//////////////////////////////////////////// + + ;//////////////// VERTEX 2 ////////////////// + VectorLoad{ vertex, vertex_data, 1 } + VectorLoad{ stq2, stq_data, 1 } + MatrixXForm{ xformed_vertex, matrix, vertex } + VectorClip{ gs_vertex, xformed_vertex } + VectorPerspectiveDivide{ xformed_vertex } + VectorAddGSScales{ gs_vertex, xformed_vertex, gs_scale } + VectorTexturePerspectiveCorrection{ pers_stq, stq2 } + VectorStore{ pers_stq, dest_address, 3 } + VectorStore{ rgba, dest_address, 4 } + VectorStore{ gs_vertex, dest_address, 5 } + ;//////////////////////////////////////////// + + ;//////////////// VERTEX 3 ////////////////// + VectorLoad{ vertex, vertex_data, 2 } + VectorLoad{ stq3, stq_data, 2 } + MatrixXForm{ xformed_vertex, matrix, vertex } + VectorClip{ gs_vertex, xformed_vertex } + VectorPerspectiveDivide{ xformed_vertex } + VectorAddGSScales{ gs_vertex, xformed_vertex, gs_scale } + VectorTexturePerspectiveCorrection{ pers_stq, stq3 } + VectorStore{ pers_stq, dest_address, 6 } + VectorStore{ rgba, dest_address, 7 } + + fcand vi01, 0x03FFFF + iaddiu new_adc_bit, vi01, 0x7FFF + mfir.w gs_vertex, new_adc_bit + VectorStore{ gs_vertex, dest_address, 8 } + ;//////////////////////////////////////////// + + ;////////////// LOOP CONTROL //////////////// + iaddiu vertex_data, vertex_data, 3 + iaddiu stq_data, stq_data, 3 + iaddiu dest_address, dest_address, 9 + + iaddiu triangle_counter, triangle_counter, 1 // Incrementing this + // by other value than 1 is causing HUGE problems, but.. why? + // My first idea was do vertex_counter and incrementing by 3 + ibne triangle_counter, triangles_count, triangle_loop + ;//////////////////////////////////////////// + +;//////////////////////////////////////////// + +--barrier + +xgkick kick_address ; dispatch to the GS rasterizer. + +--exit +--endexit + +#endvuprog \ No newline at end of file diff --git a/src/engine/vu1_progs/draw3D.vsm b/src/engine/vu1_progs/draw3D.vsm index f8c1e0e..f557b72 100644 --- a/src/engine/vu1_progs/draw3D.vsm +++ b/src/engine/vu1_progs/draw3D.vsm @@ -11,63 +11,83 @@ .global VU1Draw3D_CodeEnd VU1Draw3D_CodeStart: __v_draw3D_vcl_4: -; _LNOPT_w=[ normal2 ] 23 [23 0] 23 [__v_draw3D_vcl_4] - NOP lq VF01,0(VI00) - NOP xtop VI02 - NOP lq VF02,1(VI00) - NOP lq VF06,1(VI02) - NOP lq VF09,2(VI02) - NOP lq VF08,3(VI02) - NOP lq VF07,4(VI02) - NOP lq VF03,2(VI00) - NOP iaddiu VI03,VI02,0x00000007 - NOP ilw.w VI07,0(VI02) - NOP lq VF04,3(VI00) - NOP fcset 0 - NOP lq.xyz VF05,0(VI02) - NOP iadd VI04,VI03,VI07 - NOP iadd VI06,VI04,VI07 - NOP sqi VF06,(VI06++) +; _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 + NOP loi 0x44fff000 + NOP lq VF04,3(VI07) + NOP ilw.z VI02,4(VI07) + NOP sqi VF05,(VI06++) NOP sqi VF09,(VI06++) - NOP sqi VF06,(VI06++) + NOP sqi VF05,(VI06++) NOP sqi VF08,(VI06++) - NOP lq VF06,5(VI02) - NOP iadd VI05,VI04,VI07 + NOP lq VF05,9(VI07) + NOP iaddiu VI07,VI00,0x00007fff + NOP iadd VI05,VI04,VI05 + addi.xy VF06,VF00,I loi 0x492aaaaa + NOP fcset 0 NOP sqi VF07,(VI06++) - NOP iadd VI07,VI02,VI07 -vertexLoop: -; _LNOPT_w=[ normal2 ] 21 [31 14] 31 [vertexLoop] + 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 sq VF06,1(VI06) ; STALL_LATENCY ?3 - madday ACC,VF02,VF07y lq VF08,0(VI04) - maddaz ACC,VF03,VF07z iaddiu VI06,VI06,0x00000003 + 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 - clipw.xyz VF07xyz,VF07w div Q,VF00w,VF07w ; STALL_LATENCY ?3 - NOP NOP - NOP NOP - NOP NOP - NOP NOP - NOP NOP - NOP NOP - mulq.xyz VF07,VF07,Q fcand VI01,262143 - mulaw.xyz ACC,VF05,VF00w iaddiu VI03,VI03,0x00000001 - madd.xyz VF07,VF07,VF05 iaddiu VI04,VI04,0x00000001 ; STALL_LATENCY ?2 - mulq VF08,VF08,Q isubiu VI07,VI07,1 - ftoi4.xyz VF07,VF07 iaddiu VI01,VI01,0x00007fff ; STALL_LATENCY ?2 - NOP isw.w VI01,-1(VI06) - NOP sq VF08,-3(VI06) - NOP ibne VI07,VI02,vertexLoop - NOP sq.xyz VF07,-1(VI06) + 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] NOP xgkick VI05 NOP[E] NOP NOP NOP .align 4 VU1Draw3D_CodeEnd: -; iCount=47 +; iCount=67 ; register stats: -; 8 VU User integer -; 10 VU User floating point +; 9 VU User integer +; 12 VU User floating point ;------------------------- ;------------------------- ;------------------------- diff --git a/src/engine/vu1_progs/geometry.inc b/src/engine/vu1_progs/geometry.inc new file mode 100644 index 0000000..2562412 --- /dev/null +++ b/src/engine/vu1_progs/geometry.inc @@ -0,0 +1,7 @@ +; Load GS offsets to center xformed vertex in gs coord space and color clamping constant +#macro LoadScaleConstant: gs_scale + loi 2047.5 + addi.xy gs_scale, vf00, i + loi 699050.625000 // ((float)0xFFFFFF) / 24.0F + addi.z gs_scale, vf00, i +#endmacro diff --git a/src/engine/vu1_progs/matrix.inc b/src/engine/vu1_progs/matrix.inc new file mode 100644 index 0000000..47615e5 --- /dev/null +++ b/src/engine/vu1_progs/matrix.inc @@ -0,0 +1,13 @@ +#macro MatrixLoad: matrix, offset, vumem + lq matrix[0], offset+0(vumem) + lq matrix[1], offset+1(vumem) + lq matrix[2], offset+2(vumem) + lq matrix[3], offset+3(vumem) +#endmacro + +#macro MatrixXForm: output_vertex, matrix, input_vertex + mul acc, matrix[0], input_vertex[x] + madd acc, matrix[1], input_vertex[y] + madd acc, matrix[2], input_vertex[z] + madd output_vertex, matrix[3], input_vertex[w] +#endmacro diff --git a/src/engine/vu1_progs/vector.inc b/src/engine/vu1_progs/vector.inc new file mode 100644 index 0000000..c492916 --- /dev/null +++ b/src/engine/vu1_progs/vector.inc @@ -0,0 +1,27 @@ +#macro VectorPerspectiveDivide: vertex + div q, vf00[w], vertex[w] + mulq.xyz vertex, vertex, q +#endmacro + +#macro VectorAddGSScales: output_vertex, input_vertex, gs_scale + mula.xyz acc, gs_scale, vf00[w] + madd.xyz output_vertex, input_vertex, gs_scale + ftoi4.xyz output_vertex, output_vertex +#endmacro + +#macro VectorTexturePerspectiveCorrection: output_vertex, input_vertex + mulq output_vertex, input_vertex, q +#endmacro + +#macro VectorStore: vertex, vumem, num + sq vertex, num(vumem) +#endmacro + +#macro VectorClip: output_vertex, input_vertex + clipw.xyz input_vertex, input_vertex + mfir.w output_vertex, adc_bit +#endmacro + +#macro VectorLoad: output_vertex, vumem, offset + lq output_vertex, offset(vumem) +#endmacro