Fix incorrect setup of boolean uniform instances

This commit is contained in:
Yuri Rubinsky 2022-10-09 08:14:07 +03:00
parent 880a0177d1
commit f4db4bb7a2
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
}
} else {
int v = value;
uint32_t v = value;
gui[0] = v & 1 ? 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
}
} else {
int v = value;
uint32_t v = value;
gui[0] = (v & 1) ? 1 : 0;
gui[1] = (v & 2) ? 1 : 0;
gui[2] = (v & 4) ? 1 : 0;
@ -145,7 +145,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
}
}
} else {
int v = value;
uint32_t v = value;
gui[0] = (v & 1) ? 1 : 0;
gui[1] = (v & 2) ? 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) {
case ShaderLanguage::TYPE_BOOL: {
uint32_t *gui = (uint32_t *)data;
*gui = value[0].boolean ? 1 : 0;
gui[0] = value[0].boolean ? 1 : 0;
} break;
case ShaderLanguage::TYPE_BVEC2: {
uint32_t *gui = (uint32_t *)data;
@ -2312,7 +2312,7 @@ void MaterialStorage::global_shader_parameters_instance_free(RID 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)) {
return; //just not allocated, ignore
}
@ -2322,7 +2322,9 @@ void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, i
return; //again, not allocated, ignore
}
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::TYPE_MAX, //nil
@ -2348,9 +2350,24 @@ void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, i
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;

View File

@ -530,7 +530,7 @@ public:
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_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;

View File

@ -54,7 +54,7 @@ public:
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_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 */

View File

@ -85,7 +85,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
gui[j + 3] = 0; // ignored
}
} else {
int v = value;
uint32_t v = value;
gui[0] = v & 1 ? 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
}
} else {
int v = value;
uint32_t v = value;
gui[0] = (v & 1) ? 1 : 0;
gui[1] = (v & 2) ? 1 : 0;
gui[2] = (v & 4) ? 1 : 0;
@ -141,7 +141,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
}
}
} else {
int v = value;
uint32_t v = value;
gui[0] = (v & 1) ? 1 : 0;
gui[1] = (v & 2) ? 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) {
case ShaderLanguage::TYPE_BOOL: {
uint32_t *gui = (uint32_t *)data;
*gui = value[0].boolean ? 1 : 0;
gui[0] = value[0].boolean ? 1 : 0;
} break;
case ShaderLanguage::TYPE_BVEC2: {
uint32_t *gui = (uint32_t *)data;
@ -2211,7 +2211,7 @@ void MaterialStorage::global_shader_parameters_instance_free(RID 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)) {
return; //just not allocated, ignore
}
@ -2221,7 +2221,9 @@ void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, i
return; //again, not allocated, ignore
}
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] = {
ShaderLanguage::TYPE_MAX, //nil
@ -2247,9 +2249,23 @@ void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, i
ShaderLanguage::TYPE_VEC4 //color
};
ShaderLanguage::DataType datatype = datatype_from_value[p_value.get_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
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(value_type)); //anything greater not supported
pos += p_index;

View File

@ -361,7 +361,7 @@ public:
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_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;

View File

@ -1454,8 +1454,23 @@ void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, c
} else {
E->value.value = p_value;
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
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);
}
}
}
@ -3889,7 +3904,22 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : p_instance->instance_shader_uniforms) {
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 {

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) {
switch (p_type) {
case ShaderLanguage::TYPE_BOOL: {
return "(" + p_buffer + "[" + p_index + "].x != 0.0)";
return "(floatBitsToUint(" + p_buffer + "[" + p_index + "].x) != 0)";
}
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: {
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: {
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: {
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 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 */
virtual RID shader_allocate() = 0;