vu1 animation

This commit is contained in:
h4570
2022-07-23 18:32:38 +02:00
parent 1ffba47119
commit e7a9230b59
7 changed files with 270 additions and 95 deletions
+1
View File
@@ -7,6 +7,7 @@
- [StaPip] Remove animation - [StaPip] Remove animation
- [StaPip] Dbufferring during mesh unrolling - [StaPip] Dbufferring during mesh unrolling
- [StaPip] Info about: full plane clip - [StaPip] Info about: full plane clip
- [Game] Update intellisense from docker
- [Renderer] Add possibility to on/off frustum check in all pipelines (renderOptions?) - [Renderer] Add possibility to on/off frustum check in all pipelines (renderOptions?)
- [Loaders] Think about ".tyrobj" format - implement it (add multicolor support) - [Loaders] Think about ".tyrobj" format - implement it (add multicolor support)
- [Loaders] DFF loader as static Mesh loader - [Loaders] DFF loader as static Mesh loader
@@ -9,15 +9,15 @@
// //
// Updated once per mesh // Updated once per mesh
// #define VU1_MVP_MATRIX_ADDR 0 #define VU1_MVP_MATRIX_ADDR 0
// #define VU1_LIGHTS_MATRIX_ADDR 4 #define VU1_LIGHTS_MATRIX_ADDR 4
// #define VU1_SINGLE_COLOR_ADDR 7 #define VU1_SINGLE_COLOR_ADDR 7
// #define VU1_OPTIONS_ADDR 8 #define VU1_OPTIONS_ADDR 8
// #define VU1_LOD_ADDR 9 #define VU1_LOD_ADDR 9
// #define VU1_CLUT_ADDR 10 #define VU1_CLUT_ADDR 10
// #define VU1_LIGHTS_DIRS_ADDR 11 #define VU1_LIGHTS_DIRS_ADDR 11
// #define VU1_LIGHTS_COLORS_ADDR 14 #define VU1_LIGHTS_COLORS_ADDR 14
// #define VU1_SET_GIFTAG_ADDR 18 #define VU1_SET_GIFTAG_ADDR 18
#define VU1_LAST_ITEM_ADDR 18 #define VU1_LAST_ITEM_ADDR 18
// Buffer data (xtop) // Buffer data (xtop)
@@ -73,67 +73,65 @@ void DynPipRenderer::setProgramsCache() {
} }
void DynPipRenderer::sendStaticData() const { void DynPipRenderer::sendStaticData() const {
// packet2_reset(staticDataPacket, false); packet2_reset(staticDataPacket, false);
// packet2_utils_vu_open_unpack(staticDataPacket, VU1_SET_GIFTAG_ADDR, packet2_utils_vu_open_unpack(staticDataPacket, VU1_SET_GIFTAG_ADDR, false);
// false); { packet2_utils_gif_add_set(staticDataPacket, 1); } { packet2_utils_gif_add_set(staticDataPacket, 1); }
// packet2_utils_vu_close_unpack(staticDataPacket); packet2_utils_vu_close_unpack(staticDataPacket);
// packet2_utils_vu_add_end_tag(staticDataPacket); packet2_utils_vu_add_end_tag(staticDataPacket);
// dma_channel_wait(DMA_CHANNEL_VIF1, 0); dma_channel_wait(DMA_CHANNEL_VIF1, 0);
// dma_channel_send_packet2(staticDataPacket, DMA_CHANNEL_VIF1, true); dma_channel_send_packet2(staticDataPacket, DMA_CHANNEL_VIF1, true);
} }
void DynPipRenderer::sendObjectData( void DynPipRenderer::sendObjectData(
DynPipBag* bag, M4x4* mvp, RendererCoreTextureBuffers* texBuffers) const { DynPipBag* bag, M4x4* mvp, RendererCoreTextureBuffers* texBuffers) const {
// packet2_reset(objectDataPacket, false); packet2_reset(objectDataPacket, false);
// packet2_utils_vu_add_unpack_data(objectDataPacket, VU1_MVP_MATRIX_ADDR, packet2_utils_vu_add_unpack_data(objectDataPacket, VU1_MVP_MATRIX_ADDR,
// mvp->data, 4, false); mvp->data, 4, false);
// if (bag->lighting) { if (bag->lighting) {
// packet2_utils_vu_add_unpack_data(objectDataPacket, packet2_utils_vu_add_unpack_data(objectDataPacket, VU1_LIGHTS_MATRIX_ADDR,
// VU1_LIGHTS_MATRIX_ADDR, bag->lighting->lightMatrix, 3, false);
// bag->lighting->lightMatrix, 3, false);
// packet2_utils_vu_add_unpack_data( packet2_utils_vu_add_unpack_data(
// objectDataPacket, VU1_LIGHTS_DIRS_ADDR, objectDataPacket, VU1_LIGHTS_DIRS_ADDR,
// bag->lighting->dirLights->getLightDirections(), 3, false); bag->lighting->dirLights->getLightDirections(), 3, false);
// packet2_utils_vu_add_unpack_data(objectDataPacket, packet2_utils_vu_add_unpack_data(objectDataPacket, VU1_LIGHTS_COLORS_ADDR,
// VU1_LIGHTS_COLORS_ADDR, bag->lighting->dirLights->getLightColors(),
// bag->lighting->dirLights->getLightColors(), 4, false);
// 4, false); }
// }
// u8 singleColorEnabled = bag->color->single != nullptr; u8 singleColorEnabled = bag->color->single != nullptr;
// if (singleColorEnabled) // Color is placed in 4th slot of if (singleColorEnabled) // Color is placed in 4th slot of
// // VU1_LIGHTS_MATRIX_ADDR // VU1_LIGHTS_MATRIX_ADDR
// packet2_utils_vu_add_unpack_data(objectDataPacket, packet2_utils_vu_add_unpack_data(objectDataPacket, VU1_SINGLE_COLOR_ADDR,
// VU1_SINGLE_COLOR_ADDR, bag->color->single->rgba, 1, false);
// bag->color->single->rgba, 1, false);
// packet2_utils_vu_open_unpack(objectDataPacket, VU1_OPTIONS_ADDR, false); packet2_utils_vu_open_unpack(objectDataPacket, VU1_OPTIONS_ADDR, false);
// { {
// packet2_add_u32(objectDataPacket, packet2_add_u32(objectDataPacket,
// singleColorEnabled); // Single color enabled. singleColorEnabled); // Single color enabled.
// packet2_add_u32(objectDataPacket, 0); // not used, padding packet2_add_float(objectDataPacket,
// packet2_add_u32(objectDataPacket, 0); // not used, padding bag->interpolation); // Interpolation value
// 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_gs_add_lod(objectDataPacket, &rendererCore->gs.lod); packet2_utils_gs_add_lod(objectDataPacket, &rendererCore->gs.lod);
// if (texBuffers != nullptr) { if (texBuffers != nullptr) {
// packet2_utils_gs_add_texbuff_clut(objectDataPacket, texBuffers->core, packet2_utils_gs_add_texbuff_clut(objectDataPacket, texBuffers->core,
// &rendererCore->texture.clut); &rendererCore->texture.clut);
// rendererCore->texture.updateClutBuffer(texBuffers->clut); rendererCore->texture.updateClutBuffer(texBuffers->clut);
// } }
// } }
// packet2_utils_vu_close_unpack(objectDataPacket); packet2_utils_vu_close_unpack(objectDataPacket);
// packet2_utils_vu_add_end_tag(objectDataPacket); packet2_utils_vu_add_end_tag(objectDataPacket);
// dma_channel_wait(DMA_CHANNEL_VIF1, 0); dma_channel_wait(DMA_CHANNEL_VIF1, 0);
// dma_channel_send_packet2(objectDataPacket, DMA_CHANNEL_VIF1, true); dma_channel_send_packet2(objectDataPacket, DMA_CHANNEL_VIF1, true);
} }
void DynPipRenderer::render(DynPipBag** bags, const u32& count) { void DynPipRenderer::render(DynPipBag** bags, const u32& count) {
@@ -41,23 +41,23 @@ void DynPipVU1Program::addBufferDataToPacket(packet2_t* packet, DynPipBag* bag,
void DynPipVU1Program::addStandardBufferDataToPacket(packet2_t* packet, void DynPipVU1Program::addStandardBufferDataToPacket(packet2_t* packet,
DynPipBag* bag, DynPipBag* bag,
prim_t* prim) { prim_t* prim) {
// if (buffer->bag->texture) if (bag->texture)
// prim->mapping = 1; prim->mapping = 1;
// else else
// prim->mapping = 0; prim->mapping = 0;
// packet2_utils_vu_open_unpack(packet, 0, true); 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, 2048.0F); // scale packet2_add_float(packet, 2048.0F); // scale
// packet2_add_float(packet, packet2_add_float(packet,
// static_cast<float>(0xFFFFFF) / 32.0F); // scale static_cast<float>(0xFFFFFF) / 32.0F); // scale
// packet2_add_u32(packet, buffer->size); // vertex count packet2_add_u32(packet, bag->count); // vertex count
// packet2_utils_gs_add_prim_giftag(packet, prim, buffer->size, reglist, packet2_utils_gs_add_prim_giftag(packet, prim, bag->count, reglist,
// reglistCount, 0); reglistCount, 0);
// } }
// packet2_utils_vu_close_unpack(packet); packet2_utils_vu_close_unpack(packet);
} }
u16 DynPipVU1Program::getMaxVertCount(const u16& bufferSize) const { u16 DynPipVU1Program::getMaxVertCount(const u16& bufferSize) const {
@@ -32,14 +32,151 @@
#vuprog DynPipVU1TD #vuprog DynPipVU1TD
ResetClipFlags{ } ResetClipFlags{ }
LoadTyraStaticData{ gifSetTag }
MatrixLoad{ mvp, VU1_MVP_MATRIX_ADDR, vi00 }
LoadTyraTags{ lodGifTag, texBufferClutGifTag, VU1_LOD_ADDR, VU1_CLUT_ADDR }
begin: begin:
xtop buffer 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 #endvuprog
--exit --exit
@@ -28,7 +28,7 @@ DynamicPipeline::~DynamicPipeline() {
void DynamicPipeline::init(RendererCore* t_core) { void DynamicPipeline::init(RendererCore* t_core) {
rendererCore = t_core; rendererCore = t_core;
auto packetSize = buffersCount * 3.1F; auto packetSize = buffersCount * 4.8F;
core.init(t_core, static_cast<u32>(packetSize)); core.init(t_core, static_cast<u32>(packetSize));
} }
@@ -123,22 +123,21 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) {
void DynamicPipeline::setBuffer(DynPipBag* buffers, DynPipBag* buffer, void DynamicPipeline::setBuffer(DynPipBag* buffers, DynPipBag* buffer,
u16* bufferIndex, u16* bufferIndex,
const DynPipFrustumCulling& frustumCulling) { const DynPipFrustumCulling& frustumCulling) {
auto isHalf = *bufferIndex == halfBuffersCount - 1; // auto isHalf = *bufferIndex == halfBuffersCount - 1;
auto isFull = *bufferIndex == buffersCount - 1; auto isFull = *bufferIndex == buffersCount - 1;
if (isHalf || isFull) { // if (isHalf || isFull) {
u32 offset = isHalf ? 0 : halfBuffersCount; // u32 offset = isHalf ? 0 : halfBuffersCount;
DynPipBag** sendBuffers = new DynPipBag*[halfBuffersCount]; DynPipBag** sendBuffers = new DynPipBag*[1];
for (u32 i = 0; i < halfBuffersCount; i++) sendBuffers[0] = buffer;
sendBuffers[i] = &buffers[offset + i];
core.renderPart(sendBuffers, halfBuffersCount, core.renderPart(sendBuffers, 1,
frustumCulling == DynPipFrustumCulling_Precise); frustumCulling == DynPipFrustumCulling_Precise);
delete[] sendBuffers; delete[] sendBuffers;
} // }
if (isFull) if (isFull)
*bufferIndex = 0; *bufferIndex = 0;
@@ -149,22 +148,22 @@ void DynamicPipeline::setBuffer(DynPipBag* buffers, DynPipBag* buffer,
void DynamicPipeline::sendRestOfBuffers( void DynamicPipeline::sendRestOfBuffers(
DynPipBag* buffers, u16* bufferIndex, DynPipBag* buffers, u16* bufferIndex,
const DynPipFrustumCulling& frustumCulling) { const DynPipFrustumCulling& frustumCulling) {
auto isHalf = *bufferIndex == halfBuffersCount - 1; // auto isHalf = *bufferIndex == halfBuffersCount - 1;
u32 offset = isHalf ? 0 : halfBuffersCount; // u32 offset = isHalf ? 0 : halfBuffersCount;
u32 size = *bufferIndex - offset; // u32 size = *bufferIndex - offset;
if (size <= 0) return; // if (size <= 0) return;
DynPipBag** sendBuffers = new DynPipBag*[size]; // DynPipBag** sendBuffers = new DynPipBag*[size];
for (u32 i = 0; i < size; i++) { // for (u32 i = 0; i < size; i++) {
sendBuffers[i] = &buffers[offset + i]; // sendBuffers[i] = &buffers[offset + i];
} // }
core.renderPart(sendBuffers, size, // core.renderPart(sendBuffers, size,
frustumCulling == DynPipFrustumCulling_Precise); // frustumCulling == DynPipFrustumCulling_Precise);
delete[] sendBuffers; // delete[] sendBuffers;
} }
void DynamicPipeline::setBuffersDefaultVars(DynPipBag* buffers, void DynamicPipeline::setBuffersDefaultVars(DynPipBag* buffers,
@@ -17,6 +17,20 @@
ilw.x t_singleColorEnabled, t_optionsAddr(vi00) ilw.x t_singleColorEnabled, t_optionsAddr(vi00)
#endmacro #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 ;// LoadTyraTags - Load lod, texture buffer and clut
;// 1 - GIF tag - texture LOD ;// 1 - GIF tag - texture LOD
@@ -27,6 +41,14 @@
lq t_texBufferClutGifTag, t_ClutAddr(vi00) lq t_texBufferClutGifTag, t_ClutAddr(vi00)
#endmacro #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 ;// 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. ;// 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 loi 128
addi.w t_outputColor, vf00, i addi.w t_outputColor, vf00, i
#endmacro #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