You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-09 12:50:35 +00:00
Add Persistent Buffers
This work is a heavily refactored and rewritten from TheForge's initial code. TheForge's original code had too many race conditions and was fundamentally flawed as it was too easy to incur into those data races by accident. However they identified the proper places that needed changes, and the idea was sound. I used their work as a blueprint to design this work. This PR implements: - Introduction of UMA buffers used by a few buffers (most notably the ones filled by _fill_instance_data). Ironically this change seems to positively affect PC more than it does on Mobile. Updates D3D12 Memory Allocator to get GPU_UPLOAD heap support. Metal implementation by Stuart Carnie. Co-authored-by: Stuart Carnie <stuart.carnie@gmail.com> Co-authored-by: TheForge team
This commit is contained in:
@@ -171,19 +171,30 @@ public:
|
||||
BUFFER_USAGE_VERTEX_BIT = (1 << 7),
|
||||
BUFFER_USAGE_INDIRECT_BIT = (1 << 8),
|
||||
BUFFER_USAGE_DEVICE_ADDRESS_BIT = (1 << 17),
|
||||
// There are no Vulkan-equivalent. Try to use unused/unclaimed bits.
|
||||
BUFFER_USAGE_DYNAMIC_PERSISTENT_BIT = (1 << 31),
|
||||
};
|
||||
|
||||
enum {
|
||||
BUFFER_WHOLE_SIZE = ~0ULL
|
||||
};
|
||||
|
||||
virtual BufferID buffer_create(uint64_t p_size, BitField<BufferUsageBits> p_usage, MemoryAllocationType p_allocation_type) = 0;
|
||||
/** Allocates a new GPU buffer. Must be destroyed with buffer_free().
|
||||
* @param p_size The size in bytes of the buffer.
|
||||
* @param p_usage Usage flags.
|
||||
* @param p_allocation_type See MemoryAllocationType.
|
||||
* @param p_frames_drawn Used for debug checks when BUFFER_USAGE_DYNAMIC_PERSISTENT_BIT is set.
|
||||
* @return the buffer.
|
||||
*/
|
||||
virtual BufferID buffer_create(uint64_t p_size, BitField<BufferUsageBits> p_usage, MemoryAllocationType p_allocation_type, uint64_t p_frames_drawn) = 0;
|
||||
// Only for a buffer with BUFFER_USAGE_TEXEL_BIT.
|
||||
virtual bool buffer_set_texel_format(BufferID p_buffer, DataFormat p_format) = 0;
|
||||
virtual void buffer_free(BufferID p_buffer) = 0;
|
||||
virtual uint64_t buffer_get_allocation_size(BufferID p_buffer) = 0;
|
||||
virtual uint8_t *buffer_map(BufferID p_buffer) = 0;
|
||||
virtual void buffer_unmap(BufferID p_buffer) = 0;
|
||||
virtual uint8_t *buffer_persistent_map_advance(BufferID p_buffer, uint64_t p_frames_drawn) = 0;
|
||||
virtual void buffer_flush(BufferID p_buffer) {}
|
||||
// Only for a buffer with BUFFER_USAGE_DEVICE_ADDRESS_BIT.
|
||||
virtual uint64_t buffer_get_device_address(BufferID p_buffer) = 0;
|
||||
|
||||
@@ -499,12 +510,17 @@ public:
|
||||
// Flag to indicate that this is an immutable sampler so it is skipped when creating uniform
|
||||
// sets, as it would be set previously when creating the pipeline layout.
|
||||
bool immutable_sampler = false;
|
||||
|
||||
_FORCE_INLINE_ bool is_dynamic() const {
|
||||
return type == UNIFORM_TYPE_STORAGE_BUFFER_DYNAMIC || type == UNIFORM_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
||||
}
|
||||
};
|
||||
|
||||
virtual UniformSetID uniform_set_create(VectorView<BoundUniform> p_uniforms, ShaderID p_shader, uint32_t p_set_index, int p_linear_pool_index) = 0;
|
||||
virtual void linear_uniform_set_pools_reset(int p_linear_pool_index) {}
|
||||
virtual void uniform_set_free(UniformSetID p_uniform_set) = 0;
|
||||
virtual bool uniform_sets_have_linear_pools() const { return false; }
|
||||
virtual uint32_t uniform_sets_get_dynamic_offsets(VectorView<UniformSetID> p_uniform_sets, ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count) const = 0;
|
||||
|
||||
// ----- COMMANDS -----
|
||||
|
||||
@@ -646,8 +662,7 @@ public:
|
||||
|
||||
// Binding.
|
||||
virtual void command_bind_render_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) = 0;
|
||||
virtual void command_bind_render_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) = 0;
|
||||
virtual void command_bind_render_uniform_sets(CommandBufferID p_cmd_buffer, VectorView<UniformSetID> p_uniform_sets, ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count) = 0;
|
||||
virtual void command_bind_render_uniform_sets(CommandBufferID p_cmd_buffer, VectorView<UniformSetID> p_uniform_sets, ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count, uint32_t p_dynamic_offsets) = 0;
|
||||
|
||||
// Drawing.
|
||||
virtual void command_render_draw(CommandBufferID p_cmd_buffer, uint32_t p_vertex_count, uint32_t p_instance_count, uint32_t p_base_vertex, uint32_t p_first_instance) = 0;
|
||||
@@ -689,8 +704,7 @@ public:
|
||||
|
||||
// Binding.
|
||||
virtual void command_bind_compute_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) = 0;
|
||||
virtual void command_bind_compute_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) = 0;
|
||||
virtual void command_bind_compute_uniform_sets(CommandBufferID p_cmd_buffer, VectorView<UniformSetID> p_uniform_sets, ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count) = 0;
|
||||
virtual void command_bind_compute_uniform_sets(CommandBufferID p_cmd_buffer, VectorView<UniformSetID> p_uniform_sets, ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count, uint32_t p_dynamic_offsets) = 0;
|
||||
|
||||
// Dispatching.
|
||||
virtual void command_compute_dispatch(CommandBufferID p_cmd_buffer, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) = 0;
|
||||
|
||||
Reference in New Issue
Block a user