Merge pull request #67112 from Chaosus/fix_boolean_uniform_instances
This commit is contained in:
commit
11e1bac768
|
@ -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;
|
||||
|
@ -2314,7 +2314,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
|
||||
}
|
||||
|
@ -2324,7 +2324,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
|
||||
|
@ -2350,9 +2352,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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -2213,7 +2213,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
|
||||
}
|
||||
|
@ -2223,7 +2223,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
|
||||
|
@ -2249,9 +2251,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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -1449,8 +1449,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3884,7 +3899,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 {
|
||||
|
|
|
@ -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)";
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue