Procházet zdrojové kódy

WIP: Adding texture compare modes and shadow samplers support.

Branimir Karadžić před 12 roky
rodič
revize
a68ffbf4a0

+ 17 - 5
include/bgfx.h

@@ -199,6 +199,16 @@
 #define BGFX_TEXTURE_RT_MSAA_MASK        UINT32_C(0x00007000)
 #define BGFX_TEXTURE_RT_BUFFER_ONLY      UINT32_C(0x00008000)
 #define BGFX_TEXTURE_RT_MASK             UINT32_C(0x0000f000)
+#define BGFX_TEXTURE_COMPARE_LESS        UINT32_C(0x00010000)
+#define BGFX_TEXTURE_COMPARE_LEQUAL      UINT32_C(0x00020000)
+#define BGFX_TEXTURE_COMPARE_EQUAL       UINT32_C(0x00030000)
+#define BGFX_TEXTURE_COMPARE_GEQUAL      UINT32_C(0x00040000)
+#define BGFX_TEXTURE_COMPARE_GREATER     UINT32_C(0x00050000)
+#define BGFX_TEXTURE_COMPARE_NOTEQUAL    UINT32_C(0x00060000)
+#define BGFX_TEXTURE_COMPARE_NEVER       UINT32_C(0x00070000)
+#define BGFX_TEXTURE_COMPARE_ALWAYS      UINT32_C(0x00080000)
+#define BGFX_TEXTURE_COMPARE_SHIFT       16
+#define BGFX_TEXTURE_COMPARE_MASK        UINT32_C(0x000f0000)
 #define BGFX_TEXTURE_RESERVED_SHIFT      24
 #define BGFX_TEXTURE_RESERVED_MASK       UINT32_C(0xff000000)
 
@@ -240,11 +250,13 @@
 #define BGFX_CAPS_TEXTURE_FORMAT_D24F    UINT64_C(0x0000000000100000)
 #define BGFX_CAPS_TEXTURE_FORMAT_D32F    UINT64_C(0x0000000000200000)
 #define BGFX_CAPS_TEXTURE_FORMAT_D0S8    UINT64_C(0x0000000000400000)
-#define BGFX_CAPS_TEXTURE_3D             UINT64_C(0x0000000001000000)
-#define BGFX_CAPS_VERTEX_ATTRIB_HALF     UINT64_C(0x0000000004000000)
-#define BGFX_CAPS_INSTANCING             UINT64_C(0x0000000008000000)
-#define BGFX_CAPS_RENDERER_MULTITHREADED UINT64_C(0x0000000010000000)
-#define BGFX_CAPS_FRAGMENT_DEPTH         UINT64_C(0x0000000020000000)
+#define BGFX_CAPS_TEXTURE_COMPARE_LEQUAL UINT64_C(0x0000000001000000)
+#define BGFX_CAPS_TEXTURE_COMPARE_ALL    UINT64_C(0x0000000003000000)
+#define BGFX_CAPS_TEXTURE_3D             UINT64_C(0x0000000004000000)
+#define BGFX_CAPS_VERTEX_ATTRIB_HALF     UINT64_C(0x0000000008000000)
+#define BGFX_CAPS_INSTANCING             UINT64_C(0x0000000010000000)
+#define BGFX_CAPS_RENDERER_MULTITHREADED UINT64_C(0x0000000020000000)
+#define BGFX_CAPS_FRAGMENT_DEPTH         UINT64_C(0x0000000040000000)
 
 #define BGFX_CAPS_TEXTURE_DEPTH_MASK (0 \
 			| BGFX_CAPS_TEXTURE_FORMAT_D16 \

+ 90 - 18
src/bgfx_shader.sh

@@ -35,6 +35,35 @@ vec4 bgfxTexture2DLod(BgfxSampler2D _sampler, vec2 _coord, float _level)
 	return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level);
 }
 
+vec4 bgfxTexture2DProj(BgfxSampler2D _sampler, vec3 _coord)
+{
+	vec2 coord = _coord.xy * rcp(_coord.z);
+	return _sampler.m_texture.Sample(_sampler.m_sampler, coord);
+}
+
+vec4 bgfxTexture2DProj(BgfxSampler2D _sampler, vec4 _coord)
+{
+	vec2 coord = _coord.xy * rcp(_coord.w);
+	return _sampler.m_texture.Sample(_sampler.m_sampler, coord);
+}
+
+struct BgfxSampler2DShadow
+{
+	SamplerComparisonState m_sampler;
+	Texture2D m_texture;
+};
+
+float bgfxShadow2D(BgfxSampler2DShadow _sampler, vec3 _coord)
+{
+	return _sampler.m_texture.SampleCmp(_sampler.m_sampler, _coord.xy, _coord.z);
+}
+
+float bgfxShadow2DProj(BgfxSampler2DShadow _sampler, vec4 _coord)
+{
+	vec3 coord = _coord.xyz * rcp(_coord.w);
+	return _sampler.m_texture.SampleCmp(_sampler.m_sampler, coord.xy, coord.z);
+}
+
 struct BgfxSampler3D
 {
 	SamplerState m_sampler;
@@ -74,6 +103,15 @@ vec4 bgfxTextureCubeLod(BgfxSamplerCube _sampler, vec3 _coord, float _level)
 #		define sampler2D BgfxSampler2D
 #		define texture2D(_sampler, _coord) bgfxTexture2D(_sampler, _coord)
 #		define texture2DLod(_sampler, _coord, _level) bgfxTexture2DLod(_sampler, _coord, _level)
+#		define texture2DProj(_sampler, _coord) bgfxTexture2DProj(_sampler, _coord)
+
+#		define SAMPLER2DSHADOW(_name, _reg) \
+			uniform SamplerComparisonState _name ## Sampler : register(s[_reg]); \
+			uniform Texture2D _name ## Texture : register(t[_reg]); \
+			static BgfxSampler2DShadow _name = { _name ## Sampler, _name ## Texture }
+#		define sampler2DShadow BgfxSampler2DShadow
+#		define shadow2D(_sampler, _coord) bgfxShadow2D(_sampler, _coord)
+#		define shadow2DProj(_sampler, _coord) bgfxShadow2DProj(_sampler, _coord)
 
 #		define SAMPLER3D(_name, _reg) \
 			uniform SamplerState _name ## Sampler : register(s[_reg]); \
@@ -91,12 +129,45 @@ vec4 bgfxTextureCubeLod(BgfxSamplerCube _sampler, vec3 _coord, float _level)
 #		define textureCube(_sampler, _coord) bgfxTextureCube(_sampler, _coord)
 #		define textureCubeLod(_sampler, _coord, _level) bgfxTextureCubeLod(_sampler, _coord, _level)
 #	else
+
+#		define sampler2DShadow sampler2D
+
+vec4 bgfxTexture2DProj(sampler2D _sampler, vec3 _coord)
+{
+	return tex2Dproj(_sampler, vec4(_coord.xy, 0.0, _coord.z) );
+}
+
+vec4 bgfxTexture2DProj(sampler2D _sampler, vec4 _coord)
+{
+	return tex2Dproj(_sampler, _coord);
+}
+
+float bgfxShadow2D(sampler2DShadow _sampler, vec3 _coord)
+{
+	float occluder = tex2D(_sampler, _coord.xy).x;
+	return step(_coord.z, occluder);
+}
+
+float bgfxShadow2DProj(sampler2DShadow _sampler, vec4 _coord)
+{
+	vec3 coord = _coord.xyz * rcp(_coord.w);
+	float occluder = tex2D(_sampler, coord.xy).x;
+	return step(coord.z, occluder);
+}
+
 #		define SAMPLER2D(_name, _reg) uniform sampler2D _name : register(s ## _reg)
 #		define texture2D(_sampler, _coord) tex2D(_sampler, _coord)
 #		define texture2DLod(_sampler, _coord, _level) tex2Dlod(_sampler, vec4( (_coord).xy, _level, 0.0) )
+#		define texture2DProj(_sampler, _coord) bgfxTexture2DProj(_sampler, _coord)
+
+#		define SAMPLER2DSHADOW(_name, _reg) uniform sampler2DShadow _name : register(s ## _reg)
+#		define shadow2D(_sampler, _coord) bgfxShadow2D(_sampler, _coord)
+#		define shadow2DProj(_sampler, _coord) bgfxShadow2DProj(_sampler, _coord)
+
 #		define SAMPLER3D(_name, _reg) uniform sampler3D _name : register(s ## _reg)
 #		define texture3D(_sampler, _coord) tex3D(_sampler, _coord)
 #		define texture3DLod(_sampler, _coord, _level) tex3Dlod(_sampler, vec4( (_coord).xyz, _level) )
+
 #		define SAMPLERCUBE(_name, _reg) uniform samplerCUBE _name : register(s[_reg])
 #		define textureCube(_sampler, _coord) texCUBE(_sampler, _coord)
 #		define textureCubeLod(_sampler, _coord, _level) texCUBElod(_sampler, vec4( (_coord).xyz, _level) )
@@ -140,14 +211,14 @@ bvec3 equal(vec3 _a, vec3 _b) { return _a == _b; }
 bvec4 equal(vec4 _a, vec4 _b) { return _a == _b; }
 
 float mix(float _a, float _b, float _t) { return lerp(_a, _b, _t); }
-vec2 mix(vec2 _a, vec2 _b, vec2 _t) { return lerp(_a, _b, _t); }
-vec3 mix(vec3 _a, vec3 _b, vec3 _t) { return lerp(_a, _b, _t); }
-vec4 mix(vec4 _a, vec4 _b, vec4 _t) { return lerp(_a, _b, _t); }
+vec2  mix(vec2  _a, vec2  _b, vec2  _t) { return lerp(_a, _b, _t); }
+vec3  mix(vec3  _a, vec3  _b, vec3  _t) { return lerp(_a, _b, _t); }
+vec4  mix(vec4  _a, vec4  _b, vec4  _t) { return lerp(_a, _b, _t); }
 
 float mod(float _a, float _b) { return _a - _b * floor(_a / _b); }
-vec2 mod(vec2 _a, vec2 _b) { return _a - _b * floor(_a / _b); }
-vec3 mod(vec3 _a, vec3 _b) { return _a - _b * floor(_a / _b); }
-vec4 mod(vec4 _a, vec4 _b) { return _a - _b * floor(_a / _b); }
+vec2  mod(vec2  _a, vec2  _b) { return _a - _b * floor(_a / _b); }
+vec3  mod(vec3  _a, vec3  _b) { return _a - _b * floor(_a / _b); }
+vec4  mod(vec4  _a, vec4  _b) { return _a - _b * floor(_a / _b); }
 
 #elif BGFX_SHADER_LANGUAGE_GLSL
 #	define atan2(_x, _y) atan(_x, _y)
@@ -156,6 +227,7 @@ vec4 mod(vec4 _a, vec4 _b) { return _a - _b * floor(_a / _b); }
 #	define SAMPLER2D(_name, _reg) uniform sampler2D _name
 #	define SAMPLER3D(_name, _reg) uniform sampler3D _name
 #	define SAMPLERCUBE(_name, _reg) uniform samplerCube _name
+#	define SAMPLER2DSHADOW(_name, _reg) uniform sampler2DShadow _name
 #	define vec2_splat(_x) vec2(_x)
 #	define vec3_splat(_x) vec3(_x)
 #	define vec4_splat(_x) vec4(_x)
@@ -166,20 +238,20 @@ vec4 instMul(vec4 _vec, mat4 _mtx) { return mul(_vec, _mtx); }
 vec4 instMul(mat4 _mtx, vec4 _vec) { return mul(_mtx, _vec); }
 
 float rcp(float _a) { return 1.0/_a; }
-vec2 rcp(vec2 _a) { return vec2(1.0)/_a; }
-vec3 rcp(vec3 _a) { return vec3(1.0)/_a; }
-vec4 rcp(vec4 _a) { return vec4(1.0)/_a; }
+vec2  rcp(vec2  _a) { return vec2(1.0)/_a; }
+vec3  rcp(vec3  _a) { return vec3(1.0)/_a; }
+vec4  rcp(vec4  _a) { return vec4(1.0)/_a; }
 #endif // BGFX_SHADER_LANGUAGE_HLSL
 
-uniform vec4 u_viewRect;
-uniform vec4 u_viewTexel;
-uniform mat4 u_view;
-uniform mat4 u_viewProj;
-uniform mat4 u_model[BGFX_CONFIG_MAX_BONES];
-uniform mat4 u_modelView;
-uniform mat4 u_modelViewProj;
-uniform mat4 u_modelViewProjX;
-uniform mat4 u_viewProjX;
+uniform vec4  u_viewRect;
+uniform vec4  u_viewTexel;
+uniform mat4  u_view;
+uniform mat4  u_viewProj;
+uniform mat4  u_model[BGFX_CONFIG_MAX_BONES];
+uniform mat4  u_modelView;
+uniform mat4  u_modelViewProj;
+uniform mat4  u_modelViewProjX;
+uniform mat4  u_viewProjX;
 uniform float u_alphaRef;
 
 #endif // __cplusplus

+ 7 - 0
src/glimports.h

@@ -136,6 +136,8 @@ typedef void           (GL_APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint
 typedef void           (GL_APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);
 typedef void           (GL_APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
 typedef void           (GL_APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void           (GL_APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void           (GL_APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
 typedef void           (GL_APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
 typedef void           (GL_APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
 typedef void           (GL_APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
@@ -264,6 +266,8 @@ GL_IMPORT______(true,  PFNGLTEXIMAGE3DPROC,                        glTexImage3D)
 GL_IMPORT______(false, PFNGLTEXPARAMETERIPROC,                     glTexParameteri);
 GL_IMPORT______(false, PFNGLTEXPARAMETERIVPROC,                    glTexParameteriv);
 GL_IMPORT______(false, PFNGLTEXPARAMETERFPROC,                     glTexParameterf);
+GL_IMPORT______(true,  PFNGLTEXSTORAGE2DPROC,                      glTexStorage2D);
+GL_IMPORT______(true,  PFNGLTEXSTORAGE3DPROC,                      glTexStorage3D);
 GL_IMPORT______(false, PFNGLTEXSUBIMAGE2DPROC,                     glTexSubImage2D);
 GL_IMPORT______(true,  PFNGLTEXSUBIMAGE3DPROC,                     glTexSubImage3D);
 GL_IMPORT______(false, PFNGLUNIFORM1IPROC,                         glUniform1i);
@@ -328,6 +332,9 @@ GL_IMPORT_OES__(true,  PFNGLTEXSUBIMAGE3DPROC,                     glTexSubImage
 GL_IMPORT_OES__(true,  PFNGLCOMPRESSEDTEXIMAGE3DPROC,              glCompressedTexImage3D);
 GL_IMPORT_OES__(true,  PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC,           glCompressedTexSubImage3D);
 
+GL_IMPORT_EXT__(true,  PFNGLTEXSTORAGE2DPROC,                      glTexStorage2D);
+GL_IMPORT_EXT__(true,  PFNGLTEXSTORAGE3DPROC,                      glTexStorage3D);
+
 GL_IMPORT_OES__(true,  PFNGLGETPROGRAMBINARYPROC,                  glGetProgramBinary);
 GL_IMPORT_OES__(true,  PFNGLPROGRAMBINARYPROC,                     glProgramBinary);
 

+ 17 - 23
src/renderer_d3d11.cpp

@@ -64,20 +64,7 @@ namespace bgfx
 		D3D11_BLEND_OP_MAX,
 	};
 
-	static const D3D11_COMPARISON_FUNC s_depthFunc[] =
-	{
-		D3D11_COMPARISON_FUNC(0), // ignored
-		D3D11_COMPARISON_LESS,
-		D3D11_COMPARISON_LESS_EQUAL,
-		D3D11_COMPARISON_EQUAL,
-		D3D11_COMPARISON_GREATER_EQUAL,
-		D3D11_COMPARISON_GREATER,
-		D3D11_COMPARISON_NOT_EQUAL,
-		D3D11_COMPARISON_NEVER,
-		D3D11_COMPARISON_ALWAYS,
-	};
-
-	static const D3D11_COMPARISON_FUNC s_stencilFunc[] =
+	static const D3D11_COMPARISON_FUNC s_cmpFunc[] =
 	{
 		D3D11_COMPARISON_FUNC(0), // ignored
 		D3D11_COMPARISON_LESS,
@@ -151,6 +138,9 @@ namespace bgfx
 	 * D3D11_FILTER_MIN_MAG_MIP_LINEAR              = 0x15,
 	 * D3D11_FILTER_ANISOTROPIC                     = 0x55,
 	 *
+	 * D3D11_COMPARISON_FILTERING_BIT               = 0x80,
+	 * D3D11_ANISOTROPIC_FILTERING_BIT              = 0x40,
+	 *
 	 * According to D3D11_FILTER enum bits for mip, mag and mip are:
 	 * 0x10 // MIN_LINEAR
 	 * 0x04 // MAG_LINEAR
@@ -516,8 +506,9 @@ namespace bgfx
 								| BGFX_CAPS_TEXTURE_FORMAT_BC3
 								| BGFX_CAPS_TEXTURE_FORMAT_BC4
 								| BGFX_CAPS_TEXTURE_FORMAT_BC5
-								| BGFX_CAPS_INSTANCING
 								| BGFX_CAPS_TEXTURE_3D
+								| BGFX_CAPS_TEXTURE_COMPARE_ALL
+								| BGFX_CAPS_INSTANCING
 								| BGFX_CAPS_VERTEX_ATTRIB_HALF
 								| BGFX_CAPS_FRAGMENT_DEPTH
 								);
@@ -929,7 +920,7 @@ namespace bgfx
 				uint32_t func = (_state&BGFX_STATE_DEPTH_TEST_MASK)>>BGFX_STATE_DEPTH_TEST_SHIFT;
 				desc.DepthEnable = 0 != func;
 				desc.DepthWriteMask = !!(BGFX_STATE_DEPTH_WRITE & _state) ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
-				desc.DepthFunc = s_depthFunc[func];
+				desc.DepthFunc = s_cmpFunc[func];
 
 				uint32_t bstencil = unpackStencil(1, _stencil);
 				uint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != fstencil;
@@ -941,11 +932,11 @@ namespace bgfx
 				desc.FrontFace.StencilFailOp      = s_stencilOp[(fstencil&BGFX_STENCIL_OP_FAIL_S_MASK)>>BGFX_STENCIL_OP_FAIL_S_SHIFT];
 				desc.FrontFace.StencilDepthFailOp = s_stencilOp[(fstencil&BGFX_STENCIL_OP_FAIL_Z_MASK)>>BGFX_STENCIL_OP_FAIL_Z_SHIFT];
 				desc.FrontFace.StencilPassOp      = s_stencilOp[(fstencil&BGFX_STENCIL_OP_PASS_Z_MASK)>>BGFX_STENCIL_OP_PASS_Z_SHIFT];
-				desc.FrontFace.StencilFunc        = s_stencilFunc[(fstencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT];
+				desc.FrontFace.StencilFunc        = s_cmpFunc[(fstencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT];
 				desc.BackFace.StencilFailOp       = s_stencilOp[(bstencil&BGFX_STENCIL_OP_FAIL_S_MASK)>>BGFX_STENCIL_OP_FAIL_S_SHIFT];
 				desc.BackFace.StencilDepthFailOp  = s_stencilOp[(bstencil&BGFX_STENCIL_OP_FAIL_Z_MASK)>>BGFX_STENCIL_OP_FAIL_Z_SHIFT];
 				desc.BackFace.StencilPassOp       = s_stencilOp[(bstencil&BGFX_STENCIL_OP_PASS_Z_MASK)>>BGFX_STENCIL_OP_PASS_Z_SHIFT];
-				desc.BackFace.StencilFunc         = s_stencilFunc[(bstencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT];
+				desc.BackFace.StencilFunc         = s_cmpFunc[(bstencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT];
 
 				DX_CHECK(m_device->CreateDepthStencilState(&desc, &dss) );
 
@@ -999,23 +990,26 @@ namespace bgfx
 		{
 			_flags &= BGFX_TEXTURE_MIN_MASK|BGFX_TEXTURE_MAG_MASK|BGFX_TEXTURE_MIP_MASK
 					| BGFX_TEXTURE_U_MASK|BGFX_TEXTURE_V_MASK|BGFX_TEXTURE_W_MASK
+					| BGFX_TEXTURE_COMPARE_MASK
 					;
 
 			ID3D11SamplerState* sampler = m_samplerStateCache.find(_flags);
 			if (NULL == sampler)
 			{
-				uint8_t minFilter = s_textureFilter[0][(_flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT];
-				uint8_t magFilter = s_textureFilter[1][(_flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT];
-				uint8_t mipFilter = s_textureFilter[2][(_flags&BGFX_TEXTURE_MIP_MASK)>>BGFX_TEXTURE_MIP_SHIFT];
+				const uint32_t cmpFunc = (_flags&BGFX_TEXTURE_COMPARE_MASK)>>BGFX_TEXTURE_COMPARE_SHIFT;
+				const uint8_t minFilter = s_textureFilter[0][(_flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT];
+				const uint8_t magFilter = s_textureFilter[1][(_flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT];
+				const uint8_t mipFilter = s_textureFilter[2][(_flags&BGFX_TEXTURE_MIP_MASK)>>BGFX_TEXTURE_MIP_SHIFT];
+				const uint8_t filter = 0 == cmpFunc ? 0 : D3D11_COMPARISON_FILTERING_BIT;
 
 				D3D11_SAMPLER_DESC sd;
-				sd.Filter = (D3D11_FILTER)(minFilter|magFilter|mipFilter);
+				sd.Filter = (D3D11_FILTER)(filter|minFilter|magFilter|mipFilter);
 				sd.AddressU = s_textureAddress[(_flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT];
 				sd.AddressV = s_textureAddress[(_flags&BGFX_TEXTURE_V_MASK)>>BGFX_TEXTURE_V_SHIFT];
 				sd.AddressW = s_textureAddress[(_flags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT];
 				sd.MipLODBias = 0.0f;
 				sd.MaxAnisotropy = 1;
-				sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
+				sd.ComparisonFunc = 0 == cmpFunc ? D3D11_COMPARISON_NEVER : s_cmpFunc[cmpFunc];
 				sd.BorderColor[0] = 0.0f;
 				sd.BorderColor[1] = 0.0f;
 				sd.BorderColor[2] = 0.0f;

+ 1 - 0
src/renderer_d3d9.cpp

@@ -410,6 +410,7 @@ namespace bgfx
 								| BGFX_CAPS_TEXTURE_FORMAT_BC2
 								| BGFX_CAPS_TEXTURE_FORMAT_BC3
 								| BGFX_CAPS_TEXTURE_3D
+								| BGFX_CAPS_TEXTURE_COMPARE_LEQUAL
 								| BGFX_CAPS_VERTEX_ATTRIB_HALF
 								| BGFX_CAPS_FRAGMENT_DEPTH
 								);

+ 103 - 51
src/renderer_gl.cpp

@@ -91,20 +91,7 @@ namespace bgfx
 		GL_MAX,
 	};
 
-	static const GLenum s_depthFunc[] =
-	{
-		0, // ignored
-		GL_LESS,
-		GL_LEQUAL,
-		GL_EQUAL,
-		GL_GEQUAL,
-		GL_GREATER,
-		GL_NOTEQUAL,
-		GL_NEVER,
-		GL_ALWAYS,
-	};
-
-	static const GLenum s_stencilFunc[] =
+	static const GLenum s_cmpFunc[] =
 	{
 		0, // ignored
 		GL_LESS,
@@ -605,7 +592,9 @@ namespace bgfx
 			, m_maxAnisotropy(0.0f)
 			, m_maxMsaa(0)
 			, m_vao(0)
-			, m_vaoSupport(BGFX_CONFIG_RENDERER_OPENGL >= 31)
+			, m_vaoSupport(false)
+			, m_samplerObjectSupport(false)
+			, m_shadowSamplersSupport(false)
 			, m_programBinarySupport(false)
 			, m_textureSwizzleSupport(false)
 			, m_depthTextureSupport(false)
@@ -793,9 +782,9 @@ namespace bgfx
 						GL_CHECK(glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, s_textureAddress[(_flags&BGFX_TEXTURE_V_MASK)>>BGFX_TEXTURE_V_SHIFT]) );
 						GL_CHECK(glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, s_textureAddress[(_flags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT]) );
 
-						uint32_t mag = (_flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT;
-						uint32_t min = (_flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT;
-						uint32_t mip = (_flags&BGFX_TEXTURE_MIP_MASK)>>BGFX_TEXTURE_MIP_SHIFT;
+						const uint32_t mag = (_flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT;
+						const uint32_t min = (_flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT;
+						const uint32_t mip = (_flags&BGFX_TEXTURE_MIP_MASK)>>BGFX_TEXTURE_MIP_SHIFT;
 						GLenum minFilter = s_textureFilterMin[min][1 < _numMips ? mip+1 : 0];
 						GL_CHECK(glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, s_textureFilterMag[mag]) );
 						GL_CHECK(glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, minFilter) );
@@ -804,6 +793,21 @@ namespace bgfx
 						{
 							GL_CHECK(glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_maxAnisotropy) );
 						}
+
+						if (BX_ENABLED(!BGFX_CONFIG_RENDERER_OPENGLES2)
+						||  m_shadowSamplersSupport)
+						{
+							const uint32_t cmpFunc = (_flags&BGFX_TEXTURE_COMPARE_MASK)>>BGFX_TEXTURE_COMPARE_SHIFT;
+							if (0 == cmpFunc)
+							{
+								GL_CHECK(glSamplerParameteri(sampler, GL_TEXTURE_COMPARE_MODE, GL_NONE) );
+							}
+							else
+							{
+								GL_CHECK(glSamplerParameteri(sampler, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE) );
+								GL_CHECK(glSamplerParameteri(sampler, GL_TEXTURE_COMPARE_FUNC, s_cmpFunc[cmpFunc]) );
+							}
+						}
 					}
 
 					GL_CHECK(glBindSampler(_stage, sampler) );
@@ -960,6 +964,7 @@ namespace bgfx
 		GLuint m_vao;
 		bool m_vaoSupport;
 		bool m_samplerObjectSupport;
+		bool m_shadowSamplersSupport;
 		bool m_programBinarySupport;
 		bool m_textureSwizzleSupport;
 		bool m_depthTextureSupport;
@@ -1006,7 +1011,7 @@ namespace bgfx
 			GLSL_TYPE(GL_SAMPLER_3D);
 			GLSL_TYPE(GL_SAMPLER_CUBE);
 // 			GLSL_TYPE(GL_SAMPLER_1D_SHADOW);
-// 			GLSL_TYPE(GL_SAMPLER_2D_SHADOW);
+			GLSL_TYPE(GL_SAMPLER_2D_SHADOW);
 		}
 
 #undef GLSL_TYPE
@@ -1067,7 +1072,7 @@ namespace bgfx
 		case GL_SAMPLER_3D:
 		case GL_SAMPLER_CUBE:
 // 		case GL_SAMPLER_1D_SHADOW:
-// 		case GL_SAMPLER_2D_SHADOW:
+ 		case GL_SAMPLER_2D_SHADOW:
 			return UniformType::Uniform1iv;
 		};
 
@@ -1239,12 +1244,20 @@ namespace bgfx
 				offset = atoi(array);
 			}
 
- 			if (GL_SAMPLER_2D == gltype)
- 			{
- 				BX_TRACE("Sampler %d at %d.", m_numSamplers, loc);
- 				m_sampler[m_numSamplers] = loc;
- 				m_numSamplers++;
- 			}
+			switch (gltype)
+			{
+			case GL_SAMPLER_2D:
+			case GL_SAMPLER_3D:
+			case GL_SAMPLER_CUBE:
+			case GL_SAMPLER_2D_SHADOW:
+				BX_TRACE("Sampler %d at %d.", m_numSamplers, loc);
+				m_sampler[m_numSamplers] = loc;
+				m_numSamplers++;
+				break;
+
+			default:
+				break;
+			}
 
 			const void* data = NULL;
 			PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);
@@ -1826,10 +1839,10 @@ namespace bgfx
 				GL_CHECK(glTexParameteri(target, GL_TEXTURE_WRAP_R, s_textureAddress[(flags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT]) );
 			}
 
-			uint32_t mag = (flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT;
-			uint32_t min = (flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT;
-			uint32_t mip = (flags&BGFX_TEXTURE_MIP_MASK)>>BGFX_TEXTURE_MIP_SHIFT;
-			GLenum minFilter = s_textureFilterMin[min][1 < numMips ? mip+1 : 0];
+			const uint32_t mag = (flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT;
+			const uint32_t min = (flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT;
+			const uint32_t mip = (flags&BGFX_TEXTURE_MIP_MASK)>>BGFX_TEXTURE_MIP_SHIFT;
+			const GLenum minFilter = s_textureFilterMin[min][1 < numMips ? mip+1 : 0];
 			GL_CHECK(glTexParameteri(target, GL_TEXTURE_MAG_FILTER, s_textureFilterMag[mag]) );
 			GL_CHECK(glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter) );
 			if (0 != (flags & (BGFX_TEXTURE_MIN_ANISOTROPIC|BGFX_TEXTURE_MAG_ANISOTROPIC) )
@@ -1838,6 +1851,21 @@ namespace bgfx
 				GL_CHECK(glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, s_renderCtx->m_maxAnisotropy) );
 			}
 
+			if (!BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES2)
+			||  s_renderCtx->m_shadowSamplersSupport)
+			{
+				const uint32_t cmpFunc = (flags&BGFX_TEXTURE_COMPARE_MASK)>>BGFX_TEXTURE_COMPARE_SHIFT;
+				if (0 == cmpFunc)
+				{
+					GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_COMPARE_MODE, GL_NONE) );
+				}
+				else
+				{
+					GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE) );
+					GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_COMPARE_FUNC, s_cmpFunc[cmpFunc]) );
+				}
+			}
+
 			m_currentFlags = flags;
 		}
 	}
@@ -1902,7 +1930,7 @@ namespace bgfx
 		if (0 != m_id)
 		{
 			int32_t codeLen = (int32_t)strlen(code);
-			int32_t tempLen = codeLen + 1024;
+			int32_t tempLen = codeLen + (4<<10);
 			char* temp = (char*)alloca(tempLen);
 			bx::StaticMemoryBlockWriter writer(temp, tempLen);
 
@@ -1914,9 +1942,7 @@ namespace bgfx
 
 				bool usesFragDepth = !!bx::findIdentifierMatch(code, "gl_FragDepth");
 
-				bool usesShadowSamplers = s_extension[Extension::EXT_shadow_samplers].m_supported
-					&& bx::findIdentifierMatch(code, s_EXT_shadow_samplers)
-					;
+				bool usesShadowSamplers = !!bx::findIdentifierMatch(code, s_EXT_shadow_samplers);
 
 				bool usesTexture3D = s_extension[Extension::OES_texture_3D].m_supported
 					&& bx::findIdentifierMatch(code, s_OES_texture_3D)
@@ -1954,7 +1980,22 @@ namespace bgfx
 
 				if (usesShadowSamplers)
 				{
-					writeString(&writer, "#extension GL_EXT_shadow_samplers : enable\n");
+					if (s_renderCtx->m_shadowSamplersSupport)
+					{
+						writeString(&writer
+							, "#extension GL_EXT_shadow_samplers : enable\n"
+							  "#define shadow2D shadow2DEXT\n"
+							  "#define shadow2DProj shadow2DProjEXT\n"
+							);
+					}
+					else
+					{
+						writeString(&writer
+							, "#define sampler2DShadow sampler2D\n"
+							  "#define shadow2D(_sampler, _coord) step(_coord.z, texture2D(_sampler, _coord.xy).x)\n"
+							  "#define shadow2DProj(_sampler, _coord) step(_coord.z/_coord.w, texture2DProj(_sampler, _coord).x)\n"
+							);
+					}
 				}
 
 				if (usesTexture3D)
@@ -2102,7 +2143,7 @@ namespace bgfx
 	void FrameBuffer::create(uint8_t _num, const TextureHandle* _handles)
 	{
 		GL_CHECK(glGenFramebuffers(1, &m_fbo[0]) );
-		GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo[0]) );
+		GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo[0]) );
 
 		bool needResolve = false;
 
@@ -2120,18 +2161,18 @@ namespace bgfx
 				}
 				else
 				{
-					if (0 == colorIdx)
-					{
-						m_width  = texture.m_width;
-						m_height = texture.m_height;
-					}
-
 					++colorIdx;
 				}
 
+				if (0 == colorIdx)
+				{
+					m_width  = texture.m_width;
+					m_height = texture.m_height;
+				}
+
 				if (0 != texture.m_rbo)
 				{
-					GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER
+					GL_CHECK(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER
 						, attachment
 						, GL_RENDERBUFFER
 						, texture.m_rbo
@@ -2139,7 +2180,7 @@ namespace bgfx
 				}
 				else
 				{
-					GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER
+					GL_CHECK(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER
 						, attachment
 						, texture.m_target
 						, texture.m_id
@@ -2151,15 +2192,15 @@ namespace bgfx
 			}
 		}
 
-		BX_CHECK(GL_FRAMEBUFFER_COMPLETE ==  glCheckFramebufferStatus(GL_FRAMEBUFFER)
+		BX_CHECK(GL_FRAMEBUFFER_COMPLETE ==  glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)
 			, "glCheckFramebufferStatus failed 0x%08x"
-			, glCheckFramebufferStatus(GL_FRAMEBUFFER)
+			, glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)
 			);
 
 		if (needResolve)
 		{
 			GL_CHECK(glGenFramebuffers(1, &m_fbo[1]) );
-			GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo[1]) );
+			GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo[1]) );
 
 			for (uint32_t ii = 0, colorIdx = 0; ii < _num; ++ii)
 			{
@@ -2178,7 +2219,7 @@ namespace bgfx
 						else
 						{
 							++colorIdx;
-							GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER
+							GL_CHECK(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER
 								, attachment
 								, texture.m_target
 								, texture.m_id
@@ -2734,6 +2775,10 @@ namespace bgfx
 						 ? BGFX_CAPS_TEXTURE_3D
 						 : 0
 						 ;
+		g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3)|s_extension[Extension::EXT_shadow_samplers].m_supported
+						 ? BGFX_CAPS_TEXTURE_COMPARE_ALL
+						 : 0
+						 ;
 		g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3)|s_extension[Extension::OES_vertex_half_float].m_supported
 						 ? BGFX_CAPS_VERTEX_ATTRIB_HALF
 						 : 0
@@ -2771,6 +2816,10 @@ namespace bgfx
 			|| s_extension[Extension::ARB_sampler_objects].m_supported
 			;
 
+		s_renderCtx->m_shadowSamplersSupport = !!(BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3)
+			|| s_extension[Extension::EXT_shadow_samplers].m_supported
+			;
+
 		s_renderCtx->m_programBinarySupport = !!BGFX_CONFIG_RENDERER_OPENGLES3
 			|| s_extension[Extension::ARB_get_program_binary].m_supported
 			|| s_extension[Extension::OES_get_program_binary].m_supported
@@ -2788,7 +2837,10 @@ namespace bgfx
 			|| s_extension[Extension::OES_depth_texture].m_supported
 			;
 
-		g_caps.supported |= s_renderCtx->m_depthTextureSupport ? BGFX_CAPS_TEXTURE_DEPTH_MASK : 0;
+		g_caps.supported |= s_renderCtx->m_depthTextureSupport 
+						 ? (BGFX_CAPS_TEXTURE_DEPTH_MASK|BGFX_CAPS_TEXTURE_COMPARE_LEQUAL) 
+						 : 0
+						 ;
 
 		if (s_extension[Extension::EXT_texture_filter_anisotropic].m_supported)
 		{
@@ -3244,7 +3296,7 @@ namespace bgfx
 								GLint ref = (stencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;
 								GLint mask = (stencil&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT;
 								uint32_t func = (stencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT;
-								GL_CHECK(glStencilFuncSeparate(face, s_stencilFunc[func], ref, mask));
+								GL_CHECK(glStencilFuncSeparate(face, s_cmpFunc[func], ref, mask));
 							}
 
 							if ( (BGFX_STENCIL_OP_FAIL_S_MASK|BGFX_STENCIL_OP_FAIL_Z_MASK|BGFX_STENCIL_OP_PASS_Z_MASK) & changed)
@@ -3306,7 +3358,7 @@ namespace bgfx
 						if (0 != func)
 						{
 							GL_CHECK(glEnable(GL_DEPTH_TEST) );
-							GL_CHECK(glDepthFunc(s_depthFunc[func]) );
+							GL_CHECK(glDepthFunc(s_cmpFunc[func]) );
 						}
 						else
 						{

+ 16 - 0
src/renderer_gl.h

@@ -279,6 +279,22 @@ typedef uint64_t GLuint64;
 #	define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
 #endif // GL_DEPTH_STENCIL_ATTACHMENT
 
+#ifndef GL_TEXTURE_COMPARE_MODE
+#	define GL_TEXTURE_COMPARE_MODE 0x884C
+#endif // GL_TEXTURE_COMPARE_MODE
+
+#ifndef GL_TEXTURE_COMPARE_FUNC
+#	define GL_TEXTURE_COMPARE_FUNC 0x884D
+#endif // GL_TEXTURE_COMPARE_FUNC
+
+#ifndef GL_COMPARE_REF_TO_TEXTURE
+#	define GL_COMPARE_REF_TO_TEXTURE 0x884E
+#endif // GL_COMPARE_REF_TO_TEXTURE
+
+#ifndef GL_SAMPLER_2D_SHADOW
+#	define GL_SAMPLER_2D_SHADOW 0x8B62
+#endif // GL_SAMPLER_2D_SHADOW
+
 #if BX_PLATFORM_NACL
 #	include "glcontext_ppapi.h"
 #elif BX_PLATFORM_WINDOWS

+ 1 - 0
tools/shaderc/shaderc.cpp

@@ -127,6 +127,7 @@ static const char* s_EXT_shadow_samplers[] =
 {
 	"shadow2D",
 	"shadow2DProj",
+	"sampler2DShadow",
 	NULL
 };