Implement asynchronous transfer queues, thread guards on RenderingDevice. Add ubershaders and rework pipeline caches for Forward+ and Mobile.
- Implements asynchronous transfer queues from PR #87590. - Adds ubershaders that can run with specialization constants specified as push constants. - Pipelines with specialization constants can compile in the background. - Added monitoring for pipeline compilations. - Materials and shaders can now be created asynchronously on background threads. - Meshes that are loaded on background threads can also compile pipelines as part of the loading process.
This commit is contained in:
@ -129,32 +129,32 @@ public:
|
||||
#define ServerName RendererTextureStorage
|
||||
#define server_name RSG::texture_storage
|
||||
|
||||
#define FUNCRIDTEX0(m_type) \
|
||||
virtual RID m_type##_create() override { \
|
||||
RID ret = RSG::texture_storage->texture_allocate(); \
|
||||
if (Thread::get_caller_id() == server_thread || RSG::texture_storage->can_create_resources_async()) { \
|
||||
RSG::texture_storage->m_type##_initialize(ret); \
|
||||
} else { \
|
||||
command_queue.push(RSG::texture_storage, &RendererTextureStorage::m_type##_initialize, ret); \
|
||||
} \
|
||||
return ret; \
|
||||
#define FUNCRIDTEX0(m_type) \
|
||||
virtual RID m_type##_create() override { \
|
||||
RID ret = RSG::texture_storage->texture_allocate(); \
|
||||
if (Thread::get_caller_id() == server_thread || RSG::rasterizer->can_create_resources_async()) { \
|
||||
RSG::texture_storage->m_type##_initialize(ret); \
|
||||
} else { \
|
||||
command_queue.push(RSG::texture_storage, &RendererTextureStorage::m_type##_initialize, ret); \
|
||||
} \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define FUNCRIDTEX1(m_type, m_type1) \
|
||||
virtual RID m_type##_create(m_type1 p1) override { \
|
||||
RID ret = RSG::texture_storage->texture_allocate(); \
|
||||
if (Thread::get_caller_id() == server_thread || RSG::texture_storage->can_create_resources_async()) { \
|
||||
RSG::texture_storage->m_type##_initialize(ret, p1); \
|
||||
} else { \
|
||||
command_queue.push(RSG::texture_storage, &RendererTextureStorage::m_type##_initialize, ret, p1); \
|
||||
} \
|
||||
return ret; \
|
||||
#define FUNCRIDTEX1(m_type, m_type1) \
|
||||
virtual RID m_type##_create(m_type1 p1) override { \
|
||||
RID ret = RSG::texture_storage->texture_allocate(); \
|
||||
if (Thread::get_caller_id() == server_thread || RSG::rasterizer->can_create_resources_async()) { \
|
||||
RSG::texture_storage->m_type##_initialize(ret, p1); \
|
||||
} else { \
|
||||
command_queue.push(RSG::texture_storage, &RendererTextureStorage::m_type##_initialize, ret, p1); \
|
||||
} \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define FUNCRIDTEX2(m_type, m_type1, m_type2) \
|
||||
virtual RID m_type##_create(m_type1 p1, m_type2 p2) override { \
|
||||
RID ret = RSG::texture_storage->texture_allocate(); \
|
||||
if (Thread::get_caller_id() == server_thread || RSG::texture_storage->can_create_resources_async()) { \
|
||||
if (Thread::get_caller_id() == server_thread || RSG::rasterizer->can_create_resources_async()) { \
|
||||
RSG::texture_storage->m_type##_initialize(ret, p1, p2); \
|
||||
} else { \
|
||||
command_queue.push(RSG::texture_storage, &RendererTextureStorage::m_type##_initialize, ret, p1, p2); \
|
||||
@ -165,7 +165,7 @@ public:
|
||||
#define FUNCRIDTEX3(m_type, m_type1, m_type2, m_type3) \
|
||||
virtual RID m_type##_create(m_type1 p1, m_type2 p2, m_type3 p3) override { \
|
||||
RID ret = RSG::texture_storage->texture_allocate(); \
|
||||
if (Thread::get_caller_id() == server_thread || RSG::texture_storage->can_create_resources_async()) { \
|
||||
if (Thread::get_caller_id() == server_thread || RSG::rasterizer->can_create_resources_async()) { \
|
||||
RSG::texture_storage->m_type##_initialize(ret, p1, p2, p3); \
|
||||
} else { \
|
||||
command_queue.push(RSG::texture_storage, &RendererTextureStorage::m_type##_initialize, ret, p1, p2, p3); \
|
||||
@ -176,7 +176,7 @@ public:
|
||||
#define FUNCRIDTEX6(m_type, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \
|
||||
virtual RID m_type##_create(m_type1 p1, m_type2 p2, m_type3 p3, m_type4 p4, m_type5 p5, m_type6 p6) override { \
|
||||
RID ret = RSG::texture_storage->texture_allocate(); \
|
||||
if (Thread::get_caller_id() == server_thread || RSG::texture_storage->can_create_resources_async()) { \
|
||||
if (Thread::get_caller_id() == server_thread || RSG::rasterizer->can_create_resources_async()) { \
|
||||
RSG::texture_storage->m_type##_initialize(ret, p1, p2, p3, p4, p5, p6); \
|
||||
} else { \
|
||||
command_queue.push(RSG::texture_storage, &RendererTextureStorage::m_type##_initialize, ret, p1, p2, p3, p4, p5, p6); \
|
||||
@ -245,6 +245,26 @@ public:
|
||||
|
||||
FUNCRIDSPLIT(shader)
|
||||
|
||||
virtual RID shader_create_from_code(const String &p_code, const String &p_path_hint = String()) override {
|
||||
RID shader = RSG::material_storage->shader_allocate();
|
||||
bool using_server_thread = Thread::get_caller_id() == server_thread;
|
||||
if (using_server_thread || RSG::rasterizer->can_create_resources_async()) {
|
||||
if (using_server_thread) {
|
||||
command_queue.flush_if_pending();
|
||||
}
|
||||
|
||||
RSG::material_storage->shader_initialize(shader);
|
||||
RSG::material_storage->shader_set_code(shader, p_code);
|
||||
RSG::material_storage->shader_set_path_hint(shader, p_path_hint);
|
||||
} else {
|
||||
command_queue.push(RSG::material_storage, &RendererMaterialStorage::shader_initialize, shader);
|
||||
command_queue.push(RSG::material_storage, &RendererMaterialStorage::shader_set_code, shader, p_code);
|
||||
command_queue.push(RSG::material_storage, &RendererMaterialStorage::shader_set_path_hint, shader, p_path_hint);
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
FUNC2(shader_set_code, RID, const String &)
|
||||
FUNC2(shader_set_path_hint, RID, const String &)
|
||||
FUNC1RC(String, shader_get_code, RID)
|
||||
@ -261,6 +281,28 @@ public:
|
||||
|
||||
FUNCRIDSPLIT(material)
|
||||
|
||||
virtual RID material_create_from_shader(RID p_next_pass, int p_render_priority, RID p_shader) override {
|
||||
RID material = RSG::material_storage->material_allocate();
|
||||
bool using_server_thread = Thread::get_caller_id() == server_thread;
|
||||
if (using_server_thread || RSG::rasterizer->can_create_resources_async()) {
|
||||
if (using_server_thread) {
|
||||
command_queue.flush_if_pending();
|
||||
}
|
||||
|
||||
RSG::material_storage->material_initialize(material);
|
||||
RSG::material_storage->material_set_next_pass(material, p_next_pass);
|
||||
RSG::material_storage->material_set_render_priority(material, p_render_priority);
|
||||
RSG::material_storage->material_set_shader(material, p_shader);
|
||||
} else {
|
||||
command_queue.push(RSG::material_storage, &RendererMaterialStorage::material_initialize, material);
|
||||
command_queue.push(RSG::material_storage, &RendererMaterialStorage::material_set_next_pass, material, p_next_pass);
|
||||
command_queue.push(RSG::material_storage, &RendererMaterialStorage::material_set_render_priority, material, p_render_priority);
|
||||
command_queue.push(RSG::material_storage, &RendererMaterialStorage::material_set_shader, material, p_shader);
|
||||
}
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
FUNC2(material_set_shader, RID, RID)
|
||||
|
||||
FUNC3(material_set_param, RID, const StringName &, const Variant &)
|
||||
@ -281,10 +323,9 @@ public:
|
||||
virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces, int p_blend_shape_count = 0) override {
|
||||
RID mesh = RSG::mesh_storage->mesh_allocate();
|
||||
|
||||
// TODO once we have RSG::mesh_storage, add can_create_resources_async and call here instead of texture_storage!!
|
||||
|
||||
if (Thread::get_caller_id() == server_thread || RSG::texture_storage->can_create_resources_async()) {
|
||||
if (Thread::get_caller_id() == server_thread) {
|
||||
bool using_server_thread = Thread::get_caller_id() == server_thread;
|
||||
if (using_server_thread || RSG::rasterizer->can_create_resources_async()) {
|
||||
if (using_server_thread) {
|
||||
command_queue.flush_if_pending();
|
||||
}
|
||||
RSG::mesh_storage->mesh_initialize(mesh);
|
||||
@ -292,12 +333,14 @@ public:
|
||||
for (int i = 0; i < p_surfaces.size(); i++) {
|
||||
RSG::mesh_storage->mesh_add_surface(mesh, p_surfaces[i]);
|
||||
}
|
||||
RSG::scene->mesh_generate_pipelines(mesh, using_server_thread);
|
||||
} else {
|
||||
command_queue.push(RSG::mesh_storage, &RendererMeshStorage::mesh_initialize, mesh);
|
||||
command_queue.push(RSG::mesh_storage, &RendererMeshStorage::mesh_set_blend_shape_count, mesh, p_blend_shape_count);
|
||||
for (int i = 0; i < p_surfaces.size(); i++) {
|
||||
command_queue.push(RSG::mesh_storage, &RendererMeshStorage::mesh_add_surface, mesh, p_surfaces[i]);
|
||||
}
|
||||
command_queue.push(RSG::scene, &RenderingMethod::mesh_generate_pipelines, mesh, true);
|
||||
}
|
||||
|
||||
return mesh;
|
||||
|
||||
Reference in New Issue
Block a user