diff options
author | EpEpDragon <bergapie@gmail.com> | 2022-12-28 10:37:42 +0200 |
---|---|---|
committer | EpEpDragon <bergapie@gmail.com> | 2023-01-06 17:08:37 +0200 |
commit | 36d02882b9ac773416fb3304fa7679bcdb45e7b9 (patch) | |
tree | 231def654067d772ed7d2567e42e8418d921007e | |
parent | b14f7aa9f92ff44135c283a9c88dab5ef9136d64 (diff) |
Added optional offset and size parameter to RenderDevice buffer_get_data method
-rw-r--r-- | doc/classes/RenderingDevice.xml | 3 | ||||
-rw-r--r-- | drivers/vulkan/rendering_device_vulkan.cpp | 20 | ||||
-rw-r--r-- | drivers/vulkan/rendering_device_vulkan.h | 2 | ||||
-rw-r--r-- | servers/rendering/rendering_device.cpp | 2 | ||||
-rw-r--r-- | servers/rendering/rendering_device.h | 2 |
5 files changed, 20 insertions, 9 deletions
diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml index f318430611..a575ea80b0 100644 --- a/doc/classes/RenderingDevice.xml +++ b/doc/classes/RenderingDevice.xml @@ -26,7 +26,10 @@ <method name="buffer_get_data"> <return type="PackedByteArray" /> <param index="0" name="buffer" type="RID" /> + <param index="1" name="offset_bytes" type="int" default="0" /> + <param index="2" name="size_bytes" type="int" default="0" /> <description> + Returns a copy of the data of the specified [param buffer], optionally [param offset_bytes] and [param size_bytes] can be set to copy only a portion of the buffer. </description> </method> <method name="buffer_update"> diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 425ca1c516..5c834be0b9 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -5926,7 +5926,7 @@ Error RenderingDeviceVulkan::buffer_clear(RID p_buffer, uint32_t p_offset, uint3 return OK; } -Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) { +Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer, uint32_t p_offset, uint32_t p_size) { _THREAD_SAFE_METHOD_ // It could be this buffer was just created. @@ -5943,12 +5943,20 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) { VkCommandBuffer command_buffer = frames[frame].setup_command_buffer; + // Size of buffer to retrieve. + if (!p_size) { + p_size = buffer->size; + } else { + ERR_FAIL_COND_V_MSG(p_size + p_offset > buffer->size, Vector<uint8_t>(), + "Size is larger than the buffer."); + } + Buffer tmp_buffer; - _buffer_allocate(&tmp_buffer, buffer->size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_HOST, VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT); + _buffer_allocate(&tmp_buffer, p_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_HOST, VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT); VkBufferCopy region; - region.srcOffset = 0; + region.srcOffset = p_offset; region.dstOffset = 0; - region.size = buffer->size; + region.size = p_size; vkCmdCopyBuffer(command_buffer, buffer->buffer, tmp_buffer.buffer, 1, ®ion); // Dst buffer is in CPU, but I wonder if src buffer needs a barrier for this. // Flush everything so memory can be safely mapped. _flush(true); @@ -5959,9 +5967,9 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) { Vector<uint8_t> buffer_data; { - buffer_data.resize(buffer->size); + buffer_data.resize(p_size); uint8_t *w = buffer_data.ptrw(); - memcpy(w, buffer_mem, buffer->size); + memcpy(w, buffer_mem, p_size); } vmaUnmapMemory(allocator, tmp_buffer.allocation); diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index b2c2a03a87..5d81e20fe2 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -1122,7 +1122,7 @@ public: virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS); // Works for any buffer. virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS); - virtual Vector<uint8_t> buffer_get_data(RID p_buffer); + virtual Vector<uint8_t> buffer_get_data(RID p_buffer, uint32_t p_offset = 0, uint32_t p_size = 0); /*************************/ /**** RENDER PIPELINE ****/ diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 28f872761a..286d1b683f 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -746,7 +746,7 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("buffer_update", "buffer", "offset", "size_bytes", "data", "post_barrier"), &RenderingDevice::_buffer_update, DEFVAL(BARRIER_MASK_ALL_BARRIERS)); ClassDB::bind_method(D_METHOD("buffer_clear", "buffer", "offset", "size_bytes", "post_barrier"), &RenderingDevice::buffer_clear, DEFVAL(BARRIER_MASK_ALL_BARRIERS)); - ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer"), &RenderingDevice::buffer_get_data); + ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer", "offset_bytes", "size_bytes"), &RenderingDevice::buffer_get_data, DEFVAL(0), DEFVAL(0)); ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags", "for_render_pass", "specialization_constants"), &RenderingDevice::_render_pipeline_create, DEFVAL(0), DEFVAL(0), DEFVAL(TypedArray<RDPipelineSpecializationConstant>())); ClassDB::bind_method(D_METHOD("render_pipeline_is_valid", "render_pipeline"), &RenderingDevice::render_pipeline_is_valid); diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 08ca25b64b..9de21dcac6 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -828,7 +828,7 @@ public: virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0; virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0; - virtual Vector<uint8_t> buffer_get_data(RID p_buffer) = 0; //this causes stall, only use to retrieve large buffers for saving + virtual Vector<uint8_t> buffer_get_data(RID p_buffer, uint32_t p_offset = 0, uint32_t p_size = 0) = 0; // This causes stall, only use to retrieve large buffers for saving. /******************************************/ /**** PIPELINE SPECIALIZATION CONSTANT ****/ |