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

Unify material parameter update

* Unifies how material parameters are updated.
* Single function, easier to maintain.
* Updates materials properly when textures change.
This commit is contained in:
reduz
2021-07-06 18:56:28 -03:00
parent 5d7c23dcc6
commit c43f624d44
11 changed files with 143 additions and 461 deletions

View File

@@ -435,94 +435,16 @@ void SceneShaderForwardClustered::MaterialData::set_next_pass(RID p_pass) {
next_pass = p_pass;
}
void SceneShaderForwardClustered::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
bool SceneShaderForwardClustered::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
SceneShaderForwardClustered *shader_singleton = (SceneShaderForwardClustered *)SceneShaderForwardClustered::singleton;
if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
p_uniform_dirty = true;
if (uniform_buffer.is_valid()) {
RD::get_singleton()->free(uniform_buffer);
uniform_buffer = RID();
}
ubo_data.resize(shader_data->ubo_size);
if (ubo_data.size()) {
uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
}
//clear previous uniform set
if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
RD::get_singleton()->free(uniform_set);
uniform_set = RID();
}
}
//check whether buffer changed
if (p_uniform_dirty && ubo_data.size()) {
update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw(), RD::BARRIER_MASK_RASTER);
}
uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
if ((uint32_t)texture_cache.size() != tex_uniform_count) {
texture_cache.resize(tex_uniform_count);
p_textures_dirty = true;
//clear previous uniform set
if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
RD::get_singleton()->free(uniform_set);
uniform_set = RID();
}
}
if (p_textures_dirty && tex_uniform_count) {
update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
}
if (shader_data->ubo_size == 0 && shader_data->texture_uniforms.size() == 0) {
// This material does not require an uniform set, so don't create it.
return;
}
if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
//no reason to update uniform set, only UBO (or nothing) was needed to update
return;
}
Vector<RD::Uniform> uniforms;
{
if (shader_data->ubo_size) {
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 0;
u.ids.push_back(uniform_buffer);
uniforms.push_back(u);
}
const RID *textures = texture_cache.ptrw();
for (uint32_t i = 0; i < tex_uniform_count; i++) {
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 1 + i;
u.ids.push_back(textures[i]);
uniforms.push_back(u);
}
}
uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardClustered::MATERIAL_UNIFORM_SET);
return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardClustered::MATERIAL_UNIFORM_SET, RD::BARRIER_MASK_RASTER);
}
SceneShaderForwardClustered::MaterialData::~MaterialData() {
if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
RD::get_singleton()->free(uniform_set);
}
if (uniform_buffer.is_valid()) {
RD::get_singleton()->free(uniform_buffer);
}
}
RendererStorageRD::MaterialData *SceneShaderForwardClustered::_create_material_func(ShaderData *p_shader) {

View File

@@ -166,17 +166,14 @@ public:
struct MaterialData : public RendererStorageRD::MaterialData {
uint64_t last_frame;
ShaderData *shader_data;
RID uniform_buffer;
RID uniform_set;
Vector<RID> texture_cache;
Vector<uint8_t> ubo_data;
uint64_t last_pass = 0;
uint32_t index = 0;
RID next_pass;
uint8_t priority;
virtual void set_render_priority(int p_priority);
virtual void set_next_pass(RID p_pass);
virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
virtual ~MaterialData();
};