Add a shader warning when the uniform buffer limit is exceeded
This commit is contained in:
parent
9221c0f8ad
commit
fd9c92d4ab
@ -293,15 +293,20 @@ void ShaderTextEditor::_update_warning_panel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
warning_count++;
|
warning_count++;
|
||||||
|
int line = w.get_line();
|
||||||
|
|
||||||
// First cell.
|
// First cell.
|
||||||
warnings_panel->push_cell();
|
warnings_panel->push_cell();
|
||||||
warnings_panel->push_meta(w.get_line() - 1);
|
|
||||||
warnings_panel->push_color(warnings_panel->get_theme_color(SNAME("warning_color"), SNAME("Editor")));
|
warnings_panel->push_color(warnings_panel->get_theme_color(SNAME("warning_color"), SNAME("Editor")));
|
||||||
warnings_panel->add_text(TTR("Line") + " " + itos(w.get_line()));
|
if (line != -1) {
|
||||||
warnings_panel->add_text(" (" + w.get_name() + "):");
|
warnings_panel->push_meta(line - 1);
|
||||||
|
warnings_panel->add_text(TTR("Line") + " " + itos(line));
|
||||||
|
warnings_panel->add_text(" (" + w.get_name() + "):");
|
||||||
|
warnings_panel->pop(); // Meta goto.
|
||||||
|
} else {
|
||||||
|
warnings_panel->add_text(w.get_name() + ":");
|
||||||
|
}
|
||||||
warnings_panel->pop(); // Color.
|
warnings_panel->pop(); // Color.
|
||||||
warnings_panel->pop(); // Meta goto.
|
|
||||||
warnings_panel->pop(); // Cell.
|
warnings_panel->pop(); // Cell.
|
||||||
|
|
||||||
// Second cell.
|
// Second cell.
|
||||||
|
@ -350,7 +350,7 @@ void Main::print_help(const char *p_binary) {
|
|||||||
OS::get_singleton()->print(" -b, --breakpoints Breakpoint list as source::line comma-separated pairs, no spaces (use %%20 instead).\n");
|
OS::get_singleton()->print(" -b, --breakpoints Breakpoint list as source::line comma-separated pairs, no spaces (use %%20 instead).\n");
|
||||||
OS::get_singleton()->print(" --profiling Enable profiling in the script debugger.\n");
|
OS::get_singleton()->print(" --profiling Enable profiling in the script debugger.\n");
|
||||||
OS::get_singleton()->print(" --vk-layers Enable Vulkan Validation layers for debugging.\n");
|
OS::get_singleton()->print(" --vk-layers Enable Vulkan Validation layers for debugging.\n");
|
||||||
#if DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
OS::get_singleton()->print(" --gpu-abort Abort on GPU errors (usually validation layer errors), may help see the problem if your system freezes.\n");
|
OS::get_singleton()->print(" --gpu-abort Abort on GPU errors (usually validation layer errors), may help see the problem if your system freezes.\n");
|
||||||
#endif
|
#endif
|
||||||
OS::get_singleton()->print(" --remote-debug <uri> Remote debug (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007).\n");
|
OS::get_singleton()->print(" --remote-debug <uri> Remote debug (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007).\n");
|
||||||
|
@ -1591,7 +1591,7 @@ void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) {
|
|||||||
Bus::Effect bfx;
|
Bus::Effect bfx;
|
||||||
bfx.effect = fx;
|
bfx.effect = fx;
|
||||||
bfx.enabled = p_bus_layout->buses[i].effects[j].enabled;
|
bfx.enabled = p_bus_layout->buses[i].effects[j].enabled;
|
||||||
#if DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
bfx.prof_time = 0;
|
bfx.prof_time = 0;
|
||||||
#endif
|
#endif
|
||||||
bus->effects.push_back(bfx);
|
bus->effects.push_back(bfx);
|
||||||
|
@ -2655,13 +2655,13 @@ void RendererStorageRD::MaterialData::update_uniform_buffer(const Map<StringName
|
|||||||
uint32_t size = 0U;
|
uint32_t size = 0U;
|
||||||
// The following code enforces a 16-byte alignment of uniform arrays.
|
// The following code enforces a 16-byte alignment of uniform arrays.
|
||||||
if (E.value.array_size > 0) {
|
if (E.value.array_size > 0) {
|
||||||
size = ShaderLanguage::get_type_size(E.value.type) * E.value.array_size;
|
size = ShaderLanguage::get_datatype_size(E.value.type) * E.value.array_size;
|
||||||
int m = (16 * E.value.array_size);
|
int m = (16 * E.value.array_size);
|
||||||
if ((size % m) != 0U) {
|
if ((size % m) != 0U) {
|
||||||
size += m - (size % m);
|
size += m - (size % m);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
size = ShaderLanguage::get_type_size(E.value.type);
|
size = ShaderLanguage::get_datatype_size(E.value.type);
|
||||||
}
|
}
|
||||||
ERR_CONTINUE(offset + size > p_buffer_size);
|
ERR_CONTINUE(offset + size > p_buffer_size);
|
||||||
#endif
|
#endif
|
||||||
|
@ -54,81 +54,6 @@ static String _typestr(SL::DataType p_type) {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _get_datatype_size(SL::DataType p_type) {
|
|
||||||
switch (p_type) {
|
|
||||||
case SL::TYPE_VOID:
|
|
||||||
return 0;
|
|
||||||
case SL::TYPE_BOOL:
|
|
||||||
return 4;
|
|
||||||
case SL::TYPE_BVEC2:
|
|
||||||
return 8;
|
|
||||||
case SL::TYPE_BVEC3:
|
|
||||||
return 12;
|
|
||||||
case SL::TYPE_BVEC4:
|
|
||||||
return 16;
|
|
||||||
case SL::TYPE_INT:
|
|
||||||
return 4;
|
|
||||||
case SL::TYPE_IVEC2:
|
|
||||||
return 8;
|
|
||||||
case SL::TYPE_IVEC3:
|
|
||||||
return 12;
|
|
||||||
case SL::TYPE_IVEC4:
|
|
||||||
return 16;
|
|
||||||
case SL::TYPE_UINT:
|
|
||||||
return 4;
|
|
||||||
case SL::TYPE_UVEC2:
|
|
||||||
return 8;
|
|
||||||
case SL::TYPE_UVEC3:
|
|
||||||
return 12;
|
|
||||||
case SL::TYPE_UVEC4:
|
|
||||||
return 16;
|
|
||||||
case SL::TYPE_FLOAT:
|
|
||||||
return 4;
|
|
||||||
case SL::TYPE_VEC2:
|
|
||||||
return 8;
|
|
||||||
case SL::TYPE_VEC3:
|
|
||||||
return 12;
|
|
||||||
case SL::TYPE_VEC4:
|
|
||||||
return 16;
|
|
||||||
case SL::TYPE_MAT2:
|
|
||||||
return 32; // 4 * 4 + 4 * 4
|
|
||||||
case SL::TYPE_MAT3:
|
|
||||||
return 48; // 4 * 4 + 4 * 4 + 4 * 4
|
|
||||||
case SL::TYPE_MAT4:
|
|
||||||
return 64;
|
|
||||||
case SL::TYPE_SAMPLER2D:
|
|
||||||
return 16;
|
|
||||||
case SL::TYPE_ISAMPLER2D:
|
|
||||||
return 16;
|
|
||||||
case SL::TYPE_USAMPLER2D:
|
|
||||||
return 16;
|
|
||||||
case SL::TYPE_SAMPLER2DARRAY:
|
|
||||||
return 16;
|
|
||||||
case SL::TYPE_ISAMPLER2DARRAY:
|
|
||||||
return 16;
|
|
||||||
case SL::TYPE_USAMPLER2DARRAY:
|
|
||||||
return 16;
|
|
||||||
case SL::TYPE_SAMPLER3D:
|
|
||||||
return 16;
|
|
||||||
case SL::TYPE_ISAMPLER3D:
|
|
||||||
return 16;
|
|
||||||
case SL::TYPE_USAMPLER3D:
|
|
||||||
return 16;
|
|
||||||
case SL::TYPE_SAMPLERCUBE:
|
|
||||||
return 16;
|
|
||||||
case SL::TYPE_SAMPLERCUBEARRAY:
|
|
||||||
return 16;
|
|
||||||
case SL::TYPE_STRUCT:
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case SL::TYPE_MAX: {
|
|
||||||
ERR_FAIL_V(0);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
ERR_FAIL_V(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _get_datatype_alignment(SL::DataType p_type) {
|
static int _get_datatype_alignment(SL::DataType p_type) {
|
||||||
switch (p_type) {
|
switch (p_type) {
|
||||||
case SL::TYPE_VOID:
|
case SL::TYPE_VOID:
|
||||||
@ -658,12 +583,12 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
|
|||||||
uniform_defines.write[uniform.order] = ucode;
|
uniform_defines.write[uniform.order] = ucode;
|
||||||
if (is_buffer_global) {
|
if (is_buffer_global) {
|
||||||
//globals are indices into the global table
|
//globals are indices into the global table
|
||||||
uniform_sizes.write[uniform.order] = _get_datatype_size(ShaderLanguage::TYPE_UINT);
|
uniform_sizes.write[uniform.order] = ShaderLanguage::get_datatype_size(ShaderLanguage::TYPE_UINT);
|
||||||
uniform_alignments.write[uniform.order] = _get_datatype_alignment(ShaderLanguage::TYPE_UINT);
|
uniform_alignments.write[uniform.order] = _get_datatype_alignment(ShaderLanguage::TYPE_UINT);
|
||||||
} else {
|
} else {
|
||||||
// The following code enforces a 16-byte alignment of uniform arrays.
|
// The following code enforces a 16-byte alignment of uniform arrays.
|
||||||
if (uniform.array_size > 0) {
|
if (uniform.array_size > 0) {
|
||||||
int size = _get_datatype_size(uniform.type) * uniform.array_size;
|
int size = ShaderLanguage::get_datatype_size(uniform.type) * uniform.array_size;
|
||||||
int m = (16 * uniform.array_size);
|
int m = (16 * uniform.array_size);
|
||||||
if ((size % m) != 0) {
|
if ((size % m) != 0) {
|
||||||
size += m - (size % m);
|
size += m - (size % m);
|
||||||
@ -671,7 +596,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
|
|||||||
uniform_sizes.write[uniform.order] = size;
|
uniform_sizes.write[uniform.order] = size;
|
||||||
uniform_alignments.write[uniform.order] = 16;
|
uniform_alignments.write[uniform.order] = 16;
|
||||||
} else {
|
} else {
|
||||||
uniform_sizes.write[uniform.order] = _get_datatype_size(uniform.type);
|
uniform_sizes.write[uniform.order] = ShaderLanguage::get_datatype_size(uniform.type);
|
||||||
uniform_alignments.write[uniform.order] = _get_datatype_alignment(uniform.type);
|
uniform_alignments.write[uniform.order] = _get_datatype_alignment(uniform.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3866,55 +3866,77 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
|
|||||||
return pi;
|
return pi;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ShaderLanguage::get_type_size(DataType p_type) {
|
uint32_t ShaderLanguage::get_datatype_size(ShaderLanguage::DataType p_type) {
|
||||||
switch (p_type) {
|
switch (p_type) {
|
||||||
case TYPE_VOID:
|
case TYPE_VOID:
|
||||||
return 0;
|
return 0;
|
||||||
case TYPE_BOOL:
|
case TYPE_BOOL:
|
||||||
case TYPE_INT:
|
|
||||||
case TYPE_UINT:
|
|
||||||
case TYPE_FLOAT:
|
|
||||||
return 4;
|
return 4;
|
||||||
case TYPE_BVEC2:
|
case TYPE_BVEC2:
|
||||||
case TYPE_IVEC2:
|
|
||||||
case TYPE_UVEC2:
|
|
||||||
case TYPE_VEC2:
|
|
||||||
return 8;
|
return 8;
|
||||||
case TYPE_BVEC3:
|
case TYPE_BVEC3:
|
||||||
case TYPE_IVEC3:
|
|
||||||
case TYPE_UVEC3:
|
|
||||||
case TYPE_VEC3:
|
|
||||||
return 12;
|
return 12;
|
||||||
case TYPE_BVEC4:
|
case TYPE_BVEC4:
|
||||||
|
return 16;
|
||||||
|
case TYPE_INT:
|
||||||
|
return 4;
|
||||||
|
case TYPE_IVEC2:
|
||||||
|
return 8;
|
||||||
|
case TYPE_IVEC3:
|
||||||
|
return 12;
|
||||||
case TYPE_IVEC4:
|
case TYPE_IVEC4:
|
||||||
|
return 16;
|
||||||
|
case TYPE_UINT:
|
||||||
|
return 4;
|
||||||
|
case TYPE_UVEC2:
|
||||||
|
return 8;
|
||||||
|
case TYPE_UVEC3:
|
||||||
|
return 12;
|
||||||
case TYPE_UVEC4:
|
case TYPE_UVEC4:
|
||||||
|
return 16;
|
||||||
|
case TYPE_FLOAT:
|
||||||
|
return 4;
|
||||||
|
case TYPE_VEC2:
|
||||||
|
return 8;
|
||||||
|
case TYPE_VEC3:
|
||||||
|
return 12;
|
||||||
case TYPE_VEC4:
|
case TYPE_VEC4:
|
||||||
return 16;
|
return 16;
|
||||||
case TYPE_MAT2:
|
case TYPE_MAT2:
|
||||||
return 8;
|
return 32; // 4 * 4 + 4 * 4
|
||||||
case TYPE_MAT3:
|
case TYPE_MAT3:
|
||||||
return 12;
|
return 48; // 4 * 4 + 4 * 4 + 4 * 4
|
||||||
case TYPE_MAT4:
|
case TYPE_MAT4:
|
||||||
return 16;
|
return 64;
|
||||||
case TYPE_SAMPLER2D:
|
case TYPE_SAMPLER2D:
|
||||||
|
return 16;
|
||||||
case TYPE_ISAMPLER2D:
|
case TYPE_ISAMPLER2D:
|
||||||
|
return 16;
|
||||||
case TYPE_USAMPLER2D:
|
case TYPE_USAMPLER2D:
|
||||||
|
return 16;
|
||||||
case TYPE_SAMPLER2DARRAY:
|
case TYPE_SAMPLER2DARRAY:
|
||||||
|
return 16;
|
||||||
case TYPE_ISAMPLER2DARRAY:
|
case TYPE_ISAMPLER2DARRAY:
|
||||||
|
return 16;
|
||||||
case TYPE_USAMPLER2DARRAY:
|
case TYPE_USAMPLER2DARRAY:
|
||||||
|
return 16;
|
||||||
case TYPE_SAMPLER3D:
|
case TYPE_SAMPLER3D:
|
||||||
|
return 16;
|
||||||
case TYPE_ISAMPLER3D:
|
case TYPE_ISAMPLER3D:
|
||||||
|
return 16;
|
||||||
case TYPE_USAMPLER3D:
|
case TYPE_USAMPLER3D:
|
||||||
|
return 16;
|
||||||
case TYPE_SAMPLERCUBE:
|
case TYPE_SAMPLERCUBE:
|
||||||
|
return 16;
|
||||||
case TYPE_SAMPLERCUBEARRAY:
|
case TYPE_SAMPLERCUBEARRAY:
|
||||||
return 4; //not really, but useful for indices
|
return 16;
|
||||||
case TYPE_STRUCT:
|
case TYPE_STRUCT:
|
||||||
// FIXME: Implement.
|
|
||||||
return 0;
|
|
||||||
case ShaderLanguage::TYPE_MAX:
|
|
||||||
return 0;
|
return 0;
|
||||||
|
case TYPE_MAX: {
|
||||||
|
ERR_FAIL_V(0);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return 0;
|
ERR_FAIL_V(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderLanguage::get_keyword_list(List<String> *r_keywords) {
|
void ShaderLanguage::get_keyword_list(List<String> *r_keywords) {
|
||||||
@ -5309,7 +5331,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
|
|||||||
_set_error("Expected expression, found: " + get_token_text(tk));
|
_set_error("Expected expression, found: " + get_token_text(tk));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else {
|
} else {
|
||||||
#if DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (check_warnings && HAS_WARNING(ShaderWarning::FORMATTING_ERROR_FLAG)) {
|
if (check_warnings && HAS_WARNING(ShaderWarning::FORMATTING_ERROR_FLAG)) {
|
||||||
_add_line_warning(ShaderWarning::FORMATTING_ERROR, "Empty statement. Remove ';' to fix this warning.");
|
_add_line_warning(ShaderWarning::FORMATTING_ERROR, "Empty statement. Remove ';' to fix this warning.");
|
||||||
}
|
}
|
||||||
@ -6120,7 +6142,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
|
|||||||
ERR_FAIL_V(nullptr); //unexpected operator
|
ERR_FAIL_V(nullptr); //unexpected operator
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (check_warnings && HAS_WARNING(ShaderWarning::FLOAT_COMPARISON_FLAG) && (op == OP_EQUAL || op == OP_NOT_EQUAL) &&
|
if (check_warnings && HAS_WARNING(ShaderWarning::FLOAT_COMPARISON_FLAG) && (op == OP_EQUAL || op == OP_NOT_EQUAL) &&
|
||||||
(!expression[i - 1].is_op && !expression[i + 1].is_op) &&
|
(!expression[i - 1].is_op && !expression[i + 1].is_op) &&
|
||||||
(expression[i - 1].node->get_datatype() == TYPE_FLOAT && expression[i + 1].node->get_datatype() == TYPE_FLOAT)) {
|
(expression[i - 1].node->get_datatype() == TYPE_FLOAT && expression[i + 1].node->get_datatype() == TYPE_FLOAT)) {
|
||||||
@ -7571,6 +7593,10 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|||||||
int texture_binding = 0;
|
int texture_binding = 0;
|
||||||
int uniforms = 0;
|
int uniforms = 0;
|
||||||
int instance_index = 0;
|
int instance_index = 0;
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
int uniform_buffer_size = 0;
|
||||||
|
int max_uniform_buffer_size = RenderingDevice::get_singleton()->limit_get(RenderingDevice::LIMIT_MAX_UNIFORM_BUFFER_SIZE);
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
|
ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
|
||||||
|
|
||||||
stages = &p_functions;
|
stages = &p_functions;
|
||||||
@ -7971,6 +7997,18 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|||||||
uniform2.texture_order = -1;
|
uniform2.texture_order = -1;
|
||||||
if (uniform_scope != ShaderNode::Uniform::SCOPE_INSTANCE) {
|
if (uniform_scope != ShaderNode::Uniform::SCOPE_INSTANCE) {
|
||||||
uniform2.order = uniforms++;
|
uniform2.order = uniforms++;
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (uniform2.array_size > 0) {
|
||||||
|
int size = get_datatype_size(uniform2.type) * uniform2.array_size;
|
||||||
|
int m = (16 * uniform2.array_size);
|
||||||
|
if ((size % m) != 0U) {
|
||||||
|
size += m - (size % m);
|
||||||
|
}
|
||||||
|
uniform_buffer_size += size;
|
||||||
|
} else {
|
||||||
|
uniform_buffer_size += get_datatype_size(uniform2.type);
|
||||||
|
}
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8980,6 +9018,14 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|||||||
tk = _get_token();
|
tk = _get_token();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (HAS_WARNING(ShaderWarning::DEVICE_LIMIT_EXCEEDED) && (uniform_buffer_size > max_uniform_buffer_size)) {
|
||||||
|
Vector<Variant> args;
|
||||||
|
args.push_back(uniform_buffer_size);
|
||||||
|
args.push_back(max_uniform_buffer_size);
|
||||||
|
_add_global_warning(ShaderWarning::DEVICE_LIMIT_EXCEEDED, "uniform buffer", args);
|
||||||
|
}
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9687,7 +9733,7 @@ ShaderLanguage::ShaderLanguage() {
|
|||||||
nodes = nullptr;
|
nodes = nullptr;
|
||||||
completion_class = TAG_GLOBAL;
|
completion_class = TAG_GLOBAL;
|
||||||
|
|
||||||
#if DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
warnings_check_map.insert(ShaderWarning::UNUSED_CONSTANT, &used_constants);
|
warnings_check_map.insert(ShaderWarning::UNUSED_CONSTANT, &used_constants);
|
||||||
warnings_check_map.insert(ShaderWarning::UNUSED_FUNCTION, &used_functions);
|
warnings_check_map.insert(ShaderWarning::UNUSED_FUNCTION, &used_functions);
|
||||||
warnings_check_map.insert(ShaderWarning::UNUSED_STRUCT, &used_structs);
|
warnings_check_map.insert(ShaderWarning::UNUSED_STRUCT, &used_structs);
|
||||||
|
@ -787,7 +787,7 @@ public:
|
|||||||
static bool is_sampler_type(DataType p_type);
|
static bool is_sampler_type(DataType p_type);
|
||||||
static Variant constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, int p_array_size, ShaderLanguage::ShaderNode::Uniform::Hint p_hint = ShaderLanguage::ShaderNode::Uniform::HINT_NONE);
|
static Variant constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, int p_array_size, ShaderLanguage::ShaderNode::Uniform::Hint p_hint = ShaderLanguage::ShaderNode::Uniform::HINT_NONE);
|
||||||
static PropertyInfo uniform_to_property_info(const ShaderNode::Uniform &p_uniform);
|
static PropertyInfo uniform_to_property_info(const ShaderNode::Uniform &p_uniform);
|
||||||
static uint32_t get_type_size(DataType p_type);
|
static uint32_t get_datatype_size(DataType p_type);
|
||||||
|
|
||||||
static void get_keyword_list(List<String> *r_keywords);
|
static void get_keyword_list(List<String> *r_keywords);
|
||||||
static bool is_control_flow_keyword(String p_keyword);
|
static bool is_control_flow_keyword(String p_keyword);
|
||||||
@ -919,11 +919,14 @@ private:
|
|||||||
bool check_warnings = false;
|
bool check_warnings = false;
|
||||||
uint32_t warning_flags;
|
uint32_t warning_flags;
|
||||||
|
|
||||||
void _add_line_warning(ShaderWarning::Code p_code, const StringName &p_subject = "") {
|
void _add_line_warning(ShaderWarning::Code p_code, const StringName &p_subject = "", const Vector<Variant> &p_extra_args = Vector<Variant>()) {
|
||||||
warnings.push_back(ShaderWarning(p_code, tk_line, p_subject));
|
warnings.push_back(ShaderWarning(p_code, tk_line, p_subject, p_extra_args));
|
||||||
}
|
}
|
||||||
void _add_warning(ShaderWarning::Code p_code, int p_line, const StringName &p_subject = "") {
|
void _add_global_warning(ShaderWarning::Code p_code, const StringName &p_subject = "", const Vector<Variant> &p_extra_args = Vector<Variant>()) {
|
||||||
warnings.push_back(ShaderWarning(p_code, p_line, p_subject));
|
warnings.push_back(ShaderWarning(p_code, -1, p_subject, p_extra_args));
|
||||||
|
}
|
||||||
|
void _add_warning(ShaderWarning::Code p_code, int p_line, const StringName &p_subject = "", const Vector<Variant> &p_extra_args = Vector<Variant>()) {
|
||||||
|
warnings.push_back(ShaderWarning(p_code, p_line, p_subject, p_extra_args));
|
||||||
}
|
}
|
||||||
void _check_warning_accums();
|
void _check_warning_accums();
|
||||||
#endif // DEBUG_ENABLED
|
#endif // DEBUG_ENABLED
|
||||||
|
@ -63,6 +63,8 @@ String ShaderWarning::get_message() const {
|
|||||||
return vformat("The local variable '%s' is declared but never used.", subject);
|
return vformat("The local variable '%s' is declared but never used.", subject);
|
||||||
case FORMATTING_ERROR:
|
case FORMATTING_ERROR:
|
||||||
return subject;
|
return subject;
|
||||||
|
case DEVICE_LIMIT_EXCEEDED:
|
||||||
|
return vformat("The total size of the %s for this shader on this device has been exceeded (%s/%s). The shader may not work correctly.", subject, (int)extra_args[0], (int)extra_args[1]);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -73,6 +75,10 @@ String ShaderWarning::get_name() const {
|
|||||||
return get_name_from_code(code);
|
return get_name_from_code(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector<Variant> ShaderWarning::get_extra_args() const {
|
||||||
|
return extra_args;
|
||||||
|
}
|
||||||
|
|
||||||
String ShaderWarning::get_name_from_code(Code p_code) {
|
String ShaderWarning::get_name_from_code(Code p_code) {
|
||||||
ERR_FAIL_INDEX_V(p_code, WARNING_MAX, String());
|
ERR_FAIL_INDEX_V(p_code, WARNING_MAX, String());
|
||||||
|
|
||||||
@ -85,6 +91,7 @@ String ShaderWarning::get_name_from_code(Code p_code) {
|
|||||||
"UNUSED_VARYING",
|
"UNUSED_VARYING",
|
||||||
"UNUSED_LOCAL_VARIABLE",
|
"UNUSED_LOCAL_VARIABLE",
|
||||||
"FORMATTING_ERROR",
|
"FORMATTING_ERROR",
|
||||||
|
"DEVICE_LIMIT_EXCEEDED",
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert((sizeof(names) / sizeof(*names)) == WARNING_MAX, "Amount of warning types don't match the amount of warning names.");
|
static_assert((sizeof(names) / sizeof(*names)) == WARNING_MAX, "Amount of warning types don't match the amount of warning names.");
|
||||||
@ -114,6 +121,7 @@ static void init_code_to_flags_map() {
|
|||||||
code_to_flags_map->insert(ShaderWarning::UNUSED_VARYING, ShaderWarning::UNUSED_VARYING_FLAG);
|
code_to_flags_map->insert(ShaderWarning::UNUSED_VARYING, ShaderWarning::UNUSED_VARYING_FLAG);
|
||||||
code_to_flags_map->insert(ShaderWarning::UNUSED_LOCAL_VARIABLE, ShaderWarning::UNUSED_LOCAL_VARIABLE_FLAG);
|
code_to_flags_map->insert(ShaderWarning::UNUSED_LOCAL_VARIABLE, ShaderWarning::UNUSED_LOCAL_VARIABLE_FLAG);
|
||||||
code_to_flags_map->insert(ShaderWarning::FORMATTING_ERROR, ShaderWarning::FORMATTING_ERROR_FLAG);
|
code_to_flags_map->insert(ShaderWarning::FORMATTING_ERROR, ShaderWarning::FORMATTING_ERROR_FLAG);
|
||||||
|
code_to_flags_map->insert(ShaderWarning::DEVICE_LIMIT_EXCEEDED, ShaderWarning::DEVICE_LIMIT_EXCEEDED_FLAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderWarning::CodeFlags ShaderWarning::get_flags_from_codemap(const Map<Code, bool> &p_map) {
|
ShaderWarning::CodeFlags ShaderWarning::get_flags_from_codemap(const Map<Code, bool> &p_map) {
|
||||||
@ -132,8 +140,8 @@ ShaderWarning::CodeFlags ShaderWarning::get_flags_from_codemap(const Map<Code, b
|
|||||||
return (CodeFlags)result;
|
return (CodeFlags)result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderWarning::ShaderWarning(Code p_code, int p_line, const StringName &p_subject) :
|
ShaderWarning::ShaderWarning(Code p_code, int p_line, const StringName &p_subject, const Vector<Variant> &p_extra_args) :
|
||||||
code(p_code), line(p_line), subject(p_subject) {
|
code(p_code), line(p_line), subject(p_subject), extra_args(p_extra_args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // DEBUG_ENABLED
|
#endif // DEBUG_ENABLED
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "core/string/string_name.h"
|
#include "core/string/string_name.h"
|
||||||
#include "core/templates/list.h"
|
#include "core/templates/list.h"
|
||||||
#include "core/templates/map.h"
|
#include "core/templates/map.h"
|
||||||
|
#include "core/variant/variant.h"
|
||||||
|
|
||||||
class ShaderWarning {
|
class ShaderWarning {
|
||||||
public:
|
public:
|
||||||
@ -48,6 +49,7 @@ public:
|
|||||||
UNUSED_VARYING,
|
UNUSED_VARYING,
|
||||||
UNUSED_LOCAL_VARIABLE,
|
UNUSED_LOCAL_VARIABLE,
|
||||||
FORMATTING_ERROR,
|
FORMATTING_ERROR,
|
||||||
|
DEVICE_LIMIT_EXCEEDED,
|
||||||
WARNING_MAX,
|
WARNING_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -61,12 +63,14 @@ public:
|
|||||||
UNUSED_VARYING_FLAG = 32U,
|
UNUSED_VARYING_FLAG = 32U,
|
||||||
UNUSED_LOCAL_VARIABLE_FLAG = 64U,
|
UNUSED_LOCAL_VARIABLE_FLAG = 64U,
|
||||||
FORMATTING_ERROR_FLAG = 128U,
|
FORMATTING_ERROR_FLAG = 128U,
|
||||||
|
DEVICE_LIMIT_EXCEEDED_FLAG = 256U,
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Code code;
|
Code code;
|
||||||
int line;
|
int line;
|
||||||
StringName subject;
|
StringName subject;
|
||||||
|
Vector<Variant> extra_args;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Code get_code() const;
|
Code get_code() const;
|
||||||
@ -74,12 +78,13 @@ public:
|
|||||||
const StringName &get_subject() const;
|
const StringName &get_subject() const;
|
||||||
String get_message() const;
|
String get_message() const;
|
||||||
String get_name() const;
|
String get_name() const;
|
||||||
|
Vector<Variant> get_extra_args() const;
|
||||||
|
|
||||||
static String get_name_from_code(Code p_code);
|
static String get_name_from_code(Code p_code);
|
||||||
static Code get_code_from_name(const String &p_name);
|
static Code get_code_from_name(const String &p_name);
|
||||||
static CodeFlags get_flags_from_codemap(const Map<Code, bool> &p_map);
|
static CodeFlags get_flags_from_codemap(const Map<Code, bool> &p_map);
|
||||||
|
|
||||||
ShaderWarning(Code p_code = WARNING_MAX, int p_line = -1, const StringName &p_subject = "");
|
ShaderWarning(Code p_code = WARNING_MAX, int p_line = -1, const StringName &p_subject = "", const Vector<Variant> &p_extra_args = Vector<Variant>());
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DEBUG_ENABLED
|
#endif // DEBUG_ENABLED
|
||||||
|
Loading…
Reference in New Issue
Block a user