summaryrefslogtreecommitdiffstats
path: root/servers/rendering/renderer_rd/shader_rd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering/renderer_rd/shader_rd.cpp')
-rw-r--r--servers/rendering/renderer_rd/shader_rd.cpp114
1 files changed, 66 insertions, 48 deletions
diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp
index 39c3e9b168..6234cddee3 100644
--- a/servers/rendering/renderer_rd/shader_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_rd.cpp
@@ -39,6 +39,8 @@
#include "servers/rendering/rendering_device.h"
#include "thirdparty/misc/smolv.h"
+#define ENABLE_SHADER_CACHE 1
+
void ShaderRD::_add_stage(const char *p_code, StageType p_stage_type) {
Vector<String> lines = String(p_code).split("\n");
@@ -144,7 +146,8 @@ RID ShaderRD::version_create() {
version.dirty = true;
version.valid = false;
version.initialize_needed = true;
- version.variants = nullptr;
+ version.variants.clear();
+ version.variant_data.clear();
return version_owner.make_rid(version);
}
@@ -154,23 +157,25 @@ void ShaderRD::_initialize_version(Version *p_version) {
p_version->valid = false;
p_version->dirty = false;
- p_version->variants = memnew_arr(RID, variant_defines.size());
+ p_version->variants.resize_zeroed(variant_defines.size());
+ p_version->variant_data.resize(variant_defines.size());
+ p_version->group_compilation_tasks.resize(group_enabled.size());
+ p_version->group_compilation_tasks.fill(0);
}
void ShaderRD::_clear_version(Version *p_version) {
+ _compile_ensure_finished(p_version);
+
// Clear versions if they exist.
- if (p_version->variants) {
+ if (!p_version->variants.is_empty()) {
for (int i = 0; i < variant_defines.size(); i++) {
if (p_version->variants[i].is_valid()) {
RD::get_singleton()->free(p_version->variants[i]);
}
}
- memdelete_arr(p_version->variants);
- if (p_version->variant_data) {
- memdelete_arr(p_version->variant_data);
- }
- p_version->variants = nullptr;
+ p_version->variants.clear();
+ p_version->variant_data.clear();
}
}
@@ -227,8 +232,8 @@ void ShaderRD::_build_variant_code(StringBuilder &builder, uint32_t p_variant, c
}
}
-void ShaderRD::_compile_variant(uint32_t p_variant, const CompileData *p_data) {
- uint32_t variant = group_to_variant_map[p_data->group][p_variant];
+void ShaderRD::_compile_variant(uint32_t p_variant, CompileData p_data) {
+ uint32_t variant = group_to_variant_map[p_data.group][p_variant];
if (!variants_enabled[variant]) {
return; // Variant is disabled, return.
@@ -245,7 +250,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, const CompileData *p_data) {
//vertex stage
StringBuilder builder;
- _build_variant_code(builder, variant, p_data->version, stage_templates[STAGE_TYPE_VERTEX]);
+ _build_variant_code(builder, variant, p_data.version, stage_templates[STAGE_TYPE_VERTEX]);
current_source = builder.as_string();
RD::ShaderStageSPIRVData stage;
@@ -263,7 +268,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, const CompileData *p_data) {
current_stage = RD::SHADER_STAGE_FRAGMENT;
StringBuilder builder;
- _build_variant_code(builder, variant, p_data->version, stage_templates[STAGE_TYPE_FRAGMENT]);
+ _build_variant_code(builder, variant, p_data.version, stage_templates[STAGE_TYPE_FRAGMENT]);
current_source = builder.as_string();
RD::ShaderStageSPIRVData stage;
@@ -281,7 +286,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, const CompileData *p_data) {
current_stage = RD::SHADER_STAGE_COMPUTE;
StringBuilder builder;
- _build_variant_code(builder, variant, p_data->version, stage_templates[STAGE_TYPE_COMPUTE]);
+ _build_variant_code(builder, variant, p_data.version, stage_templates[STAGE_TYPE_COMPUTE]);
current_source = builder.as_string();
@@ -313,8 +318,8 @@ void ShaderRD::_compile_variant(uint32_t p_variant, const CompileData *p_data) {
{
MutexLock lock(variant_set_mutex);
- p_data->version->variants[variant] = RD::get_singleton()->shader_create_from_bytecode(shader_data, p_data->version->variants[variant]);
- p_data->version->variant_data[variant] = shader_data;
+ p_data.version->variants.write[variant] = RD::get_singleton()->shader_create_from_bytecode(shader_data, p_data.version->variants[variant]);
+ p_data.version->variant_data.write[variant] = shader_data;
}
}
@@ -443,14 +448,14 @@ bool ShaderRD::_load_from_cache(Version *p_version, int p_group) {
ERR_FAIL_COND_V(br != variant_size, false);
- p_version->variant_data[variant_id] = variant_bytes;
+ p_version->variant_data.write[variant_id] = variant_bytes;
}
for (uint32_t i = 0; i < variant_count; i++) {
int variant_id = group_to_variant_map[p_group][i];
if (!variants_enabled[variant_id]) {
MutexLock lock(variant_set_mutex);
- p_version->variants[variant_id] = RID();
+ p_version->variants.write[variant_id] = RID();
continue;
}
{
@@ -464,12 +469,10 @@ bool ShaderRD::_load_from_cache(Version *p_version, int p_group) {
ERR_FAIL_COND_V(shader.is_null(), false);
}
- p_version->variants[variant_id] = shader;
+ p_version->variants.write[variant_id] = shader;
}
}
- memdelete_arr(p_version->variant_data); //clear stages
- p_version->variant_data = nullptr;
p_version->valid = true;
return true;
}
@@ -491,48 +494,51 @@ void ShaderRD::_save_to_cache(Version *p_version, int p_group) {
}
void ShaderRD::_allocate_placeholders(Version *p_version, int p_group) {
- ERR_FAIL_NULL(p_version->variants);
+ ERR_FAIL_COND(p_version->variants.is_empty());
+
for (uint32_t i = 0; i < group_to_variant_map[p_group].size(); i++) {
int variant_id = group_to_variant_map[p_group][i];
RID shader = RD::get_singleton()->shader_create_placeholder();
{
MutexLock lock(variant_set_mutex);
- p_version->variants[variant_id] = shader;
+ p_version->variants.write[variant_id] = shader;
}
}
}
// Try to compile all variants for a given group.
// Will skip variants that are disabled.
-void ShaderRD::_compile_version(Version *p_version, int p_group) {
+void ShaderRD::_compile_version_start(Version *p_version, int p_group) {
if (!group_enabled[p_group]) {
return;
}
- typedef Vector<uint8_t> ShaderStageData;
- p_version->variant_data = memnew_arr(ShaderStageData, variant_defines.size());
-
p_version->dirty = false;
+#if ENABLE_SHADER_CACHE
if (shader_cache_dir_valid) {
if (_load_from_cache(p_version, p_group)) {
return;
}
}
+#endif
CompileData compile_data;
compile_data.version = p_version;
compile_data.group = p_group;
-#if 1
- WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &ShaderRD::_compile_variant, &compile_data, group_to_variant_map[p_group].size(), -1, true, SNAME("ShaderCompilation"));
- WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task);
+ WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &ShaderRD::_compile_variant, compile_data, group_to_variant_map[p_group].size(), -1, true, SNAME("ShaderCompilation"));
+ p_version->group_compilation_tasks.write[p_group] = group_task;
+}
-#else
- for (uint32_t i = 0; i < group_to_variant_map[p_group].size(); i++) {
- _compile_variant(i, &compile_data);
+void ShaderRD::_compile_version_end(Version *p_version, int p_group) {
+ if (p_version->group_compilation_tasks.size() <= p_group || p_version->group_compilation_tasks[p_group] == 0) {
+ return;
}
-#endif
+
+ WorkerThreadPool::GroupID group_task = p_version->group_compilation_tasks[p_group];
+ WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task);
+ p_version->group_compilation_tasks.write[p_group] = 0;
bool all_valid = true;
@@ -557,29 +563,35 @@ void ShaderRD::_compile_version(Version *p_version, int p_group) {
RD::get_singleton()->free(p_version->variants[i]);
}
}
- memdelete_arr(p_version->variants);
- if (p_version->variant_data) {
- memdelete_arr(p_version->variant_data);
- }
- p_version->variants = nullptr;
- p_version->variant_data = nullptr;
+
+ p_version->variants.clear();
+ p_version->variant_data.clear();
return;
- } else if (shader_cache_dir_valid) {
- // Save shader cache.
+ }
+#if ENABLE_SHADER_CACHE
+ else if (shader_cache_dir_valid) {
_save_to_cache(p_version, p_group);
}
-
- memdelete_arr(p_version->variant_data); //clear stages
- p_version->variant_data = nullptr;
+#endif
p_version->valid = true;
}
+void ShaderRD::_compile_ensure_finished(Version *p_version) {
+ // Wait for compilation of existing groups if necessary.
+ for (int i = 0; i < group_enabled.size(); i++) {
+ _compile_version_end(p_version, i);
+ }
+}
+
void ShaderRD::version_set_code(RID p_version, const HashMap<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines) {
ERR_FAIL_COND(is_compute);
Version *version = version_owner.get_or_null(p_version);
ERR_FAIL_NULL(version);
+
+ _compile_ensure_finished(version);
+
version->vertex_globals = p_vertex_globals.utf8();
version->fragment_globals = p_fragment_globals.utf8();
version->uniforms = p_uniforms.utf8();
@@ -601,7 +613,7 @@ void ShaderRD::version_set_code(RID p_version, const HashMap<String, String> &p_
_allocate_placeholders(version, i);
continue;
}
- _compile_version(version, i);
+ _compile_version_start(version, i);
}
version->initialize_needed = false;
}
@@ -613,6 +625,8 @@ void ShaderRD::version_set_compute_code(RID p_version, const HashMap<String, Str
Version *version = version_owner.get_or_null(p_version);
ERR_FAIL_NULL(version);
+ _compile_ensure_finished(version);
+
version->compute_globals = p_compute_globals.utf8();
version->uniforms = p_uniforms.utf8();
@@ -634,7 +648,7 @@ void ShaderRD::version_set_compute_code(RID p_version, const HashMap<String, Str
_allocate_placeholders(version, i);
continue;
}
- _compile_version(version, i);
+ _compile_version_start(version, i);
}
version->initialize_needed = false;
}
@@ -651,10 +665,12 @@ bool ShaderRD::version_is_valid(RID p_version) {
_allocate_placeholders(version, i);
continue;
}
- _compile_version(version, i);
+ _compile_version_start(version, i);
}
}
+ _compile_ensure_finished(version);
+
return version->valid;
}
@@ -696,7 +712,7 @@ void ShaderRD::enable_group(int p_group) {
version_owner.get_owned_list(&all_versions);
for (const RID &E : all_versions) {
Version *version = version_owner.get_or_null(E);
- _compile_version(version, p_group);
+ _compile_version_start(version, p_group);
}
}
@@ -735,6 +751,7 @@ void ShaderRD::initialize(const Vector<String> &p_variant_defines, const String
for (int i = 0; i < p_variant_defines.size(); i++) {
variant_defines.push_back(VariantDefine(0, p_variant_defines[i], true));
variants_enabled.push_back(true);
+ variant_to_group.push_back(0);
group_to_variant_map[0].push_back(i);
}
@@ -796,6 +813,7 @@ void ShaderRD::initialize(const Vector<VariantDefine> &p_variant_defines, const
// Fill variant array.
variant_defines.push_back(p_variant_defines[i]);
variants_enabled.push_back(true);
+ variant_to_group.push_back(p_variant_defines[i].group);
// Map variant array index to group id, so we can iterate over groups later.
if (!group_to_variant_map.has(p_variant_defines[i].group)) {