From c1d8c64c456fc3eaeeb89a955fe296a5ff9558b5 Mon Sep 17 00:00:00 2001 From: bjorn Date: Wed, 22 Jun 2022 00:39:56 -0700 Subject: [PATCH] Pass:copy can copy tables to buffers; --- src/api/l_graphics_pass.c | 23 ++++++++++++++++++++++- src/modules/graphics/graphics.c | 4 ++-- src/modules/graphics/graphics.h | 2 +- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/api/l_graphics_pass.c b/src/api/l_graphics_pass.c index 2ea5c615..eeff18df 100644 --- a/src/api/l_graphics_pass.c +++ b/src/api/l_graphics_pass.c @@ -604,6 +604,26 @@ static int l_lovrPassClear(lua_State* L) { static int l_lovrPassCopy(lua_State* L) { Pass* pass = luax_checktype(L, 1, Pass); + if (lua_istable(L, 2)) { + Buffer* buffer = luax_checktype(L, 3, Buffer); + uint32_t srcIndex = luax_optu32(L, 4, 1) - 1; + uint32_t dstIndex = luax_optu32(L, 5, 1) - 1; + + lua_rawgeti(L, 2, 1); + bool nested = lua_istable(L, -1); + lua_pop(L, 1); + + uint32_t length = luax_len(L, 2); + const BufferInfo* info = lovrBufferGetInfo(buffer); + uint32_t limit = nested ? MIN(length - srcIndex, info->length - dstIndex) : info->length - dstIndex; + uint32_t count = luax_optu32(L, 6, limit); + + void* data = lovrPassCopyDataToBuffer(pass, buffer, dstIndex * info->stride, count * info->stride); + lua_remove(L, 3); // table, srcIndex, dstIndex, count + luax_readbufferdata(L, 2, buffer, data); + return 0; + } + Blob* blob = luax_totype(L, 2, Blob); if (blob) { @@ -615,7 +635,8 @@ static int l_lovrPassCopy(lua_State* L) { uint32_t extent = luax_optu32(L, 6, limit); lovrCheck(extent <= blob->size - srcOffset, "Buffer copy range exceeds Blob size"); lovrCheck(extent <= info->length * info->stride - dstOffset, "Buffer copy offset exceeds Buffer size"); - lovrPassCopyDataToBuffer(pass, (char*) blob->data + srcOffset, buffer, dstOffset, extent); + void* data = lovrPassCopyDataToBuffer(pass, buffer, dstOffset, extent); + memcpy(data, (char*) blob->data + srcOffset, extent); return 0; } diff --git a/src/modules/graphics/graphics.c b/src/modules/graphics/graphics.c index 0da348ca..856c519b 100644 --- a/src/modules/graphics/graphics.c +++ b/src/modules/graphics/graphics.c @@ -3323,7 +3323,7 @@ void lovrPassClearTexture(Pass* pass, Texture* texture, float value[4], uint32_t trackTexture(pass, texture, GPU_PHASE_TRANSFER, GPU_CACHE_TRANSFER_WRITE); } -void lovrPassCopyDataToBuffer(Pass* pass, void* data, Buffer* buffer, uint32_t offset, uint32_t extent) { +void* lovrPassCopyDataToBuffer(Pass* pass, Buffer* buffer, uint32_t offset, uint32_t extent) { lovrCheck(pass->info.type == PASS_TRANSFER, "This function can only be called on a transfer pass"); lovrCheck(!lovrBufferIsTemporary(buffer), "Temporary buffers can not be copied to, use Buffer:setData"); lovrCheck(offset + extent <= buffer->size, "Buffer copy range goes past the end of the Buffer"); @@ -3331,7 +3331,7 @@ void lovrPassCopyDataToBuffer(Pass* pass, void* data, Buffer* buffer, uint32_t o void* pointer = gpu_map(scratchpad, extent, 4, GPU_MAP_WRITE); gpu_copy_buffers(pass->stream, scratchpad, buffer->gpu, 0, offset, extent); trackBuffer(pass, buffer, GPU_PHASE_TRANSFER, GPU_CACHE_TRANSFER_WRITE); - memcpy(pointer, data, extent); + return pointer; } void lovrPassCopyBufferToBuffer(Pass* pass, Buffer* src, Buffer* dst, uint32_t srcOffset, uint32_t dstOffset, uint32_t extent) { diff --git a/src/modules/graphics/graphics.h b/src/modules/graphics/graphics.h index a7d5bb65..1fe00660 100644 --- a/src/modules/graphics/graphics.h +++ b/src/modules/graphics/graphics.h @@ -483,7 +483,7 @@ void lovrPassMultimesh(Pass* pass, Buffer* vertices, Buffer* indices, Buffer* in 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); -void lovrPassCopyDataToBuffer(Pass* pass, void* data, Buffer* buffer, uint32_t offset, uint32_t size); +void* lovrPassCopyDataToBuffer(Pass* pass, Buffer* buffer, uint32_t offset, uint32_t extent); void lovrPassCopyBufferToBuffer(Pass* pass, Buffer* src, Buffer* dst, uint32_t srcOffset, uint32_t dstOffset, uint32_t extent); void lovrPassCopyImageToTexture(Pass* pass, struct Image* src, Texture* dst, uint32_t srcOffset[4], uint32_t dstOffset[4], uint32_t extent[3]); void lovrPassCopyTextureToTexture(Pass* pass, Texture* src, Texture* dst, uint32_t srcOffset[4], uint32_t dstOffset[4], uint32_t extent[3]);