Properly dispose of custom shaders, closes #19300
This commit is contained in:
parent
b3335e943b
commit
973b68f396
4 changed files with 58 additions and 2 deletions
|
@ -229,6 +229,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
|
|||
glDeleteShader(v.vert_id);
|
||||
glDeleteShader(v.frag_id);
|
||||
glDeleteProgram(v.id);
|
||||
memdelete_arr(v.uniform_location);
|
||||
v.id = 0;
|
||||
}
|
||||
}
|
||||
|
@ -328,6 +329,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
|
|||
if (iloglen < 0) {
|
||||
glDeleteShader(v.vert_id);
|
||||
glDeleteProgram(v.id);
|
||||
memdelete_arr(v.uniform_location);
|
||||
v.id = 0;
|
||||
|
||||
ERR_PRINT("No OpenGL vertex shader compiler log. What the frick?");
|
||||
|
@ -349,6 +351,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
|
|||
Memory::free_static(ilogmem);
|
||||
glDeleteShader(v.vert_id);
|
||||
glDeleteProgram(v.id);
|
||||
memdelete_arr(v.uniform_location);
|
||||
v.id = 0;
|
||||
}
|
||||
|
||||
|
@ -403,6 +406,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
|
|||
glDeleteShader(v.frag_id);
|
||||
glDeleteShader(v.vert_id);
|
||||
glDeleteProgram(v.id);
|
||||
memdelete_arr(v.uniform_location);
|
||||
v.id = 0;
|
||||
|
||||
ERR_PRINT("No OpenGL fragment shader compiler log. What the frick?");
|
||||
|
@ -425,6 +429,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
|
|||
glDeleteShader(v.frag_id);
|
||||
glDeleteShader(v.vert_id);
|
||||
glDeleteProgram(v.id);
|
||||
memdelete_arr(v.uniform_location);
|
||||
v.id = 0;
|
||||
}
|
||||
|
||||
|
@ -452,6 +457,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
|
|||
glDeleteShader(v.frag_id);
|
||||
glDeleteShader(v.vert_id);
|
||||
glDeleteProgram(v.id);
|
||||
memdelete_arr(v.uniform_location);
|
||||
v.id = 0;
|
||||
|
||||
ERR_PRINT("No OpenGL program link log. What the frick?");
|
||||
|
@ -476,6 +482,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
|
|||
glDeleteShader(v.frag_id);
|
||||
glDeleteShader(v.vert_id);
|
||||
glDeleteProgram(v.id);
|
||||
memdelete_arr(v.uniform_location);
|
||||
v.id = 0;
|
||||
|
||||
ERR_FAIL_V(NULL);
|
||||
|
@ -519,6 +526,10 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
|
|||
glUseProgram(0);
|
||||
v.ok = true;
|
||||
|
||||
if (cc) {
|
||||
cc->versions.insert(conditional_version.version);
|
||||
}
|
||||
|
||||
return &v;
|
||||
}
|
||||
|
||||
|
@ -683,9 +694,26 @@ void ShaderGLES2::set_custom_shader(uint32_t p_code_id) {
|
|||
}
|
||||
|
||||
void ShaderGLES2::free_custom_shader(uint32_t p_code_id) {
|
||||
|
||||
ERR_FAIL_COND(!custom_code_map.has(p_code_id));
|
||||
if (conditional_version.code_version == p_code_id)
|
||||
conditional_version.code_version = 0;
|
||||
conditional_version.code_version = 0; //do not keep using a version that is going away
|
||||
|
||||
VersionKey key;
|
||||
key.code_version = p_code_id;
|
||||
for (Set<uint32_t>::Element *E = custom_code_map[p_code_id].versions.front(); E; E = E->next()) {
|
||||
key.version = E->get();
|
||||
ERR_CONTINUE(!version_map.has(key));
|
||||
Version &v = version_map[key];
|
||||
|
||||
glDeleteShader(v.vert_id);
|
||||
glDeleteShader(v.frag_id);
|
||||
glDeleteProgram(v.id);
|
||||
memdelete_arr(v.uniform_location);
|
||||
v.id = 0;
|
||||
|
||||
version_map.erase(key);
|
||||
}
|
||||
|
||||
custom_code_map.erase(p_code_id);
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ private:
|
|||
Vector<StringName> texture_uniforms;
|
||||
Vector<StringName> custom_uniforms;
|
||||
Vector<CharString> custom_defines;
|
||||
Set<uint32_t> versions;
|
||||
};
|
||||
|
||||
struct Version {
|
||||
|
|
|
@ -204,6 +204,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
|
|||
glDeleteShader(v.vert_id);
|
||||
glDeleteShader(v.frag_id);
|
||||
glDeleteProgram(v.id);
|
||||
memdelete_arr(v.uniform_location);
|
||||
v.id = 0;
|
||||
}
|
||||
}
|
||||
|
@ -324,6 +325,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
|
|||
|
||||
glDeleteShader(v.vert_id);
|
||||
glDeleteProgram(v.id);
|
||||
memdelete_arr(v.uniform_location);
|
||||
v.id = 0;
|
||||
|
||||
ERR_PRINT("Vertex shader compilation failed with empty log");
|
||||
|
@ -345,6 +347,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
|
|||
memfree(ilogmem);
|
||||
glDeleteShader(v.vert_id);
|
||||
glDeleteProgram(v.id);
|
||||
memdelete_arr(v.uniform_location);
|
||||
v.id = 0;
|
||||
}
|
||||
|
||||
|
@ -418,6 +421,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
|
|||
glDeleteShader(v.frag_id);
|
||||
glDeleteShader(v.vert_id);
|
||||
glDeleteProgram(v.id);
|
||||
memdelete_arr(v.uniform_location);
|
||||
v.id = 0;
|
||||
ERR_PRINT("Fragment shader compilation failed with empty log");
|
||||
} else {
|
||||
|
@ -440,6 +444,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
|
|||
glDeleteShader(v.frag_id);
|
||||
glDeleteShader(v.vert_id);
|
||||
glDeleteProgram(v.id);
|
||||
memdelete_arr(v.uniform_location);
|
||||
v.id = 0;
|
||||
}
|
||||
|
||||
|
@ -486,6 +491,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
|
|||
glDeleteShader(v.frag_id);
|
||||
glDeleteShader(v.vert_id);
|
||||
glDeleteProgram(v.id);
|
||||
memdelete_arr(v.uniform_location);
|
||||
v.id = 0;
|
||||
ERR_FAIL_COND_V(iloglen <= 0, NULL);
|
||||
}
|
||||
|
@ -508,6 +514,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
|
|||
glDeleteShader(v.frag_id);
|
||||
glDeleteShader(v.vert_id);
|
||||
glDeleteProgram(v.id);
|
||||
memdelete_arr(v.uniform_location);
|
||||
v.id = 0;
|
||||
|
||||
ERR_FAIL_V(NULL);
|
||||
|
@ -559,6 +566,9 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
|
|||
glUseProgram(0);
|
||||
|
||||
v.ok = true;
|
||||
if (cc) {
|
||||
cc->versions.insert(conditional_version.version);
|
||||
}
|
||||
|
||||
return &v;
|
||||
}
|
||||
|
@ -742,7 +752,23 @@ void ShaderGLES3::free_custom_shader(uint32_t p_code_id) {
|
|||
|
||||
ERR_FAIL_COND(!custom_code_map.has(p_code_id));
|
||||
if (conditional_version.code_version == p_code_id)
|
||||
conditional_version.code_version = 0; //bye
|
||||
conditional_version.code_version = 0; //do not keep using a version that is going away
|
||||
|
||||
VersionKey key;
|
||||
key.code_version = p_code_id;
|
||||
for (Set<uint32_t>::Element *E = custom_code_map[p_code_id].versions.front(); E; E = E->next()) {
|
||||
key.version = E->get();
|
||||
ERR_CONTINUE(!version_map.has(key));
|
||||
Version &v = version_map[key];
|
||||
|
||||
glDeleteShader(v.vert_id);
|
||||
glDeleteShader(v.frag_id);
|
||||
glDeleteProgram(v.id);
|
||||
memdelete_arr(v.uniform_location);
|
||||
v.id = 0;
|
||||
|
||||
version_map.erase(key);
|
||||
}
|
||||
|
||||
custom_code_map.erase(p_code_id);
|
||||
}
|
||||
|
|
|
@ -117,6 +117,7 @@ private:
|
|||
uint32_t version;
|
||||
Vector<StringName> texture_uniforms;
|
||||
Vector<CharString> custom_defines;
|
||||
Set<uint32_t> versions;
|
||||
};
|
||||
|
||||
struct Version {
|
||||
|
|
Loading…
Reference in a new issue