Merge pull request #70663 from EpEpDragon/feature_buffer_get_data_size_option
Add optional size parameter to the RenderDevice buffer_get_data method.
This commit is contained in:
commit
ed85a2c8ce
@ -32,7 +32,10 @@
|
|||||||
<method name="buffer_get_data">
|
<method name="buffer_get_data">
|
||||||
<return type="PackedByteArray" />
|
<return type="PackedByteArray" />
|
||||||
<param index="0" name="buffer" type="RID" />
|
<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>
|
<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>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="buffer_update">
|
<method name="buffer_update">
|
||||||
|
@ -5927,7 +5927,7 @@ Error RenderingDeviceVulkan::buffer_clear(RID p_buffer, uint32_t p_offset, uint3
|
|||||||
return OK;
|
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_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
// It could be this buffer was just created.
|
// It could be this buffer was just created.
|
||||||
@ -5944,12 +5944,20 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) {
|
|||||||
|
|
||||||
VkCommandBuffer command_buffer = frames[frame].setup_command_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 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;
|
VkBufferCopy region;
|
||||||
region.srcOffset = 0;
|
region.srcOffset = p_offset;
|
||||||
region.dstOffset = 0;
|
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.
|
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 everything so memory can be safely mapped.
|
||||||
_flush(true);
|
_flush(true);
|
||||||
@ -5960,9 +5968,9 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) {
|
|||||||
|
|
||||||
Vector<uint8_t> buffer_data;
|
Vector<uint8_t> buffer_data;
|
||||||
{
|
{
|
||||||
buffer_data.resize(buffer->size);
|
buffer_data.resize(p_size);
|
||||||
uint8_t *w = buffer_data.ptrw();
|
uint8_t *w = buffer_data.ptrw();
|
||||||
memcpy(w, buffer_mem, buffer->size);
|
memcpy(w, buffer_mem, p_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
vmaUnmapMemory(allocator, tmp_buffer.allocation);
|
vmaUnmapMemory(allocator, tmp_buffer.allocation);
|
||||||
|
@ -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_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 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 ****/
|
/**** RENDER PIPELINE ****/
|
||||||
|
@ -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_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_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_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);
|
ClassDB::bind_method(D_METHOD("render_pipeline_is_valid", "render_pipeline"), &RenderingDevice::render_pipeline_is_valid);
|
||||||
|
@ -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_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 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 ****/
|
/**** PIPELINE SPECIALIZATION CONSTANT ****/
|
||||||
|
Loading…
Reference in New Issue
Block a user