mirror of https://github.com/bjornbytes/lovr.git
parent
2896dc0bfa
commit
3d83d0fcfe
|
@ -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 },
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue