Merge pull request #67112 from Chaosus/fix_boolean_uniform_instances

This commit is contained in:
Yuri Rubinsky 2022-10-28 23:17:23 +03:00 committed by GitHub
commit 11e1bac768
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 90 additions and 27 deletions

View File

@ -89,7 +89,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
gui[j + 3] = 0; // ignored gui[j + 3] = 0; // ignored
} }
} else { } else {
int v = value; uint32_t v = value;
gui[0] = v & 1 ? 1 : 0; gui[0] = v & 1 ? 1 : 0;
gui[1] = v & 2 ? 1 : 0; gui[1] = v & 2 ? 1 : 0;
} }
@ -116,7 +116,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
gui[j + 3] = 0; // ignored gui[j + 3] = 0; // ignored
} }
} else { } else {
int v = value; uint32_t v = value;
gui[0] = (v & 1) ? 1 : 0; gui[0] = (v & 1) ? 1 : 0;
gui[1] = (v & 2) ? 1 : 0; gui[1] = (v & 2) ? 1 : 0;
gui[2] = (v & 4) ? 1 : 0; gui[2] = (v & 4) ? 1 : 0;
@ -145,7 +145,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
} }
} }
} else { } else {
int v = value; uint32_t v = value;
gui[0] = (v & 1) ? 1 : 0; gui[0] = (v & 1) ? 1 : 0;
gui[1] = (v & 2) ? 1 : 0; gui[1] = (v & 2) ? 1 : 0;
gui[2] = (v & 4) ? 1 : 0; gui[2] = (v & 4) ? 1 : 0;
@ -728,7 +728,7 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type,
switch (type) { switch (type) {
case ShaderLanguage::TYPE_BOOL: { case ShaderLanguage::TYPE_BOOL: {
uint32_t *gui = (uint32_t *)data; uint32_t *gui = (uint32_t *)data;
*gui = value[0].boolean ? 1 : 0; gui[0] = value[0].boolean ? 1 : 0;
} break; } break;
case ShaderLanguage::TYPE_BVEC2: { case ShaderLanguage::TYPE_BVEC2: {
uint32_t *gui = (uint32_t *)data; uint32_t *gui = (uint32_t *)data;
@ -2314,7 +2314,7 @@ void MaterialStorage::global_shader_parameters_instance_free(RID p_instance) {
global_shader_uniforms.instance_buffer_pos.erase(p_instance); global_shader_uniforms.instance_buffer_pos.erase(p_instance);
} }
void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) { void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count) {
if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) { if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) {
return; //just not allocated, ignore return; //just not allocated, ignore
} }
@ -2324,7 +2324,9 @@ void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, i
return; //again, not allocated, ignore return; //again, not allocated, ignore
} }
ERR_FAIL_INDEX(p_index, ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); ERR_FAIL_INDEX(p_index, ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES);
ERR_FAIL_COND_MSG(p_value.get_type() > Variant::COLOR, "Unsupported variant type for instance parameter: " + Variant::get_type_name(p_value.get_type())); //anything greater not supported
Variant::Type value_type = p_value.get_type();
ERR_FAIL_COND_MSG(p_value.get_type() > Variant::COLOR, "Unsupported variant type for instance parameter: " + Variant::get_type_name(value_type)); //anything greater not supported
ShaderLanguage::DataType datatype_from_value[Variant::COLOR + 1] = { ShaderLanguage::DataType datatype_from_value[Variant::COLOR + 1] = {
ShaderLanguage::TYPE_MAX, //nil ShaderLanguage::TYPE_MAX, //nil
@ -2350,9 +2352,24 @@ void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, i
ShaderLanguage::TYPE_VEC4 //color ShaderLanguage::TYPE_VEC4 //color
}; };
ShaderLanguage::DataType datatype = datatype_from_value[p_value.get_type()]; ShaderLanguage::DataType datatype = ShaderLanguage::TYPE_MAX;
if (value_type == Variant::INT && p_flags_count > 0) {
switch (p_flags_count) {
case 1:
datatype = ShaderLanguage::TYPE_BVEC2;
break;
case 2:
datatype = ShaderLanguage::TYPE_BVEC3;
break;
case 3:
datatype = ShaderLanguage::TYPE_BVEC4;
break;
}
} else {
datatype = datatype_from_value[value_type];
}
ERR_FAIL_COND_MSG(datatype == ShaderLanguage::TYPE_MAX, "Unsupported variant type for instance parameter: " + Variant::get_type_name(p_value.get_type())); //anything greater not supported ERR_FAIL_COND_MSG(datatype == ShaderLanguage::TYPE_MAX, "Unsupported variant type for instance parameter: " + Variant::get_type_name(value_type)); //anything greater not supported
pos += p_index; pos += p_index;

View File

@ -530,7 +530,7 @@ public:
virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override; virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override;
virtual void global_shader_parameters_instance_free(RID p_instance) override; virtual void global_shader_parameters_instance_free(RID p_instance) override;
virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) override; virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0) override;
GLuint global_shader_parameters_get_uniform_buffer() const; GLuint global_shader_parameters_get_uniform_buffer() const;

View File

@ -54,7 +54,7 @@ public:
virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override { return 0; } virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override { return 0; }
virtual void global_shader_parameters_instance_free(RID p_instance) override {} virtual void global_shader_parameters_instance_free(RID p_instance) override {}
virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) override {} virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0) override {}
/* SHADER API */ /* SHADER API */

View File

@ -85,7 +85,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
gui[j + 3] = 0; // ignored gui[j + 3] = 0; // ignored
} }
} else { } else {
int v = value; uint32_t v = value;
gui[0] = v & 1 ? 1 : 0; gui[0] = v & 1 ? 1 : 0;
gui[1] = v & 2 ? 1 : 0; gui[1] = v & 2 ? 1 : 0;
} }
@ -112,7 +112,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
gui[j + 3] = 0; // ignored gui[j + 3] = 0; // ignored
} }
} else { } else {
int v = value; uint32_t v = value;
gui[0] = (v & 1) ? 1 : 0; gui[0] = (v & 1) ? 1 : 0;
gui[1] = (v & 2) ? 1 : 0; gui[1] = (v & 2) ? 1 : 0;
gui[2] = (v & 4) ? 1 : 0; gui[2] = (v & 4) ? 1 : 0;
@ -141,7 +141,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
} }
} }
} else { } else {
int v = value; uint32_t v = value;
gui[0] = (v & 1) ? 1 : 0; gui[0] = (v & 1) ? 1 : 0;
gui[1] = (v & 2) ? 1 : 0; gui[1] = (v & 2) ? 1 : 0;
gui[2] = (v & 4) ? 1 : 0; gui[2] = (v & 4) ? 1 : 0;
@ -734,7 +734,7 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type,
switch (type) { switch (type) {
case ShaderLanguage::TYPE_BOOL: { case ShaderLanguage::TYPE_BOOL: {
uint32_t *gui = (uint32_t *)data; uint32_t *gui = (uint32_t *)data;
*gui = value[0].boolean ? 1 : 0; gui[0] = value[0].boolean ? 1 : 0;
} break; } break;
case ShaderLanguage::TYPE_BVEC2: { case ShaderLanguage::TYPE_BVEC2: {
uint32_t *gui = (uint32_t *)data; uint32_t *gui = (uint32_t *)data;
@ -2213,7 +2213,7 @@ void MaterialStorage::global_shader_parameters_instance_free(RID p_instance) {
global_shader_uniforms.instance_buffer_pos.erase(p_instance); global_shader_uniforms.instance_buffer_pos.erase(p_instance);
} }
void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) { void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count) {
if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) { if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) {
return; //just not allocated, ignore return; //just not allocated, ignore
} }
@ -2223,7 +2223,9 @@ void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, i
return; //again, not allocated, ignore return; //again, not allocated, ignore
} }
ERR_FAIL_INDEX(p_index, ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); ERR_FAIL_INDEX(p_index, ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES);
ERR_FAIL_COND_MSG(p_value.get_type() > Variant::COLOR, "Unsupported variant type for instance parameter: " + Variant::get_type_name(p_value.get_type())); //anything greater not supported
Variant::Type value_type = p_value.get_type();
ERR_FAIL_COND_MSG(p_value.get_type() > Variant::COLOR, "Unsupported variant type for instance parameter: " + Variant::get_type_name(value_type)); //anything greater not supported
const ShaderLanguage::DataType datatype_from_value[Variant::COLOR + 1] = { const ShaderLanguage::DataType datatype_from_value[Variant::COLOR + 1] = {
ShaderLanguage::TYPE_MAX, //nil ShaderLanguage::TYPE_MAX, //nil
@ -2249,9 +2251,23 @@ void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, i
ShaderLanguage::TYPE_VEC4 //color ShaderLanguage::TYPE_VEC4 //color
}; };
ShaderLanguage::DataType datatype = datatype_from_value[p_value.get_type()]; ShaderLanguage::DataType datatype = ShaderLanguage::TYPE_MAX;
if (value_type == Variant::INT && p_flags_count > 0) {
ERR_FAIL_COND_MSG(datatype == ShaderLanguage::TYPE_MAX, "Unsupported variant type for instance parameter: " + Variant::get_type_name(p_value.get_type())); //anything greater not supported switch (p_flags_count) {
case 1:
datatype = ShaderLanguage::TYPE_BVEC2;
break;
case 2:
datatype = ShaderLanguage::TYPE_BVEC3;
break;
case 3:
datatype = ShaderLanguage::TYPE_BVEC4;
break;
}
} else {
datatype = datatype_from_value[value_type];
}
ERR_FAIL_COND_MSG(datatype == ShaderLanguage::TYPE_MAX, "Unsupported variant type for instance parameter: " + Variant::get_type_name(value_type)); //anything greater not supported
pos += p_index; pos += p_index;

View File

@ -361,7 +361,7 @@ public:
virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override; virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override;
virtual void global_shader_parameters_instance_free(RID p_instance) override; virtual void global_shader_parameters_instance_free(RID p_instance) override;
virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) override; virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0) override;
RID global_shader_uniforms_get_storage_buffer() const; RID global_shader_uniforms_get_storage_buffer() const;

View File

@ -1449,8 +1449,23 @@ void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, c
} else { } else {
E->value.value = p_value; E->value.value = p_value;
if (E->value.index >= 0 && instance->instance_allocated_shader_uniforms) { if (E->value.index >= 0 && instance->instance_allocated_shader_uniforms) {
int flags_count = 0;
if (E->value.info.hint == PROPERTY_HINT_FLAGS) {
// A small hack to detect boolean flags count and prevent overhead.
switch (E->value.info.hint_string.length()) {
case 3: // "x,y"
flags_count = 1;
break;
case 5: // "x,y,z"
flags_count = 2;
break;
case 7: // "x,y,z,w"
flags_count = 3;
break;
}
}
//update directly //update directly
RSG::material_storage->global_shader_parameters_instance_update(p_instance, E->value.index, p_value); RSG::material_storage->global_shader_parameters_instance_update(p_instance, E->value.index, p_value, flags_count);
} }
} }
} }
@ -3884,7 +3899,22 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : p_instance->instance_shader_uniforms) { for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : p_instance->instance_shader_uniforms) {
if (E.value.value.get_type() != Variant::NIL) { if (E.value.value.get_type() != Variant::NIL) {
RSG::material_storage->global_shader_parameters_instance_update(p_instance->self, E.value.index, E.value.value); int flags_count = 0;
if (E.value.info.hint == PROPERTY_HINT_FLAGS) {
// A small hack to detect boolean flags count and prevent overhead.
switch (E.value.info.hint_string.length()) {
case 3: // "x,y"
flags_count = 1;
break;
case 5: // "x,y,z"
flags_count = 2;
break;
case 7: // "x,y,z,w"
flags_count = 3;
break;
}
}
RSG::material_storage->global_shader_parameters_instance_update(p_instance->self, E.value.index, E.value.value, flags_count);
} }
} }
} else { } else {

View File

@ -373,16 +373,16 @@ void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const Str
static String _get_global_shader_uniform_from_type_and_index(const String &p_buffer, const String &p_index, ShaderLanguage::DataType p_type) { static String _get_global_shader_uniform_from_type_and_index(const String &p_buffer, const String &p_index, ShaderLanguage::DataType p_type) {
switch (p_type) { switch (p_type) {
case ShaderLanguage::TYPE_BOOL: { case ShaderLanguage::TYPE_BOOL: {
return "(" + p_buffer + "[" + p_index + "].x != 0.0)"; return "(floatBitsToUint(" + p_buffer + "[" + p_index + "].x) != 0)";
} }
case ShaderLanguage::TYPE_BVEC2: { case ShaderLanguage::TYPE_BVEC2: {
return "(notEqual(" + p_buffer + "[" + p_index + "].xy, vec2(0.0)))"; return "bvec2(floatBitsToUint(" + p_buffer + "[" + p_index + "].x), floatBitsToUint(" + p_buffer + "[" + p_index + "].y))";
} }
case ShaderLanguage::TYPE_BVEC3: { case ShaderLanguage::TYPE_BVEC3: {
return "(notEqual(" + p_buffer + "[" + p_index + "].xyz, vec3(0.0)))"; return "bvec3(floatBitsToUint(" + p_buffer + "[" + p_index + "].x), floatBitsToUint(" + p_buffer + "[" + p_index + "].y), floatBitsToUint(" + p_buffer + "[" + p_index + "].z))";
} }
case ShaderLanguage::TYPE_BVEC4: { case ShaderLanguage::TYPE_BVEC4: {
return "(notEqual(" + p_buffer + "[" + p_index + "].xyzw, vec4(0.0)))"; return "bvec4(floatBitsToUint(" + p_buffer + "[" + p_index + "].x), floatBitsToUint(" + p_buffer + "[" + p_index + "].y), floatBitsToUint(" + p_buffer + "[" + p_index + "].z), floatBitsToUint(" + p_buffer + "[" + p_index + "].w))";
} }
case ShaderLanguage::TYPE_INT: { case ShaderLanguage::TYPE_INT: {
return "floatBitsToInt(" + p_buffer + "[" + p_index + "].x)"; return "floatBitsToInt(" + p_buffer + "[" + p_index + "].x)";

View File

@ -53,7 +53,7 @@ public:
virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) = 0; virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) = 0;
virtual void global_shader_parameters_instance_free(RID p_instance) = 0; virtual void global_shader_parameters_instance_free(RID p_instance) = 0;
virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0; virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0) = 0;
/* SHADER API */ /* SHADER API */
virtual RID shader_allocate() = 0; virtual RID shader_allocate() = 0;