Skip to content

Commit

Permalink
rm Pass:append;
Browse files Browse the repository at this point in the history
This was an experiment that was never documented/announced.
  • Loading branch information
bjornbytes committed Nov 10, 2023
1 parent 534947b commit 62810a1
Show file tree
Hide file tree
Showing 4 changed files with 2 additions and 239 deletions.
8 changes: 0 additions & 8 deletions src/api/l_graphics_pass.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@ static int l_lovrPassReset(lua_State* L) {
return 1;
}

static int l_lovrPassAppend(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
Pass* other = luax_checktype(L, 2, Pass);
lovrPassAppend(pass, other);
return 0;
}

static int l_lovrPassGetStats(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
const PassStats* stats = lovrPassGetStats(pass);
Expand Down Expand Up @@ -1099,7 +1092,6 @@ static int l_lovrPassBarrier(lua_State* L) {

const luaL_Reg lovrPass[] = {
{ "reset", l_lovrPassReset },
{ "append", l_lovrPassAppend },
{ "getStats", l_lovrPassGetStats },

{ "getCanvas", l_lovrPassGetCanvas },
Expand Down
3 changes: 1 addition & 2 deletions src/core/gpu_vk.c
Original file line number Diff line number Diff line change
Expand Up @@ -3009,8 +3009,7 @@ static VkBufferUsageFlags getBufferUsage(gpu_buffer_type type) {
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
VK_BUFFER_USAGE_TRANSFER_DST_BIT;
VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
case GPU_BUFFER_UPLOAD:
return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
case GPU_BUFFER_DOWNLOAD:
Expand Down
229 changes: 1 addition & 228 deletions src/modules/graphics/graphics.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,8 +442,7 @@ typedef struct {
enum {
DRAW_INDIRECT = (1 << 0),
DRAW_INDEX32 = (1 << 1),
DRAW_INLINE_MESH = (1 << 2),
DRAW_HAS_BOUNDS = (1 << 3)
DRAW_HAS_BOUNDS = (1 << 2)
};

typedef struct {
Expand Down Expand Up @@ -492,8 +491,6 @@ struct Pass {
uint32_t flags;
Allocator allocator;
BufferPool buffers;
uint32_t firstScratchOffset;
ScratchBuffer* firstScratchBuffer;
Shape geocache[16];
AccessBlock* access[2];
Tally tally;
Expand Down Expand Up @@ -596,7 +593,6 @@ static size_t tempPush(Allocator* allocator);
static void tempPop(Allocator* allocator, size_t stack);
static MappedBuffer mapBuffer(BufferPool* pool, uint32_t size, size_t align);
static int u64cmp(const void* a, const void* b);
static uint32_t lcm(uint32_t a, uint32_t b);
static void beginFrame(void);
static void processReadbacks(void);
static size_t getLayout(gpu_slot* slots, uint32_t count);
Expand Down Expand Up @@ -5020,8 +5016,6 @@ void lovrPassReset(Pass* pass) {
pass->access[ACCESS_RENDER] = NULL;
pass->access[ACCESS_COMPUTE] = NULL;
pass->flags = DIRTY_BINDINGS | DIRTY_CONSTANTS;
pass->firstScratchOffset = pass->buffers.cursor;
pass->firstScratchBuffer = pass->buffers.newest;
pass->transform = lovrPassAllocate(pass, MAX_TRANSFORMS * 16 * sizeof(float));
pass->pipeline = lovrPassAllocate(pass, MAX_PIPELINES * sizeof(Pipeline));
pass->bindings = lovrPassAllocate(pass, 32 * sizeof(gpu_binding));
Expand Down Expand Up @@ -5088,217 +5082,6 @@ void lovrPassReset(Pass* pass) {
pass->drawCount = 0;
}

void lovrPassAppend(Pass* pass, Pass* other) {
lovrCheck(pass != other, "Unable to append a Pass to itself because it would destroy the universe or something...sorry");
beginFrame();

// First, copy all temporary buffer data into the buffer pool of the target Pass

uint32_t firstOffset = other->firstScratchBuffer ? other->firstScratchOffset: 0;
other->firstScratchBuffer = other->firstScratchBuffer ? other->firstScratchBuffer : other->buffers.oldest;
uint32_t totalScratchSize = 0;
uint32_t scratchBufferCount = 0;

// Need to calculate the LCM of *all* temp buffer data, because vertex data offsets need to be a
// multiple of the vertex stride after all the buffer data is copied. It's slow to go over all
// the draws like this instead of computing the align as draws are recorded, but this keeps
// overhead isolated to :append instead of increasing the overhead of all draws.
uint32_t align = state.limits.uniformBufferAlign;
for (uint32_t i = 0; i < other->drawCount; i++) {
Draw* draw = &other->draws[i >> 8][i & 0xff];
if (draw->flags & DRAW_INLINE_MESH) {
align = lcm(align, draw->pipelineInfo->vertex.bufferStrides[0]);
}
}

for (ScratchBuffer* scratchBuffer = other->firstScratchBuffer; scratchBuffer != NULL; scratchBuffer = scratchBuffer->next) {
uint32_t start = scratchBuffer == other->firstScratchBuffer ? firstOffset : 0;
uint32_t end = scratchBuffer == other->buffers.newest ? other->buffers.cursor : scratchBuffer->size;
totalScratchSize = (totalScratchSize + (align - 1)) / align * align + (end - start);
scratchBufferCount++;
}

struct {
gpu_buffer* buffer;
uint32_t stashOffset;
uint32_t base;
} *lookup = lovrPassAllocate(pass, scratchBufferCount * sizeof(*lookup));

MappedBuffer stash = mapBuffer(&pass->buffers, totalScratchSize, align);

uint32_t i = 0;
uint32_t cursor = 0;
for (ScratchBuffer* scratchBuffer = other->firstScratchBuffer; scratchBuffer != NULL; scratchBuffer = scratchBuffer->next) {
uint32_t start = scratchBuffer == other->firstScratchBuffer ? firstOffset : 0;
uint32_t end = scratchBuffer == other->buffers.newest ? other->buffers.cursor : scratchBuffer->size;
lookup[i].buffer = scratchBuffer->gpu;
lookup[i].stashOffset = stash.offset + cursor;
lookup[i].base = start;
gpu_copy_buffers(state.stream, scratchBuffer->gpu, stash.buffer, start, lookup[i].stashOffset, end - start);
cursor = (cursor + (align - 1)) / align * align + (end - start);
}

gpu_sync(state.stream, &(gpu_barrier) {
.prev = GPU_PHASE_TRANSFER,
.next = GPU_PHASE_INPUT_INDEX | GPU_PHASE_INPUT_VERTEX | GPU_PHASE_SHADER_VERTEX,
.flush = GPU_CACHE_TRANSFER_WRITE,
.clear = GPU_CACHE_INDEX | GPU_CACHE_VERTEX | GPU_CACHE_UNIFORM
}, 1);

Canvas* canvas = &pass->canvas;
uint32_t baseTally = pass->tally.count;
gpu_pipeline_info* srcPipelineInfo = NULL;
gpu_pipeline_info* dstPipelineInfo = NULL;
gpu_bundle_info* srcBundleInfo = NULL;
gpu_bundle_info* dstBundleInfo = NULL;
void* srcConstants = NULL;
void* dstConstants = NULL;

for (uint32_t i = 0; i < other->drawCount; i++) {
if ((pass->drawCount & 0xff) == 0) {
lovrCheck(pass->drawCount < 256 * 256, "Pass has too many draws!");
pass->draws[pass->drawCount >> 8] = lovrPassAllocate(pass, 256 * sizeof(Draw));
}

Draw* src = &other->draws[i >> 8][i & 0xff];
Draw* dst = &pass->draws[pass->drawCount >> 8][pass->drawCount & 0xff];

dst->flags = src->flags;
dst->camera = pass->cameraCount - 1;
dst->tally = pass->tally.active ? pass->tally.count : (baseTally + src->tally);
dst->shader = src->shader;
dst->material = src->material;
lovrRetain(dst->shader);
lovrRetain(dst->material);

dst->pipeline = NULL;
if (src->pipelineInfo != srcPipelineInfo) {
dst->pipelineInfo = lovrPassAllocate(pass, sizeof(gpu_pipeline_info));
memcpy(dst->pipelineInfo, src->pipelineInfo, sizeof(gpu_pipeline_info));

dst->pipelineInfo->attachmentCount = canvas->count;
dst->pipelineInfo->multisample.count = canvas->samples;
dst->pipelineInfo->viewCount = canvas->views;
dst->pipelineInfo->depth.format = (gpu_texture_format) canvas->depth.format;
for (uint32_t j = 0; j < canvas->count; j++) {
dst->pipelineInfo->color[j].format = (gpu_texture_format) canvas->color[j].texture->info.format;
dst->pipelineInfo->color[j].srgb = canvas->color[j].texture->info.srgb;
}

srcPipelineInfo = src->pipelineInfo;
dstPipelineInfo = dst->pipelineInfo;
} else {
dst->pipelineInfo = dstPipelineInfo;
}

dst->bundle = NULL;
if (src->bundleInfo != srcBundleInfo) {
gpu_bundle_info* bundle = lovrPassAllocate(pass, sizeof(gpu_bundle_info));
bundle->count = src->bundleInfo->count;
bundle->layout = src->bundleInfo->layout;
bundle->bindings = lovrPassAllocate(pass, bundle->count * sizeof(gpu_binding));
memcpy(bundle->bindings, src->bundleInfo->bindings, bundle->count * sizeof(gpu_binding));
dst->bundleInfo = bundle;
srcBundleInfo = src->bundleInfo;
dstBundleInfo = bundle;

for (uint32_t j = 0; j < bundle->count; j++) {
if (bundle->bindings[j].type != GPU_SLOT_UNIFORM_BUFFER) continue;
for (uint32_t k = 0; k < scratchBufferCount; k++) {
gpu_buffer_binding* buffer = &bundle->bindings[j].buffer;
if (lookup[k].buffer == buffer->object) {
buffer->object = stash.buffer;
buffer->offset = buffer->offset - lookup[k].base + lookup[k].stashOffset;
break;
}
}
}
} else {
dst->bundleInfo = dstBundleInfo;
}

if (src->constants != srcConstants) {
dst->constants = lovrPassAllocate(pass, dst->shader->constantSize);
memcpy(dst->constants, src->constants, dst->shader->constantSize);
srcConstants = src->constants;
dstConstants = dst->constants;
} else {
dst->constants = dstConstants;
}

if (dst->flags & DRAW_INLINE_MESH) {
if (src->vertexBuffer) {
dst->vertexBuffer = stash.buffer;
for (uint32_t j = 0; j < scratchBufferCount; j++) {
if (lookup[j].buffer == src->vertexBuffer) {
uint32_t stride = dst->pipelineInfo->vertex.bufferStrides[0];
uint32_t* first = src->indexBuffer ? &dst->baseVertex : &dst->start;
*first *= stride;
*first -= lookup[j].base;
*first += lookup[j].stashOffset;
*first /= stride;
break;
}
}
}

if (src->indexBuffer) {
dst->indexBuffer = stash.buffer;
for (uint32_t j = 0; j < scratchBufferCount; j++) {
if (lookup[j].buffer == src->indexBuffer) {
uint32_t stride = dst->flags & DRAW_INDEX32 ? 4 : 2;
dst->start = (dst->start * stride - lookup[j].base + lookup[j].stashOffset) * stride;
break;
}
}
}
} else {
dst->vertexBuffer = src->vertexBuffer;
dst->indexBuffer = src->indexBuffer;
}

if (dst->flags & DRAW_INDIRECT) {
dst->start = src->start;
dst->count = src->count;
dst->instances = src->instances;
dst->baseVertex = src->baseVertex;
} else {
dst->indirect.buffer = src->indirect.buffer;
dst->indirect.offset = src->indirect.offset;
dst->indirect.count = src->indirect.count;
dst->indirect.stride = src->indirect.stride;
}

memcpy(dst->transform, src->transform, sizeof(src->transform));
memcpy(dst->color, src->color, sizeof(src->color));
memcpy(dst->bounds, src->bounds, sizeof(src->bounds));

pass->lastDraw = dst;
pass->drawCount++;
}

for (AccessBlock* block = other->access[ACCESS_RENDER]; block != NULL; block = block->next) {
for (uint64_t i = 0; i < block->count; i++) {
bool isTexture = !!(block->textureMask & (1ull << i));
Access* access = getNextAccess(pass, ACCESS_RENDER, isTexture);
memcpy(access, &block->list[i], sizeof(Access));
if (isTexture) {
Texture* texture = (Texture*) ((char*) block->list[i].sync - offsetof(Texture, sync));
lovrRetain(texture);
} else {
Buffer* buffer = (Buffer*) ((char*) block->list[i].sync - offsetof(Buffer, sync));
lovrRetain(buffer);
}
}
}

if (!pass->tally.active) {
pass->tally.count += other->tally.count;
}

pass->flags &= ~DIRTY_CAMERA;
}

const PassStats* lovrPassGetStats(Pass* pass) {
pass->stats.draws = pass->drawCount;
pass->stats.computes = pass->computeCount;
Expand Down Expand Up @@ -6032,7 +5815,6 @@ static void lovrPassResolveBuffers(Pass* pass, DrawInfo* info, Draw* draw) {
uint32_t stride = state.vertexFormats[info->vertex.format].bufferStrides[0];
MappedBuffer mapped = mapBuffer(&pass->buffers, info->vertex.count * stride, stride);
*info->vertex.pointer = mapped.pointer;
draw->flags |= DRAW_INLINE_MESH;
draw->vertexBuffer = mapped.buffer;
if (info->index.buffer || info->index.count > 0) {
draw->baseVertex = mapped.offset / stride;
Expand All @@ -6050,7 +5832,6 @@ static void lovrPassResolveBuffers(Pass* pass, DrawInfo* info, Draw* draw) {
if (!info->index.buffer && info->index.count > 0) {
MappedBuffer mapped = mapBuffer(&pass->buffers, info->index.count * 2, 2);
*info->index.pointer = mapped.pointer;
draw->flags |= DRAW_INLINE_MESH;
draw->indexBuffer = mapped.buffer;
draw->start = mapped.offset / 2;
} else if (info->index.buffer) {
Expand Down Expand Up @@ -7376,14 +7157,6 @@ static int u64cmp(const void* a, const void* b) {
return (x > y) - (x < y);
}

static uint32_t gcd(uint32_t a, uint32_t b) {
return b ? gcd(b, a % b) : a;
}

static uint32_t lcm(uint32_t a, uint32_t b) {
return (a / gcd(a, b)) * b;
}

static void beginFrame(void) {
if (state.active) {
return;
Expand Down
1 change: 0 additions & 1 deletion src/modules/graphics/graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,6 @@ Pass* lovrGraphicsGetWindowPass(void);
Pass* lovrPassCreate(void);
void lovrPassDestroy(void* ref);
void lovrPassReset(Pass* pass);
void lovrPassAppend(Pass* pass, Pass* other);
const PassStats* lovrPassGetStats(Pass* pass);

void lovrPassGetCanvas(Pass* pass, Texture* color[4], Texture** depthTexture, uint32_t* depthFormat, uint32_t* samples);
Expand Down

0 comments on commit 62810a1

Please sign in to comment.