spamming with vu1 packets 2

This commit is contained in:
h4570
2022-07-23 15:55:38 +02:00
parent 17d7634f1d
commit 1ffba47119
6 changed files with 139 additions and 99 deletions
@@ -19,9 +19,9 @@ DynPipCore::DynPipCore() {}
DynPipCore::~DynPipCore() {}
void DynPipCore::init(RendererCore* t_core) {
void DynPipCore::init(RendererCore* t_core, const u32& t_packetSize) {
rendererCore = t_core;
qbufferRenderer.init(t_core, &repository);
qbufferRenderer.init(t_core, &repository, t_packetSize);
}
void DynPipCore::reinitVU1Programs() { qbufferRenderer.reinitVU1(); }
@@ -46,41 +46,54 @@ void DynPipCore::initParts(DynPipBag* bag) {
delete texBuffers;
}
void DynPipCore::renderTEST(DynPipBag** bags, const u32& count) {
qbufferRenderer.renderTEST(bags, count);
}
void DynPipCore::renderPart(DynPipBag** bags, const u32& count,
const bool& frustumCull) {
if (count <= 0) return;
void DynPipCore::renderPart(DynPipBag* bag, const bool& frustumCull) {
if (bag->count <= 0) return;
TYRA_ASSERT(bag->verticesFrom != nullptr && bag->verticesTo != nullptr,
"Vertices are required in 3D render bag!");
TYRA_ASSERT(bag->info != nullptr, "Info bag is required in 3D render bag!");
TYRA_ASSERT(bag->info->model != nullptr,
"Info bag's model pointer is empty!");
TYRA_ASSERT(bag->color != nullptr, "Color bag is required in 3D render bag!");
TYRA_ASSERT(bag->color->single, "Color is required in 3D render bag!");
TYRA_ASSERT(
!bag->lighting ||
(bag->lighting->lightMatrix && bag->lighting->normalsFrom &&
bag->lighting->normalsTo && bag->lighting->dirLights),
bags[0]->verticesFrom != nullptr && bags[0]->verticesTo != nullptr,
"Vertices are required in 3D render bag!");
TYRA_ASSERT(bags[0]->info != nullptr,
"Info bag is required in 3D render bag!");
TYRA_ASSERT(bags[0]->info->model != nullptr,
"Info bag's model pointer is empty!");
TYRA_ASSERT(bags[0]->color != nullptr,
"Color bag is required in 3D render bag!");
TYRA_ASSERT(bags[0]->color->single, "Color is required in 3D render bag!");
TYRA_ASSERT(
!bags[0]->lighting ||
(bags[0]->lighting->lightMatrix && bags[0]->lighting->normalsFrom &&
bags[0]->lighting->normalsTo && bags[0]->lighting->dirLights),
"If you want lighting, please provide light matrix normals and dir "
"lights!");
TYRA_ASSERT(!bag->texture ||
(bag->texture->texture && bag->texture->coordinatesFrom &&
bag->texture->coordinatesTo),
TYRA_ASSERT(!bags[0]->texture || (bags[0]->texture->texture &&
bags[0]->texture->coordinatesFrom &&
bags[0]->texture->coordinatesTo),
"If you want texture, please provide texture and coordinates!");
if (frustumCull) {
if (!frustumCull) {
qbufferRenderer.render(bags, count);
return;
}
DynPipBag** bagsToRender = new DynPipBag*[count];
u32 inserted = 0;
for (u32 i = 0; i < count; i++) {
auto* bag = bags[i];
CoreBBox bbox(bag->verticesTo, bag->count);
if (bbox.isInFrustum(rendererCore->renderer3D.frustumPlanes.getAll(),
*bag->info->model) ==
CoreBBoxFrustum::OUTSIDE_FRUSTUM) {
return;
continue;
}
bagsToRender[inserted++] = bag;
}
qbufferRenderer.render(bag);
qbufferRenderer.render(bagsToRender, inserted);
delete[] bagsToRender;
}
} // namespace Tyra
@@ -33,7 +33,8 @@ DynPipRenderer::~DynPipRenderer() {
}
void DynPipRenderer::init(RendererCore* t_core,
DynPipProgramsRepository* t_programRepo) {
DynPipProgramsRepository* t_programRepo,
const u32& t_packetSize) {
path1 = t_core->getPath1();
rendererCore = t_core;
programsRepo = t_programRepo;
@@ -41,13 +42,11 @@ void DynPipRenderer::init(RendererCore* t_core,
dma_channel_initialize(DMA_CHANNEL_VIF1, NULL, 0);
dma_channel_fast_waits(DMA_CHANNEL_VIF1);
const u32 VU1_PACKET_SIZE = 256;
packets[0] =
packet2_create(VU1_PACKET_SIZE, P2_TYPE_NORMAL, P2_MODE_CHAIN, true);
packet2_create(t_packetSize, P2_TYPE_NORMAL, P2_MODE_CHAIN, true);
packets[1] =
packet2_create(VU1_PACKET_SIZE, P2_TYPE_NORMAL, P2_MODE_CHAIN, true);
packet2_create(t_packetSize, P2_TYPE_NORMAL, P2_MODE_CHAIN, true);
setProgramsCache();
@@ -137,47 +136,28 @@ void DynPipRenderer::sendObjectData(
// dma_channel_send_packet2(objectDataPacket, DMA_CHANNEL_VIF1, true);
}
void DynPipRenderer::render(DynPipBag* bag) {
auto* program = programsRepo->getProgramByBag(bag);
addBufferDataToPacket(program, bag);
sendPacket();
}
void DynPipRenderer::renderTEST(DynPipBag** bags, const u32& count) {
void DynPipRenderer::render(DynPipBag** bags, const u32& count) {
if (count <= 0) return;
auto* program = programsRepo->getProgramByBag(bags[0]);
addBufferDataToPacketTEST(program, bags, count);
addBufferDataToPacket(program, bags, count);
sendPacket();
}
void DynPipRenderer::addBufferDataToPacketTEST(DynPipVU1Program* program,
DynPipBag** bags,
const u32& count) {
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);
}
packet2_utils_vu_add_end_tag(currentPacket);
}
void DynPipRenderer::addBufferDataToPacket(DynPipVU1Program* program,
DynPipBag* bag) {
currentPacket = packets[context];
packet2_reset(currentPacket, false);
program->addBufferDataToPacket(currentPacket, bag, &rendererCore->gs.prim);
if (sent == 0) return;
if (lastProgramName != program->getName()) {
packet2_utils_vu_add_start_program(currentPacket,
@@ -193,9 +173,6 @@ void DynPipRenderer::sendPacket() {
dma_channel_wait(DMA_CHANNEL_VIF1, 0);
dma_channel_send_packet2(currentPacket, DMA_CHANNEL_VIF1, true);
// TODO
// TYRA_LOG(packet2_get_qw_count(currentPacket));
// Switch packet, so we can proceed during DMA transfer
context = !context;
}
@@ -12,19 +12,28 @@
namespace Tyra {
DynamicPipeline::DynamicPipeline() { colorsCache = new Vec4[4]; }
const u32 DynamicPipeline::buffersCount = 64;
const u32 DynamicPipeline::halfBuffersCount = buffersCount / 2;
DynamicPipeline::~DynamicPipeline() { delete[] colorsCache; }
DynamicPipeline::DynamicPipeline() {
colorsCache = new Vec4[4];
buffers = new DynPipBag[buffersCount];
}
DynamicPipeline::~DynamicPipeline() {
delete[] colorsCache;
for (u32 i = 0; i < buffersCount; i++) freeBuffer(&buffers[i]);
delete[] buffers;
}
void DynamicPipeline::init(RendererCore* t_core) {
rendererCore = t_core;
core.init(t_core);
auto packetSize = buffersCount * 3.1F;
core.init(t_core, static_cast<u32>(packetSize));
}
void DynamicPipeline::onUse() { core.reinitVU1Programs(); }
#define BUFFER_COUNT 64
void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) {
auto model = mesh->getModelMatrix();
auto* infoBag = getInfoBag(mesh, options, &model);
@@ -48,8 +57,7 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) {
options->lighting->directionalDirections);
}
DynPipBag buffers[BUFFER_COUNT];
u8 context = 0;
u16 bufferIndex = 0;
setBuffersDefaultVars(buffers, mesh, infoBag);
core.clear();
@@ -72,7 +80,7 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) {
u8 isPartInitialized = false;
for (u32 k = 0; k < partsCount; k++) {
auto& buffer = buffers[context++];
auto& buffer = buffers[bufferIndex];
freeBuffer(&buffer);
buffer.count = k == partsCount - 1
@@ -91,31 +99,19 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) {
isPartInitialized = true;
}
// core.renderPart(&buffer, frustumCulling ==
// DynPipFrustumCulling_Precise);
if (context == BUFFER_COUNT / 2 || context == BUFFER_COUNT) {
DynPipBag** sendBuffers = new DynPipBag*[BUFFER_COUNT / 2];
for (u32 i = 0; i < BUFFER_COUNT / 2; i++) {
sendBuffers[i] = &buffers[context - ((BUFFER_COUNT / 2) - i)];
}
core.renderTEST(sendBuffers, BUFFER_COUNT / 2);
delete[] sendBuffers;
if (context == BUFFER_COUNT) context = 0;
}
setBuffer(buffers, &buffer, &bufferIndex, frustumCulling);
}
delete colorBag;
}
// TODO: Refactor (define itd, wywalic te wszystkie TEST i poprawic)
// TODO: Rozmiar pakietu VU1 na podstawie rozmiaru buforow
// TODO: Dorenderowac brakujace (np gdy context == 1-buffersize-1 itd)
// TODO: Program renderujacy w VU1
// TODO: Github: Ten sam myk zrobic w static pipeline?
sendRestOfBuffers(buffers, &bufferIndex, frustumCulling);
for (u32 i = 0; i < BUFFER_COUNT; i++) freeBuffer(&buffers[i]);
// 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;
@@ -124,10 +120,57 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) {
delete infoBag;
}
void DynamicPipeline::setBuffer(DynPipBag* buffers, DynPipBag* buffer,
u16* bufferIndex,
const DynPipFrustumCulling& frustumCulling) {
auto isHalf = *bufferIndex == halfBuffersCount - 1;
auto isFull = *bufferIndex == buffersCount - 1;
if (isHalf || isFull) {
u32 offset = isHalf ? 0 : halfBuffersCount;
DynPipBag** sendBuffers = new DynPipBag*[halfBuffersCount];
for (u32 i = 0; i < halfBuffersCount; i++)
sendBuffers[i] = &buffers[offset + i];
core.renderPart(sendBuffers, halfBuffersCount,
frustumCulling == DynPipFrustumCulling_Precise);
delete[] sendBuffers;
}
if (isFull)
*bufferIndex = 0;
else
*bufferIndex += 1;
}
void DynamicPipeline::sendRestOfBuffers(
DynPipBag* buffers, u16* bufferIndex,
const DynPipFrustumCulling& frustumCulling) {
auto isHalf = *bufferIndex == halfBuffersCount - 1;
u32 offset = isHalf ? 0 : halfBuffersCount;
u32 size = *bufferIndex - offset;
if (size <= 0) return;
DynPipBag** sendBuffers = new DynPipBag*[size];
for (u32 i = 0; i < size; i++) {
sendBuffers[i] = &buffers[offset + i];
}
core.renderPart(sendBuffers, size,
frustumCulling == DynPipFrustumCulling_Precise);
delete[] sendBuffers;
}
void DynamicPipeline::setBuffersDefaultVars(DynPipBag* buffers,
DynamicMesh* mesh,
PipelineInfoBag* infoBag) {
for (int i = 0; i < BUFFER_COUNT; i++) {
for (u32 i = 0; i < buffersCount; i++) {
buffers[i].info = infoBag;
buffers[i].interpolation = mesh->getAnimState().interpolation;
}
@@ -135,7 +178,7 @@ void DynamicPipeline::setBuffersDefaultVars(DynPipBag* buffers,
void DynamicPipeline::setBuffersColorBag(DynPipBag* buffers,
DynPipColorBag* colorBag) {
for (int i = 0; i < BUFFER_COUNT; i++) {
for (u32 i = 0; i < buffersCount; i++) {
buffers[i].color = colorBag;
}
}