Pass:multimesh;

IT'S ALIVE
This commit is contained in:
bjorn 2022-06-09 23:38:33 -07:00
parent 2896dc0bfa
commit 3d83d0fcfe
3 changed files with 49 additions and 15 deletions

View File

@ -519,6 +519,18 @@ static int l_lovrPassMesh(lua_State* L) {
return 0;
}
static int l_lovrPassMultimesh(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
Buffer* vertices = !lua_toboolean(L, 2) ? NULL : luax_totype(L, 2, Buffer);
Buffer* indices = luax_totype(L, 3, Buffer);
Buffer* draws = luax_checktype(L, 4, Buffer);
uint32_t count = luax_optu32(L, 5, 1);
uint32_t offset = luax_optu32(L, 6, 0);
uint32_t stride = luax_optu32(L, 7, 0);
lovrPassMultimesh(pass, vertices, indices, draws, count, offset, stride);
return 0;
}
static int l_lovrPassCompute(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
Buffer* buffer = luax_totype(L, 2, Buffer);
@ -720,6 +732,7 @@ const luaL_Reg lovrPass[] = {
{ "box", l_lovrPassBox },
{ "circle", l_lovrPassCircle },
{ "mesh", l_lovrPassMesh },
{ "multimesh", l_lovrPassMultimesh },
{ "compute", l_lovrPassCompute },

View File

@ -195,8 +195,6 @@ typedef struct {
uint32_t count;
uint32_t instances;
uint32_t base;
Buffer* indirect;
uint32_t offset;
} Draw;
typedef struct {
@ -2154,25 +2152,15 @@ static void lovrPassDraw(Pass* pass, Draw* draw) {
flushBuiltins(pass, draw, shader);
flushBuffers(pass, draw);
bool indexed = draw->index.buffer || draw->index.count > 0;
uint32_t defaultCount = draw->index.count > 0 ? draw->index.count : draw->vertex.count;
uint32_t count = draw->count > 0 ? draw->count : defaultCount;
uint32_t instances = MAX(draw->instances, 1);
uint32_t id = pass->drawCount & 0xff;
if (draw->indirect) {
trackBuffer(pass, draw->indirect, GPU_PHASE_INDIRECT, GPU_CACHE_INDIRECT);
if (indexed) {
gpu_draw_indirect_indexed(pass->stream, draw->indirect->gpu, draw->offset, count);
} else {
gpu_draw_indirect(pass->stream, draw->indirect->gpu, draw->offset, count);
}
if (draw->index.buffer || draw->index.count > 0) {
gpu_draw_indexed(pass->stream, count, instances, draw->start, draw->base, id);
} else {
if (indexed) {
gpu_draw_indexed(pass->stream, count, instances, draw->start, draw->base, id);
} else {
gpu_draw(pass->stream, count, instances, draw->start, id);
}
gpu_draw(pass->stream, count, instances, draw->start, id);
}
pass->drawCount++;
@ -2360,6 +2348,38 @@ void lovrPassMesh(Pass* pass, Buffer* vertices, Buffer* indices, float* transfor
});
}
void lovrPassMultimesh(Pass* pass, Buffer* vertices, Buffer* indices, Buffer* draws, uint32_t count, uint32_t offset, uint32_t stride) {
lovrCheck(pass->info.type == PASS_RENDER, "This function can only be called on a render pass");
lovrCheck(offset % 4 == 0, "Multimesh draw buffer offset must be a multiple of 4");
uint32_t commandSize = indices ? 20 : 16;
stride = stride ? stride : commandSize;
uint32_t totalSize = stride * (count - 1) + commandSize;
lovrCheck(offset + totalSize < draws->size, "Multimesh draw range exceeds size of draw buffer");
Draw draw = (Draw) {
.mode = pass->pipeline->drawMode,
.vertex.buffer = vertices,
.index.buffer = indices
};
Shader* shader = pass->pipeline->shader;
lovrCheck(shader, "A custom Shader must be bound to draw a multimesh");
flushPipeline(pass, &draw, shader);
flushConstants(pass, shader);
flushBindings(pass, shader);
flushBuiltins(pass, &draw, shader);
flushBuffers(pass, &draw);
if (indices) {
gpu_draw_indirect_indexed(pass->stream, draws->gpu, offset, count, stride);
} else {
gpu_draw_indirect(pass->stream, draws->gpu, offset, count, stride);
}
trackBuffer(pass, draws, GPU_PHASE_INDIRECT, GPU_CACHE_INDIRECT);
}
void lovrPassCompute(Pass* pass, uint32_t x, uint32_t y, uint32_t z, Buffer* indirect, uint32_t offset) {
lovrCheck(pass->info.type == PASS_COMPUTE, "This function can only be called on a compute pass");

View File

@ -406,6 +406,7 @@ void lovrPassPlane(Pass* pass, float* transform, uint32_t cols, uint32_t rows);
void lovrPassBox(Pass* pass, float* transform);
void lovrPassCircle(Pass* pass, float* transform, float angle1, float angle2, uint32_t segments);
void lovrPassMesh(Pass* pass, Buffer* vertices, Buffer* indices, float* transform, uint32_t start, uint32_t count, uint32_t instances);
void lovrPassMultimesh(Pass* pass, Buffer* vertices, Buffer* indices, Buffer* indirect, uint32_t count, uint32_t offset, uint32_t stride);
void lovrPassCompute(Pass* pass, uint32_t x, uint32_t y, uint32_t z, Buffer* indirect, uint32_t offset);
void lovrPassClearBuffer(Pass* pass, Buffer* buffer, uint32_t offset, uint32_t extent);
void lovrPassClearTexture(Pass* pass, Texture* texture, float value[4], uint32_t layer, uint32_t layerCount, uint32_t level, uint32_t levelCount);