Browse Source

Shaderc OpenGL fixes. (#2317)

* Reworked profile cli argument.

* Added missing GLSL profile.

* Fixed essl shader preambule.

* Fixed uniform "parsing" and hlsl profiles.

* Reworked hlsl profiles.

* Fixed missing extension for gl_FragDepth.

* Cleanup.

* Removed version preamble and reverted shadow samplers translation.

* Fixed HLSL profile tests.
MooZ 5 years ago
parent
commit
d65dac2000

+ 1 - 1
examples/31-rsm/fs_rsm_lbuffer.sc

@@ -29,7 +29,7 @@ vec3 clipToWorld(mat4 _invViewProj, vec3 _clipPos)
 
 
 void main()
 void main()
 {
 {
-#if BGFX_SHADER_LANGUAGE_HLSL && (BGFX_SHADER_LANGUAGE_HLSL < 4)
+#if BGFX_SHADER_LANGUAGE_HLSL && (BGFX_SHADER_LANGUAGE_HLSL < 400)
 	vec2 texCoord = gl_FragCoord.xy * u_viewTexel.xy + u_viewTexel.xy * vec2_splat(0.5);
 	vec2 texCoord = gl_FragCoord.xy * u_viewTexel.xy + u_viewTexel.xy * vec2_splat(0.5);
 #else
 #else
 	vec2 texCoord = gl_FragCoord.xy * u_viewTexel.xy;
 	vec2 texCoord = gl_FragCoord.xy * u_viewTexel.xy;

+ 1 - 1
examples/31-rsm/fs_rsm_shadow.sc

@@ -11,7 +11,7 @@ uniform vec4 u_tint;
 
 
 void main()
 void main()
 {
 {
-#if BGFX_SHADER_LANGUAGE_HLSL && (BGFX_SHADER_LANGUAGE_HLSL < 4)
+#if BGFX_SHADER_LANGUAGE_HLSL && (BGFX_SHADER_LANGUAGE_HLSL < 400)
 	vec2 texCoord = gl_FragCoord.xy * u_viewTexel.xy + u_viewTexel.xy * vec2_splat(0.5);
 	vec2 texCoord = gl_FragCoord.xy * u_viewTexel.xy + u_viewTexel.xy * vec2_splat(0.5);
 #else
 #else
 	vec2 texCoord = gl_FragCoord.xy * u_viewTexel.xy;
 	vec2 texCoord = gl_FragCoord.xy * u_viewTexel.xy;

+ 1 - 1
examples/common/nanovg/vs_nanovg_fill.sc

@@ -3,7 +3,7 @@ $output v_position, v_texcoord0
 
 
 #include "../common.sh"
 #include "../common.sh"
 
 
-#define NEED_HALF_TEXEL (BGFX_SHADER_LANGUAGE_HLSL < 4)
+#define NEED_HALF_TEXEL (BGFX_SHADER_LANGUAGE_HLSL < 400)
 
 
 uniform vec4 u_viewSize;
 uniform vec4 u_viewSize;
 
 

+ 1 - 1
examples/common/shaderlib.sh

@@ -387,7 +387,7 @@ vec3 fixCubeLookup(vec3 _v, float _lod, float _topLevelCubeSize)
 
 
 vec2 texture2DBc5(sampler2D _sampler, vec2 _uv)
 vec2 texture2DBc5(sampler2D _sampler, vec2 _uv)
 {
 {
-#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 3
+#if BGFX_SHADER_LANGUAGE_HLSL && BGFX_SHADER_LANGUAGE_HLSL <= 300
 	return texture2D(_sampler, _uv).yx;
 	return texture2D(_sampler, _uv).yx;
 #else
 #else
 	return texture2D(_sampler, _uv).xy;
 	return texture2D(_sampler, _uv).xy;

+ 15 - 20
src/bgfx_shader.sh

@@ -12,7 +12,7 @@
 
 
 #ifndef __cplusplus
 #ifndef __cplusplus
 
 
-#if BGFX_SHADER_LANGUAGE_HLSL > 3
+#if BGFX_SHADER_LANGUAGE_HLSL > 300
 #	define BRANCH [branch]
 #	define BRANCH [branch]
 #	define LOOP   [loop]
 #	define LOOP   [loop]
 #	define UNROLL [unroll]
 #	define UNROLL [unroll]
@@ -20,13 +20,13 @@
 #	define BRANCH
 #	define BRANCH
 #	define LOOP
 #	define LOOP
 #	define UNROLL
 #	define UNROLL
-#endif // BGFX_SHADER_LANGUAGE_HLSL > 3
+#endif // BGFX_SHADER_LANGUAGE_HLSL > 300
 
 
-#if BGFX_SHADER_LANGUAGE_HLSL > 3 && BGFX_SHADER_TYPE_FRAGMENT
+#if BGFX_SHADER_LANGUAGE_HLSL > 300 && BGFX_SHADER_TYPE_FRAGMENT
 #	define EARLY_DEPTH_STENCIL [earlydepthstencil]
 #	define EARLY_DEPTH_STENCIL [earlydepthstencil]
 #else
 #else
 #	define EARLY_DEPTH_STENCIL
 #	define EARLY_DEPTH_STENCIL
-#endif // BGFX_SHADER_LANGUAGE_HLSL > 3 && BGFX_SHADER_TYPE_FRAGMENT
+#endif // BGFX_SHADER_LANGUAGE_HLSL > 300 && BGFX_SHADER_TYPE_FRAGMENT
 
 
 #if BGFX_SHADER_LANGUAGE_GLSL
 #if BGFX_SHADER_LANGUAGE_GLSL
 #	define ARRAY_BEGIN(_type, _name, _count) _type _name[_count] = _type[](
 #	define ARRAY_BEGIN(_type, _name, _count) _type _name[_count] = _type[](
@@ -52,19 +52,19 @@
 
 
 // To be able to patch the uav registers on the DXBC SPDB Chunk (D3D11 renderer) the whitespaces around
 // To be able to patch the uav registers on the DXBC SPDB Chunk (D3D11 renderer) the whitespaces around
 // '_type[_reg]' are necessary. This only affects shaders with debug info (i.e., those that have the SPDB Chunk).
 // '_type[_reg]' are necessary. This only affects shaders with debug info (i.e., those that have the SPDB Chunk).
-#	if BGFX_SHADER_LANGUAGE_HLSL > 4
+#	if BGFX_SHADER_LANGUAGE_HLSL > 400
 #		define REGISTER(_type, _reg) register( _type[_reg] )
 #		define REGISTER(_type, _reg) register( _type[_reg] )
 #	else
 #	else
 #		define REGISTER(_type, _reg) register(_type ## _reg)
 #		define REGISTER(_type, _reg) register(_type ## _reg)
 #	endif // BGFX_SHADER_LANGUAGE_HLSL
 #	endif // BGFX_SHADER_LANGUAGE_HLSL
 
 
-#	if BGFX_SHADER_LANGUAGE_HLSL > 3 || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
-#		if BGFX_SHADER_LANGUAGE_HLSL > 4 || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
+#	if BGFX_SHADER_LANGUAGE_HLSL > 300 || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
+#		if BGFX_SHADER_LANGUAGE_HLSL > 400 || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
 #			define dFdxCoarse(_x) ddx_coarse(_x)
 #			define dFdxCoarse(_x) ddx_coarse(_x)
 #			define dFdxFine(_x)   ddx_fine(_x)
 #			define dFdxFine(_x)   ddx_fine(_x)
 #			define dFdyCoarse(_y) ddy_coarse(-_y)
 #			define dFdyCoarse(_y) ddy_coarse(-_y)
 #			define dFdyFine(_y)   ddy_fine(-_y)
 #			define dFdyFine(_y)   ddy_fine(-_y)
-#		endif // BGFX_SHADER_LANGUAGE_HLSL > 4
+#		endif // BGFX_SHADER_LANGUAGE_HLSL > 400
 
 
 #		if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
 #		if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
 float intBitsToFloat(int   _x) { return asfloat(_x); }
 float intBitsToFloat(int   _x) { return asfloat(_x); }
@@ -482,19 +482,12 @@ float bgfxShadow2DProj(sampler2DShadow _sampler, vec4 _coord)
 #		define SAMPLERCUBE(_name, _reg) uniform samplerCUBE _name : REGISTER(s, _reg)
 #		define SAMPLERCUBE(_name, _reg) uniform samplerCUBE _name : REGISTER(s, _reg)
 #		define textureCube(_sampler, _coord) texCUBE(_sampler, _coord)
 #		define textureCube(_sampler, _coord) texCUBE(_sampler, _coord)
 
 
-#		if BGFX_SHADER_LANGUAGE_HLSL == 2
-#			define texture2DLod(_sampler, _coord, _level) tex2D(_sampler, (_coord).xy)
-#			define texture2DGrad(_sampler, _coord, _dPdx, _dPdy) tex2D(_sampler, _coord)
-#			define texture3DLod(_sampler, _coord, _level) tex3D(_sampler, (_coord).xyz)
-#			define textureCubeLod(_sampler, _coord, _level) texCUBE(_sampler, (_coord).xyz)
-#		else
-#			define texture2DLod(_sampler, _coord, _level) tex2Dlod(_sampler, vec4( (_coord).xy, 0.0, _level) )
-#			define texture2DGrad(_sampler, _coord, _dPdx, _dPdy) tex2Dgrad(_sampler, _coord, _dPdx, _dPdy)
-#			define texture3DLod(_sampler, _coord, _level) tex3Dlod(_sampler, vec4( (_coord).xyz, _level) )
-#			define textureCubeLod(_sampler, _coord, _level) texCUBElod(_sampler, vec4( (_coord).xyz, _level) )
-#		endif // BGFX_SHADER_LANGUAGE_HLSL == 2
+#		define texture2DLod(_sampler, _coord, _level) tex2Dlod(_sampler, vec4( (_coord).xy, 0.0, _level) )
+#		define texture2DGrad(_sampler, _coord, _dPdx, _dPdy) tex2Dgrad(_sampler, _coord, _dPdx, _dPdy)
+#		define texture3DLod(_sampler, _coord, _level) tex3Dlod(_sampler, vec4( (_coord).xyz, _level) )
+#		define textureCubeLod(_sampler, _coord, _level) texCUBElod(_sampler, vec4( (_coord).xyz, _level) )
 
 
-#	endif // BGFX_SHADER_LANGUAGE_HLSL > 3
+#	endif // BGFX_SHADER_LANGUAGE_HLSL > 300
 
 
 vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_mtx, _vec); }
 vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_mtx, _vec); }
 vec3 instMul(mat3 _mtx, vec3 _vec) { return mul(_vec, _mtx); }
 vec3 instMul(mat3 _mtx, vec3 _vec) { return mul(_vec, _mtx); }
@@ -563,6 +556,8 @@ vec4  mod(vec4  _a, vec4  _b) { return _a - _b * floor(_a / _b); }
 #		define texture2D(_sampler, _coord)      texture(_sampler, _coord)
 #		define texture2D(_sampler, _coord)      texture(_sampler, _coord)
 #		define texture2DArray(_sampler, _coord) texture(_sampler, _coord)
 #		define texture2DArray(_sampler, _coord) texture(_sampler, _coord)
 #		define texture3D(_sampler, _coord)      texture(_sampler, _coord)
 #		define texture3D(_sampler, _coord)      texture(_sampler, _coord)
+#		define texture2DLod(_sampler, _coord_, _lod)               textureLod(_sampler, _coord, _lod)
+#		define texture2DLodOffset(_sampler, _coord, _lod, _offset) textureLodOffset(_sampler, _coord, _lod, _offset)
 #	endif // BGFX_SHADER_LANGUAGE_GLSL >= 130
 #	endif // BGFX_SHADER_LANGUAGE_GLSL >= 130
 
 
 vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_vec, _mtx); }
 vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_vec, _mtx); }

+ 222 - 199
tools/shaderc/shaderc.cpp

@@ -25,6 +25,81 @@ namespace bgfx
 {
 {
 	bool g_verbose = false;
 	bool g_verbose = false;
 
 
+	enum ShadingLang{
+		HLSL,
+		Metal,
+		PSSL,
+		Spirv,
+		GLSL,
+		ESSL,
+		ShadingLangCount
+	};
+
+	// c - compute
+	// d - domain
+	// f - fragment
+	// g - geometry
+	// h - hull
+	// v - vertex
+	//
+	// OpenGL #version Features Direct3D Features Shader Model
+	// 2.1    120      vf       9.0      vf       2.0
+	// 3.0    130
+	// 3.1    140
+	// 3.2    150      vgf
+	// 3.3    330               10.0     vgf      4.0
+	// 4.0    400      vhdgf
+	// 4.1    410
+	// 4.2    420               11.0     vhdgf+c  5.0
+	// 4.3    430      vhdgf+c
+	// 4.4    440
+	//
+	// SPIR-V profile naming convention:
+	//  spirv<SPIR-V version>-<Vulkan version>
+	//
+	// SPIR-V version | Vulkan version | shaderc encoding
+	//       1.0      |       1.0      |      1010
+	//       1.3      |       1.1      |      1311
+	//       1.4      |       1.1      |      1411
+	//       1.5      |       1.2      |      1512
+
+	static const struct Profile {
+		ShadingLang lang;
+		uint32_t id;
+		const char *name;
+		// [todo] description ?
+	} s_profiles[] = {
+		ESSL, 100, "100_es",
+		ESSL, 300, "300_es",
+		ESSL, 310, "310_es",
+		ESSL, 320, "320_es",
+
+		HLSL, 300, "s_3_0",
+		HLSL, 400, "s_4_0",
+		HLSL, 500, "s_5_0",
+
+		Metal, 1, "metal",
+		
+		PSSL, 1, "pssl",
+		
+		Spirv, 1331, "spirv13-11",
+		Spirv, 1411, "spirv14-11",
+		Spirv, 1512, "spirv15-12",
+		Spirv, 1010, "spirv10-10",
+		Spirv, 1010, "spirv",
+
+		GLSL, 120, "120",
+		GLSL, 130, "130",
+		GLSL, 140, "140",
+		GLSL, 150, "150",
+		GLSL, 330, "330",
+		GLSL, 400, "400",
+		GLSL, 410, "410",
+		GLSL, 420, "420",
+		GLSL, 430, "430",
+		GLSL, 440, "440"
+	};
+
 	static const char* s_ARB_shader_texture_lod[] =
 	static const char* s_ARB_shader_texture_lod[] =
 	{
 	{
 		"texture2DLod",
 		"texture2DLod",
@@ -87,6 +162,7 @@ namespace bgfx
 	{
 	{
 		"gl_VertexID",
 		"gl_VertexID",
 		"gl_InstanceID",
 		"gl_InstanceID",
+		"texture2DLodOffset",
 		NULL
 		NULL
 	};
 	};
 
 
@@ -129,6 +205,7 @@ namespace bgfx
 		"usampler3D",
 		"usampler3D",
 		"isamplerCube",
 		"isamplerCube",
 		"usamplerCube",
 		"usamplerCube",
+		"textureSize",
 		NULL
 		NULL
 	};
 	};
 
 
@@ -842,34 +919,6 @@ namespace bgfx
 		return bx::strFind(_filePath, fp.getBaseName() );
 		return bx::strFind(_filePath, fp.getBaseName() );
 	}
 	}
 
 
-	// c - compute
-	// d - domain
-	// f - fragment
-	// g - geometry
-	// h - hull
-	// v - vertex
-	//
-	// OpenGL #version Features Direct3D Features Shader Model
-	// 2.1    120      vf       9.0      vf       2.0
-	// 3.0    130
-	// 3.1    140
-	// 3.2    150      vgf
-	// 3.3    330               10.0     vgf      4.0
-	// 4.0    400      vhdgf
-	// 4.1    410
-	// 4.2    420               11.0     vhdgf+c  5.0
-	// 4.3    430      vhdgf+c
-	// 4.4    440
-	//
-	// SPIR-V profile naming convention:
-	//  spirv<SPIR-V version>-<Vulkan version>
-	//
-	// SPIR-V version | Vulkan version | shaderc encoding
-	//       1.0      |       1.0      |      1010
-	//       1.3      |       1.1      |      1311
-	//       1.4      |       1.1      |      1411
-	//       1.5      |       1.2      |      1512
-
 	void help(const char* _error = NULL)
 	void help(const char* _error = NULL)
 	{
 	{
 		if (NULL != _error)
 		if (NULL != _error)
@@ -907,17 +956,13 @@ namespace bgfx
 			  "           osx\n"
 			  "           osx\n"
 			  "           windows\n"
 			  "           windows\n"
 			  "      -p, --profile <profile>   Shader model (default GLSL).\n"
 			  "      -p, --profile <profile>   Shader model (default GLSL).\n"
-			  "           s_3\n"
-			  "           s_4\n"
-			  "           s_4_0_level\n"
-			  "           s_5\n"
-			  "           metal\n"
-			  "           pssl\n"
-			  "           spirv                Alias for spirv10-10.\n"
-			  "           spirv10-10\n"
-			  "           spirv13-11\n"
-			  "           spirv14-11\n"
-			  "           spirv15-12\n"
+			);
+
+		for(unsigned int i=0; i<BX_COUNTOF(s_profiles); i++) {
+				bx::printf("           %s\n", s_profiles[i].name);
+		}
+
+		bx::printf(
 			  "      --preprocess              Preprocess only.\n"
 			  "      --preprocess              Preprocess only.\n"
 			  "      --define <defines>        Add defines to preprocessor (semicolon separated).\n"
 			  "      --define <defines>        Add defines to preprocessor (semicolon separated).\n"
 			  "      --raw                     Do not process shader. No preprocessor, and no glsl-optimizer (GLSL only).\n"
 			  "      --raw                     Do not process shader. No preprocessor, and no glsl-optimizer (GLSL only).\n"
@@ -948,69 +993,32 @@ namespace bgfx
 
 
 	bool compileShader(const char* _varying, const char* _comment, char* _shader, uint32_t _shaderLen, Options& _options, bx::FileWriter* _writer)
 	bool compileShader(const char* _varying, const char* _comment, char* _shader, uint32_t _shaderLen, Options& _options, bx::FileWriter* _writer)
 	{
 	{
-		uint32_t glsl  = 0;
-		uint32_t essl  = 0;
-		uint32_t hlsl  = 0;
-		uint32_t d3d   = 11;
-		uint32_t metal = 0;
-		uint32_t pssl  = 0;
-		uint32_t spirv = 0;
-		const char* profile = _options.profile.c_str();
-		if ('\0' != profile[0])
-		{
-			if (0 == bx::strCmp(&profile[1], "s_4_0_level", 11) )
-			{
-				hlsl = 2;
-			}
-			else if (0 == bx::strCmp(&profile[1], "s_3", 3) )
-			{
-				hlsl = 3;
-				d3d  = 9;
-			}
-			else if (0 == bx::strCmp(&profile[1], "s_4", 3) )
-			{
-				hlsl = 4;
-			}
-			else if (0 == bx::strCmp(&profile[1], "s_5", 3) )
-			{
-				hlsl = 5;
-			}
-			else if (0 == bx::strCmp(profile, "metal") )
-			{
-				metal = 1;
-			}
-			else if (0 == bx::strCmp(profile, "pssl") )
-			{
-				pssl = 1;
-			}
-			else if (0 == bx::strCmp(profile, "spirv13-11") )
-			{
-				spirv = 1311;
-			}
-			else if (0 == bx::strCmp(profile, "spirv14-11") )
-			{
-				spirv = 1411;
-			}
-			else if (0 == bx::strCmp(profile, "spirv15-12") )
-			{
-				spirv = 1512;
-			}
-			else if (0 == bx::strCmp(profile, "spirv10-10")
-			      || 0 == bx::strCmp(profile, "spirv") )
-			{
-				spirv = 1010;
+		uint32_t profile_id = 0;
+
+		const char* profile_opt = _options.profile.c_str();
+		if ('\0' != profile_opt[0])
+		{
+			const uint32_t count = BX_COUNTOF(s_profiles);
+			for(profile_id=0; profile_id<count; profile_id++) {
+				if(0 == bx::strCmp(profile_opt, s_profiles[profile_id].name)) {
+					break;
+				}
+				else if((s_profiles[profile_id].lang == HLSL)&& (0 == bx::strCmp(&profile_opt[1], s_profiles[profile_id].name))) {
+					// This test is here to allow hlsl profile names e.g:
+					// cs_4_0, gs_5_0, etc...
+					// There's no check to ensure that the profile name matches the shader type set via the cli.
+					// This means that you can pass `hs_5_0` when compiling a fragment shader.
+					break;
+				}
 			}
 			}
-			else
-			{
-				bx::fromString(&glsl, profile);
+			if(profile_id == count) {
+				bx::printf("Unknown profile: %s\n", profile_opt);
+				return false;
 			}
 			}
 		}
 		}
-		else
-		{
-			essl = 2;
-		}
+		const Profile *profile = &s_profiles[profile_id];
 
 
-		Preprocessor preprocessor(_options.inputFilePath.c_str(), 0 != essl);
+		Preprocessor preprocessor(_options.inputFilePath.c_str(), profile->lang != ESSL);
 
 
 		for (size_t ii = 0; ii < _options.includeDirs.size(); ++ii)
 		for (size_t ii = 0; ii < _options.includeDirs.size(); ++ii)
 		{
 		{
@@ -1050,15 +1058,15 @@ namespace bgfx
 		char glslDefine[128];
 		char glslDefine[128];
 		bx::snprintf(glslDefine, BX_COUNTOF(glslDefine)
 		bx::snprintf(glslDefine, BX_COUNTOF(glslDefine)
 				, "BGFX_SHADER_LANGUAGE_GLSL=%d"
 				, "BGFX_SHADER_LANGUAGE_GLSL=%d"
-				, essl ? 1 : glsl
+				, (profile->lang == ESSL) ? 1 : profile->id
 				);
 				);
 
 
 		char hlslDefine[128];
 		char hlslDefine[128];
-		if (0 != hlsl)
+		if (profile->lang == HLSL)
 		{
 		{
 			bx::snprintf(hlslDefine, BX_COUNTOF(hlslDefine)
 			bx::snprintf(hlslDefine, BX_COUNTOF(hlslDefine)
 					, "BGFX_SHADER_LANGUAGE_HLSL=%d"
 					, "BGFX_SHADER_LANGUAGE_HLSL=%d"
-					, hlsl);
+					, profile->id);
 		}
 		}
 
 
 		const char* platform = _options.platform.c_str();
 		const char* platform = _options.platform.c_str();
@@ -1076,7 +1084,7 @@ namespace bgfx
 		else if (0 == bx::strCmpI(platform, "ios") )
 		else if (0 == bx::strCmpI(platform, "ios") )
 		{
 		{
 			preprocessor.setDefine("BX_PLATFORM_IOS=1");
 			preprocessor.setDefine("BX_PLATFORM_IOS=1");
-			if (metal)
+			if (profile->lang == Metal)
 			{
 			{
 				preprocessor.setDefine("BGFX_SHADER_LANGUAGE_METAL=1");
 				preprocessor.setDefine("BGFX_SHADER_LANGUAGE_METAL=1");
 			}
 			}
@@ -1088,7 +1096,7 @@ namespace bgfx
 		else if (0 == bx::strCmpI(platform, "linux") )
 		else if (0 == bx::strCmpI(platform, "linux") )
 		{
 		{
 			preprocessor.setDefine("BX_PLATFORM_LINUX=1");
 			preprocessor.setDefine("BX_PLATFORM_LINUX=1");
-			if (0 != spirv)
+			if (profile->lang == Spirv)
 			{
 			{
 				preprocessor.setDefine("BGFX_SHADER_LANGUAGE_SPIRV=1");
 				preprocessor.setDefine("BGFX_SHADER_LANGUAGE_SPIRV=1");
 			}
 			}
@@ -1100,27 +1108,27 @@ namespace bgfx
 		else if (0 == bx::strCmpI(platform, "osx") )
 		else if (0 == bx::strCmpI(platform, "osx") )
 		{
 		{
 			preprocessor.setDefine("BX_PLATFORM_OSX=1");
 			preprocessor.setDefine("BX_PLATFORM_OSX=1");
-			if (!metal)
+			if (profile->lang != Metal)
 			{
 			{
 				preprocessor.setDefine(glslDefine);
 				preprocessor.setDefine(glslDefine);
 			}
 			}
 			char temp[256];
 			char temp[256];
-			bx::snprintf(temp, sizeof(temp), "BGFX_SHADER_LANGUAGE_METAL=%d", metal);
+			bx::snprintf(temp, sizeof(temp), "BGFX_SHADER_LANGUAGE_METAL=%d", (profile->lang == Metal) ? profile->id : 0);
 			preprocessor.setDefine(temp);
 			preprocessor.setDefine(temp);
 		}
 		}
 		else if (0 == bx::strCmpI(platform, "windows") )
 		else if (0 == bx::strCmpI(platform, "windows") )
 		{
 		{
 			preprocessor.setDefine("BX_PLATFORM_WINDOWS=1");
 			preprocessor.setDefine("BX_PLATFORM_WINDOWS=1");
-			if (0 != hlsl)
+			if (profile->lang == HLSL)
 			{
 			{
 				preprocessor.setDefine(hlslDefine);
 				preprocessor.setDefine(hlslDefine);
 			}
 			}
-			else if (0 != glsl
-			     ||  0 != essl)
+			else if (profile->lang == GLSL
+			     ||  profile->lang == ESSL)
 			{
 			{
 				preprocessor.setDefine(glslDefine);
 				preprocessor.setDefine(glslDefine);
 			}
 			}
-			else if (0 != spirv)
+			else if (profile->lang == Spirv)
 			{
 			{
 				preprocessor.setDefine("BGFX_SHADER_LANGUAGE_SPIRV=1");
 				preprocessor.setDefine("BGFX_SHADER_LANGUAGE_SPIRV=1");
 			}
 			}
@@ -1133,16 +1141,16 @@ namespace bgfx
 		}
 		}
 		else
 		else
 		{
 		{
-			if (0 != hlsl)
+			if (profile->lang == HLSL)
 			{
 			{
 				preprocessor.setDefine(hlslDefine);
 				preprocessor.setDefine(hlslDefine);
 			}
 			}
-			else if (0 != glsl
-			     ||  0 != essl)
+			else if (profile->lang == GLSL
+			     ||  profile->lang == ESSL)
 			{
 			{
 				preprocessor.setDefine(glslDefine);
 				preprocessor.setDefine(glslDefine);
 			}
 			}
-			else if (0 != spirv)
+			else if (profile->lang == Spirv)
 			{
 			{
 				preprocessor.setDefine("BGFX_SHADER_LANGUAGE_SPIRV=1");
 				preprocessor.setDefine("BGFX_SHADER_LANGUAGE_SPIRV=1");
 			}
 			}
@@ -1208,8 +1216,8 @@ namespace bgfx
 				||  0 == bx::strCmp(typen, "centroid", 8) )
 				||  0 == bx::strCmp(typen, "centroid", 8) )
 				{
 				{
 					if ('f' == _options.shaderType
 					if ('f' == _options.shaderType
-					||    0 != glsl
-					||    0 != essl)
+					||   profile->lang == GLSL
+					||   profile->lang == ESSL)
 					{
 					{
 						interpolation = typen;
 						interpolation = typen;
 						usesInterpolationQualifiers = true;
 						usesInterpolationQualifiers = true;
@@ -1254,7 +1262,7 @@ namespace bgfx
 					var.m_name.assign(name.getPtr(), name.getTerm() );
 					var.m_name.assign(name.getPtr(), name.getTerm() );
 					var.m_semantics.assign(semantics.getPtr(), semantics.getTerm() );
 					var.m_semantics.assign(semantics.getPtr(), semantics.getTerm() );
 
 
-					if (d3d == 9
+					if ((profile->lang == HLSL && profile->id < 400)
 					&&  var.m_semantics == "BITANGENT")
 					&&  var.m_semantics == "BITANGENT")
 					{
 					{
 						var.m_semantics = "BINORMAL";
 						var.m_semantics = "BINORMAL";
@@ -1386,7 +1394,7 @@ namespace bgfx
 
 
 		if (raw)
 		if (raw)
 		{
 		{
-			if (0 != glsl)
+			if (profile->lang == GLSL)
 			{
 			{
 				bx::write(_writer, uint16_t(0) );
 				bx::write(_writer, uint16_t(0) );
 
 
@@ -1397,13 +1405,13 @@ namespace bgfx
 
 
 				compiled = true;
 				compiled = true;
 			}
 			}
-			else if (0 != pssl)
+			else if (profile->lang == PSSL)
 			{
 			{
 				compiled = compilePSSLShader(_options, 0, input, _writer);
 				compiled = compilePSSLShader(_options, 0, input, _writer);
 			}
 			}
 			else
 			else
 			{
 			{
-				compiled = compileHLSLShader(_options, d3d, input, _writer);
+				compiled = compileHLSLShader(_options, profile->id, input, _writer);
 			}
 			}
 		}
 		}
 		else if ('c' == _options.shaderType) // Compute
 		else if ('c' == _options.shaderType) // Compute
@@ -1415,13 +1423,13 @@ namespace bgfx
 			}
 			}
 			else
 			else
 			{
 			{
-				if (0 != glsl
-				||  0 != essl)
+				if (profile->lang == GLSL
+				||  profile->lang == ESSL)
 				{
 				{
 				}
 				}
 				else
 				else
 				{
 				{
-					if (0 != pssl)
+					if (profile->lang != PSSL)
 					{
 					{
 						preprocessor.writef(getPsslPreamble() );
 						preprocessor.writef(getPsslPreamble() );
 					}
 					}
@@ -1509,16 +1517,16 @@ namespace bgfx
 						bx::write(_writer, uint32_t(0) );
 						bx::write(_writer, uint32_t(0) );
 						bx::write(_writer, outputHash);
 						bx::write(_writer, outputHash);
 
 
-						if (0 != glsl
-						||  0 != essl)
+						if (profile->lang == GLSL
+						||  profile->lang == ESSL)
 						{
 						{
-							if (essl)
+							if (profile->lang == ESSL)
 							{
 							{
 								bx::stringPrintf(code, "#version 310 es\n");
 								bx::stringPrintf(code, "#version 310 es\n");
 							}
 							}
 							else
 							else
 							{
 							{
-								bx::stringPrintf(code, "#version %d\n", glsl == 0 ? 430 : glsl);
+								bx::stringPrintf(code, "#version %d\n", (profile->lang != GLSL) ? 430 : profile->id);
 							}
 							}
 
 
 #if 1
 #if 1
@@ -1544,21 +1552,21 @@ namespace bgfx
 							code += _comment;
 							code += _comment;
 							code += preprocessor.m_preprocessed;
 							code += preprocessor.m_preprocessed;
 
 
-							if (0 != metal)
+							if (profile->lang == Metal)
 							{
 							{
 								compiled = compileMetalShader(_options, BX_MAKEFOURCC('M', 'T', 'L', 0), code, _writer);
 								compiled = compileMetalShader(_options, BX_MAKEFOURCC('M', 'T', 'L', 0), code, _writer);
 							}
 							}
-							else if (0 != spirv)
+							else if (profile->lang == Spirv)
 							{
 							{
-								compiled = compileSPIRVShader(_options, spirv, code, _writer);
+								compiled = compileSPIRVShader(_options, profile->id, code, _writer);
 							}
 							}
-							else if (0 != pssl)
+							else if (profile->lang == PSSL)
 							{
 							{
 								compiled = compilePSSLShader(_options, 0, code, _writer);
 								compiled = compilePSSLShader(_options, 0, code, _writer);
 							}
 							}
 							else
 							else
 							{
 							{
-								compiled = compileHLSLShader(_options, d3d, code, _writer);
+								compiled = compileHLSLShader(_options, profile->id, code, _writer);
 							}
 							}
 						}
 						}
 					}
 					}
@@ -1590,11 +1598,10 @@ namespace bgfx
 			}
 			}
 			else
 			else
 			{
 			{
-				if (0 != glsl
-				||  0 != essl)
+				if (profile->lang == GLSL
+				||  profile->lang == ESSL)
 				{
 				{
-					if (0 == essl)
-					{
+					if(profile->lang != ESSL) {
 						// bgfx shadow2D/Proj behave like EXT_shadow_samplers
 						// bgfx shadow2D/Proj behave like EXT_shadow_samplers
 						// not as GLSL language 1.2 specs shadow2D/Proj.
 						// not as GLSL language 1.2 specs shadow2D/Proj.
 						preprocessor.writef(
 						preprocessor.writef(
@@ -1603,6 +1610,29 @@ namespace bgfx
 							);
 							);
 					}
 					}
 
 
+					// gl_FragColor and gl_FragData are deprecated for essl > 300
+					if((profile->lang == ESSL) && (profile->id >= 300))
+					{
+						const bool hasFragColor   = !bx::strFind(input, "gl_FragColor").isEmpty();
+						bool hasFragData[8] = {};
+						uint32_t numFragData = 0;
+						for (uint32_t ii = 0; ii < BX_COUNTOF(hasFragData); ++ii)
+						{
+							char temp[32];
+							bx::snprintf(temp, BX_COUNTOF(temp), "gl_FragData[%d]", ii);
+							hasFragData[ii] = !bx::strFind(input, temp).isEmpty();
+							numFragData += hasFragData[ii];
+						}
+						if(hasFragColor) {
+							preprocessor.writef("#define gl_FragColor bgfx_FragData0\n");
+							preprocessor.writef("out mediump vec4 bgfx_FragData0;\n");
+						}
+						else if(numFragData) {
+							preprocessor.writef("#define gl_FragData bgfx_FragData\n");
+							preprocessor.writef("out mediump vec4 bgfx_FragData[gl_MaxDrawBuffers];\n");
+						}
+					}
+
 					for (InOut::const_iterator it = shaderInputs.begin(), itEnd = shaderInputs.end(); it != itEnd; ++it)
 					for (InOut::const_iterator it = shaderInputs.begin(), itEnd = shaderInputs.end(); it != itEnd; ++it)
 					{
 					{
 						VaryingMap::const_iterator varyingIt = varyingMap.find(*it);
 						VaryingMap::const_iterator varyingIt = varyingMap.find(*it);
@@ -1651,7 +1681,7 @@ namespace bgfx
 				}
 				}
 				else
 				else
 				{
 				{
-					if (0 != pssl)
+					if (profile->lang == PSSL)
 					{
 					{
 						preprocessor.writef(getPsslPreamble() );
 						preprocessor.writef(getPsslPreamble() );
 					}
 					}
@@ -1674,8 +1704,8 @@ namespace bgfx
 						"#define mat4 float4x4\n"
 						"#define mat4 float4x4\n"
 						);
 						);
 
 
-					if (hlsl != 0
-					&&  hlsl < 4)
+					if (profile->lang == HLSL
+					&&  profile->id < 400)
 					{
 					{
 						preprocessor.writef(
 						preprocessor.writef(
 							"#define centroid\n"
 							"#define centroid\n"
@@ -1696,7 +1726,7 @@ namespace bgfx
 						}
 						}
 
 
 						const bool hasFragColor   = !bx::strFind(input, "gl_FragColor").isEmpty();
 						const bool hasFragColor   = !bx::strFind(input, "gl_FragColor").isEmpty();
-						const bool hasFragCoord   = !bx::strFind(input, "gl_FragCoord").isEmpty() || hlsl > 3 || hlsl == 2;
+						const bool hasFragCoord   = !bx::strFind(input, "gl_FragCoord").isEmpty() || profile->id >= 400;
 						const bool hasFragDepth   = !bx::strFind(input, "gl_FragDepth").isEmpty();
 						const bool hasFragDepth   = !bx::strFind(input, "gl_FragDepth").isEmpty();
 						const bool hasFrontFacing = !bx::strFind(input, "gl_FrontFacing").isEmpty();
 						const bool hasFrontFacing = !bx::strFind(input, "gl_FrontFacing").isEmpty();
 						const bool hasPrimitiveId = !bx::strFind(input, "gl_PrimitiveID").isEmpty();
 						const bool hasPrimitiveId = !bx::strFind(input, "gl_PrimitiveID").isEmpty();
@@ -1720,10 +1750,10 @@ namespace bgfx
 							// If it has gl_FragData or gl_FragColor, color target at
 							// If it has gl_FragData or gl_FragColor, color target at
 							// index 0 exists, otherwise shader is not modifying color
 							// index 0 exists, otherwise shader is not modifying color
 							// targets.
 							// targets.
-							hasFragData[0] |= hasFragColor || d3d < 11;
+							hasFragData[0] |= hasFragColor || profile->id < 400;
 
 
 							if (!insert.isEmpty()
 							if (!insert.isEmpty()
-							&&  d3d < 11
+							&&  profile->id < 400
 							&&  !hasFragColor)
 							&&  !hasFragColor)
 							{
 							{
 								insert = strInsert(const_cast<char*>(insert.getPtr()+1), "\ngl_FragColor = bgfx_VoidFrag;\n");
 								insert = strInsert(const_cast<char*>(insert.getPtr()+1), "\ngl_FragColor = bgfx_VoidFrag;\n");
@@ -1757,7 +1787,7 @@ namespace bgfx
 							}
 							}
 						}
 						}
 
 
-						const uint32_t maxRT = d3d > 9 ? BX_COUNTOF(hasFragData) : 4;
+						const uint32_t maxRT = profile->id >= 400 ? BX_COUNTOF(hasFragData) : 4;
 
 
 						for (uint32_t ii = 0; ii < BX_COUNTOF(hasFragData); ++ii)
 						for (uint32_t ii = 0; ii < BX_COUNTOF(hasFragData); ++ii)
 						{
 						{
@@ -1784,7 +1814,7 @@ namespace bgfx
 
 
 						if (hasFrontFacing)
 						if (hasFrontFacing)
 						{
 						{
-							if (hlsl == 3)
+							if (profile->id < 400)
 							{
 							{
 								preprocessor.writef(
 								preprocessor.writef(
 									" \\\n\t%sfloat __vface : VFACE"
 									" \\\n\t%sfloat __vface : VFACE"
@@ -1802,7 +1832,7 @@ namespace bgfx
 
 
 						if (hasPrimitiveId)
 						if (hasPrimitiveId)
 						{
 						{
-							if (hlsl > 3)
+							if (profile->id >= 400)
 							{
 							{
 								preprocessor.writef(
 								preprocessor.writef(
 									" \\\n\t%suint gl_PrimitiveID : SV_PrimitiveID"
 									" \\\n\t%suint gl_PrimitiveID : SV_PrimitiveID"
@@ -1822,7 +1852,7 @@ namespace bgfx
 
 
 						if (hasFrontFacing)
 						if (hasFrontFacing)
 						{
 						{
-							if (hlsl == 3)
+							if (profile->id < 400)
 							{
 							{
 								preprocessor.writef(
 								preprocessor.writef(
 									"#define gl_FrontFacing (__vface >= 0.0)\n"
 									"#define gl_FrontFacing (__vface >= 0.0)\n"
@@ -1877,7 +1907,7 @@ namespace bgfx
 
 
 						if (hasViewportId)
 						if (hasViewportId)
 						{
 						{
-							if (d3d > 9)
+							if (profile->id >= 400)
 							{
 							{
 								preprocessor.writef(
 								preprocessor.writef(
 									"\tuint gl_ViewportIndex : SV_ViewportArrayIndex;\n"
 									"\tuint gl_ViewportIndex : SV_ViewportArrayIndex;\n"
@@ -1893,7 +1923,7 @@ namespace bgfx
 
 
 						if (hasLayerId)
 						if (hasLayerId)
 						{
 						{
-							if (d3d > 9)
+							if (profile->id >= 400)
 							{
 							{
 								preprocessor.writef(
 								preprocessor.writef(
 									"\tuint gl_Layer : SV_RenderTargetArrayIndex;\n"
 									"\tuint gl_Layer : SV_RenderTargetArrayIndex;\n"
@@ -1932,7 +1962,7 @@ namespace bgfx
 
 
 						if (hasVertexId)
 						if (hasVertexId)
 						{
 						{
-							if (d3d > 9)
+							if (profile->id >= 400)
 							{
 							{
 								preprocessor.writef(
 								preprocessor.writef(
 									" \\\n\t%suint gl_VertexID : SV_VertexID"
 									" \\\n\t%suint gl_VertexID : SV_VertexID"
@@ -1948,7 +1978,7 @@ namespace bgfx
 
 
 						if (hasInstanceId)
 						if (hasInstanceId)
 						{
 						{
-							if (d3d > 9)
+							if (profile->id >= 400)
 							{
 							{
 								preprocessor.writef(
 								preprocessor.writef(
 									" \\\n\t%suint gl_InstanceID : SV_InstanceID"
 									" \\\n\t%suint gl_InstanceID : SV_InstanceID"
@@ -2001,17 +2031,6 @@ namespace bgfx
 
 
 					if (_options.preprocessOnly)
 					if (_options.preprocessOnly)
 					{
 					{
-						if (0 != glsl)
-						{
-							if (essl != 0)
-							{
-								writef(_writer
-									, "#ifdef GL_ES\n"
-										"precision highp float;\n"
-										"#endif // GL_ES\n\n"
-									);
-							}
-						}
 						bx::write(_writer, preprocessor.m_preprocessed.c_str(), (int32_t)preprocessor.m_preprocessed.size() );
 						bx::write(_writer, preprocessor.m_preprocessed.c_str(), (int32_t)preprocessor.m_preprocessed.size() );
 
 
 						return true;
 						return true;
@@ -2039,10 +2058,11 @@ namespace bgfx
 							bx::write(_writer, outputHash);
 							bx::write(_writer, outputHash);
 						}
 						}
 
 
-						if (0 != glsl
-						||  0 != essl)
+						if (profile->lang == GLSL
+						||  profile->lang == ESSL)
 						{
 						{
 							const bx::StringView preprocessedInput(preprocessor.m_preprocessed.c_str() );
 							const bx::StringView preprocessedInput(preprocessor.m_preprocessed.c_str() );
+							uint32_t glsl_profile = profile->id;
 
 
 							if (!bx::strFind(preprocessedInput, "layout(std430").isEmpty()
 							if (!bx::strFind(preprocessedInput, "layout(std430").isEmpty()
 							||  !bx::strFind(preprocessedInput, "image2D").isEmpty()
 							||  !bx::strFind(preprocessedInput, "image2D").isEmpty()
@@ -2054,10 +2074,15 @@ namespace bgfx
 									) )
 									) )
 								)
 								)
 							{
 							{
-								glsl = 430;
+								if((profile->lang == GLSL) && (glsl_profile < 430)) {
+									glsl_profile = 430;
+								}
+								else if(glsl_profile < 310) {
+									glsl_profile = 310;
+								}
 							}
 							}
 
 
-							if (glsl < 400)
+							if (glsl_profile < 400)
 							{
 							{
 								const bool usesTextureLod   = false
 								const bool usesTextureLod   = false
 									|| !bx::findIdentifierMatch(input, s_ARB_shader_texture_lod).isEmpty()
 									|| !bx::findIdentifierMatch(input, s_ARB_shader_texture_lod).isEmpty()
@@ -2077,16 +2102,16 @@ namespace bgfx
 								const bool usesPacking            = !bx::findIdentifierMatch(input, s_ARB_shading_language_packing).isEmpty();
 								const bool usesPacking            = !bx::findIdentifierMatch(input, s_ARB_shading_language_packing).isEmpty();
 								const bool usesViewportLayerArray = !bx::findIdentifierMatch(input, s_ARB_shader_viewport_layer_array).isEmpty();
 								const bool usesViewportLayerArray = !bx::findIdentifierMatch(input, s_ARB_shader_viewport_layer_array).isEmpty();
 
 
-								if (0 == essl)
+								if (profile->lang != ESSL)
 								{
 								{
-									const bool need130 = (120 == glsl && (false
+									const bool need130 = (120 == glsl_profile && (false
 										|| !bx::findIdentifierMatch(input, s_130).isEmpty()
 										|| !bx::findIdentifierMatch(input, s_130).isEmpty()
 										|| usesInterpolationQualifiers
 										|| usesInterpolationQualifiers
 										|| usesTexelFetch
 										|| usesTexelFetch
 										) );
 										) );
 
 
-									bx::stringPrintf(code, "#version %s\n", need130 ? "130" : _options.profile.c_str());
-									glsl = 130;
+									bx::stringPrintf(code, "#version %d\n", need130 ? 130 : glsl_profile);
+									glsl_profile = 130;
 
 
 									if (need130)
 									if (need130)
 									{
 									{
@@ -2165,7 +2190,7 @@ namespace bgfx
 											);
 											);
 									}
 									}
 
 
-									if (130 > glsl)
+									if (130 > glsl_profile)
 									{
 									{
 										bx::stringPrintf(code,
 										bx::stringPrintf(code,
 											"#define ivec2 vec2\n"
 											"#define ivec2 vec2\n"
@@ -2204,21 +2229,23 @@ namespace bgfx
 									{
 									{
 										bx::stringPrintf(code
 										bx::stringPrintf(code
 											, "#define bgfxShadow2D     shadow2D\n"
 											, "#define bgfxShadow2D     shadow2D\n"
-											  "#define bgfxShadow2DProj shadow2DProj\n"
+											  "#define bgfxShadow2DProj shader2DProj\n"
 											);
 											);
 									}
 									}
 								}
 								}
 								else
 								else
 								{
 								{
-									if (usesInterpolationQualifiers)
+									if (glsl_profile > 100)
 									{
 									{
-										bx::stringPrintf(code, "#version 300 es\n");
+										bx::stringPrintf(code, "#version %d es\n", glsl_profile);
 										bx::stringPrintf(code, "#define attribute in\n");
 										bx::stringPrintf(code, "#define attribute in\n");
 										bx::stringPrintf(code, "#define varying %s\n"
 										bx::stringPrintf(code, "#define varying %s\n"
 											, 'f' == _options.shaderType ? "in" : "out"
 											, 'f' == _options.shaderType ? "in" : "out"
 											);
 											);
+										bx::stringPrintf(code, "precision highp float;\n");
+										bx::stringPrintf(code, "precision highp int;\n");
 									}
 									}
-									else if (essl == 2)
+									else
 									{
 									{
 										code +=
 										code +=
 											"mat2 transpose(mat2 _mtx)\n"
 											"mat2 transpose(mat2 _mtx)\n"
@@ -2287,7 +2314,7 @@ namespace bgfx
 										bx::stringPrintf(code, "#extension GL_OES_texture_3D : enable\n");
 										bx::stringPrintf(code, "#extension GL_OES_texture_3D : enable\n");
 									}
 									}
 
 
-									if (!bx::findIdentifierMatch(input, s_EXT_shadow_samplers).isEmpty() )
+									if ((glsl_profile < 300) && (!bx::findIdentifierMatch(input, s_EXT_shadow_samplers).isEmpty()))
 									{
 									{
 										bx::stringPrintf(code
 										bx::stringPrintf(code
 											, "#extension GL_EXT_shadow_samplers : enable\n"
 											, "#extension GL_EXT_shadow_samplers : enable\n"
@@ -2310,7 +2337,7 @@ namespace bgfx
 											);
 											);
 									}
 									}
 
 
-									if (!bx::findIdentifierMatch(input, "gl_FragDepth").isEmpty() )
+									if ((glsl_profile < 300) && (!bx::findIdentifierMatch(input, "gl_FragDepth").isEmpty() ))
 									{
 									{
 										bx::stringPrintf(code
 										bx::stringPrintf(code
 											, "#extension GL_EXT_frag_depth : enable\n"
 											, "#extension GL_EXT_frag_depth : enable\n"
@@ -2324,29 +2351,21 @@ namespace bgfx
 											, "#extension GL_EXT_texture_array : enable\n"
 											, "#extension GL_EXT_texture_array : enable\n"
 											);
 											);
 									}
 									}
-
-									bx::stringPrintf(code
-										, "#define ivec2 vec2\n"
-										  "#define ivec3 vec3\n"
-										  "#define ivec4 vec4\n"
-										  "#define uvec2 vec2\n"
-										  "#define uvec3 vec3\n"
-										  "#define uvec4 vec4\n"
-									);
 								}
 								}
 							}
 							}
 							else
 							else
 							{
 							{
-								bx::stringPrintf(code, "#version %d\n", glsl);
+								bx::stringPrintf(code, "#version %d\n", glsl_profile);
 
 
 								bx::stringPrintf(code
 								bx::stringPrintf(code
-									, "#define texture2DLod      textureLod\n"
-									  "#define texture2DGrad     textureGrad\n"
-									  "#define texture2DProjLod  textureProjLod\n"
-									  "#define texture2DProjGrad textureProjGrad\n"
-									  "#define textureCubeLod    textureLod\n"
-									  "#define textureCubeGrad   textureGrad\n"
-									  "#define texture3D         texture\n"
+									, "#define texture2DLod       textureLod\n"
+									  "#define texture2DGrad      textureGrad\n"
+									  "#define texture2DProjLod   textureProjLod\n"
+									  "#define texture2DProjGrad  textureProjGrad\n"
+									  "#define textureCubeLod     textureLod\n"
+									  "#define textureCubeGrad    textureGrad\n"
+									  "#define texture3D          texture\n"
+									  "#define texture2DLofOffset textureLodOffset\n"
 									);
 									);
 
 
 								bx::stringPrintf(code, "#define attribute in\n");
 								bx::stringPrintf(code, "#define attribute in\n");
@@ -2360,7 +2379,8 @@ namespace bgfx
 									);
 									);
 							}
 							}
 
 
-							if (glsl > 400)
+							if ( ((profile->lang == GLSL) && (glsl_profile > 400)) 
+							  || ((profile->lang == ESSL) && (glsl_profile > 300)) )
 							{
 							{
 								code += preprocessor.m_preprocessed;
 								code += preprocessor.m_preprocessed;
 
 
@@ -2378,7 +2398,10 @@ namespace bgfx
 								code += _comment;
 								code += _comment;
 								code += preprocessor.m_preprocessed;
 								code += preprocessor.m_preprocessed;
 
 
-								compiled = compileGLSLShader(_options, metal ? BX_MAKEFOURCC('M', 'T', 'L', 0) : essl, code, _writer);
+								if(profile->lang == ESSL) {
+									glsl_profile |= 0x80000000;
+								}
+								compiled = compileGLSLShader(_options, glsl_profile, code, _writer);
 							}
 							}
 						}
 						}
 						else
 						else
@@ -2386,21 +2409,21 @@ namespace bgfx
 							code += _comment;
 							code += _comment;
 							code += preprocessor.m_preprocessed;
 							code += preprocessor.m_preprocessed;
 
 
-							if (0 != metal)
+							if (profile->lang == Metal)
 							{
 							{
 								compiled = compileMetalShader(_options, BX_MAKEFOURCC('M', 'T', 'L', 0), code, _writer);
 								compiled = compileMetalShader(_options, BX_MAKEFOURCC('M', 'T', 'L', 0), code, _writer);
 							}
 							}
-							else if (0 != spirv)
+							else if (profile->lang == Spirv)
 							{
 							{
-								compiled = compileSPIRVShader(_options, spirv, code, _writer);
+								compiled = compileSPIRVShader(_options, profile->id, code, _writer);
 							}
 							}
-							else if (0 != pssl)
+							else if (profile->lang == PSSL)
 							{
 							{
 								compiled = compilePSSLShader(_options, 0, code, _writer);
 								compiled = compilePSSLShader(_options, 0, code, _writer);
 							}
 							}
 							else
 							else
 							{
 							{
-								compiled = compileHLSLShader(_options, d3d, code, _writer);
+								compiled = compileHLSLShader(_options, profile->id, code, _writer);
 							}
 							}
 						}
 						}
 					}
 					}

+ 17 - 14
tools/shaderc/shaderc_glsl.cpp

@@ -16,23 +16,15 @@ namespace bgfx { namespace glsl
 			: (ch == 'c' ? kGlslOptShaderCompute : kGlslOptShaderVertex);
 			: (ch == 'c' ? kGlslOptShaderCompute : kGlslOptShaderVertex);
 
 
 		glslopt_target target = kGlslTargetOpenGL;
 		glslopt_target target = kGlslTargetOpenGL;
-		switch (_version)
+		if(_version == BX_MAKEFOURCC('M', 'T', 'L', 0))
 		{
 		{
-		case BX_MAKEFOURCC('M', 'T', 'L', 0):
 			target = kGlslTargetMetal;
 			target = kGlslTargetMetal;
-			break;
-
-		case 2:
-			target = kGlslTargetOpenGLES20;
-			break;
-
-		case 3:
-			target = kGlslTargetOpenGLES30;
-			break;
-
-		default:
+		} else if(_version < 0x80000000) {
 			target = kGlslTargetOpenGL;
 			target = kGlslTargetOpenGL;
-			break;
+		}
+		else {
+			_version &= ~0x80000000;
+			target = (_version >= 300) ? kGlslTargetOpenGLES30 : kGlslTargetOpenGLES20;
 		}
 		}
 
 
 		glslopt_ctx* ctx = glslopt_initialize(target);
 		glslopt_ctx* ctx = glslopt_initialize(target);
@@ -69,12 +61,16 @@ namespace bgfx { namespace glsl
 
 
 		const char* optimizedShader = glslopt_get_output(shader);
 		const char* optimizedShader = glslopt_get_output(shader);
 
 
+		std::string out;
 		// Trim all directives.
 		// Trim all directives.
 		while ('#' == *optimizedShader)
 		while ('#' == *optimizedShader)
 		{
 		{
 			optimizedShader = bx::strFindNl(optimizedShader).getPtr();
 			optimizedShader = bx::strFindNl(optimizedShader).getPtr();
 		}
 		}
 
 
+		out.append(optimizedShader, strlen(optimizedShader));
+		optimizedShader = out.c_str();
+
 		{
 		{
 			char* code = const_cast<char*>(optimizedShader);
 			char* code = const_cast<char*>(optimizedShader);
 			strReplace(code, "gl_FragDepthEXT", "gl_FragDepth");
 			strReplace(code, "gl_FragDepthEXT", "gl_FragDepth");
@@ -114,6 +110,13 @@ namespace bgfx { namespace glsl
 				{
 				{
 					bx::StringView qualifier = nextWord(parse);
 					bx::StringView qualifier = nextWord(parse);
 
 
+					if (0 == bx::strCmp(qualifier, "precision", 9) )
+					{
+						// skip precision
+						parse.set(eol.getPtr() + 1, parse.getTerm() );
+						continue;
+					}
+
 					if (0 == bx::strCmp(qualifier, "attribute", 9)
 					if (0 == bx::strCmp(qualifier, "attribute", 9)
 					||  0 == bx::strCmp(qualifier, "varying",   7)
 					||  0 == bx::strCmp(qualifier, "varying",   7)
 					||  0 == bx::strCmp(qualifier, "in",        2)
 					||  0 == bx::strCmp(qualifier, "in",        2)

+ 2 - 2
tools/shaderc/shaderc_hlsl.cpp

@@ -663,7 +663,7 @@ namespace bgfx { namespace hlsl
 		uint16_t attrs[bgfx::Attrib::Count];
 		uint16_t attrs[bgfx::Attrib::Count];
 		uint16_t size = 0;
 		uint16_t size = 0;
 
 
-		if (_version == 9)
+		if (_version < 400)
 		{
 		{
 			if (!getReflectionDataD3D9(code, uniforms) )
 			if (!getReflectionDataD3D9(code, uniforms) )
 			{
 			{
@@ -782,7 +782,7 @@ namespace bgfx { namespace hlsl
 			bx::write(_writer, nul);
 			bx::write(_writer, nul);
 		}
 		}
 
 
-		if (_version > 9)
+		if (_version >= 400)
 		{
 		{
 			bx::write(_writer, numAttrs);
 			bx::write(_writer, numAttrs);
 			bx::write(_writer, attrs, numAttrs*sizeof(uint16_t) );
 			bx::write(_writer, attrs, numAttrs*sizeof(uint16_t) );