summaryrefslogtreecommitdiffstats
path: root/servers/rendering/rendering_device.h
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering/rendering_device.h')
-rw-r--r--servers/rendering/rendering_device.h124
1 files changed, 89 insertions, 35 deletions
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index d8bf845756..19d21dfda2 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -33,6 +33,7 @@
#include "core/object/class_db.h"
#include "core/object/worker_thread_pool.h"
+#include "core/os/condition_variable.h"
#include "core/os/thread_safe.h"
#include "core/templates/local_vector.h"
#include "core/templates/oa_hash_map.h"
@@ -62,6 +63,10 @@ class RenderingDevice : public RenderingDeviceCommons {
GDCLASS(RenderingDevice, Object)
_THREAD_SAFE_CLASS_
+
+private:
+ Thread::ID render_thread_id;
+
public:
enum ShaderLanguage {
SHADER_LANGUAGE_GLSL,
@@ -178,10 +183,12 @@ private:
uint32_t size = 0;
BitField<RDD::BufferUsageBits> usage;
RDG::ResourceTracker *draw_tracker = nullptr;
+ int32_t transfer_worker_index = -1;
+ uint64_t transfer_worker_operation = 0;
};
Buffer *_get_buffer_from_owner(RID p_buffer);
- Error _buffer_update(Buffer *p_buffer, RID p_buffer_id, size_t p_offset, const uint8_t *p_data, size_t p_data_size, bool p_use_draw_queue = false, uint32_t p_required_align = 32);
+ Error _buffer_initialize(Buffer *p_buffer, const uint8_t *p_data, size_t p_data_size, uint32_t p_required_align = 32);
void update_perf_report();
@@ -189,9 +196,9 @@ private:
uint32_t copy_bytes_count = 0;
String perf_report_text;
- RID_Owner<Buffer> uniform_buffer_owner;
- RID_Owner<Buffer> storage_buffer_owner;
- RID_Owner<Buffer> texture_buffer_owner;
+ RID_Owner<Buffer, true> uniform_buffer_owner;
+ RID_Owner<Buffer, true> storage_buffer_owner;
+ RID_Owner<Buffer, true> texture_buffer_owner;
public:
Error buffer_copy(RID p_src_buffer, RID p_dst_buffer, uint32_t p_src_offset, uint32_t p_dst_offset, uint32_t p_size);
@@ -254,6 +261,8 @@ public:
RDG::ResourceTracker *draw_tracker = nullptr;
HashMap<Rect2i, RDG::ResourceTracker *> slice_trackers;
SharedFallback *shared_fallback = nullptr;
+ int32_t transfer_worker_index = -1;
+ uint64_t transfer_worker_operation = 0;
RDD::TextureSubresourceRange barrier_range() const {
RDD::TextureSubresourceRange r;
@@ -282,11 +291,13 @@ public:
}
};
- RID_Owner<Texture> texture_owner;
+ RID_Owner<Texture, true> texture_owner;
uint32_t texture_upload_region_size_px = 0;
Vector<uint8_t> _texture_get_data(Texture *tex, uint32_t p_layer, bool p_2d = false);
- Error _texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, bool p_use_setup_queue, bool p_validate_can_update);
+ uint32_t _texture_layer_count(Texture *p_texture) const;
+ uint32_t _texture_alignment(Texture *p_texture) const;
+ Error _texture_initialize(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data);
void _texture_check_shared_fallback(Texture *p_texture);
void _texture_update_shared_fallback(RID p_texture_rid, Texture *p_texture, bool p_for_writing);
void _texture_free_shared_fallback(Texture *p_texture);
@@ -572,7 +583,7 @@ private:
uint32_t view_count;
};
- RID_Owner<Framebuffer> framebuffer_owner;
+ RID_Owner<Framebuffer, true> framebuffer_owner;
public:
// This ID is warranted to be unique for the same formats, does not need to be freed
@@ -593,7 +604,7 @@ public:
/**** SAMPLER ****/
/*****************/
private:
- RID_Owner<RDD::SamplerID> sampler_owner;
+ RID_Owner<RDD::SamplerID, true> sampler_owner;
public:
RID sampler_create(const SamplerState &p_state);
@@ -615,7 +626,7 @@ private:
// This mapping is done here internally, and it's not
// exposed.
- RID_Owner<Buffer> vertex_buffer_owner;
+ RID_Owner<Buffer, true> vertex_buffer_owner;
struct VertexDescriptionKey {
Vector<VertexAttribute> vertex_formats;
@@ -695,10 +706,12 @@ private:
Vector<RDD::BufferID> buffers; // Not owned, just referenced.
Vector<RDG::ResourceTracker *> draw_trackers; // Not owned, just referenced.
Vector<uint64_t> offsets;
+ Vector<int32_t> transfer_worker_indices;
+ Vector<uint64_t> transfer_worker_operations;
HashSet<RID> untracked_buffers;
};
- RID_Owner<VertexArray> vertex_array_owner;
+ RID_Owner<VertexArray, true> vertex_array_owner;
struct IndexBuffer : public Buffer {
uint32_t max_index = 0; // Used for validation.
@@ -707,7 +720,7 @@ private:
bool supports_restart_indices = false;
};
- RID_Owner<IndexBuffer> index_buffer_owner;
+ RID_Owner<IndexBuffer, true> index_buffer_owner;
struct IndexArray {
uint32_t max_index = 0; // Remember the maximum index here too, for validation.
@@ -717,9 +730,11 @@ private:
uint32_t indices = 0;
IndexBufferFormat format = INDEX_BUFFER_FORMAT_UINT16;
bool supports_restart_indices = false;
+ int32_t transfer_worker_index = -1;
+ uint64_t transfer_worker_operation = 0;
};
- RID_Owner<IndexArray> index_array_owner;
+ RID_Owner<IndexArray, true> index_array_owner;
public:
RID vertex_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>(), bool p_use_as_storage = false);
@@ -796,7 +811,7 @@ private:
String _shader_uniform_debug(RID p_shader, int p_set = -1);
- RID_Owner<Shader> shader_owner;
+ RID_Owner<Shader, true> shader_owner;
#ifndef DISABLE_DEPRECATED
public:
@@ -977,7 +992,7 @@ private:
void *invalidated_callback_userdata = nullptr;
};
- RID_Owner<UniformSet> uniform_set_owner;
+ RID_Owner<UniformSet, true> uniform_set_owner;
void _uniform_set_update_shared(UniformSet *p_uniform_set);
@@ -1024,7 +1039,7 @@ private:
uint32_t push_constant_size = 0;
};
- RID_Owner<RenderPipeline> render_pipeline_owner;
+ RID_Owner<RenderPipeline, true> render_pipeline_owner;
bool pipeline_cache_enabled = false;
size_t pipeline_cache_size = 0;
@@ -1045,7 +1060,7 @@ private:
uint32_t local_group_size[3] = { 0, 0, 0 };
};
- RID_Owner<ComputePipeline> compute_pipeline_owner;
+ RID_Owner<ComputePipeline, true> compute_pipeline_owner;
public:
RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, BitField<PipelineDynamicStateFlags> p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0, const Vector<PipelineSpecializationConstant> &p_specialization_constants = Vector<PipelineSpecializationConstant>());
@@ -1101,6 +1116,7 @@ private:
RID pipeline_shader;
RDD::ShaderID pipeline_shader_driver_id;
uint32_t pipeline_shader_layout_hash = 0;
+ uint32_t pipeline_push_constant_size = 0;
RID vertex_array;
RID index_array;
uint32_t draw_count = 0;
@@ -1153,8 +1169,6 @@ private:
void _draw_list_insert_clear_region(DrawList *p_draw_list, Framebuffer *p_framebuffer, Point2i p_viewport_offset, Point2i p_viewport_size, bool p_clear_color, const Vector<Color> &p_clear_colors, bool p_clear_depth, float p_depth, uint32_t p_stencil);
Error _draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, RDD::FramebufferID *r_framebuffer, RDD::RenderPassID *r_render_pass, uint32_t *r_subpass_count);
Error _draw_list_render_pass_begin(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i p_viewport_offset, Point2i p_viewport_size, RDD::FramebufferID p_framebuffer_driver_id, RDD::RenderPassID p_render_pass, uint32_t p_breadcrumb);
- void _draw_list_set_viewport(Rect2i p_rect);
- void _draw_list_set_scissor(Rect2i p_rect);
_FORCE_INLINE_ DrawList *_get_draw_list_ptr(DrawListID p_id);
Error _draw_list_allocate(const Rect2i &p_viewport, uint32_t p_subpass);
void _draw_list_free(Rect2i *r_last_viewport = nullptr);
@@ -1240,6 +1254,50 @@ public:
void compute_list_end();
private:
+ /*************************/
+ /**** TRANSFER WORKER ****/
+ /*************************/
+
+ struct TransferWorker {
+ uint32_t index = 0;
+ RDD::BufferID staging_buffer;
+ uint32_t max_transfer_size = 0;
+ uint32_t staging_buffer_size_in_use = 0;
+ uint32_t staging_buffer_size_allocated = 0;
+ RDD::CommandBufferID command_buffer;
+ RDD::CommandPoolID command_pool;
+ RDD::FenceID command_fence;
+ RDD::SemaphoreID command_semaphore;
+ bool recording = false;
+ bool submitted = false;
+ BinaryMutex thread_mutex;
+ uint64_t operations_processed = 0;
+ uint64_t operations_submitted = 0;
+ uint64_t operations_counter = 0;
+ BinaryMutex operations_mutex;
+ };
+
+ LocalVector<TransferWorker *> transfer_worker_pool;
+ uint32_t transfer_worker_pool_max_size = 1;
+ LocalVector<uint64_t> transfer_worker_operation_used_by_draw;
+ LocalVector<uint32_t> transfer_worker_pool_available_list;
+ BinaryMutex transfer_worker_pool_mutex;
+ ConditionVariable transfer_worker_pool_condition;
+
+ TransferWorker *_acquire_transfer_worker(uint32_t p_transfer_size, uint32_t p_required_align, uint32_t &r_staging_offset);
+ void _release_transfer_worker(TransferWorker *p_transfer_worker);
+ void _end_transfer_worker(TransferWorker *p_transfer_worker);
+ void _submit_transfer_worker(TransferWorker *p_transfer_worker, bool p_signal_semaphore);
+ void _wait_for_transfer_worker(TransferWorker *p_transfer_worker);
+ void _check_transfer_worker_operation(uint32_t p_transfer_worker_index, uint64_t p_transfer_worker_operation);
+ void _check_transfer_worker_buffer(Buffer *p_buffer);
+ void _check_transfer_worker_texture(Texture *p_texture);
+ void _check_transfer_worker_vertex_array(VertexArray *p_vertex_array);
+ void _check_transfer_worker_index_array(IndexArray *p_index_array);
+ void _submit_transfer_workers(bool p_operations_used_by_draw);
+ void _wait_for_transfer_workers();
+ void _free_transfer_workers();
+
/***********************/
/**** COMMAND GRAPH ****/
/***********************/
@@ -1250,6 +1308,7 @@ private:
bool _index_array_make_mutable(IndexArray *p_index_array, RDG::ResourceTracker *p_resource_tracker);
bool _uniform_set_make_mutable(UniformSet *p_uniform_set, RID p_resource_id, RDG::ResourceTracker *p_resource_tracker);
bool _dependency_make_mutable(RID p_id, RID p_resource_id, RDG::ResourceTracker *p_resource_tracker);
+ bool _dependencies_make_mutable_recursive(RID p_id, RDG::ResourceTracker *p_resource_tracker);
bool _dependencies_make_mutable(RID p_id, RDG::ResourceTracker *p_resource_tracker);
RenderingDeviceGraph draw_graph;
@@ -1259,8 +1318,10 @@ private:
/**************************/
RDD::CommandQueueFamilyID main_queue_family;
+ RDD::CommandQueueFamilyID transfer_queue_family;
RDD::CommandQueueFamilyID present_queue_family;
RDD::CommandQueueID main_queue;
+ RDD::CommandQueueID transfer_queue;
RDD::CommandQueueID present_queue;
/**************************/
@@ -1292,28 +1353,21 @@ private:
List<RenderPipeline> render_pipelines_to_dispose_of;
List<ComputePipeline> compute_pipelines_to_dispose_of;
+ // The command pool used by the command buffer.
RDD::CommandPoolID command_pool;
- // Used at the beginning of every frame for set-up.
- // Used for filling up newly created buffers with data provided on creation.
- // Primarily intended to be accessed by worker threads.
- // Ideally this command buffer should use an async transfer queue.
- RDD::CommandBufferID setup_command_buffer;
-
- // The main command buffer for drawing and compute.
- // Primarily intended to be used by the main thread to do most stuff.
- RDD::CommandBufferID draw_command_buffer;
+ // The command buffer used by the main thread when recording the frame.
+ RDD::CommandBufferID command_buffer;
- // Signaled by the setup submission. Draw must wait on this semaphore.
- RDD::SemaphoreID setup_semaphore;
+ // Signaled by the command buffer submission. Present must wait on this semaphore.
+ RDD::SemaphoreID semaphore;
- // Signaled by the draw submission. Present must wait on this semaphore.
- RDD::SemaphoreID draw_semaphore;
+ // Signaled by the command buffer submission. Must wait on this fence before beginning command recording for the frame.
+ RDD::FenceID fence;
+ bool fence_signaled = false;
- // Signaled by the draw submission. Must wait on this fence before beginning
- // command recording for the frame.
- RDD::FenceID draw_fence;
- bool draw_fence_signaled = false;
+ // Semaphores the frame must wait on before executing the command buffer.
+ LocalVector<RDD::SemaphoreID> semaphores_to_wait_on;
// Swap chains prepared for drawing during the frame that must be presented.
LocalVector<RDD::SwapChainID> swap_chains_to_present;