2020-05-10 12:53:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/**************************************************************************/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*  rendering_device_binds.cpp                                            */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/**************************************************************************/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                         This file is part of:                          */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                             GODOT ENGINE                               */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                        https://godotengine.org                         */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/**************************************************************************/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                                                                        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Permission is hereby granted, free of charge, to any person obtaining  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* a copy of this software and associated documentation files (the        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* "Software"), to deal in the Software without restriction, including    */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* without limitation the rights to use, copy, modify, merge, publish,    */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* distribute, sublicense, and/or sell copies of the Software, and to     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* permit persons to whom the Software is furnished to do so, subject to  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* the following conditions:                                              */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                                                                        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* The above copyright notice and this permission notice shall be         */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* included in all copies or substantial portions of the Software.        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                                                                        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/**************************************************************************/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# include  "rendering_device_binds.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-01 09:34:23 -03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Error  RDShaderFile : : parse_versions_from_text ( const  String  & p_text ,  const  String  p_defines ,  OpenIncludeFunction  p_include_func ,  void  * p_include_func_userdata )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-22 16:17:09 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ERR_FAIL_NULL_V_MSG ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											RenderingDevice : : get_singleton ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ERR_UNAVAILABLE , 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-01 17:00:35 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											" Cannot import custom .glsl shaders when running without a RenderingDevice. This can happen if you are using the headless more or the Compatibility renderer. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-13 12:53:19 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									Vector < String >  lines  =  p_text . split ( " \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									bool  reading_versions  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									bool  stage_found [ RD : : SHADER_STAGE_MAX ]  =  {  false ,  false ,  false ,  false ,  false  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									RD : : ShaderStage  stage  =  RD : : SHADER_STAGE_MAX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									static  const  char  * stage_str [ RD : : SHADER_STAGE_MAX ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" vertex " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" fragment " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" tesselation_control " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" tesselation_evaluation " , 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 10:56:22 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										" compute " , 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									String  stage_code [ RD : : SHADER_STAGE_MAX ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  stages_found  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									HashMap < StringName ,  String >  version_texts ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									versions . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									base_error  =  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( int  lidx  =  0 ;  lidx  <  lines . size ( ) ;  lidx + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										String  line  =  lines [ lidx ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											String  ls  =  line . strip_edges ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 10:56:22 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ls . begins_with ( " #[ " )  & &  ls . ends_with ( " ] " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												String  section  =  ls . substr ( 2 ,  ls . length ( )  -  3 ) . strip_edges ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												if  ( section  = =  " versions " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ( stages_found )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 10:56:22 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														base_error  =  " Invalid shader file, #[versions] must be the first section found. " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													reading_versions  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													for  ( int  i  =  0 ;  i  <  RD : : SHADER_STAGE_MAX ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														if  ( section  = =  stage_str [ i ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															if  ( stage_found [ i ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
																base_error  =  " Invalid shader file, stage appears twice:  "  +  section ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
																break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															stage_found [ i ]  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															stages_found + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															stage  =  RD : : ShaderStage ( i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															reading_versions  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:42:46 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													if  ( ! base_error . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:42:46 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( stage  = =  RD : : SHADER_STAGE_MAX  & &  ! line . strip_edges ( ) . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-01 09:34:23 -03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											line  =  line . strip_edges ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( line . begins_with ( " // " )  | |  line . begins_with ( " /* " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												continue ;  //assuming comment (single line)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										if  ( reading_versions )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											String  l  =  line . strip_edges ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:42:46 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ! l . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-03 21:48:38 +05:45 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( ! l . contains ( " = " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 10:56:22 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													base_error  =  " Missing `=` in ' "  +  l  +  " '. Version syntax is `version =  \" <defines with C escaping> \" ;`. " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-03 21:48:38 +05:45 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( ! l . contains ( " ; " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 10:56:22 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													// We don't require a semicolon per se, but it's needed for clang-format to handle things properly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													base_error  =  " Missing `;` in ' "  +  l  +  " '. Version syntax is `version =  \" <defines with C escaping> \" ;`. " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 10:56:22 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												Vector < String >  slices  =  l . get_slice ( " ; " ,  0 ) . split ( " = " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												String  version  =  slices [ 0 ] . strip_edges ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-23 14:30:51 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( ! version . is_valid_ascii_identifier ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
													base_error  =  " Version names must be valid identifiers, found ' "  +  version  +  " ' instead. " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 10:56:22 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												String  define  =  slices [ 1 ] . strip_edges ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												if  ( ! define . begins_with ( " \" " )  | |  ! define . ends_with ( " \" " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													base_error  =  " Version text must be quoted using  \" \" , instead found ' "  +  define  +  " '. " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 10:56:22 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												define  =  " \n "  +  define . substr ( 1 ,  define . length ( )  -  2 ) . c_unescape ( )  +  " \n " ;  // Add newline before and after just in case.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-01 09:34:23 -03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												version_texts [ version ]  =  define  +  " \n "  +  p_defines ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:42:46 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( stage  = =  RD : : SHADER_STAGE_MAX  & &  ! line . strip_edges ( ) . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												base_error  =  " Text was found that does not belong to a valid section:  "  +  line ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( stage  ! =  RD : : SHADER_STAGE_MAX )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( line . strip_edges ( ) . begins_with ( " #include " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ( p_include_func )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														//process include
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														String  include  =  line . replace ( " #include " ,  " " ) . strip_edges ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														if  ( ! include . begins_with ( " \" " )  | |  ! include . ends_with ( " \" " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-16 12:54:15 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
															base_error  =  " Malformed #include syntax, expected #include  \" <path> \" , found instead:  "  +  include ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
															break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														include  =  include . substr ( 1 ,  include . length ( )  -  2 ) . strip_edges ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														String  include_text  =  p_include_func ( include ,  p_include_func_userdata ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:42:46 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														if  ( ! include_text . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
															stage_code [ stage ]  + =  " \n "  +  include_text  +  " \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															base_error  =  " #include failed for file ' "  +  include  +  " ' " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														base_error  =  " #include used, but no include function provided. " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													stage_code [ stage ]  + =  line  +  " \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:42:46 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( base_error . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										if  ( stage_found [ RD : : SHADER_STAGE_COMPUTE ]  & &  stages_found  >  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ERR_FAIL_V_MSG ( ERR_PARSE_ERROR ,  " When writing compute shaders, [compute] mustbe the only stage present. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-15 12:04:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( version_texts . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											version_texts [ " " ]  =  " " ;  //make sure a default version exists
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										bool  errors_found  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* STEP 2, Compile the versions, add to shader file */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 14:13:42 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										for  ( const  KeyValue < StringName ,  String >  & E  :  version_texts )  { 
							 
						 
					
						
							
								
									
										
										
											
												Implement Binary Shader Compilation
* Added an extra stage before compiling shader, which is generating a binary blob.
* On Vulkan, this allows caching the SPIRV reflection information, which is expensive to parse.
* On other (future) RenderingDevices, it allows caching converted binary data, such as DXIL or MSL.
This PR makes the shader cache include the reflection information, hence editor startup times are significantly improved.
I tested this well and it appears to work, and I added a lot of consistency checks, but because it includes writing and reading binary information, rare bugs may pop up, so be aware.
There was not much of a choice for storing the reflection information, given shaders can be a lot, take a lot of space and take time to parse.
											 
										 
										
											2021-07-25 11:22:55 -03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											Ref < RDShaderSPIRV >  bytecode ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-17 16:03:09 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											bytecode . instantiate ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											for  ( int  i  =  0 ;  i  <  RD : : SHADER_STAGE_MAX ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												String  code  =  stage_code [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:42:46 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( code . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
													continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 14:13:42 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												code  =  code . replace ( " VERSION_DEFINES " ,  E . value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												String  error ; 
							 
						 
					
						
							
								
									
										
										
											
												Implement Binary Shader Compilation
* Added an extra stage before compiling shader, which is generating a binary blob.
* On Vulkan, this allows caching the SPIRV reflection information, which is expensive to parse.
* On other (future) RenderingDevices, it allows caching converted binary data, such as DXIL or MSL.
This PR makes the shader cache include the reflection information, hence editor startup times are significantly improved.
I tested this well and it appears to work, and I added a lot of consistency checks, but because it includes writing and reading binary information, rare bugs may pop up, so be aware.
There was not much of a choice for storing the reflection information, given shaders can be a lot, take a lot of space and take time to parse.
											 
										 
										
											2021-07-25 11:22:55 -03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												Vector < uint8_t >  spirv  =  RenderingDevice : : get_singleton ( ) - > shader_compile_spirv_from_source ( RD : : ShaderStage ( i ) ,  code ,  RD : : SHADER_LANGUAGE_GLSL ,  & error ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												bytecode - > set_stage_bytecode ( RD : : ShaderStage ( i ) ,  spirv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:42:46 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( ! error . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
													error  + =  String ( )  +  " \n \n Stage ' "  +  stage_str [ i ]  +  " ' source code:  \n \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													Vector < String >  sclines  =  code . split ( " \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													for  ( int  j  =  0 ;  j  <  sclines . size ( ) ;  j + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														error  + =  itos ( j  +  1 )  +  " \t \t "  +  sclines [ j ]  +  " \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													errors_found  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												bytecode - > set_stage_compile_error ( RD : : ShaderStage ( i ) ,  error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 14:13:42 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											set_bytecode ( bytecode ,  E . key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:19:21 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  errors_found  ?  ERR_PARSE_ERROR  :  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  ERR_PARSE_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}