mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 21:51:22 +00:00 
			
		
		
		
	Add a shader warning when the uniform buffer limit is exceeded
This commit is contained in:
		
							parent
							
								
									9221c0f8ad
								
							
						
					
					
						commit
						fd9c92d4ab
					
				
					 9 changed files with 107 additions and 115 deletions
				
			
		|  | @ -293,15 +293,20 @@ void ShaderTextEditor::_update_warning_panel() { | |||
| 		} | ||||
| 
 | ||||
| 		warning_count++; | ||||
| 		int line = w.get_line(); | ||||
| 
 | ||||
| 		// First 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->add_text(TTR("Line") + " " + itos(w.get_line())); | ||||
| 		warnings_panel->add_text(" (" + w.get_name() + "):"); | ||||
| 		if (line != -1) { | ||||
| 			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(); // Meta goto.
 | ||||
| 		warnings_panel->pop(); // 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("  --profiling                                  Enable profiling in the script debugger.\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"); | ||||
| #endif | ||||
| 	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; | ||||
| 				bfx.effect = fx; | ||||
| 				bfx.enabled = p_bus_layout->buses[i].effects[j].enabled; | ||||
| #if DEBUG_ENABLED | ||||
| #ifdef DEBUG_ENABLED | ||||
| 				bfx.prof_time = 0; | ||||
| #endif | ||||
| 				bus->effects.push_back(bfx); | ||||
|  |  | |||
|  | @ -2655,13 +2655,13 @@ void RendererStorageRD::MaterialData::update_uniform_buffer(const Map<StringName | |||
| 		uint32_t size = 0U; | ||||
| 		// The following code enforces a 16-byte alignment of uniform arrays.
 | ||||
| 		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); | ||||
| 			if ((size % m) != 0U) { | ||||
| 				size += m - (size % m); | ||||
| 			} | ||||
| 		} else { | ||||
| 			size = ShaderLanguage::get_type_size(E.value.type); | ||||
| 			size = ShaderLanguage::get_datatype_size(E.value.type); | ||||
| 		} | ||||
| 		ERR_CONTINUE(offset + size > p_buffer_size); | ||||
| #endif | ||||
|  |  | |||
|  | @ -54,81 +54,6 @@ static String _typestr(SL::DataType p_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) { | ||||
| 	switch (p_type) { | ||||
| 		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; | ||||
| 					if (is_buffer_global) { | ||||
| 						//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); | ||||
| 					} else { | ||||
| 						// The following code enforces a 16-byte alignment of uniform arrays.
 | ||||
| 						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); | ||||
| 							if ((size % m) != 0) { | ||||
| 								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_alignments.write[uniform.order] = 16; | ||||
| 						} 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); | ||||
| 						} | ||||
| 					} | ||||
|  |  | |||
|  | @ -3866,55 +3866,77 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform | |||
| 	return pi; | ||||
| } | ||||
| 
 | ||||
| uint32_t ShaderLanguage::get_type_size(DataType p_type) { | ||||
| uint32_t ShaderLanguage::get_datatype_size(ShaderLanguage::DataType p_type) { | ||||
| 	switch (p_type) { | ||||
| 		case TYPE_VOID: | ||||
| 			return 0; | ||||
| 		case TYPE_BOOL: | ||||
| 		case TYPE_INT: | ||||
| 		case TYPE_UINT: | ||||
| 		case TYPE_FLOAT: | ||||
| 			return 4; | ||||
| 		case TYPE_BVEC2: | ||||
| 		case TYPE_IVEC2: | ||||
| 		case TYPE_UVEC2: | ||||
| 		case TYPE_VEC2: | ||||
| 			return 8; | ||||
| 		case TYPE_BVEC3: | ||||
| 		case TYPE_IVEC3: | ||||
| 		case TYPE_UVEC3: | ||||
| 		case TYPE_VEC3: | ||||
| 			return 12; | ||||
| 		case TYPE_BVEC4: | ||||
| 			return 16; | ||||
| 		case TYPE_INT: | ||||
| 			return 4; | ||||
| 		case TYPE_IVEC2: | ||||
| 			return 8; | ||||
| 		case TYPE_IVEC3: | ||||
| 			return 12; | ||||
| 		case TYPE_IVEC4: | ||||
| 			return 16; | ||||
| 		case TYPE_UINT: | ||||
| 			return 4; | ||||
| 		case TYPE_UVEC2: | ||||
| 			return 8; | ||||
| 		case TYPE_UVEC3: | ||||
| 			return 12; | ||||
| 		case TYPE_UVEC4: | ||||
| 			return 16; | ||||
| 		case TYPE_FLOAT: | ||||
| 			return 4; | ||||
| 		case TYPE_VEC2: | ||||
| 			return 8; | ||||
| 		case TYPE_VEC3: | ||||
| 			return 12; | ||||
| 		case TYPE_VEC4: | ||||
| 			return 16; | ||||
| 		case TYPE_MAT2: | ||||
| 			return 8; | ||||
| 			return 32; // 4 * 4 + 4 * 4
 | ||||
| 		case TYPE_MAT3: | ||||
| 			return 12; | ||||
| 			return 48; // 4 * 4 + 4 * 4 + 4 * 4
 | ||||
| 		case TYPE_MAT4: | ||||
| 			return 16; | ||||
| 			return 64; | ||||
| 		case TYPE_SAMPLER2D: | ||||
| 			return 16; | ||||
| 		case TYPE_ISAMPLER2D: | ||||
| 			return 16; | ||||
| 		case TYPE_USAMPLER2D: | ||||
| 			return 16; | ||||
| 		case TYPE_SAMPLER2DARRAY: | ||||
| 			return 16; | ||||
| 		case TYPE_ISAMPLER2DARRAY: | ||||
| 			return 16; | ||||
| 		case TYPE_USAMPLER2DARRAY: | ||||
| 			return 16; | ||||
| 		case TYPE_SAMPLER3D: | ||||
| 			return 16; | ||||
| 		case TYPE_ISAMPLER3D: | ||||
| 			return 16; | ||||
| 		case TYPE_USAMPLER3D: | ||||
| 			return 16; | ||||
| 		case TYPE_SAMPLERCUBE: | ||||
| 			return 16; | ||||
| 		case TYPE_SAMPLERCUBEARRAY: | ||||
| 			return 4; //not really, but useful for indices
 | ||||
| 			return 16; | ||||
| 		case TYPE_STRUCT: | ||||
| 			// FIXME: Implement.
 | ||||
| 			return 0; | ||||
| 		case ShaderLanguage::TYPE_MAX: | ||||
| 			return 0; | ||||
| 		case TYPE_MAX: { | ||||
| 			ERR_FAIL_V(0); | ||||
| 		}; | ||||
| 	} | ||||
| 	return 0; | ||||
| 	ERR_FAIL_V(0); | ||||
| } | ||||
| 
 | ||||
| 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)); | ||||
| 				return nullptr; | ||||
| 			} else { | ||||
| #if DEBUG_ENABLED | ||||
| #ifdef DEBUG_ENABLED | ||||
| 				if (check_warnings && HAS_WARNING(ShaderWarning::FORMATTING_ERROR_FLAG)) { | ||||
| 					_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
 | ||||
| 			} | ||||
| 
 | ||||
| #if DEBUG_ENABLED | ||||
| #ifdef DEBUG_ENABLED | ||||
| 			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].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 uniforms = 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; | ||||
| 
 | ||||
| 	stages = &p_functions; | ||||
|  | @ -7971,6 +7997,18 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct | |||
| 						uniform2.texture_order = -1; | ||||
| 						if (uniform_scope != ShaderNode::Uniform::SCOPE_INSTANCE) { | ||||
| 							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(); | ||||
| 	} | ||||
| 
 | ||||
| #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; | ||||
| } | ||||
| 
 | ||||
|  | @ -9687,7 +9733,7 @@ ShaderLanguage::ShaderLanguage() { | |||
| 	nodes = nullptr; | ||||
| 	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_FUNCTION, &used_functions); | ||||
| 	warnings_check_map.insert(ShaderWarning::UNUSED_STRUCT, &used_structs); | ||||
|  |  | |||
|  | @ -787,7 +787,7 @@ public: | |||
| 	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 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 bool is_control_flow_keyword(String p_keyword); | ||||
|  | @ -919,11 +919,14 @@ private: | |||
| 	bool check_warnings = false; | ||||
| 	uint32_t warning_flags; | ||||
| 
 | ||||
| 	void _add_line_warning(ShaderWarning::Code p_code, const StringName &p_subject = "") { | ||||
| 		warnings.push_back(ShaderWarning(p_code, tk_line, 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, p_extra_args)); | ||||
| 	} | ||||
| 	void _add_warning(ShaderWarning::Code p_code, int p_line, const StringName &p_subject = "") { | ||||
| 		warnings.push_back(ShaderWarning(p_code, p_line, 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, -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(); | ||||
| #endif // DEBUG_ENABLED
 | ||||
|  |  | |||
|  | @ -63,6 +63,8 @@ String ShaderWarning::get_message() const { | |||
| 			return vformat("The local variable '%s' is declared but never used.", subject); | ||||
| 		case FORMATTING_ERROR: | ||||
| 			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: | ||||
| 			break; | ||||
| 	} | ||||
|  | @ -73,6 +75,10 @@ String ShaderWarning::get_name() const { | |||
| 	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) { | ||||
| 	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_LOCAL_VARIABLE", | ||||
| 		"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."); | ||||
|  | @ -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_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::DEVICE_LIMIT_EXCEEDED, ShaderWarning::DEVICE_LIMIT_EXCEEDED_FLAG); | ||||
| } | ||||
| 
 | ||||
| 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; | ||||
| } | ||||
| 
 | ||||
| ShaderWarning::ShaderWarning(Code p_code, int p_line, const StringName &p_subject) : | ||||
| 		code(p_code), line(p_line), subject(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), extra_args(p_extra_args) { | ||||
| } | ||||
| 
 | ||||
| #endif // DEBUG_ENABLED
 | ||||
|  |  | |||
|  | @ -36,6 +36,7 @@ | |||
| #include "core/string/string_name.h" | ||||
| #include "core/templates/list.h" | ||||
| #include "core/templates/map.h" | ||||
| #include "core/variant/variant.h" | ||||
| 
 | ||||
| class ShaderWarning { | ||||
| public: | ||||
|  | @ -48,6 +49,7 @@ public: | |||
| 		UNUSED_VARYING, | ||||
| 		UNUSED_LOCAL_VARIABLE, | ||||
| 		FORMATTING_ERROR, | ||||
| 		DEVICE_LIMIT_EXCEEDED, | ||||
| 		WARNING_MAX, | ||||
| 	}; | ||||
| 
 | ||||
|  | @ -61,12 +63,14 @@ public: | |||
| 		UNUSED_VARYING_FLAG = 32U, | ||||
| 		UNUSED_LOCAL_VARIABLE_FLAG = 64U, | ||||
| 		FORMATTING_ERROR_FLAG = 128U, | ||||
| 		DEVICE_LIMIT_EXCEEDED_FLAG = 256U, | ||||
| 	}; | ||||
| 
 | ||||
| private: | ||||
| 	Code code; | ||||
| 	int line; | ||||
| 	StringName subject; | ||||
| 	Vector<Variant> extra_args; | ||||
| 
 | ||||
| public: | ||||
| 	Code get_code() const; | ||||
|  | @ -74,12 +78,13 @@ public: | |||
| 	const StringName &get_subject() const; | ||||
| 	String get_message() const; | ||||
| 	String get_name() const; | ||||
| 	Vector<Variant> get_extra_args() const; | ||||
| 
 | ||||
| 	static String get_name_from_code(Code p_code); | ||||
| 	static Code get_code_from_name(const String &p_name); | ||||
| 	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
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Yuri Roubinsky
						Yuri Roubinsky