1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-13 13:31:48 +00:00

Add Shader compile groups to RD Shader system

This allows us to specify a subset of variants to compile at load time and conditionally other variants later.

This works seamlessly with shader caching.

Needed to ensure that users only pay the cost for variants they use
This commit is contained in:
clayjohn
2023-07-18 11:21:27 +02:00
parent f8dbed4d0a
commit e970f5249c
13 changed files with 355 additions and 140 deletions

View File

@@ -41,10 +41,26 @@
#include "servers/rendering_server.h"
class ShaderRD {
public:
struct VariantDefine {
int group = 0;
CharString text;
bool default_enabled = true;
VariantDefine(){};
VariantDefine(int p_group, const String &p_text, bool p_default_enabled) {
group = p_group;
default_enabled = p_default_enabled;
text = p_text.utf8();
}
};
private:
//versions
CharString general_defines;
Vector<CharString> variant_defines;
Vector<VariantDefine> variant_defines;
Vector<bool> variants_enabled;
HashMap<int, LocalVector<int>> group_to_variant_map;
Vector<bool> group_enabled;
struct Version {
CharString uniforms;
@@ -55,7 +71,7 @@ class ShaderRD {
Vector<CharString> custom_defines;
Vector<uint8_t> *variant_data = nullptr;
RID *variants = nullptr; //same size as version defines
RID *variants = nullptr; // Same size as variant defines.
bool valid;
bool dirty;
@@ -64,10 +80,17 @@ class ShaderRD {
Mutex variant_set_mutex;
void _compile_variant(uint32_t p_variant, Version *p_version);
struct CompileData {
Version *version;
int group = 0;
};
void _compile_variant(uint32_t p_variant, const CompileData *p_data);
void _initialize_version(Version *p_version);
void _clear_version(Version *p_version);
void _compile_version(Version *p_version);
void _compile_version(Version *p_version, int p_group);
void _allocate_placeholders(Version *p_version, int p_group);
RID_Owner<Version> version_owner;
@@ -97,6 +120,7 @@ class ShaderRD {
CharString base_compute_defines;
String base_sha256;
LocalVector<String> group_sha256;
static String shader_cache_dir;
static bool shader_cache_cleanup_on_start;
@@ -119,8 +143,9 @@ class ShaderRD {
void _add_stage(const char *p_code, StageType p_stage_type);
String _version_get_sha1(Version *p_version) const;
bool _load_from_cache(Version *p_version);
void _save_to_cache(Version *p_version);
bool _load_from_cache(Version *p_version, int p_group);
void _save_to_cache(Version *p_version, int p_group);
void _initialize_cache();
protected:
ShaderRD();
@@ -140,7 +165,14 @@ public:
ERR_FAIL_COND_V(!version, RID());
if (version->dirty) {
_compile_version(version);
_initialize_version(version);
for (int i = 0; i < group_enabled.size(); i++) {
if (!group_enabled[i]) {
_allocate_placeholders(version, i);
continue;
}
_compile_version(version, i);
}
}
if (!version->valid) {
@@ -154,9 +186,14 @@ public:
bool version_free(RID p_version);
// Enable/disable variants for things that you know won't be used at engine initialization time .
void set_variant_enabled(int p_variant, bool p_enabled);
bool is_variant_enabled(int p_variant) const;
// Enable/disable groups for things that might be enabled at run time.
void enable_group(int p_group);
bool is_group_enabled(int p_group) const;
static void set_shader_cache_dir(const String &p_dir);
static void set_shader_cache_save_compressed(bool p_enable);
static void set_shader_cache_save_compressed_zstd(bool p_enable);
@@ -165,6 +202,8 @@ public:
RS::ShaderNativeSourceCode version_get_native_source_code(RID p_version);
void initialize(const Vector<String> &p_variant_defines, const String &p_general_defines = "");
void initialize(const Vector<VariantDefine> &p_variant_defines, const String &p_general_defines = "");
virtual ~ShaderRD();
};