mirror of
https://github.com/bjornbytes/lovr.git
synced 2024-07-04 13:33:34 +00:00
Simplify Pass draw list;
It's a normal stretchy buffer instead of a weird page table thing. This was definitely overdesigned. Now it uses less memory too.
This commit is contained in:
parent
e5733bc667
commit
209ea1e4b5
|
@ -504,14 +504,14 @@ struct Pass {
|
||||||
Pipeline* pipeline;
|
Pipeline* pipeline;
|
||||||
uint32_t transformIndex;
|
uint32_t transformIndex;
|
||||||
uint32_t pipelineIndex;
|
uint32_t pipelineIndex;
|
||||||
|
char* constants;
|
||||||
gpu_binding* bindings;
|
gpu_binding* bindings;
|
||||||
uint32_t bindingMask;
|
uint32_t bindingMask;
|
||||||
char* constants;
|
|
||||||
uint32_t computeCount;
|
uint32_t computeCount;
|
||||||
uint32_t drawCount;
|
|
||||||
Compute* computes;
|
Compute* computes;
|
||||||
Draw** draws;
|
uint32_t drawCount;
|
||||||
Draw* lastDraw;
|
uint32_t drawCapacity;
|
||||||
|
Draw* draws;
|
||||||
PassStats stats;
|
PassStats stats;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1115,7 +1115,7 @@ static void recordRenderPass(Pass* pass, gpu_stream* stream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (drawIndex < pass->drawCount) {
|
while (drawIndex < pass->drawCount) {
|
||||||
Draw* draw = &pass->draws[drawIndex >> 8][drawIndex & 0xff];
|
Draw* draw = &pass->draws[drawIndex];
|
||||||
|
|
||||||
if (draw->camera != c) {
|
if (draw->camera != c) {
|
||||||
break;
|
break;
|
||||||
|
@ -1217,7 +1217,7 @@ static void recordRenderPass(Pass* pass, gpu_stream* stream) {
|
||||||
DrawData* data = mapped.pointer;
|
DrawData* data = mapped.pointer;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < activeDrawCount; i++, data++) {
|
for (uint32_t i = 0; i < activeDrawCount; i++, data++) {
|
||||||
Draw* draw = &pass->draws[activeDraws[i] >> 8][activeDraws[i] & 0xff];
|
Draw* draw = &pass->draws[activeDraws[i]];
|
||||||
// transform is provided as 4x3 row-major matrix for packing reasons, need to transpose
|
// transform is provided as 4x3 row-major matrix for packing reasons, need to transpose
|
||||||
data->transform[0] = draw->transform[0];
|
data->transform[0] = draw->transform[0];
|
||||||
data->transform[1] = draw->transform[4];
|
data->transform[1] = draw->transform[4];
|
||||||
|
@ -1241,20 +1241,19 @@ static void recordRenderPass(Pass* pass, gpu_stream* stream) {
|
||||||
|
|
||||||
// Pipelines
|
// Pipelines
|
||||||
|
|
||||||
if (!pass->lastDraw->pipeline) {
|
if (!pass->draws[pass->drawCount - 1].pipeline) {
|
||||||
uint32_t i = 0;
|
uint32_t first = 0;
|
||||||
Draw* prev = NULL;
|
|
||||||
|
|
||||||
while (i < pass->drawCount && pass->draws[i >> 8][i & 0xff].pipeline) {
|
while (pass->draws[first].pipeline) {
|
||||||
i++;
|
first++; // TODO could binary search or cache
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i < pass->drawCount) {
|
for (uint32_t i = first; i < pass->drawCount; i++) {
|
||||||
Draw* draw = &pass->draws[i >> 8][i & 0xff];
|
Draw* prev = &pass->draws[i - 1];
|
||||||
|
Draw* draw = &pass->draws[i];
|
||||||
|
|
||||||
if (prev && draw->pipelineInfo == prev->pipelineInfo) {
|
if (i > 0 && draw->pipelineInfo == prev->pipelineInfo) {
|
||||||
draw->pipeline = prev->pipeline;
|
draw->pipeline = prev->pipeline;
|
||||||
i++;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1271,8 +1270,6 @@ static void recordRenderPass(Pass* pass, gpu_stream* stream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
draw->pipeline = state.pipelines.data[index];
|
draw->pipeline = state.pipelines.data[index];
|
||||||
prev = draw;
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1280,7 +1277,7 @@ static void recordRenderPass(Pass* pass, gpu_stream* stream) {
|
||||||
|
|
||||||
Draw* prev = NULL;
|
Draw* prev = NULL;
|
||||||
for (uint32_t i = 0; i < activeDrawCount; i++) {
|
for (uint32_t i = 0; i < activeDrawCount; i++) {
|
||||||
Draw* draw = &pass->draws[activeDraws[i] >> 8][activeDraws[i] & 0xff];
|
Draw* draw = &pass->draws[activeDraws[i]];
|
||||||
|
|
||||||
if (i > 0 && draw->bundleInfo == prev->bundleInfo) {
|
if (i > 0 && draw->bundleInfo == prev->bundleInfo) {
|
||||||
draw->bundle = prev->bundle;
|
draw->bundle = prev->bundle;
|
||||||
|
@ -1344,7 +1341,7 @@ static void recordRenderPass(Pass* pass, gpu_stream* stream) {
|
||||||
gpu_bind_vertex_buffers(stream, &state.defaultBuffer->gpu, NULL, 1, 1);
|
gpu_bind_vertex_buffers(stream, &state.defaultBuffer->gpu, NULL, 1, 1);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < activeDrawCount; i++) {
|
for (uint32_t i = 0; i < activeDrawCount; i++) {
|
||||||
Draw* draw = &pass->draws[activeDraws[i] >> 8][activeDraws[i] & 0xff];
|
Draw* draw = &pass->draws[activeDraws[i]];
|
||||||
bool constantsDirty = draw->constants != constants;
|
bool constantsDirty = draw->constants != constants;
|
||||||
|
|
||||||
if (pass->tally.buffer && draw->tally != tally) {
|
if (pass->tally.buffer && draw->tally != tally) {
|
||||||
|
@ -4931,7 +4928,7 @@ static void lovrPassRelease(Pass* pass) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < pass->drawCount; i++) {
|
for (uint32_t i = 0; i < pass->drawCount; i++) {
|
||||||
Draw* draw = &pass->draws[i >> 8][i & 0xff];
|
Draw* draw = &pass->draws[i];
|
||||||
lovrRelease(draw->shader, lovrShaderDestroy);
|
lovrRelease(draw->shader, lovrShaderDestroy);
|
||||||
lovrRelease(draw->material, lovrMaterialDestroy);
|
lovrRelease(draw->material, lovrMaterialDestroy);
|
||||||
}
|
}
|
||||||
|
@ -4976,7 +4973,7 @@ Pass* lovrPassCreate(void) {
|
||||||
pass->ref = 1;
|
pass->ref = 1;
|
||||||
|
|
||||||
pass->allocator.limit = 1 << 28;
|
pass->allocator.limit = 1 << 28;
|
||||||
pass->allocator.length = 1 << 16;
|
pass->allocator.length = 1 << 12;
|
||||||
pass->allocator.memory = os_vm_init(pass->allocator.limit);
|
pass->allocator.memory = os_vm_init(pass->allocator.limit);
|
||||||
os_vm_commit(pass->allocator.memory, pass->allocator.length);
|
os_vm_commit(pass->allocator.memory, pass->allocator.length);
|
||||||
pass->buffers.type = GPU_BUFFER_STREAM;
|
pass->buffers.type = GPU_BUFFER_STREAM;
|
||||||
|
@ -5018,11 +5015,12 @@ void lovrPassReset(Pass* pass) {
|
||||||
pass->flags = DIRTY_BINDINGS | DIRTY_CONSTANTS;
|
pass->flags = DIRTY_BINDINGS | DIRTY_CONSTANTS;
|
||||||
pass->transform = lovrPassAllocate(pass, MAX_TRANSFORMS * 16 * sizeof(float));
|
pass->transform = lovrPassAllocate(pass, MAX_TRANSFORMS * 16 * sizeof(float));
|
||||||
pass->pipeline = lovrPassAllocate(pass, MAX_PIPELINES * sizeof(Pipeline));
|
pass->pipeline = lovrPassAllocate(pass, MAX_PIPELINES * sizeof(Pipeline));
|
||||||
pass->bindings = lovrPassAllocate(pass, 32 * sizeof(gpu_binding));
|
|
||||||
pass->constants = lovrPassAllocate(pass, state.limits.pushConstantSize);
|
pass->constants = lovrPassAllocate(pass, state.limits.pushConstantSize);
|
||||||
pass->draws = lovrPassAllocate(pass, 256 * sizeof(Draw*));
|
pass->bindings = lovrPassAllocate(pass, 32 * sizeof(gpu_binding));
|
||||||
pass->lastDraw = NULL;
|
pass->computeCount = 0;
|
||||||
pass->computes = NULL;
|
pass->computes = NULL;
|
||||||
|
pass->drawCount = 0;
|
||||||
|
pass->draws = lovrPassAllocate(pass, pass->drawCapacity * sizeof(Draw));
|
||||||
|
|
||||||
memset(&pass->geocache, 0, sizeof(pass->geocache));
|
memset(&pass->geocache, 0, sizeof(pass->geocache));
|
||||||
|
|
||||||
|
@ -5077,9 +5075,6 @@ void lovrPassReset(Pass* pass) {
|
||||||
|
|
||||||
pass->sampler = NULL;
|
pass->sampler = NULL;
|
||||||
pass->bindingMask = 0;
|
pass->bindingMask = 0;
|
||||||
|
|
||||||
pass->computeCount = 0;
|
|
||||||
pass->drawCount = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const PassStats* lovrPassGetStats(Pass* pass) {
|
const PassStats* lovrPassGetStats(Pass* pass) {
|
||||||
|
@ -5709,7 +5704,7 @@ void lovrPassSendData(Pass* pass, const char* name, size_t length, uint32_t slot
|
||||||
*format = resource->format;
|
*format = resource->format;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lovrPassResolvePipeline(Pass* pass, DrawInfo* info, Draw* draw) {
|
static void lovrPassResolvePipeline(Pass* pass, DrawInfo* info, Draw* draw, Draw* prev) {
|
||||||
Pipeline* pipeline = pass->pipeline;
|
Pipeline* pipeline = pass->pipeline;
|
||||||
Shader* shader = draw->shader;
|
Shader* shader = draw->shader;
|
||||||
|
|
||||||
|
@ -5792,8 +5787,8 @@ static void lovrPassResolvePipeline(Pass* pass, DrawInfo* info, Draw* draw) {
|
||||||
memcpy(draw->pipelineInfo, &pipeline->info, sizeof(pipeline->info));
|
memcpy(draw->pipelineInfo, &pipeline->info, sizeof(pipeline->info));
|
||||||
draw->pipeline = NULL;
|
draw->pipeline = NULL;
|
||||||
} else {
|
} else {
|
||||||
draw->pipelineInfo = pass->lastDraw->pipelineInfo;
|
draw->pipelineInfo = prev->pipelineInfo;
|
||||||
draw->pipeline = pass->lastDraw->pipeline;
|
draw->pipeline = prev->pipeline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5890,12 +5885,16 @@ static void* lovrPassResolveConstants(Pass* pass, Shader* shader, void* previous
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrPassDraw(Pass* pass, DrawInfo* info) {
|
void lovrPassDraw(Pass* pass, DrawInfo* info) {
|
||||||
if ((pass->drawCount & 0xff) == 0) {
|
if (pass->drawCount >= pass->drawCapacity) {
|
||||||
lovrCheck(pass->drawCount < 256 * 256, "Pass has too many draws!");
|
lovrAssert(pass->drawCount < 1 << 16, "Pass has too many draws!");
|
||||||
pass->draws[pass->drawCount >> 8] = lovrPassAllocate(pass, 256 * sizeof(Draw));
|
pass->drawCapacity = pass->drawCapacity > 0 ? pass->drawCapacity << 1 : 1;
|
||||||
|
Draw* draws = lovrPassAllocate(pass, pass->drawCapacity * sizeof(Draw));
|
||||||
|
memcpy(draws, pass->draws, pass->drawCount * sizeof(Draw));
|
||||||
|
pass->draws = draws;
|
||||||
}
|
}
|
||||||
|
|
||||||
Draw* draw = &pass->draws[pass->drawCount >> 8][pass->drawCount & 0xff];
|
Draw* prev = pass->drawCount > 0 ? &pass->draws[pass->drawCount - 1] : NULL;
|
||||||
|
Draw* draw = &pass->draws[pass->drawCount++];
|
||||||
|
|
||||||
draw->flags = 0;
|
draw->flags = 0;
|
||||||
draw->tally = pass->tally.active ? pass->tally.count : ~0u;
|
draw->tally = pass->tally.active ? pass->tally.count : ~0u;
|
||||||
|
@ -5916,11 +5915,11 @@ void lovrPassDraw(Pass* pass, DrawInfo* info) {
|
||||||
draw->instances = MAX(info->instances, 1);
|
draw->instances = MAX(info->instances, 1);
|
||||||
draw->baseVertex = info->base;
|
draw->baseVertex = info->base;
|
||||||
|
|
||||||
lovrPassResolvePipeline(pass, info, draw);
|
lovrPassResolvePipeline(pass, info, draw, prev);
|
||||||
lovrPassResolveBuffers(pass, info, draw);
|
lovrPassResolveBuffers(pass, info, draw);
|
||||||
|
|
||||||
draw->bundleInfo = lovrPassResolveBindings(pass, draw->shader, pass->lastDraw ? pass->lastDraw->bundleInfo : NULL);
|
draw->bundleInfo = lovrPassResolveBindings(pass, draw->shader, prev ? prev->bundleInfo : NULL);
|
||||||
draw->constants = lovrPassResolveConstants(pass, draw->shader, pass->lastDraw ? pass->lastDraw->constants : NULL);
|
draw->constants = lovrPassResolveConstants(pass, draw->shader, prev ? prev->constants : NULL);
|
||||||
|
|
||||||
if (pass->pipeline->viewCull && info->bounds) {
|
if (pass->pipeline->viewCull && info->bounds) {
|
||||||
memcpy(draw->bounds, info->bounds, sizeof(draw->bounds));
|
memcpy(draw->bounds, info->bounds, sizeof(draw->bounds));
|
||||||
|
@ -5931,8 +5930,6 @@ void lovrPassDraw(Pass* pass, DrawInfo* info) {
|
||||||
mat4_init(draw->transform, pass->transform);
|
mat4_init(draw->transform, pass->transform);
|
||||||
if (info->transform) mat4_mul(draw->transform, info->transform);
|
if (info->transform) mat4_mul(draw->transform, info->transform);
|
||||||
memcpy(draw->color, pass->pipeline->color, 4 * sizeof(float));
|
memcpy(draw->color, pass->pipeline->color, 4 * sizeof(float));
|
||||||
pass->lastDraw = draw;
|
|
||||||
pass->drawCount++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrPassPoints(Pass* pass, uint32_t count, float** points) {
|
void lovrPassPoints(Pass* pass, uint32_t count, float** points) {
|
||||||
|
@ -6968,12 +6965,16 @@ void lovrPassMeshIndirect(Pass* pass, Buffer* vertices, Buffer* indices, Buffer*
|
||||||
.index.buffer = indices
|
.index.buffer = indices
|
||||||
};
|
};
|
||||||
|
|
||||||
if ((pass->drawCount & 0xff) == 0) {
|
if (pass->drawCount >= pass->drawCapacity) {
|
||||||
lovrCheck(pass->drawCount < 256 * 256, "Pass has too many draws!");
|
lovrAssert(pass->drawCount < 1 << 16, "Pass has too many draws!");
|
||||||
pass->draws[pass->drawCount >> 8] = lovrPassAllocate(pass, 256 * sizeof(Draw));
|
pass->drawCapacity = pass->drawCapacity > 0 ? pass->drawCapacity << 1 : 1;
|
||||||
|
Draw* draws = lovrPassAllocate(pass, pass->drawCapacity * sizeof(Draw));
|
||||||
|
memcpy(draws, pass->draws, pass->drawCount * sizeof(Draw));
|
||||||
|
pass->draws = draws;
|
||||||
}
|
}
|
||||||
|
|
||||||
Draw* draw = &pass->draws[pass->drawCount >> 8][pass->drawCount++ & 0xff];
|
Draw* prev = pass->drawCount > 0 ? &pass->draws[pass->drawCount - 1] : NULL;
|
||||||
|
Draw* draw = &pass->draws[pass->drawCount++];
|
||||||
|
|
||||||
draw->flags = DRAW_INDIRECT;
|
draw->flags = DRAW_INDIRECT;
|
||||||
draw->tally = pass->tally.active ? pass->tally.count : ~0u;
|
draw->tally = pass->tally.active ? pass->tally.count : ~0u;
|
||||||
|
@ -6992,15 +6993,14 @@ void lovrPassMeshIndirect(Pass* pass, Buffer* vertices, Buffer* indices, Buffer*
|
||||||
draw->indirect.count = count;
|
draw->indirect.count = count;
|
||||||
draw->indirect.stride = stride;
|
draw->indirect.stride = stride;
|
||||||
|
|
||||||
lovrPassResolvePipeline(pass, &info, draw);
|
lovrPassResolvePipeline(pass, &info, draw, prev);
|
||||||
lovrPassResolveBuffers(pass, &info, draw);
|
lovrPassResolveBuffers(pass, &info, draw);
|
||||||
|
|
||||||
draw->bundleInfo = lovrPassResolveBindings(pass, shader, pass->lastDraw ? pass->lastDraw->bundleInfo : NULL);
|
draw->bundleInfo = lovrPassResolveBindings(pass, shader, prev ? prev->bundleInfo : NULL);
|
||||||
draw->constants = lovrPassResolveConstants(pass, shader, pass->lastDraw ? pass->lastDraw->constants : NULL);
|
draw->constants = lovrPassResolveConstants(pass, shader, prev ? prev->constants : NULL);
|
||||||
|
|
||||||
mat4_init(draw->transform, pass->transform);
|
mat4_init(draw->transform, pass->transform);
|
||||||
memcpy(draw->color, pass->pipeline->color, 4 * sizeof(float));
|
memcpy(draw->color, pass->pipeline->color, 4 * sizeof(float));
|
||||||
pass->lastDraw = draw;
|
|
||||||
|
|
||||||
trackBuffer(pass, draws, GPU_PHASE_INDIRECT, GPU_CACHE_INDIRECT);
|
trackBuffer(pass, draws, GPU_PHASE_INDIRECT, GPU_CACHE_INDIRECT);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue