mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-30 21:21:10 +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++; | 		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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Yuri Roubinsky
						Yuri Roubinsky