Skip to content

Commit 58a98cd

Browse files
Allow shader containers to be loaded in parallel.
1 parent a0375dd commit 58a98cd

4 files changed

Lines changed: 54 additions & 43 deletions

File tree

core/io/compression.cpp

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,34 @@
4040
#include <brotli/decode.h>
4141
#endif
4242

43-
// Caches for zstd.
44-
static BinaryMutex mutex;
45-
static ZSTD_DCtx *current_zstd_d_ctx = nullptr;
46-
static bool current_zstd_long_distance_matching;
47-
static int current_zstd_window_log_size;
43+
namespace {
44+
struct ZstdDecompressorContext {
45+
ZSTD_DCtx *zstd_d_ctx = nullptr;
46+
bool zstd_long_distance_matching = false;
47+
int zstd_window_log_size = 0;
48+
49+
~ZstdDecompressorContext() {
50+
if (zstd_d_ctx) {
51+
ZSTD_freeDCtx(zstd_d_ctx);
52+
}
53+
}
54+
55+
void invalidate(bool p_zstd_long_distance_matching, int p_zstd_window_log_size) {
56+
if (!zstd_d_ctx || zstd_long_distance_matching != p_zstd_long_distance_matching || zstd_window_log_size != p_zstd_window_log_size) {
57+
if (zstd_d_ctx) {
58+
ZSTD_freeDCtx(zstd_d_ctx);
59+
}
60+
61+
zstd_d_ctx = ZSTD_createDCtx();
62+
if (p_zstd_long_distance_matching) {
63+
ZSTD_DCtx_setParameter(zstd_d_ctx, ZSTD_d_windowLogMax, p_zstd_window_log_size);
64+
}
65+
zstd_long_distance_matching = p_zstd_long_distance_matching;
66+
zstd_window_log_size = p_zstd_window_log_size;
67+
}
68+
}
69+
};
70+
} //namespace
4871

4972
int64_t Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int64_t p_src_size, Mode p_mode) {
5073
switch (p_mode) {
@@ -197,22 +220,10 @@ int64_t Compression::decompress(uint8_t *p_dst, int64_t p_dst_max_size, const ui
197220
return total;
198221
} break;
199222
case MODE_ZSTD: {
200-
MutexLock lock(mutex);
201-
202-
if (!current_zstd_d_ctx || current_zstd_long_distance_matching != zstd_long_distance_matching || current_zstd_window_log_size != zstd_window_log_size) {
203-
if (current_zstd_d_ctx) {
204-
ZSTD_freeDCtx(current_zstd_d_ctx);
205-
}
206-
207-
current_zstd_d_ctx = ZSTD_createDCtx();
208-
if (zstd_long_distance_matching) {
209-
ZSTD_DCtx_setParameter(current_zstd_d_ctx, ZSTD_d_windowLogMax, zstd_window_log_size);
210-
}
211-
current_zstd_long_distance_matching = zstd_long_distance_matching;
212-
current_zstd_window_log_size = zstd_window_log_size;
213-
}
223+
thread_local ZstdDecompressorContext decompressor_ctx;
224+
decompressor_ctx.invalidate(zstd_long_distance_matching, zstd_window_log_size);
214225

215-
size_t ret = ZSTD_decompressDCtx(current_zstd_d_ctx, p_dst, p_dst_max_size, p_src, p_src_size);
226+
size_t ret = ZSTD_decompressDCtx(decompressor_ctx.zstd_d_ctx, p_dst, p_dst_max_size, p_src, p_src_size);
216227
return (int64_t)ret;
217228
} break;
218229
}

servers/rendering/renderer_rd/shader_rd.cpp

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ void ShaderRD::_initialize_version(Version *p_version) {
258258
p_version->variants.resize_initialized(variant_defines.size());
259259
p_version->variant_data.resize(variant_defines.size());
260260
p_version->group_compilation_tasks.resize_initialized(group_enabled.size());
261+
p_version->group_loaded_from_cache.resize_initialized(group_enabled.size());
261262
}
262263

263264
void ShaderRD::_clear_version(Version *p_version) {
@@ -611,6 +612,16 @@ String ShaderRD::_get_cache_file_path(Version *p_version, int p_group, const Str
611612
return shader_cache_dir.path_join(relative_path);
612613
}
613614

615+
void ShaderRD::_load_variant_from_cache(uint32_t p_variant, CompileData p_data) {
616+
uint32_t variant = group_to_variant_map[p_data.group][p_variant];
617+
if (!variants_enabled[variant]) {
618+
p_data.version->variants.write[variant] = RID();
619+
return; // Variant is disabled, return.
620+
}
621+
622+
p_data.version->variants.write[variant] = RD::get_singleton()->shader_create_from_bytecode_with_samplers(p_data.version->variant_data[variant], p_data.version->variants[variant], immutable_samplers);
623+
}
624+
614625
bool ShaderRD::_load_from_cache(Version *p_version, int p_group) {
615626
String api_safe_name = String(RD::get_singleton()->get_device_api_name()).validate_filename().to_lower();
616627
Ref<FileAccess> f;
@@ -662,28 +673,14 @@ bool ShaderRD::_load_from_cache(Version *p_version, int p_group) {
662673
p_version->variant_data.write[variant_id] = variant_bytes;
663674
}
664675

665-
for (uint32_t i = 0; i < variant_count; i++) {
666-
int variant_id = group_to_variant_map[p_group][i];
667-
if (!variants_enabled[variant_id]) {
668-
p_version->variants.write[variant_id] = RID();
669-
continue;
670-
}
671-
print_verbose(vformat("Loading cache for shader %s, variant %d", name, i));
672-
{
673-
RID shader = RD::get_singleton()->shader_create_from_bytecode_with_samplers(p_version->variant_data[variant_id], p_version->variants[variant_id], immutable_samplers);
674-
if (shader.is_null()) {
675-
for (uint32_t j = 0; j < i; j++) {
676-
int variant_free_id = group_to_variant_map[p_group][j];
677-
RD::get_singleton()->free_rid(p_version->variants[variant_free_id]);
678-
}
679-
ERR_FAIL_COND_V(shader.is_null(), false);
680-
}
676+
CompileData compile_data;
677+
compile_data.version = p_version;
678+
compile_data.group = p_group;
681679

682-
p_version->variants.write[variant_id] = shader;
683-
}
684-
}
680+
WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &ShaderRD::_load_variant_from_cache, compile_data, variant_count, -1, true, SNAME("LoadVariantFromCache"));
681+
p_version->group_compilation_tasks.write[p_group] = group_task;
682+
p_version->group_loaded_from_cache.write[p_group] = true;
685683

686-
p_version->valid = true;
687684
return true;
688685
}
689686

@@ -733,6 +730,7 @@ void ShaderRD::_compile_version_start(Version *p_version, int p_group) {
733730

734731
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"));
735732
p_version->group_compilation_tasks.write[p_group] = group_task;
733+
p_version->group_loaded_from_cache.write[p_group] = false;
736734
}
737735

738736
void ShaderRD::_compile_version_end(Version *p_version, int p_group) {
@@ -772,7 +770,7 @@ void ShaderRD::_compile_version_end(Version *p_version, int p_group) {
772770
return;
773771
}
774772
#if ENABLE_SHADER_CACHE
775-
else if (shader_cache_user_dir_valid) {
773+
else if (shader_cache_user_dir_valid && !p_version->group_loaded_from_cache[p_group]) {
776774
_save_to_cache(p_version, p_group);
777775
}
778776
#endif

servers/rendering/renderer_rd/shader_rd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class ShaderRD {
8282
HashMap<StringName, CharString> code_sections;
8383
Vector<CharString> custom_defines;
8484
Vector<WorkerThreadPool::GroupID> group_compilation_tasks;
85+
Vector<bool> group_loaded_from_cache;
8586

8687
Vector<Vector<uint8_t>> variant_data;
8788
Vector<RID> variants;
@@ -178,6 +179,7 @@ class ShaderRD {
178179
String _version_get_sha1(Version *p_version) const;
179180
String _get_cache_file_relative_path(Version *p_version, int p_group, const String &p_api_name);
180181
String _get_cache_file_path(Version *p_version, int p_group, const String &p_api_name, bool p_user_dir);
182+
void _load_variant_from_cache(uint32_t p_variant, CompileData p_data);
181183
bool _load_from_cache(Version *p_version, int p_group);
182184
void _save_to_cache(Version *p_version, int p_group);
183185
void _initialize_cache();

servers/rendering/rendering_device.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4170,8 +4170,6 @@ RID RenderingDevice::shader_create_from_bytecode(const Vector<uint8_t> &p_shader
41704170
}
41714171

41724172
RID RenderingDevice::shader_create_from_bytecode_with_samplers(const Vector<uint8_t> &p_shader_binary, RID p_placeholder, const Vector<PipelineImmutableSampler> &p_immutable_samplers) {
4173-
_THREAD_SAFE_METHOD_
4174-
41754173
Ref<RenderingShaderContainer> shader_container = driver->get_shader_container_format().create_container();
41764174
ERR_FAIL_COND_V(shader_container.is_null(), RID());
41774175

@@ -4195,6 +4193,8 @@ RID RenderingDevice::shader_create_from_bytecode_with_samplers(const Vector<uint
41954193
RDD::ShaderID shader_id = driver->shader_create_from_container(shader_container, driver_immutable_samplers);
41964194
ERR_FAIL_COND_V(!shader_id, RID());
41974195

4196+
_THREAD_SAFE_METHOD_
4197+
41984198
// All good, let's create modules.
41994199

42004200
RID id;

0 commit comments

Comments
 (0)