diff --git a/ROADMAP.txt b/ROADMAP.txt index 55b2d8c..e569046 100644 --- a/ROADMAP.txt +++ b/ROADMAP.txt @@ -7,6 +7,7 @@ - [StaPip] Remove animation - [StaPip] Dbufferring during mesh unrolling - [StaPip] Info about: full plane clip +- [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) - [Loaders] DFF loader as static Mesh loader diff --git a/engine/inc/renderer/3d/pipeline/dynamic/core/programs/dynpip_vu1_shared_defines.h b/engine/inc/renderer/3d/pipeline/dynamic/core/programs/dynpip_vu1_shared_defines.h index 3f19da4..712c07a 100644 --- a/engine/inc/renderer/3d/pipeline/dynamic/core/programs/dynpip_vu1_shared_defines.h +++ b/engine/inc/renderer/3d/pipeline/dynamic/core/programs/dynpip_vu1_shared_defines.h @@ -9,15 +9,15 @@ // // Updated once per mesh -// #define VU1_MVP_MATRIX_ADDR 0 -// #define VU1_LIGHTS_MATRIX_ADDR 4 -// #define VU1_SINGLE_COLOR_ADDR 7 -// #define VU1_OPTIONS_ADDR 8 -// #define VU1_LOD_ADDR 9 -// #define VU1_CLUT_ADDR 10 -// #define VU1_LIGHTS_DIRS_ADDR 11 -// #define VU1_LIGHTS_COLORS_ADDR 14 -// #define VU1_SET_GIFTAG_ADDR 18 +#define VU1_MVP_MATRIX_ADDR 0 +#define VU1_LIGHTS_MATRIX_ADDR 4 +#define VU1_SINGLE_COLOR_ADDR 7 +#define VU1_OPTIONS_ADDR 8 +#define VU1_LOD_ADDR 9 +#define VU1_CLUT_ADDR 10 +#define VU1_LIGHTS_DIRS_ADDR 11 +#define VU1_LIGHTS_COLORS_ADDR 14 +#define VU1_SET_GIFTAG_ADDR 18 #define VU1_LAST_ITEM_ADDR 18 // Buffer data (xtop) 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 e7ebad9..daa4976 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_renderer.cpp +++ b/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_renderer.cpp @@ -73,67 +73,65 @@ void DynPipRenderer::setProgramsCache() { } void DynPipRenderer::sendStaticData() const { - // packet2_reset(staticDataPacket, false); - // packet2_utils_vu_open_unpack(staticDataPacket, VU1_SET_GIFTAG_ADDR, - // false); { packet2_utils_gif_add_set(staticDataPacket, 1); } - // packet2_utils_vu_close_unpack(staticDataPacket); + packet2_reset(staticDataPacket, false); + packet2_utils_vu_open_unpack(staticDataPacket, VU1_SET_GIFTAG_ADDR, false); + { packet2_utils_gif_add_set(staticDataPacket, 1); } + packet2_utils_vu_close_unpack(staticDataPacket); - // packet2_utils_vu_add_end_tag(staticDataPacket); - // dma_channel_wait(DMA_CHANNEL_VIF1, 0); - // dma_channel_send_packet2(staticDataPacket, DMA_CHANNEL_VIF1, true); + packet2_utils_vu_add_end_tag(staticDataPacket); + dma_channel_wait(DMA_CHANNEL_VIF1, 0); + dma_channel_send_packet2(staticDataPacket, DMA_CHANNEL_VIF1, true); } void DynPipRenderer::sendObjectData( DynPipBag* bag, M4x4* mvp, RendererCoreTextureBuffers* texBuffers) const { - // packet2_reset(objectDataPacket, false); - // packet2_utils_vu_add_unpack_data(objectDataPacket, VU1_MVP_MATRIX_ADDR, - // mvp->data, 4, false); + packet2_reset(objectDataPacket, false); + packet2_utils_vu_add_unpack_data(objectDataPacket, VU1_MVP_MATRIX_ADDR, + mvp->data, 4, false); - // if (bag->lighting) { - // packet2_utils_vu_add_unpack_data(objectDataPacket, - // VU1_LIGHTS_MATRIX_ADDR, - // bag->lighting->lightMatrix, 3, false); + if (bag->lighting) { + packet2_utils_vu_add_unpack_data(objectDataPacket, VU1_LIGHTS_MATRIX_ADDR, + bag->lighting->lightMatrix, 3, false); - // packet2_utils_vu_add_unpack_data( - // objectDataPacket, VU1_LIGHTS_DIRS_ADDR, - // bag->lighting->dirLights->getLightDirections(), 3, false); + packet2_utils_vu_add_unpack_data( + objectDataPacket, VU1_LIGHTS_DIRS_ADDR, + bag->lighting->dirLights->getLightDirections(), 3, false); - // packet2_utils_vu_add_unpack_data(objectDataPacket, - // VU1_LIGHTS_COLORS_ADDR, - // bag->lighting->dirLights->getLightColors(), - // 4, false); - // } + packet2_utils_vu_add_unpack_data(objectDataPacket, VU1_LIGHTS_COLORS_ADDR, + bag->lighting->dirLights->getLightColors(), + 4, false); + } - // u8 singleColorEnabled = bag->color->single != nullptr; + u8 singleColorEnabled = bag->color->single != nullptr; - // if (singleColorEnabled) // Color is placed in 4th slot of - // // VU1_LIGHTS_MATRIX_ADDR - // packet2_utils_vu_add_unpack_data(objectDataPacket, - // VU1_SINGLE_COLOR_ADDR, - // bag->color->single->rgba, 1, false); + if (singleColorEnabled) // Color is placed in 4th slot of + // VU1_LIGHTS_MATRIX_ADDR + packet2_utils_vu_add_unpack_data(objectDataPacket, VU1_SINGLE_COLOR_ADDR, + bag->color->single->rgba, 1, false); - // packet2_utils_vu_open_unpack(objectDataPacket, VU1_OPTIONS_ADDR, false); - // { - // packet2_add_u32(objectDataPacket, - // singleColorEnabled); // Single color enabled. - // packet2_add_u32(objectDataPacket, 0); // not used, padding - // packet2_add_u32(objectDataPacket, 0); // not used, padding - // packet2_add_u32(objectDataPacket, 0); // not used, padding + packet2_utils_vu_open_unpack(objectDataPacket, VU1_OPTIONS_ADDR, false); + { + packet2_add_u32(objectDataPacket, + singleColorEnabled); // Single color enabled. + packet2_add_float(objectDataPacket, + bag->interpolation); // Interpolation value + packet2_add_u32(objectDataPacket, 0); // not used, padding + packet2_add_u32(objectDataPacket, 0); // not used, padding - // packet2_utils_gs_add_lod(objectDataPacket, &rendererCore->gs.lod); + packet2_utils_gs_add_lod(objectDataPacket, &rendererCore->gs.lod); - // if (texBuffers != nullptr) { - // packet2_utils_gs_add_texbuff_clut(objectDataPacket, texBuffers->core, - // &rendererCore->texture.clut); + if (texBuffers != nullptr) { + packet2_utils_gs_add_texbuff_clut(objectDataPacket, texBuffers->core, + &rendererCore->texture.clut); - // rendererCore->texture.updateClutBuffer(texBuffers->clut); - // } - // } - // packet2_utils_vu_close_unpack(objectDataPacket); + rendererCore->texture.updateClutBuffer(texBuffers->clut); + } + } + packet2_utils_vu_close_unpack(objectDataPacket); - // packet2_utils_vu_add_end_tag(objectDataPacket); - // dma_channel_wait(DMA_CHANNEL_VIF1, 0); - // dma_channel_send_packet2(objectDataPacket, DMA_CHANNEL_VIF1, true); + packet2_utils_vu_add_end_tag(objectDataPacket); + dma_channel_wait(DMA_CHANNEL_VIF1, 0); + dma_channel_send_packet2(objectDataPacket, DMA_CHANNEL_VIF1, true); } void DynPipRenderer::render(DynPipBag** bags, const u32& count) { diff --git a/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_vu1_program.cpp b/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_vu1_program.cpp index 50b8819..6e20408 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_vu1_program.cpp +++ b/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_vu1_program.cpp @@ -41,23 +41,23 @@ void DynPipVU1Program::addBufferDataToPacket(packet2_t* packet, DynPipBag* bag, void DynPipVU1Program::addStandardBufferDataToPacket(packet2_t* packet, DynPipBag* bag, prim_t* prim) { - // if (buffer->bag->texture) - // prim->mapping = 1; - // else - // prim->mapping = 0; + if (bag->texture) + prim->mapping = 1; + else + prim->mapping = 0; - // packet2_utils_vu_open_unpack(packet, 0, true); - // { - // packet2_add_float(packet, 2048.0F); // scale - // packet2_add_float(packet, 2048.0F); // scale - // packet2_add_float(packet, - // static_cast(0xFFFFFF) / 32.0F); // scale - // packet2_add_u32(packet, buffer->size); // vertex count + packet2_utils_vu_open_unpack(packet, 0, true); + { + packet2_add_float(packet, 2048.0F); // scale + packet2_add_float(packet, 2048.0F); // scale + packet2_add_float(packet, + static_cast(0xFFFFFF) / 32.0F); // scale + packet2_add_u32(packet, bag->count); // vertex count - // packet2_utils_gs_add_prim_giftag(packet, prim, buffer->size, reglist, - // reglistCount, 0); - // } - // packet2_utils_vu_close_unpack(packet); + packet2_utils_gs_add_prim_giftag(packet, prim, bag->count, reglist, + reglistCount, 0); + } + packet2_utils_vu_close_unpack(packet); } u16 DynPipVU1Program::getMaxVertCount(const u16& bufferSize) const { 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 3c0beec..dfb19d1 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 @@ -32,14 +32,151 @@ #vuprog DynPipVU1TD -ResetClipFlags{ } + 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 stqDataFrom, vertexDataFrom, vertexCount + iadd stqDataFrom, stqDataFrom, vertexCount + + iadd normalDataFrom, stqDataFrom, 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: + ;--- 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 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 } + PerformTexturePerspectiveCorrection{ outputStq1, stq1 } + 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 outputStq1, STQ_STORE_OFFSET(destAddress) + sq outputColor1, RGBA_STORE_OFFSET(destAddress) + sq.xyz vertex1, XYZ2_STORE_OFFSET(destAddress) + + ; --------------------------------------- + + ;--- 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 } + + ;--- Vertex 2 - Calculate + MatrixMultiplyVertex{ vertex2, mvp, vertex2 } + PerformClipCheck{ vertex2, destAddress, XYZ2_STORE_OFFSET+3 } + VertexPersCorr{ vertex2, vertex2 } + ScaleVertexToGSFormat{ scale, vertex2 } + PerformTexturePerspectiveCorrection{ outputStq2, stq2 } + 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 outputStq2, STQ_STORE_OFFSET+3(destAddress) + sq outputColor2, RGBA_STORE_OFFSET+3(destAddress) + sq.xyz vertex2, XYZ2_STORE_OFFSET+3(destAddress) + + ; --------------------------------------- + + ;--- 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 } + + ;--- Vertex 3 - Calculate + MatrixMultiplyVertex{ vertex3, mvp, vertex3 } + PerformClipCheck{ vertex3, destAddress, XYZ2_STORE_OFFSET+6 } + VertexPersCorr{ vertex3, vertex3 } + ScaleVertexToGSFormat{ scale, vertex3 } + PerformTexturePerspectiveCorrection{ outputStq3, stq3 } + 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 outputStq3, STQ_STORE_OFFSET+6(destAddress) + sq outputColor3, RGBA_STORE_OFFSET+6(destAddress) + sq.xyz vertex3, XYZ2_STORE_OFFSET+6(destAddress) + + ;------------------------------- + + iaddiu vertexDataFrom, vertexDataFrom, 3 + iaddiu stqDataFrom, stqDataFrom, 3 + iaddiu normalDataFrom, normalDataFrom, 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 -; --cont - #endvuprog --exit diff --git a/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp b/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp index 7d42752..ce665cc 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp +++ b/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp @@ -28,7 +28,7 @@ DynamicPipeline::~DynamicPipeline() { void DynamicPipeline::init(RendererCore* t_core) { rendererCore = t_core; - auto packetSize = buffersCount * 3.1F; + auto packetSize = buffersCount * 4.8F; core.init(t_core, static_cast(packetSize)); } @@ -123,22 +123,21 @@ 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 isHalf = *bufferIndex == halfBuffersCount - 1; auto isFull = *bufferIndex == buffersCount - 1; - if (isHalf || isFull) { - u32 offset = isHalf ? 0 : halfBuffersCount; + // if (isHalf || isFull) { + // u32 offset = isHalf ? 0 : halfBuffersCount; - DynPipBag** sendBuffers = new DynPipBag*[halfBuffersCount]; + DynPipBag** sendBuffers = new DynPipBag*[1]; - for (u32 i = 0; i < halfBuffersCount; i++) - sendBuffers[i] = &buffers[offset + i]; + sendBuffers[0] = buffer; - core.renderPart(sendBuffers, halfBuffersCount, - frustumCulling == DynPipFrustumCulling_Precise); + core.renderPart(sendBuffers, 1, + frustumCulling == DynPipFrustumCulling_Precise); - delete[] sendBuffers; - } + delete[] sendBuffers; + // } if (isFull) *bufferIndex = 0; @@ -149,22 +148,22 @@ void DynamicPipeline::setBuffer(DynPipBag* buffers, DynPipBag* buffer, void DynamicPipeline::sendRestOfBuffers( DynPipBag* buffers, u16* bufferIndex, const DynPipFrustumCulling& frustumCulling) { - auto isHalf = *bufferIndex == halfBuffersCount - 1; + // auto isHalf = *bufferIndex == halfBuffersCount - 1; - u32 offset = isHalf ? 0 : halfBuffersCount; - u32 size = *bufferIndex - offset; + // u32 offset = isHalf ? 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/engine/src/renderer/3d/pipeline/shared/tyra_macros.i b/engine/src/renderer/3d/pipeline/shared/tyra_macros.i index 4b4214c..27f339e 100644 --- a/engine/src/renderer/3d/pipeline/shared/tyra_macros.i +++ b/engine/src/renderer/3d/pipeline/shared/tyra_macros.i @@ -17,6 +17,20 @@ ilw.x t_singleColorEnabled, t_optionsAddr(vi00) #endmacro +;//--------------------------------------------------------- +;// LoadTyraLerpValue - Loads interpolation value. +;//--------------------------------------------------------- +#macro LoadTyraLerpValue: t_lerpValue, t_optionsAddr + lq.y t_lerpValue, t_optionsAddr(vi00) +#endmacro + +;//--------------------------------------------------------- +;// LoadTyraScaleValue - Loads screen scales. +;//--------------------------------------------------------- +#macro LoadTyraScaleValue: t_scale, t_buffer + lq.xyz t_scale, 0(t_buffer) +#endmacro + ;//--------------------------------------------------------- ;// LoadTyraTags - Load lod, texture buffer and clut ;// 1 - GIF tag - texture LOD @@ -27,6 +41,14 @@ lq t_texBufferClutGifTag, t_ClutAddr(vi00) #endmacro +;//--------------------------------------------------------- +;// LoadTyraPrimTag - Load prim tag +;// 2 - GIF tag - tell GS how many data we will send +;//--------------------------------------------------------- +#macro LoadTyraPrimTag: t_primTag, t_buffer + lq t_primTag, 1(t_buffer) +#endmacro + ;//--------------------------------------------------------- ;// LoadTyraBufferTags - Load scales and prim tag ;// 1 - float : X, Y, Z - scale vector that we will use to scale the verts after projecting them, float : W - vert count. @@ -97,3 +119,21 @@ loi 128 addi.w t_outputColor, vf00, i #endmacro + +;//--------------------------------------------------------- +;// LerpXYZ - Linear interpolation between two points +;//--------------------------------------------------------- +#macro LerpXYZ: t_output, t_from, t_to, t_interp + sub.xyz temp1, t_to, t_from + mul.xyz temp2, temp1, t_interp[y] + add.xyz t_output, temp2, t_from +#endmacro + +;//--------------------------------------------------------- +;// Lerp - Linear interpolation between two points +;//--------------------------------------------------------- +#macro Lerp: t_output, t_from, t_to, t_interp + sub temp1, t_to, t_from + mul temp2, temp1, t_interp[y] + add t_output, temp2, t_from +#endmacro \ No newline at end of file