diff --git a/include/bgfx.h b/include/bgfx.h index 4c4ca0566..17484a927 100644 --- a/include/bgfx.h +++ b/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 \ diff --git a/src/bgfx_shader.sh b/src/bgfx_shader.sh index a0ee09bf2..39e969097 100644 --- a/src/bgfx_shader.sh +++ b/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 diff --git a/src/glimports.h b/src/glimports.h index 5e55a2b9a..b72b9ead0 100644 --- a/src/glimports.h +++ b/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); diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 0c1a9a7aa..e3ecbbd04 100644 --- a/src/renderer_d3d11.cpp +++ b/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; diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index ff3cffb0e..8c171d237 100644 --- a/src/renderer_d3d9.cpp +++ b/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 ); diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 51e7f96fa..54549b181 100644 --- a/src/renderer_gl.cpp +++ b/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 { diff --git a/src/renderer_gl.h b/src/renderer_gl.h index 26dd24e84..8ca1b7f69 100644 --- a/src/renderer_gl.h +++ b/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 diff --git a/tools/shaderc/shaderc.cpp b/tools/shaderc/shaderc.cpp index 29cfa8fdf..e9a561664 100644 --- a/tools/shaderc/shaderc.cpp +++ b/tools/shaderc/shaderc.cpp @@ -127,6 +127,7 @@ static const char* s_EXT_shadow_samplers[] = { "shadow2D", "shadow2DProj", + "sampler2DShadow", NULL };