rework/optimize RenderCore VBO implementation

This commit is contained in:
zetaPRIME 2017-12-25 01:26:45 -05:00
parent 3c9fc00ac8
commit 7e1d160914

View File

@ -25,35 +25,24 @@ namespace { // internals
typedef struct { typedef struct {
float x, y, z, u, v; float x, y, z, u, v;
} vbo_xyzuv; } vbo_xyzuv;
void setXYZUV(vbo_xyzuv& vbo, float x, float y, float z, float u, float v) {
vbo.x = x;
vbo.y = y;
vbo.z = z;
vbo.u = u;
vbo.v = v;
}
void setXYZUV(vbo_xyzuv& vbo, Vector2 xy, Vector2 uv) { setXYZUV(vbo, xy.x, xy.y, 0, uv.x, uv.y); }
void* bufferStart = nullptr; vbo_xyzuv* vboArray = nullptr;
size_t bufferInd = 0; size_t vboIndex = 0;
size_t bufferSize = 0; size_t vboSize = 0;
void addVertXYZUV(float x, float y, float z, float u, float v) {
// TODO: maybe add bounds check
vbo_xyzuv* vert = &vboArray[vboIndex++];
vert->x = x; vert->y = y; vert->z = z;
vert->u = u; vert->v = v;
}
void addVertXYZUV(Vector2 xy, Vector2 uv) { addVertXYZUV(xy.x, xy.y, 0, uv.x, uv.y); }
DVLB_s* dvlb = nullptr; DVLB_s* dvlb = nullptr;
shaderProgram_s shader; shaderProgram_s shader;
int sLocProjection = -1; int sLocProjection = -1;
C3D_AttrInfo* attrInfo = nullptr; C3D_AttrInfo* attrInfo = nullptr;
C3D_BufInfo* bufInfo = nullptr;
void ResetBuffer() { bufferInd = 0; }
void* AllocBuffer(size_t size, size_t align = 1) {
bufferInd += align - (bufferInd % align); // prealign
void* b = reinterpret_cast<void*>(reinterpret_cast<size_t>(bufferStart) + bufferInd);
bufferInd += size;
if (bufferInd > bufferSize) return nullptr;
return b;
}
inline unsigned int NextPow2(unsigned int x) { inline unsigned int NextPow2(unsigned int x) {
--x; --x;
@ -98,13 +87,15 @@ void RenderCore::Open() {
gfxSet3D(true); gfxSet3D(true);
C3D_Init(0x80000*8); C3D_Init(0x80000*8);
// allocate and init VBO // allocate and initialize VBO
bufferSize = 0x80000; vboSize = 0x80000;
bufferStart = linearAlloc(bufferSize); void* vboAddr = linearAlloc(vboSize);
bufferInd = 0; vboArray = reinterpret_cast<vbo_xyzuv*>(vboAddr);
vboIndex = 0;
bufInfo = C3D_GetBufInfo(); C3D_BufInfo* bufInfo = C3D_GetBufInfo();
BufInfo_Init(bufInfo); BufInfo_Init(bufInfo);
BufInfo_Add(bufInfo, vboAddr, sizeof(vbo_xyzuv), 2, 0x10);
// set up shader attribute passing // set up shader attribute passing
attrInfo = C3D_GetAttrInfo(); attrInfo = C3D_GetAttrInfo();
@ -143,7 +134,7 @@ void RenderCore::Close() {
targetTopRight.reset(nullptr); targetTopRight.reset(nullptr);
targetBottom.reset(nullptr); targetBottom.reset(nullptr);
linearFree(bufferStart); linearFree(reinterpret_cast<void*>(vboArray));
C3D_Fini(); C3D_Fini();
gfxExit(); gfxExit();
@ -154,8 +145,9 @@ void RenderCore::SyncFrame() {
} }
void RenderCore::BeginFrame() { void RenderCore::BeginFrame() {
ResetBuffer();
C3D_FrameBegin(0/*C3D_FRAME_SYNCDRAW*/); C3D_FrameBegin(0/*C3D_FRAME_SYNCDRAW*/);
vboIndex = 0;
} }
void RenderCore::EndFrame() { void RenderCore::EndFrame() {
@ -210,7 +202,7 @@ void RenderCore::BindColor(const Color& color, BlendMode mode) {
} }
void RenderCore::DrawQuad(const VRect& rect, const VRect& src, bool noSnap) { void RenderCore::DrawQuad(const VRect& rect, const VRect& src, bool noSnap) {
vbo_xyzuv* verts = static_cast<vbo_xyzuv*>(AllocBuffer(4 * sizeof(vbo_xyzuv), 8)); size_t vboNum = vboIndex;
VRect r = noSnap ? rect : rect.IntSnap(); // screen-space snap VRect r = noSnap ? rect : rect.IntSnap(); // screen-space snap
@ -222,31 +214,23 @@ void RenderCore::DrawQuad(const VRect& rect, const VRect& src, bool noSnap) {
// let's make this recalculate things a bit less // let's make this recalculate things a bit less
float rl = r.pos.x, rr = rl + r.size.x, rt = r.pos.y, rb = rt + r.size.y; float rl = r.pos.x, rr = rl + r.size.x, rt = r.pos.y, rb = rt + r.size.y;
float srl = src.pos.x, srr = srl + src.size.x, srt = src.pos.y, srb = srt + src.size.y; float srl = src.pos.x, srr = srl + src.size.x, srt = src.pos.y, srb = srt + src.size.y;
setXYZUV(verts[0], rl, rt, 0, srl, srt); addVertXYZUV(rl, rt, 0, srl, srt);
setXYZUV(verts[1], rr, rt, 0, srr, srt); addVertXYZUV(rr, rt, 0, srr, srt);
setXYZUV(verts[2], rl, rb, 0, srl, srb); addVertXYZUV(rl, rb, 0, srl, srb);
setXYZUV(verts[3], rr, rb, 0, srr, srb); addVertXYZUV(rr, rb, 0, srr, srb);
bufInfo = C3D_GetBufInfo(); C3D_DrawArrays(GPU_TRIANGLE_STRIP, vboNum, 4);
BufInfo_Init(bufInfo);
BufInfo_Add(bufInfo, verts, sizeof(vbo_xyzuv), 2, 0x10);
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
} }
void RenderCore::DrawQuad(const VRect& rect, const Vector2& anchor, float angle, const VRect& src) { void RenderCore::DrawQuad(const VRect& rect, const Vector2& anchor, float angle, const VRect& src) {
vbo_xyzuv* verts = static_cast<vbo_xyzuv*>(AllocBuffer(4 * sizeof(vbo_xyzuv), 8)); size_t vboNum = vboIndex;
setXYZUV(verts[0], rect.TopLeft().RotateAround(anchor, angle), src.TopLeft()); addVertXYZUV(rect.TopLeft().RotateAround(anchor, angle), src.TopLeft());
setXYZUV(verts[1], rect.TopRight().RotateAround(anchor, angle), src.TopRight()); addVertXYZUV(rect.TopRight().RotateAround(anchor, angle), src.TopRight());
setXYZUV(verts[2], rect.BottomLeft().RotateAround(anchor, angle), src.BottomLeft()); addVertXYZUV(rect.BottomLeft().RotateAround(anchor, angle), src.BottomLeft());
setXYZUV(verts[3], rect.BottomRight().RotateAround(anchor, angle), src.BottomRight()); addVertXYZUV(rect.BottomRight().RotateAround(anchor, angle), src.BottomRight());
bufInfo = C3D_GetBufInfo(); C3D_DrawArrays(GPU_TRIANGLE_STRIP, vboNum, 4);
BufInfo_Init(bufInfo);
BufInfo_Add(bufInfo, verts, sizeof(vbo_xyzuv), 2, 0x10);
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
} }
// specifically RGBA // specifically RGBA