sending vu1 programs

This commit is contained in:
h4570
2022-07-21 18:39:37 +02:00
parent aad634a241
commit 0b60aa0f6d
9 changed files with 290 additions and 116 deletions
@@ -14,7 +14,7 @@
#include "./bag/dynpip_bag.hpp"
#include "renderer/core/renderer_core.hpp"
#include "./dynpip_programs_repository.hpp"
#include "./dynpip_qbuffer_renderer.hpp"
#include "./dynpip_renderer.hpp"
namespace Tyra {
@@ -27,8 +27,17 @@ class DynPipCore {
void init(RendererCore* t_core);
/** Force starting VU1 program instead of continueing */
void clear() { qbufferRenderer.clearLastProgramName(); }
/**
* Send model matrix, lighting data and other
* repetitve stuff to VU1
*/
void initParts(DynPipBag* data);
/** Render 3D via "bags" */
void render(DynPipBag* data);
void renderPart(DynPipBag* data, const bool& frustumCull = true);
/** Get max vert count of VU1 qbuffer (for optimizations) */
u32 getMaxVertCountByParams(const bool& isSingleColor,
@@ -44,8 +53,9 @@ class DynPipCore {
void reinitVU1Programs();
private:
M4x4 mvp;
RendererCore* rendererCore;
DynPipQBufferRenderer qbufferRenderer;
DynPipRenderer qbufferRenderer;
};
} // namespace Tyra
@@ -1,68 +0,0 @@
/*
# ______ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licenced under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tamtypes.h>
namespace Tyra {
class DynPipQBufferRenderer {
public:
DynPipQBufferRenderer();
~DynPipQBufferRenderer();
// void init(RendererCore* t_core);
// void reinitVU1();
// DynPipQBuffer* getBuffer();
// void sendObjectData(DynPipBag* bag, M4x4* mvp,
// RendererCoreTextureBuffers* texBuffers) const;
// void setMaxVertCount(const u32& count);
// void setInfo(PipelineInfoBag* bag);
// void render(DynPipQBuffer* buffer);
// void clearLastProgramName();
const u16& getBufferSize() { return bufferSize; }
private:
// void sendStaticData() const;
// void setProgramsCache();
// void uploadPrograms();
// void setDoubleBuffer();
// void addBufferDataToPacket(DynPipVU1Program* program, DynPipQBuffer*
// buffer); void sendPacket();
// packet2_t* packets[2];
// packet2_t* programsPacket;
// DynPipQBuffer buffers[2];
// packet2_t* currentPacket;
// packet2_t* staticDataPacket;
// packet2_t* objectDataPacket;
// RendererCore* rendererCore;
// DynPipProgramName lastProgramName;
// Path1* path1;
// DynPipClipper clipper;
// DynPipProgramsRepository repository;
u16 bufferSize;
// u8 context;
};
} // namespace Tyra
@@ -0,0 +1,69 @@
/*
# ______ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licenced under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tamtypes.h>
#include "renderer/core/renderer_core.hpp"
#include "./dynpip_programs_repository.hpp"
namespace Tyra {
class DynPipRenderer {
public:
DynPipRenderer();
~DynPipRenderer();
void init(RendererCore* t_core, DynPipProgramsRepository* t_programRepo);
void reinitVU1();
// DynPipQBuffer* getBuffer();
void sendObjectData(DynPipBag* bag, M4x4* mvp,
RendererCoreTextureBuffers* texBuffers) const;
// void setMaxVertCount(const u32& count);
// void setInfo(PipelineInfoBag* bag);
// void render(DynPipQBuffer* buffer);
void clearLastProgramName();
const u16& getBufferSize() { return bufferSize; }
private:
void sendStaticData() const;
void setProgramsCache();
void uploadPrograms();
void setDoubleBuffer();
// void addBufferDataToPacket(DynPipVU1Program* program, DynPipQBuffer*
// buffer); void sendPacket();
// DynPipQBuffer buffers[2];
packet2_t* packets[2];
packet2_t* programsPacket;
packet2_t* currentPacket;
packet2_t* staticDataPacket;
packet2_t* objectDataPacket;
DynPipProgramsRepository* programsRepo;
RendererCore* rendererCore;
Path1* path1;
DynPipProgramName lastProgramName;
u16 bufferSize;
u8 context;
};
} // namespace Tyra
@@ -18,7 +18,7 @@
// #define VU1_LIGHTS_DIRS_ADDR 11
// #define VU1_LIGHTS_COLORS_ADDR 14
// #define VU1_SET_GIFTAG_ADDR 18
// #define VU1_LAST_ITEM_ADDR 18
#define VU1_LAST_ITEM_ADDR 18
// Buffer data (xtop)
#define VU1_VERT_DATA_ADDR 2
@@ -18,9 +18,12 @@ DynPipCore::DynPipCore() {}
DynPipCore::~DynPipCore() {}
void DynPipCore::init(RendererCore* t_core) { rendererCore = t_core; }
void DynPipCore::init(RendererCore* t_core) {
rendererCore = t_core;
qbufferRenderer.init(t_core, &repository);
}
void DynPipCore::reinitVU1Programs() {}
void DynPipCore::reinitVU1Programs() { qbufferRenderer.reinitVU1(); }
u32 DynPipCore::getMaxVertCountByParams(const bool& isSingleColor,
const bool& isLightingEnabled,
@@ -29,9 +32,36 @@ u32 DynPipCore::getMaxVertCountByParams(const bool& isSingleColor,
->getMaxVertCount(isSingleColor, qbufferRenderer.getBufferSize());
}
void DynPipCore::render(DynPipBag* bag) {
// Zrobic bbox
// TODO: Potem wrzucic programy i obliczyc bufferSize w qbufferrenderer
void DynPipCore::initParts(DynPipBag* bag) {
RendererCoreTextureBuffers* texBuffers = nullptr;
if (bag->texture) {
auto temp = rendererCore->texture.useTexture(bag->texture->texture);
texBuffers = new RendererCoreTextureBuffers{temp.id, temp.core, temp.clut};
}
mvp = rendererCore->renderer3D.getViewProj() * *bag->info->model;
qbufferRenderer.sendObjectData(bag, &mvp, texBuffers);
delete texBuffers;
}
void DynPipCore::renderPart(DynPipBag* bag, const bool& frustumCull) {
if (bag->count <= 0) return;
if (frustumCull) {
CoreBBox bbox(bag->verticesTo, bag->count);
if (bbox.isInFrustum(rendererCore->renderer3D.frustumPlanes.getAll(),
*bag->info->model) ==
CoreBBoxFrustum::OUTSIDE_FRUSTUM) {
return;
}
}
// TODO: Uruchomic odpowiedni program
// TODO: Wyslac wierzcholki
// TODO: Program VU1 TD
// TODO: Reszta programow VU1
}
} // namespace Tyra
@@ -1,19 +0,0 @@
/*
# ______ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licenced under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "renderer/3d/pipeline/dynamic/core/dynpip_qbuffer_renderer.hpp"
#include "renderer/3d/pipeline/dynamic/core/programs/dynpip_vu1_shared_defines.h"
namespace Tyra {
DynPipQBufferRenderer::DynPipQBufferRenderer() {}
DynPipQBufferRenderer::~DynPipQBufferRenderer() {}
} // namespace Tyra
@@ -0,0 +1,160 @@
/*
# ______ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licenced under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "renderer/3d/pipeline/dynamic/core/dynpip_renderer.hpp"
#include "renderer/3d/pipeline/dynamic/core/programs/dynpip_vu1_shared_defines.h"
#include <dma.h>
namespace Tyra {
DynPipRenderer::DynPipRenderer() {
context = 0;
lastProgramName = DynPipProgramName::DynPipUndefinedProgram;
staticDataPacket = packet2_create(3, P2_TYPE_NORMAL, P2_MODE_CHAIN, true);
objectDataPacket = packet2_create(16, P2_TYPE_NORMAL, P2_MODE_CHAIN, true);
programsPacket = nullptr;
}
DynPipRenderer::~DynPipRenderer() {
packet2_free(packets[0]);
packet2_free(packets[1]);
packet2_free(staticDataPacket);
packet2_free(objectDataPacket);
if (programsPacket) packet2_free(programsPacket);
}
void DynPipRenderer::init(RendererCore* t_core,
DynPipProgramsRepository* t_programRepo) {
// path1 = t_core->getPath1();
// rendererCore = t_core;
// programsRepo = t_programRepo;
// dma_channel_initialize(DMA_CHANNEL_VIF1, NULL, 0);
// dma_channel_fast_waits(DMA_CHANNEL_VIF1);
// const u32 VU1_PACKET_SIZE = 16;
// 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);
// setProgramsCache();
// reinitVU1();
// TYRA_LOG("Renderer3DQBufferRenderer initialized");
}
void DynPipRenderer::reinitVU1() {
// sendStaticData();
// uploadPrograms();
// setDoubleBuffer();
}
void DynPipRenderer::setProgramsCache() {
VU1Program** programs = new VU1Program*[4];
programs[0] = programsRepo->getProgram(DynPipProgramName::DynPipColor);
programs[1] = programsRepo->getProgram(DynPipProgramName::DynPipDirLights);
programs[2] = programsRepo->getProgram(DynPipProgramName::DynPipTextureColor);
programs[3] =
programsRepo->getProgram(DynPipProgramName::DynPipTextureDirLights);
programsPacket = path1->createProgramsCache(programs, 4, 0);
delete[] programs;
}
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_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);
// 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_COLORS_ADDR,
// bag->lighting->dirLights->getLightColors(),
// 4, false);
// }
// 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);
// 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_gs_add_lod(objectDataPacket, &rendererCore->gs.lod);
// 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);
// 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::clearLastProgramName() {
lastProgramName = DynPipUndefinedProgram;
}
void DynPipRenderer::uploadPrograms() {
dma_channel_wait(DMA_CHANNEL_VIF1, 0);
dma_channel_send_packet2(programsPacket, DMA_CHANNEL_VIF1, true);
dma_channel_wait(DMA_CHANNEL_VIF1, 0);
}
void DynPipRenderer::setDoubleBuffer() {
u16 startingAddr = VU1_LAST_ITEM_ADDR + 1;
const u16 bufferMaxSize = 1000;
bufferSize = (bufferMaxSize - startingAddr) / 2;
path1->setDoubleBuffer(startingAddr, bufferSize);
bufferSize -= 1; // Because we don't want to upload anything from first
// buffer, to first addr of second buffer
}
} // namespace Tyra
@@ -16,7 +16,10 @@ DynamicPipeline::DynamicPipeline() { colorsCache = new Vec4[4]; }
DynamicPipeline::~DynamicPipeline() { delete[] colorsCache; }
void DynamicPipeline::init(RendererCore* t_core) { rendererCore = t_core; }
void DynamicPipeline::init(RendererCore* t_core) {
rendererCore = t_core;
core.init(t_core);
}
void DynamicPipeline::onUse() {}
@@ -38,6 +41,7 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) {
u8 context = 0;
setBuffersDefaultVars(buffers, mesh, infoBag);
core.clear();
for (u32 i = 0; i < mesh->getMaterialsCount(); i++) {
auto* material = mesh->getMaterial(i);
@@ -48,6 +52,7 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) {
ceil(material->getFacesCount() / static_cast<float>(partSize));
auto* colorBag = getColorBag(material);
setBuffersColorBag(buffers, colorBag);
u8 isPartInitialized = false;
for (u32 j = 0; j < partsCount; j++) {
auto& buffer = buffers[context];
@@ -66,7 +71,12 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) {
getLightingBag(mesh, material, &model, frameFrom, frameTo, options,
dirLights, buffer.count, startIndex);
core.render(&buffer);
if (!isPartInitialized) {
core.initParts(&buffer);
isPartInitialized = true;
}
core.renderPart(&buffer);
context = !context;
}
@@ -189,24 +189,6 @@ void StaPipQBufferRenderer::cull(StaPipQBuffer* buffer) {
sendPacket();
}
// void StaPipQBufferRenderer::sendFinishTag() {
// StaPipQBufferRenderer way proposition
// auto program = path1->getProgramByName(Draw_Finish);
// addBufferDataToPacket(program, nullptr);
// sendPacket();
// packet2_t* packet2 = packet2_create(8, P2_TYPE_NORMAL, P2_MODE_CHAIN,
// true); auto program =
// static_cast<VU1DrawFinish*>(getProgramByName(Draw_Finish));
// program->addTag(packet2, prim);
// packet2_utils_vu_add_start_program(packet2,
// program->getDestinationAddress()); packet2_utils_vu_add_end_tag(packet2);
// dma_channel_wait(DMA_CHANNEL_VIF1, 0);
// dma_channel_send_packet2(packet2, DMA_CHANNEL_VIF1, true);
// packet2_free(packet2);
// }
void StaPipQBufferRenderer::clip(StaPipQBuffer* buffer) {
if (buffer->size == 0) {
return;