From 91ba265310d38c74c8d472b71ce32eaa41421cb7 Mon Sep 17 00:00:00 2001 From: h4570 Date: Sat, 23 Jul 2022 20:25:08 +0200 Subject: [PATCH] dynpip vu1 programs --- ROADMAP.txt | 4 +- .../renderer/3d/mesh/dynamic/dynamic_mesh.hpp | 10 +- .../3d/pipeline/shared/pipeline_options.hpp | 2 +- .../pipeline/dynamic/core/dynpip_renderer.cpp | 21 ++-- .../dynamic/core/programs/dynpip_c_vu1.vclpp | 93 +++++++++++++- .../core/programs/dynpip_c_vu1_program.cpp | 18 ++- .../dynamic/core/programs/dynpip_d_vu1.vclpp | 117 +++++++++++++++++- .../core/programs/dynpip_d_vu1_program.cpp | 32 ++--- .../dynamic/core/programs/dynpip_tc_vu1.vclpp | 116 ++++++++++++++++- .../core/programs/dynpip_tc_vu1_program.cpp | 32 ++--- .../dynamic/core/programs/dynpip_td_vu1.vclpp | 17 +-- .../3d/pipeline/dynamic/dynamic_pipeline.cpp | 54 ++++---- samples/h4570/inc/h4570.hpp | 5 +- samples/h4570/src/h4570.cpp | 105 +++++----------- 14 files changed, 448 insertions(+), 178 deletions(-) diff --git a/ROADMAP.txt b/ROADMAP.txt index e569046..631fbf6 100644 --- a/ROADMAP.txt +++ b/ROADMAP.txt @@ -2,11 +2,13 @@ --- H4570 - [DynPip] TD VU1 program -- [DynPip] C++ pipeline - [DynPip] Info about: simple clip - [StaPip] Remove animation - [StaPip] Dbufferring during mesh unrolling +- [StaPip] VU1 packets spamming +- [McPip] VU1 packets spamming - [StaPip] Info about: full plane clip +- [Renderer] Github: Allocate dynamic pipeline memory only in "onUse" (core,qbuffrenderer,pipeline..) - [Game] Update intellisense from docker - [Renderer] Add possibility to on/off frustum check in all pipelines (renderOptions?) - [Loaders] Think about ".tyrobj" format - implement it (add multicolor support) diff --git a/engine/inc/renderer/3d/mesh/dynamic/dynamic_mesh.hpp b/engine/inc/renderer/3d/mesh/dynamic/dynamic_mesh.hpp index 42fb100..d8f47d4 100644 --- a/engine/inc/renderer/3d/mesh/dynamic/dynamic_mesh.hpp +++ b/engine/inc/renderer/3d/mesh/dynamic/dynamic_mesh.hpp @@ -35,15 +35,17 @@ class DynamicMesh : public Mesh { const u32& getFramesCount() const { return framesCount; } const u32& getCurrentAnimationFrame() const { return animState.currentFrame; } - const u32& getNextAnimationFrame() const { return animState.nextFrame; } - const u32& getStartAnimationFrame() const { return animState.startFrame; } - const u32& getEndAnimationFrame() const { return animState.endFrame; } - const u32& getStayAnimationFrame() const { return animState.stayFrame; } + void setCurrentAnimationFrame(const u32& v) { animState.currentFrame = v; } + void setNextAnimationFrame(const u32& v) { animState.nextFrame = v; } + void setStartAnimationFrame(const u32& v) { animState.startFrame = v; } + void setEndAnimationFrame(const u32& v) { animState.endFrame = v; } + void setStayAnimationFrame(const u32& v) { animState.stayFrame = v; } + /** @returns bounding box object of current frame. */ const BBox& getCurrentBoundingBox() const { return frames[animState.currentFrame]->getBBox(); diff --git a/engine/inc/renderer/3d/pipeline/shared/pipeline_options.hpp b/engine/inc/renderer/3d/pipeline/shared/pipeline_options.hpp index 000ccdd..ced7f37 100644 --- a/engine/inc/renderer/3d/pipeline/shared/pipeline_options.hpp +++ b/engine/inc/renderer/3d/pipeline/shared/pipeline_options.hpp @@ -17,7 +17,7 @@ namespace Tyra { class PipelineOptions { public: - PipelineOptions() {} + PipelineOptions() { lighting = nullptr; } ~PipelineOptions() {} PipelineShadingType shadingType; diff --git a/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_renderer.cpp b/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_renderer.cpp index daa4976..2ddc43f 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_renderer.cpp +++ b/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_renderer.cpp @@ -146,31 +146,28 @@ void DynPipRenderer::addBufferDataToPacket(DynPipVU1Program* program, DynPipBag** bags, const u32& count) { currentPacket = packets[context]; packet2_reset(currentPacket, false); - u32 sent = 0; for (u32 i = 0; i < count; i++) { if (bags[i]->count <= 0) continue; + program->addBufferDataToPacket(currentPacket, bags[i], &rendererCore->gs.prim); - sent++; + + if (lastProgramName != program->getName()) { + packet2_utils_vu_add_start_program(currentPacket, + program->getDestinationAddress()); + lastProgramName = program->getName(); + } else { + packet2_utils_vu_add_continue_program(currentPacket); + } } - if (sent == 0) return; - - if (lastProgramName != program->getName()) { - packet2_utils_vu_add_start_program(currentPacket, - program->getDestinationAddress()); - lastProgramName = program->getName(); - } else { - packet2_utils_vu_add_continue_program(currentPacket); - } packet2_utils_vu_add_end_tag(currentPacket); } void DynPipRenderer::sendPacket() { dma_channel_wait(DMA_CHANNEL_VIF1, 0); dma_channel_send_packet2(currentPacket, DMA_CHANNEL_VIF1, true); - // Switch packet, so we can proceed during DMA transfer context = !context; } diff --git a/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_c_vu1.vclpp b/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_c_vu1.vclpp index 0d3cec6..273ea2e 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_c_vu1.vclpp +++ b/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_c_vu1.vclpp @@ -10,7 +10,7 @@ ; Triangle list ; Cull = Standard PS2 way. clipw polys are culled. ; Animation -; Colors +; Color ;--------------------------------------------------------------- .syntax new @@ -31,8 +31,99 @@ #vuprog DynPipVU1C + ResetClipFlags{ } + LoadTyraStaticData{ gifSetTag } + MatrixLoad{ mvp, VU1_MVP_MATRIX_ADDR, vi00 } + LoadTyraSingleColor{ singleColor, singleColorEnabled, VU1_SINGLE_COLOR_ADDR, VU1_OPTIONS_ADDR } + LoadTyraTags{ lodGifTag, texBufferClutGifTag, VU1_LOD_ADDR, VU1_CLUT_ADDR } + FixColor{ singleColor } + +begin: + xtop buffer + LoadTyraPrimTag{ primTag, buffer } + + ilw.w vertexCount, 0(buffer) + iaddiu vertexDataFrom, buffer, VU1_VERT_DATA_ADDR + + iadd kickAddress, vertexDataFrom, vertexCount + iadd destAddress, kickAddress, vertexCount + iadd kickAddress, kickAddress, vertexCount + + StoreTyraGifTags{ gifSetTag, lodGifTag, texBufferClutGifTag, primTag, destAddress } + LoadTyraLerpValue{ interp, VU1_OPTIONS_ADDR } + LoadTyraScaleValue{ scale, buffer } + + ;--- Loop + iadd vertexCounter, buffer, vertexCount +vertexLoop: + + iadd vertexDataTo, vertexDataFrom, vertexCount + + ;--- Vertex 1 - from-to -> lerp + lq vertex1From, (vertexDataFrom) + lq vertex1To, (vertexDataTo) + Lerp{ vertex1, vertex1From, vertex1To, interp } + + ;--- Vertex 1 - Calculate + MatrixMultiplyVertex{ vertex1, mvp, vertex1 } + PerformClipCheck{ vertex1, destAddress, XYZ2_STORE_OFFSET } + VertexPersCorr{ vertex1, vertex1 } + ScaleVertexToGSFormat{ scale, vertex1 } + + ;--- Vertex 1 - Store + sq singleColor, RGBA_STORE_OFFSET(destAddress) + sq.xyz vertex1, XYZ2_STORE_OFFSET(destAddress) + + ; --------------------------------------- + + ;--- Vertex 2 - from-to -> lerp + lq vertex2From, 1(vertexDataFrom) + lq vertex2To, 1(vertexDataTo) + Lerp{ vertex2, vertex2From, vertex2To, interp } + + ;--- Vertex 2 - Calculate + MatrixMultiplyVertex{ vertex2, mvp, vertex2 } + PerformClipCheck{ vertex2, destAddress, XYZ2_STORE_OFFSET+2 } + VertexPersCorr{ vertex2, vertex2 } + ScaleVertexToGSFormat{ scale, vertex2 } + + ;--- Vertex 2 - Store + sq singleColor, RGBA_STORE_OFFSET+2(destAddress) + sq.xyz vertex2, XYZ2_STORE_OFFSET+2(destAddress) + + ; --------------------------------------- + + ;--- Vertex 3 - from-to -> lerp + lq vertex3From, 2(vertexDataFrom) + lq vertex3To, 2(vertexDataTo) + Lerp{ vertex3, vertex3From, vertex3To, interp } + + ;--- Vertex 3 - Calculate + MatrixMultiplyVertex{ vertex3, mvp, vertex3 } + PerformClipCheck{ vertex3, destAddress, XYZ2_STORE_OFFSET+4 } + VertexPersCorr{ vertex3, vertex3 } + ScaleVertexToGSFormat{ scale, vertex3 } + + ;--- Vertex 3 - Store + sq singleColor, RGBA_STORE_OFFSET+4(destAddress) + sq.xyz vertex3, XYZ2_STORE_OFFSET+4(destAddress) + + ;------------------------------- + + iaddiu vertexDataFrom, vertexDataFrom, 3 + iaddiu destAddress, destAddress, 6 + + ;--- Fix loop + iaddi vertexCounter, vertexCounter, -3 ; decrement the loop counter + ibne vertexCounter, buffer, vertexLoop ; and repeat if needed + + xgkick kickAddress ; dispatch to the GS rasterizer. + +--barrier ; Why the hell I must add barrier AFTER XGKICK? VCL does not adds E bit without it... --cont + b begin + #endvuprog --exit diff --git a/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_c_vu1_program.cpp b/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_c_vu1_program.cpp index 497efdc..986098e 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_c_vu1_program.cpp +++ b/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_c_vu1_program.cpp @@ -29,18 +29,14 @@ std::string DynPipCVU1Program::getStringName() const { void DynPipCVU1Program::addProgramQBufferDataToPacket(packet2_t* packet, DynPipBag* bag) const { - // u32 addr = VU1_VERT_DATA_ADDR; + u32 addr = VU1_VERT_DATA_ADDR; - // // Add vertices - // packet2_utils_vu_add_unpack_data(packet, addr, qbuffer->vertices, - // qbuffer->size, true); - - // // Add colors - // if (qbuffer->bag->color->single == nullptr) { - // addr += qbuffer->size; - // packet2_utils_vu_add_unpack_data(packet, addr, qbuffer->colors, - // qbuffer->size, true); - // } + // Add vertices + packet2_utils_vu_add_unpack_data(packet, addr, bag->verticesFrom, bag->count, + true); + addr += bag->count; + packet2_utils_vu_add_unpack_data(packet, addr, bag->verticesTo, bag->count, + true); } } // namespace Tyra diff --git a/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_d_vu1.vclpp b/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_d_vu1.vclpp index b5f6e8b..d7ab38f 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_d_vu1.vclpp +++ b/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_d_vu1.vclpp @@ -31,7 +31,122 @@ #vuprog DynPipVU1D - --cont + ResetClipFlags{ } + LoadTyraStaticData{ gifSetTag } + MatrixLoad{ mvp, VU1_MVP_MATRIX_ADDR, vi00 } + LoadTyraTags{ lodGifTag, texBufferClutGifTag, VU1_LOD_ADDR, VU1_CLUT_ADDR } + +begin: + xtop buffer + LoadTyraPrimTag{ primTag, buffer } + + ilw.w vertexCount, 0(buffer) + iaddiu vertexDataFrom, buffer, VU1_VERT_DATA_ADDR + + iadd normalDataFrom, vertexDataFrom, vertexCount + iadd normalDataFrom, normalDataFrom, vertexCount + + iadd kickAddress, normalDataFrom, vertexCount + iadd destAddress, kickAddress, vertexCount + iadd kickAddress, kickAddress, vertexCount + + StoreTyraGifTags{ gifSetTag, lodGifTag, texBufferClutGifTag, primTag, destAddress } + LoadTyraLerpValue{ interp, VU1_OPTIONS_ADDR } + LoadTyraScaleValue{ scale, buffer } + + ;--- Loop + iadd vertexCounter, buffer, vertexCount +vertexLoop: + + iadd vertexDataTo, vertexDataFrom, vertexCount + iadd normalDataTo, normalDataFrom, vertexCount + + ;--- Vertex 1 - from-to -> lerp + lq vertex1From, (vertexDataFrom) + lq vertex1To, (vertexDataTo) + Lerp{ vertex1, vertex1From, vertex1To, interp } + + lq.xyz normal1From, (normalDataFrom) + lq.xyz normal1To, (normalDataTo) + LerpXYZ{ normal1, normal1From, normal1To, interp } + + ;--- Vertex 1 - Calculate + MatrixMultiplyVertex{ vertex1, mvp, vertex1 } + PerformClipCheck{ vertex1, destAddress, XYZ2_STORE_OFFSET } + VertexPersCorr{ vertex1, vertex1 } + ScaleVertexToGSFormat{ scale, vertex1 } + LoadTyraDirectionalLights{ lightMatrix, lightDirections, lightColors, ambientColor, VU1_LIGHTS_DIRS_ADDR, VU1_LIGHTS_COLORS_ADDR, VU1_LIGHTS_MATRIX_ADDR } + CalculateTyraDirectionalLights{ outputColor1, normal1, lightDirections, lightColors, lightMatrix, ambientColor } + FixColor{ outputColor1 } + + ;--- Vertex 1 - Store + sq outputColor1, RGBA_STORE_OFFSET(destAddress) + sq.xyz vertex1, XYZ2_STORE_OFFSET(destAddress) + + ; --------------------------------------- + + ;--- Vertex 2 - from-to -> lerp + lq vertex2From, 1(vertexDataFrom) + lq vertex2To, 1(vertexDataTo) + Lerp{ vertex2, vertex2From, vertex2To, interp } + + lq.xyz normal2From, 1(normalDataFrom) + lq.xyz normal2To, 1(normalDataTo) + LerpXYZ{ normal2, normal2From, normal2To, interp } + + ;--- Vertex 2 - Calculate + MatrixMultiplyVertex{ vertex2, mvp, vertex2 } + PerformClipCheck{ vertex2, destAddress, XYZ2_STORE_OFFSET } + VertexPersCorr{ vertex2, vertex2 } + ScaleVertexToGSFormat{ scale, vertex2 } + LoadTyraDirectionalLights{ lightMatrix, lightDirections, lightColors, ambientColor, VU1_LIGHTS_DIRS_ADDR, VU1_LIGHTS_COLORS_ADDR, VU1_LIGHTS_MATRIX_ADDR } + CalculateTyraDirectionalLights{ outputColor2, normal2, lightDirections, lightColors, lightMatrix, ambientColor } + FixColor{ outputColor2 } + + ;--- Vertex 2 - Store + sq outputColor2, RGBA_STORE_OFFSET+2(destAddress) + sq.xyz vertex2, XYZ2_STORE_OFFSET+2(destAddress) + + ; --------------------------------------- + + ;--- Vertex 3 - from-to -> lerp + lq vertex3From, 2(vertexDataFrom) + lq vertex3To, 2(vertexDataTo) + Lerp{ vertex3, vertex3From, vertex3To, interp } + + lq.xyz normal3From, 2(normalDataFrom) + lq.xyz normal3To, 2(normalDataTo) + LerpXYZ{ normal3, normal3From, normal3To, interp } + + ;--- Vertex 3 - Calculate + MatrixMultiplyVertex{ vertex3, mvp, vertex3 } + PerformClipCheck{ vertex3, destAddress, XYZ2_STORE_OFFSET } + VertexPersCorr{ vertex3, vertex3 } + ScaleVertexToGSFormat{ scale, vertex3 } + LoadTyraDirectionalLights{ lightMatrix, lightDirections, lightColors, ambientColor, VU1_LIGHTS_DIRS_ADDR, VU1_LIGHTS_COLORS_ADDR, VU1_LIGHTS_MATRIX_ADDR } + CalculateTyraDirectionalLights{ outputColor3, normal3, lightDirections, lightColors, lightMatrix, ambientColor } + FixColor{ outputColor3 } + + ;--- Vertex 3 - Store + sq outputColor3, RGBA_STORE_OFFSET+4(destAddress) + sq.xyz vertex3, XYZ2_STORE_OFFSET+4(destAddress) + + ;------------------------------- + + iaddiu vertexDataFrom, vertexDataFrom, 3 + iaddiu normalDataFrom, normalDataFrom, 3 + iaddiu destAddress, destAddress, 6 + + ;--- Fix loop + iaddi vertexCounter, vertexCounter, -3 ; decrement the loop counter + ibne vertexCounter, buffer, vertexLoop ; and repeat if needed + + xgkick kickAddress ; dispatch to the GS rasterizer. + +--barrier ; Why the hell I must add barrier AFTER XGKICK? VCL does not adds E bit without it... +--cont + + b begin #endvuprog diff --git a/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_d_vu1_program.cpp b/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_d_vu1_program.cpp index 6bd8653..0be32ed 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_d_vu1_program.cpp +++ b/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_d_vu1_program.cpp @@ -29,23 +29,25 @@ std::string DynPipDVU1Program::getStringName() const { void DynPipDVU1Program::addProgramQBufferDataToPacket(packet2_t* packet, DynPipBag* bag) const { - // u32 addr = VU1_VERT_DATA_ADDR; + u32 addr = VU1_VERT_DATA_ADDR; - // // Add vertices - // packet2_utils_vu_add_unpack_data(packet, addr, qbuffer->vertices, - // qbuffer->size, true); - // addr += qbuffer->size; + // Add vertices + packet2_utils_vu_add_unpack_data(packet, addr, bag->verticesFrom, bag->count, + true); + addr += bag->count; + packet2_utils_vu_add_unpack_data(packet, addr, bag->verticesTo, bag->count, + true); + addr += bag->count; - // // Add normal - // packet2_utils_vu_add_unpack_data(packet, addr, qbuffer->normals, - // qbuffer->size, true); - - // // Add colors - // if (qbuffer->bag->color->single == nullptr) { - // addr += qbuffer->size; - // packet2_utils_vu_add_unpack_data(packet, addr, qbuffer->colors, - // qbuffer->size, true); - // } + if (bag->lighting) { + // Add normal + packet2_utils_vu_add_unpack_data(packet, addr, bag->lighting->normalsFrom, + bag->count, true); + addr += bag->count; + packet2_utils_vu_add_unpack_data(packet, addr, bag->lighting->normalsTo, + bag->count, true); + addr += bag->count; + } } } // namespace Tyra diff --git a/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_tc_vu1.vclpp b/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_tc_vu1.vclpp index cd13d85..3d4a361 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_tc_vu1.vclpp +++ b/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_tc_vu1.vclpp @@ -10,7 +10,7 @@ ; Triangle list ; Cull = Standard PS2 way. clipw polys are culled. ; Animation -; Lighting, texture, colors +; Lighting, texture, color ;--------------------------------------------------------------- .syntax new @@ -32,8 +32,122 @@ #vuprog DynPipVU1TC + ResetClipFlags{ } + LoadTyraStaticData{ gifSetTag } + MatrixLoad{ mvp, VU1_MVP_MATRIX_ADDR, vi00 } + LoadTyraSingleColor{ singleColor, singleColorEnabled, VU1_SINGLE_COLOR_ADDR, VU1_OPTIONS_ADDR } + LoadTyraTags{ lodGifTag, texBufferClutGifTag, VU1_LOD_ADDR, VU1_CLUT_ADDR } + FixColor{ singleColor } + +begin: + xtop buffer + LoadTyraPrimTag{ primTag, buffer } + + ilw.w vertexCount, 0(buffer) + iaddiu vertexDataFrom, buffer, VU1_VERT_DATA_ADDR + + iadd stqDataFrom, vertexDataFrom, vertexCount + iadd stqDataFrom, stqDataFrom, vertexCount + + iadd kickAddress, stqDataFrom, vertexCount + iadd destAddress, kickAddress, vertexCount + iadd kickAddress, kickAddress, vertexCount + + StoreTyraGifTags{ gifSetTag, lodGifTag, texBufferClutGifTag, primTag, destAddress } + LoadTyraLerpValue{ interp, VU1_OPTIONS_ADDR } + LoadTyraScaleValue{ scale, buffer } + + ;--- Loop + iadd vertexCounter, buffer, vertexCount +vertexLoop: + + iadd vertexDataTo, vertexDataFrom, vertexCount + iadd stqDataTo, stqDataFrom, vertexCount + + ;--- Vertex 1 - from-to -> lerp + lq vertex1From, (vertexDataFrom) + lq vertex1To, (vertexDataTo) + Lerp{ vertex1, vertex1From, vertex1To, interp } + + lq stq1From, (stqDataFrom) + lq stq1To, (stqDataTo) + Lerp{ stq1, stq1From, stq1To, interp } + + ;--- Vertex 1 - Calculate + MatrixMultiplyVertex{ vertex1, mvp, vertex1 } + PerformClipCheck{ vertex1, destAddress, XYZ2_STORE_OFFSET } + VertexPersCorr{ vertex1, vertex1 } + ScaleVertexToGSFormat{ scale, vertex1 } + PerformTexturePerspectiveCorrection{ outputStq1, stq1 } + + ;--- Vertex 1 - Store + sq outputStq1, STQ_STORE_OFFSET(destAddress) + sq singleColor, RGBA_STORE_OFFSET(destAddress) + sq.xyz vertex1, XYZ2_STORE_OFFSET(destAddress) + + ; --------------------------------------- + + ;--- Vertex 2 - from-to -> lerp + lq vertex2From, 1(vertexDataFrom) + lq vertex2To, 1(vertexDataTo) + Lerp{ vertex2, vertex2From, vertex2To, interp } + + lq stq2From, 1(stqDataFrom) + lq stq2To, 1(stqDataTo) + Lerp{ stq2, stq2From, stq2To, interp } + + ;--- Vertex 2 - Calculate + MatrixMultiplyVertex{ vertex2, mvp, vertex2 } + PerformClipCheck{ vertex2, destAddress, XYZ2_STORE_OFFSET+3 } + VertexPersCorr{ vertex2, vertex2 } + ScaleVertexToGSFormat{ scale, vertex2 } + PerformTexturePerspectiveCorrection{ outputStq2, stq2 } + + ;--- Vertex 2 - Store + sq outputStq2, STQ_STORE_OFFSET+3(destAddress) + sq singleColor, RGBA_STORE_OFFSET+3(destAddress) + sq.xyz vertex2, XYZ2_STORE_OFFSET+3(destAddress) + + ; --------------------------------------- + + ;--- Vertex 3 - from-to -> lerp + lq vertex3From, 2(vertexDataFrom) + lq vertex3To, 2(vertexDataTo) + Lerp{ vertex3, vertex3From, vertex3To, interp } + + lq stq3From, 2(stqDataFrom) + lq stq3To, 2(stqDataTo) + Lerp{ stq3, stq3From, stq3To, interp } + + ;--- Vertex 3 - Calculate + MatrixMultiplyVertex{ vertex3, mvp, vertex3 } + PerformClipCheck{ vertex3, destAddress, XYZ2_STORE_OFFSET+6 } + VertexPersCorr{ vertex3, vertex3 } + ScaleVertexToGSFormat{ scale, vertex3 } + PerformTexturePerspectiveCorrection{ outputStq3, stq3 } + + ;--- Vertex 3 - Store + sq outputStq3, STQ_STORE_OFFSET+6(destAddress) + sq singleColor, RGBA_STORE_OFFSET+6(destAddress) + sq.xyz vertex3, XYZ2_STORE_OFFSET+6(destAddress) + + ;------------------------------- + + iaddiu vertexDataFrom, vertexDataFrom, 3 + iaddiu stqDataFrom, stqDataFrom, 3 + iaddiu destAddress, destAddress, 9 + + ;--- Fix loop + iaddi vertexCounter, vertexCounter, -3 ; decrement the loop counter + ibne vertexCounter, buffer, vertexLoop ; and repeat if needed + + xgkick kickAddress ; dispatch to the GS rasterizer. + +--barrier ; Why the hell I must add barrier AFTER XGKICK? VCL does not adds E bit without it... --cont + b begin + #endvuprog --exit diff --git a/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_tc_vu1_program.cpp b/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_tc_vu1_program.cpp index 676fd6d..73572c0 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_tc_vu1_program.cpp +++ b/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_tc_vu1_program.cpp @@ -31,23 +31,25 @@ std::string DynPipTCVU1Program::getStringName() const { void DynPipTCVU1Program::addProgramQBufferDataToPacket(packet2_t* packet, DynPipBag* bag) const { - // u32 addr = VU1_VERT_DATA_ADDR; + u32 addr = VU1_VERT_DATA_ADDR; - // // Add vertices - // packet2_utils_vu_add_unpack_data(packet, addr, qbuffer->vertices, - // qbuffer->size, true); - // addr += qbuffer->size; + // Add vertices + packet2_utils_vu_add_unpack_data(packet, addr, bag->verticesFrom, bag->count, + true); + addr += bag->count; + packet2_utils_vu_add_unpack_data(packet, addr, bag->verticesTo, bag->count, + true); + addr += bag->count; - // // Add sts - // packet2_utils_vu_add_unpack_data(packet, addr, qbuffer->sts, qbuffer->size, - // true); - - // // Add colors - // if (qbuffer->bag->color->single == nullptr) { - // addr += qbuffer->size; - // packet2_utils_vu_add_unpack_data(packet, addr, qbuffer->colors, - // qbuffer->size, true); - // } + if (bag->texture) { + // Add sts + packet2_utils_vu_add_unpack_data( + packet, addr, bag->texture->coordinatesFrom, bag->count, true); + addr += bag->count; + packet2_utils_vu_add_unpack_data(packet, addr, bag->texture->coordinatesTo, + bag->count, true); + addr += bag->count; + } } } // namespace Tyra diff --git a/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_td_vu1.vclpp b/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_td_vu1.vclpp index dfb19d1..ec06ea3 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_td_vu1.vclpp +++ b/engine/src/renderer/3d/pipeline/dynamic/core/programs/dynpip_td_vu1.vclpp @@ -61,19 +61,21 @@ begin: ;--- Loop iadd vertexCounter, buffer, vertexCount vertexLoop: + + iadd vertexDataTo, vertexDataFrom, vertexCount + iadd stqDataTo, stqDataFrom, vertexCount + iadd normalDataTo, normalDataFrom, vertexCount + ;--- Vertex 1 - from-to -> lerp lq vertex1From, (vertexDataFrom) - iadd vertexDataTo, vertexDataFrom, vertexCount lq vertex1To, (vertexDataTo) Lerp{ vertex1, vertex1From, vertex1To, interp } lq stq1From, (stqDataFrom) - iadd stqDataTo, stqDataFrom, vertexCount lq stq1To, (stqDataTo) Lerp{ stq1, stq1From, stq1To, interp } - lq.xyz normal1From, (normalDataFrom) - iadd normalDataTo, normalDataFrom, vertexCount + lq.xyz normal1From, (normalDataFrom) lq.xyz normal1To, (normalDataTo) LerpXYZ{ normal1, normal1From, normal1To, interp } @@ -96,18 +98,14 @@ vertexLoop: ;--- Vertex 2 - from-to -> lerp lq vertex2From, 1(vertexDataFrom) - ; TODO: Move DataTo upper!!!!!!!!!!!!!! - iadd vertexDataTo, vertexDataFrom, vertexCount lq vertex2To, 1(vertexDataTo) Lerp{ vertex2, vertex2From, vertex2To, interp } lq stq2From, 1(stqDataFrom) - iadd stqDataTo, stqDataFrom, vertexCount lq stq2To, 1(stqDataTo) Lerp{ stq2, stq2From, stq2To, interp } lq.xyz normal2From, 1(normalDataFrom) - iadd normalDataTo, normalDataFrom, vertexCount lq.xyz normal2To, 1(normalDataTo) LerpXYZ{ normal2, normal2From, normal2To, interp } @@ -130,17 +128,14 @@ vertexLoop: ;--- Vertex 3 - from-to -> lerp lq vertex3From, 2(vertexDataFrom) - iadd vertexDataTo, vertexDataFrom, vertexCount lq vertex3To, 2(vertexDataTo) Lerp{ vertex3, vertex3From, vertex3To, interp } lq stq3From, 2(stqDataFrom) - iadd stqDataTo, stqDataFrom, vertexCount lq stq3To, 2(stqDataTo) Lerp{ stq3, stq3From, stq3To, interp } lq.xyz normal3From, 2(normalDataFrom) - iadd normalDataTo, normalDataFrom, vertexCount lq.xyz normal3To, 2(normalDataTo) LerpXYZ{ normal3, normal3From, normal3To, interp } diff --git a/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp b/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp index ce665cc..f2f81ba 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp +++ b/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp @@ -28,7 +28,8 @@ DynamicPipeline::~DynamicPipeline() { void DynamicPipeline::init(RendererCore* t_core) { rendererCore = t_core; - auto packetSize = buffersCount * 4.8F; + auto packetSize = + buffersCount * 5.1F; // 5.1 = packet2_get_qw_count / buffersCount core.init(t_core, static_cast(packetSize)); } @@ -107,12 +108,6 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) { sendRestOfBuffers(buffers, &bufferIndex, frustumCulling); - // TODO: Program renderujacy w VU1 - // TODO: Github: Ten sam myk zrobic w static pipeline - // TODO: Github: Ten sam myk zrobic w mc pipeline - // TODO: Github: Allocate dynamic pipeline memory only in "onUse" - // (core,qbuffrenderer,pipeline..) - if (dirLights) { delete dirLights; } @@ -123,23 +118,24 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) { void DynamicPipeline::setBuffer(DynPipBag* buffers, DynPipBag* buffer, u16* bufferIndex, const DynPipFrustumCulling& frustumCulling) { - // auto isHalf = *bufferIndex == halfBuffersCount - 1; - auto isFull = *bufferIndex == buffersCount - 1; + auto isEndOf1stDBuffer = *bufferIndex == halfBuffersCount - 1; + auto isEndOf2ndDBuffer = *bufferIndex == buffersCount - 1; - // if (isHalf || isFull) { - // u32 offset = isHalf ? 0 : halfBuffersCount; + if (isEndOf1stDBuffer || isEndOf2ndDBuffer) { + u32 offset = isEndOf1stDBuffer ? 0 : halfBuffersCount; - DynPipBag** sendBuffers = new DynPipBag*[1]; + DynPipBag** sendBuffers = new DynPipBag*[halfBuffersCount]; - sendBuffers[0] = buffer; + for (u32 i = 0; i < halfBuffersCount; i++) + sendBuffers[i] = &buffers[offset + i]; - core.renderPart(sendBuffers, 1, - frustumCulling == DynPipFrustumCulling_Precise); + core.renderPart(sendBuffers, halfBuffersCount, + frustumCulling == DynPipFrustumCulling_Precise); - delete[] sendBuffers; - // } + delete[] sendBuffers; + } - if (isFull) + if (isEndOf2ndDBuffer) *bufferIndex = 0; else *bufferIndex += 1; @@ -148,22 +144,22 @@ void DynamicPipeline::setBuffer(DynPipBag* buffers, DynPipBag* buffer, void DynamicPipeline::sendRestOfBuffers( DynPipBag* buffers, u16* bufferIndex, const DynPipFrustumCulling& frustumCulling) { - // auto isHalf = *bufferIndex == halfBuffersCount - 1; + auto isEndOf1stDBuffer = *bufferIndex <= halfBuffersCount - 1; - // u32 offset = isHalf ? 0 : halfBuffersCount; - // u32 size = *bufferIndex - offset; + u32 offset = isEndOf1stDBuffer ? 0 : halfBuffersCount; + u32 size = *bufferIndex - offset; - // if (size <= 0) return; + if (size <= 0) return; - // DynPipBag** sendBuffers = new DynPipBag*[size]; - // for (u32 i = 0; i < size; i++) { - // sendBuffers[i] = &buffers[offset + i]; - // } + DynPipBag** sendBuffers = new DynPipBag*[size]; + for (u32 i = 0; i < size; i++) { + sendBuffers[i] = &buffers[offset + i]; + } - // core.renderPart(sendBuffers, size, - // frustumCulling == DynPipFrustumCulling_Precise); + core.renderPart(sendBuffers, size, + frustumCulling == DynPipFrustumCulling_Precise); - // delete[] sendBuffers; + delete[] sendBuffers; } void DynamicPipeline::setBuffersDefaultVars(DynPipBag* buffers, diff --git a/samples/h4570/inc/h4570.hpp b/samples/h4570/inc/h4570.hpp index 6dc7d89..30bd4ab 100644 --- a/samples/h4570/inc/h4570.hpp +++ b/samples/h4570/inc/h4570.hpp @@ -30,9 +30,8 @@ class H4570 : public Game { Engine* engine; DynamicMesh* warrior; - DynamicMesh* warrior2; - DynamicMesh* warrior3; - DynamicMesh* warrior4; + u8 warriorsCount; + DynamicMesh** warriors; Sprite* picture; audsrv_adpcm_t* adpcmSample; Timer adpcmTimer; diff --git a/samples/h4570/src/h4570.cpp b/samples/h4570/src/h4570.cpp index bf40fb6..9584b78 100644 --- a/samples/h4570/src/h4570.cpp +++ b/samples/h4570/src/h4570.cpp @@ -11,9 +11,19 @@ #include "h4570.hpp" #include "file/file_utils.hpp" #include "loaders/3d/md2/md2_loader.hpp" +#include "thread/threading.hpp" namespace Tyra { +float getRandomFloat(float a, float b) { + float random = ((float)rand()) / (float)RAND_MAX; + float diff = b - a; + float r = random * diff; + return a + r; +} + +int getRandomInt(int a, int b) { return (rand() % (b - a + 1)) + a; } + H4570::H4570(Engine* t_engine) { engine = t_engine; } H4570::~H4570() {} @@ -39,23 +49,20 @@ void H4570::init() { warriorTex = engine->renderer.core.texture.repository.getBySpriteOrMesh( warrior->getMaterial(0)->getId()); - warrior2 = new DynamicMesh(*warrior); - warrior2->translation.translateX(-3.0F); - warriorTex->addLink(warrior2->getMaterial(0)->getId()); - warrior2->playAnimation(0, warrior2->getFramesCount() - 1); - warrior2->setAnimSpeed(0.10F); - - warrior3 = new DynamicMesh(*warrior); - warrior3->translation.translateX(-6.0F); - warriorTex->addLink(warrior3->getMaterial(0)->getId()); - warrior3->playAnimation(0, warrior3->getFramesCount() - 1); - warrior3->setAnimSpeed(0.7F); - - warrior4 = new DynamicMesh(*warrior); - warrior4->translation.translateX(3.0F); - warriorTex->addLink(warrior4->getMaterial(0)->getId()); - warrior4->playAnimation(0, warrior4->getFramesCount() - 1); - warrior4->setAnimSpeed(0.5F); + warriorsCount = 22; + warriors = new DynamicMesh*[warriorsCount]; + for (u8 i = 0; i < warriorsCount; i++) { + warriors[i] = new DynamicMesh(*warrior); + warriors[i]->translation.translateX(-40.0F + static_cast(i) * 4); + warriors[i]->translation.translateY(30.0F); + warriors[i]->translation.translateZ(-10.0F); + warriors[i]->translation.rotateX(-1.5F); + warriorTex->addLink(warriors[i]->getMaterial(0)->getId()); + warriors[i]->playAnimation(0, warriors[i]->getFramesCount() - 1); + warriors[i]->setCurrentAnimationFrame( + getRandomInt(0, warriors[i]->getFramesCount() - 1)); + warriors[i]->setAnimSpeed(getRandomFloat(0.1F, 0.9F)); + } staOptions = getStaPipOptions(); dynOptions = getDynPipOptions(); @@ -107,27 +114,8 @@ void H4570::init() { engine->renderer.setFrameLimit(false); } -u32 counter = 0; - void H4570::loop() { - if (counter++ > 100) { - counter = 0; - TYRA_LOG(engine->info.getFps()); - } - - warrior->animate(); - warrior2->animate(); - warrior3->animate(); - warrior4->animate(); - - // if ((engine->pad.getPressed().DpadUp || engine->pad.getPressed().DpadDown - // || - // engine->pad.getPressed().DpadLeft || - // engine->pad.getPressed().DpadRight) && - // adpcmTimer.getTimeDelta() > 8000) { - // adpcmTimer.prime(); - // engine->audio.playADPCM(adpcmSample, 1); - // } + for (u8 i = 0; i < warriorsCount; i++) warriors[i]->animate(); engine->renderer.beginFrame(CameraInfo3D(&cameraPosition, &cameraLookAt)); { @@ -139,44 +127,15 @@ void H4570::loop() { blocks[i].model = translations[i] * rotations[i] * scales[i]; } - // engine->renderer.renderer2D.render(picture); - - // engine->renderer.renderer3D.usePipeline(&stapip); - // { - // stapip.render(terrain, staOptions); - // } - engine->renderer.renderer3D.usePipeline(&dynpip); { - dynpip.render(warrior, dynOptions); - - // dynpip.render(warrior2, dynOptions); - // dynpip.render(warrior3, dynOptions); - // dynpip.render(warrior4, dynOptions); - - // dynpip.render(warrior2, dynOptions); - // dynpip.render(warrior2, dynOptions); - // dynpip.render(warrior2, dynOptions); - // dynpip.render(warrior2, dynOptions); - // dynpip.render(warrior2, dynOptions); - // dynpip.render(warrior2, dynOptions); - // dynpip.render(warrior2, dynOptions); - // dynpip.render(warrior2, dynOptions); - // dynpip.render(warrior2, dynOptions); - // dynpip.render(warrior2, dynOptions); - // dynpip.render(warrior2, dynOptions); - - // dynpip.render(warrior3, dynOptions); - // dynpip.render(warrior3, dynOptions); - // dynpip.render(warrior3, dynOptions); - // dynpip.render(warrior3, dynOptions); - // dynpip.render(warrior3, dynOptions); - // dynpip.render(warrior3, dynOptions); - // dynpip.render(warrior3, dynOptions); - // dynpip.render(warrior3, dynOptions); - // dynpip.render(warrior3, dynOptions); - // dynpip.render(warrior3, dynOptions); - // dynpip.render(warrior3, dynOptions); + Threading::switchThread(); + for (u8 i = 0; i < warriorsCount; i++) { + dynpip.render(warriors[i], dynOptions); + if (i == 5) Threading::switchThread(); + if (i == 10) Threading::switchThread(); + if (i == 15) Threading::switchThread(); + } } engine->renderer.renderer3D.usePipeline(&mcPip);