From f440f160f9402b90e9af64b0e69f06a5e6274edf Mon Sep 17 00:00:00 2001 From: bkaradzic Date: Thu, 10 Oct 2013 18:29:57 -0700 Subject: [PATCH] Exposed renderer capabilities. --- README.md | 1 - examples/05-instancing/instancing.cpp | 106 +++++++++------- examples/06-bump/bump.cpp | 118 ++++++++++++------ examples/06-bump/vs_bump.sc | 16 +-- examples/06-bump/vs_bump_instanced.sc | 43 +++++++ examples/runtime/shaders/dx11/vs_bump.bin | Bin 2880 -> 2806 bytes .../shaders/dx11/vs_bump_instanced.bin | Bin 0 -> 2880 bytes examples/runtime/shaders/dx9/vs_bump.bin | Bin 1083 -> 1089 bytes .../runtime/shaders/dx9/vs_bump_instanced.bin | Bin 0 -> 1083 bytes examples/runtime/shaders/gles/vs_bump.bin | Bin 1773 -> 1596 bytes .../shaders/gles/vs_bump_instanced.bin | Bin 0 -> 1773 bytes examples/runtime/shaders/glsl/vs_bump.bin | Bin 1734 -> 1557 bytes .../shaders/glsl/vs_bump_instanced.bin | Bin 0 -> 1734 bytes include/bgfx.h | 42 +++++++ src/bgfx.cpp | 28 ++++- src/bgfx_p.h | 1 + src/renderer_d3d11.cpp | 12 ++ src/renderer_d3d9.cpp | 14 +++ src/renderer_gl.cpp | 22 +++- 19 files changed, 305 insertions(+), 98 deletions(-) create mode 100644 examples/06-bump/vs_bump_instanced.sc create mode 100644 examples/runtime/shaders/dx11/vs_bump_instanced.bin create mode 100644 examples/runtime/shaders/dx9/vs_bump_instanced.bin create mode 100644 examples/runtime/shaders/gles/vs_bump_instanced.bin create mode 100644 examples/runtime/shaders/glsl/vs_bump_instanced.bin diff --git a/README.md b/README.md index 19b2d7a5..2293ec94 100644 --- a/README.md +++ b/README.md @@ -291,7 +291,6 @@ Todo - DX11: MSAA. - Fullscreen mode. - ETC2, PVRTC1/2 decoding fallback for targets that don't support it natively. - - Capabilities flags for user to have idea what features are available. Contact ------- diff --git a/examples/05-instancing/instancing.cpp b/examples/05-instancing/instancing.cpp index ab69c517..91a6b623 100644 --- a/examples/05-instancing/instancing.cpp +++ b/examples/05-instancing/instancing.cpp @@ -113,9 +113,12 @@ int _main_(int /*_argc*/, char** /*_argv*/) , 0 ); + // Get renderer capabilities info. + const bgfx::Caps* caps = bgfx::getCaps(); + // Setup root path for binary shaders. Shader binaries are different // for each renderer. - switch (bgfx::getRendererType() ) + switch (caps->rendererType) { default: case bgfx::RendererType::Direct3D9: @@ -195,59 +198,70 @@ int _main_(int /*_argc*/, char** /*_argv*/) bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Geometry instancing."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); - float at[3] = { 0.0f, 0.0f, 0.0f }; - float eye[3] = { 0.0f, 0.0f, -35.0f }; - - float view[16]; - float proj[16]; - mtxLookAt(view, eye, at); - mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); - - // Set view and projection matrix for view 0. - bgfx::setViewTransform(0, view, proj); - - const uint16_t instanceStride = 80; - const bgfx::InstanceDataBuffer* idb = bgfx::allocInstanceDataBuffer(121, instanceStride); - if (NULL != idb) + // Check if instancing is supported. + if (0 == (BGFX_CAPS_INSTANCING & caps->supported) ) { - uint8_t* data = idb->data; + // When instancing is not supported by GPU, implement alternative + // code path that doesn't use instancing. + bool blink = uint32_t(time*3.0f)&1; + bgfx::dbgTextPrintf(0, 5, blink ? 0x1f : 0x01, " Instancing is not supported by GPU. "); + } + else + { + float at[3] = { 0.0f, 0.0f, 0.0f }; + float eye[3] = { 0.0f, 0.0f, -35.0f }; + + float view[16]; + float proj[16]; + mtxLookAt(view, eye, at); + mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); - // Write instance data for 11x11 cubes. - for (uint32_t yy = 0; yy < 11; ++yy) + // Set view and projection matrix for view 0. + bgfx::setViewTransform(0, view, proj); + + const uint16_t instanceStride = 80; + const bgfx::InstanceDataBuffer* idb = bgfx::allocInstanceDataBuffer(121, instanceStride); + if (NULL != idb) { - for (uint32_t xx = 0; xx < 11; ++xx) + uint8_t* data = idb->data; + + // Write instance data for 11x11 cubes. + for (uint32_t yy = 0; yy < 11; ++yy) { - float* mtx = (float*)data; - mtxRotateXY(mtx, time + xx*0.21f, time + yy*0.37f); - mtx[12] = -15.0f + float(xx)*3.0f; - mtx[13] = -15.0f + float(yy)*3.0f; - mtx[14] = 0.0f; + for (uint32_t xx = 0; xx < 11; ++xx) + { + float* mtx = (float*)data; + mtxRotateXY(mtx, time + xx*0.21f, time + yy*0.37f); + mtx[12] = -15.0f + float(xx)*3.0f; + mtx[13] = -15.0f + float(yy)*3.0f; + mtx[14] = 0.0f; - float* color = (float*)&data[64]; - color[0] = sin(time+float(xx)/11.0f)*0.5f+0.5f; - color[1] = cos(time+float(yy)/11.0f)*0.5f+0.5f; - color[2] = sin(time*3.0f)*0.5f+0.5f; - color[3] = 1.0f; + float* color = (float*)&data[64]; + color[0] = sin(time+float(xx)/11.0f)*0.5f+0.5f; + color[1] = cos(time+float(yy)/11.0f)*0.5f+0.5f; + color[2] = sin(time*3.0f)*0.5f+0.5f; + color[3] = 1.0f; - data += instanceStride; + data += instanceStride; + } } + + // Set vertex and fragment shaders. + bgfx::setProgram(program); + + // Set vertex and index buffer. + bgfx::setVertexBuffer(vbh); + bgfx::setIndexBuffer(ibh); + + // Set instance data buffer. + bgfx::setInstanceDataBuffer(idb); + + // Set render states. + bgfx::setState(BGFX_STATE_DEFAULT); + + // Submit primitive for rendering to view 0. + bgfx::submit(0); } - - // Set vertex and fragment shaders. - bgfx::setProgram(program); - - // Set vertex and index buffer. - bgfx::setVertexBuffer(vbh); - bgfx::setIndexBuffer(ibh); - - // Set instance data buffer. - bgfx::setInstanceDataBuffer(idb); - - // Set render states. - bgfx::setState(BGFX_STATE_DEFAULT); - - // Submit primitive for rendering to view 0. - bgfx::submit(0); } // Advance to next frame. Rendering thread will be kicked to diff --git a/examples/06-bump/bump.cpp b/examples/06-bump/bump.cpp index 5af2241f..4a8544fd 100644 --- a/examples/06-bump/bump.cpp +++ b/examples/06-bump/bump.cpp @@ -268,9 +268,14 @@ int _main_(int /*_argc*/, char** /*_argv*/) , 0 ); + // Get renderer capabilities info. + const bgfx::Caps* caps = bgfx::getCaps(); + + bool instancingSupported = 0 != (caps->supported & BGFX_CAPS_INSTANCING); + // Setup root path for binary shaders. Shader binaries are different // for each renderer. - switch (bgfx::getRendererType() ) + switch (caps->rendererType) { default: case bgfx::RendererType::Direct3D9: @@ -320,7 +325,7 @@ int _main_(int /*_argc*/, char** /*_argv*/) bgfx::UniformHandle u_lightRgbInnerR = bgfx::createUniform("u_lightRgbInnerR", bgfx::UniformType::Uniform4fv, numLights); // Load vertex shader. - mem = loadShader("vs_bump"); + mem = loadShader(instancingSupported ? "vs_bump_instanced" : "vs_bump"); bgfx::VertexShaderHandle vsh = bgfx::createVertexShader(mem); // Load fragment shader. @@ -406,50 +411,93 @@ int _main_(int /*_argc*/, char** /*_argv*/) const uint16_t instanceStride = 64; const uint16_t numInstances = 3; - // Write instance data for 3x3 cubes. - for (uint32_t yy = 0; yy < 3; ++yy) + if (instancingSupported) { - const bgfx::InstanceDataBuffer* idb = bgfx::allocInstanceDataBuffer(numInstances, instanceStride); - if (NULL != idb) + // Write instance data for 3x3 cubes. + for (uint32_t yy = 0; yy < 3; ++yy) { - uint8_t* data = idb->data; + const bgfx::InstanceDataBuffer* idb = bgfx::allocInstanceDataBuffer(numInstances, instanceStride); + if (NULL != idb) + { + uint8_t* data = idb->data; + for (uint32_t xx = 0; xx < 3; ++xx) + { + float* mtx = (float*)data; + mtxRotateXY(mtx, time*0.023f + xx*0.21f, time*0.03f + yy*0.37f); + mtx[12] = -3.0f + float(xx)*3.0f; + mtx[13] = -3.0f + float(yy)*3.0f; + mtx[14] = 0.0f; + + data += instanceStride; + } + + // Set instance data buffer. + bgfx::setInstanceDataBuffer(idb, numInstances); + + // Set vertex and fragment shaders. + bgfx::setProgram(program); + + // Set vertex and index buffer. + bgfx::setVertexBuffer(vbh); + bgfx::setIndexBuffer(ibh); + + // Bind textures. + bgfx::setTexture(0, u_texColor, textureColor); + bgfx::setTexture(1, u_texNormal, textureNormal); + + // Set render states. + bgfx::setState(0 + |BGFX_STATE_RGB_WRITE + |BGFX_STATE_ALPHA_WRITE + |BGFX_STATE_DEPTH_WRITE + |BGFX_STATE_DEPTH_TEST_LESS + |BGFX_STATE_MSAA + ); + + // Submit primitive for rendering to view 0. + bgfx::submit(0); + } + } + } + else + { + for (uint32_t yy = 0; yy < 3; ++yy) + { for (uint32_t xx = 0; xx < 3; ++xx) { - float* mtx = (float*)data; + float mtx[16]; mtxRotateXY(mtx, time*0.023f + xx*0.21f, time*0.03f + yy*0.37f); mtx[12] = -3.0f + float(xx)*3.0f; mtx[13] = -3.0f + float(yy)*3.0f; mtx[14] = 0.0f; - data += instanceStride; + // Set transform for draw call. + bgfx::setTransform(mtx); + + // Set vertex and fragment shaders. + bgfx::setProgram(program); + + // Set vertex and index buffer. + bgfx::setVertexBuffer(vbh); + bgfx::setIndexBuffer(ibh); + + // Bind textures. + bgfx::setTexture(0, u_texColor, textureColor); + bgfx::setTexture(1, u_texNormal, textureNormal); + + // Set render states. + bgfx::setState(0 + |BGFX_STATE_RGB_WRITE + |BGFX_STATE_ALPHA_WRITE + |BGFX_STATE_DEPTH_WRITE + |BGFX_STATE_DEPTH_TEST_LESS + |BGFX_STATE_MSAA + ); + + // Submit primitive for rendering to view 0. + bgfx::submit(0); } - - // Set vertex and fragment shaders. - bgfx::setProgram(program); - - // Set vertex and index buffer. - bgfx::setVertexBuffer(vbh); - bgfx::setIndexBuffer(ibh); - - // Set instance data buffer. - bgfx::setInstanceDataBuffer(idb, numInstances); - - // Bind textures. - bgfx::setTexture(0, u_texColor, textureColor); - bgfx::setTexture(1, u_texNormal, textureNormal); - - // Set render states. - bgfx::setState(0 - |BGFX_STATE_RGB_WRITE - |BGFX_STATE_ALPHA_WRITE - |BGFX_STATE_DEPTH_WRITE - |BGFX_STATE_DEPTH_TEST_LESS - |BGFX_STATE_MSAA - ); - - // Submit primitive for rendering to view 0. - bgfx::submit(0); } } diff --git a/examples/06-bump/vs_bump.sc b/examples/06-bump/vs_bump.sc index d93bbdce..0c9a7546 100644 --- a/examples/06-bump/vs_bump.sc +++ b/examples/06-bump/vs_bump.sc @@ -1,4 +1,4 @@ -$input a_position, a_normal, a_tangent, a_texcoord0, i_data0, i_data1, i_data2, i_data3 +$input a_position, a_normal, a_tangent, a_texcoord0 $output v_wpos, v_view, v_normal, v_tangent, v_bitangent, v_texcoord0 /* @@ -10,20 +10,14 @@ $output v_wpos, v_view, v_normal, v_tangent, v_bitangent, v_texcoord0 void main() { - mat4 model; - model[0] = i_data0; - model[1] = i_data1; - model[2] = i_data2; - model[3] = i_data3; - - vec3 wpos = instMul(model, vec4(a_position, 1.0) ).xyz; + vec3 wpos = mul(u_model[0], vec4(a_position, 1.0) ).xyz; gl_Position = mul(u_viewProj, vec4(wpos, 1.0) ); vec4 normal = a_normal * 2.0f - 1.0f; - vec3 wnormal = instMul(model, vec4(normal.xyz, 0.0) ).xyz; + vec3 wnormal = mul(u_model[0], vec4(normal.xyz, 0.0) ).xyz; vec4 tangent = a_tangent * 2.0f - 1.0f; - vec3 wtangent = instMul(model, vec4(tangent.xyz, 0.0) ).xyz; + vec3 wtangent = mul(u_model[0], vec4(tangent.xyz, 0.0) ).xyz; vec3 viewNormal = normalize(mul(u_view, vec4(wnormal, 0.0) ).xyz); vec3 viewTangent = normalize(mul(u_view, vec4(wtangent, 0.0) ).xyz); @@ -33,7 +27,7 @@ void main() v_wpos = wpos; vec3 view = mul(u_view, vec4(wpos, 0.0) ).xyz; - v_view = instMul(view, tbn); + v_view = mul(view, tbn); v_normal = viewNormal; v_tangent = viewTangent; diff --git a/examples/06-bump/vs_bump_instanced.sc b/examples/06-bump/vs_bump_instanced.sc new file mode 100644 index 00000000..d93bbdce --- /dev/null +++ b/examples/06-bump/vs_bump_instanced.sc @@ -0,0 +1,43 @@ +$input a_position, a_normal, a_tangent, a_texcoord0, i_data0, i_data1, i_data2, i_data3 +$output v_wpos, v_view, v_normal, v_tangent, v_bitangent, v_texcoord0 + +/* + * Copyright 2011-2013 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#include "../common/common.sh" + +void main() +{ + mat4 model; + model[0] = i_data0; + model[1] = i_data1; + model[2] = i_data2; + model[3] = i_data3; + + vec3 wpos = instMul(model, vec4(a_position, 1.0) ).xyz; + gl_Position = mul(u_viewProj, vec4(wpos, 1.0) ); + + vec4 normal = a_normal * 2.0f - 1.0f; + vec3 wnormal = instMul(model, vec4(normal.xyz, 0.0) ).xyz; + + vec4 tangent = a_tangent * 2.0f - 1.0f; + vec3 wtangent = instMul(model, vec4(tangent.xyz, 0.0) ).xyz; + + vec3 viewNormal = normalize(mul(u_view, vec4(wnormal, 0.0) ).xyz); + vec3 viewTangent = normalize(mul(u_view, vec4(wtangent, 0.0) ).xyz); + vec3 viewBitangent = cross(viewNormal, viewTangent) * tangent.w; + mat3 tbn = mat3(viewTangent, viewBitangent, viewNormal); + + v_wpos = wpos; + + vec3 view = mul(u_view, vec4(wpos, 0.0) ).xyz; + v_view = instMul(view, tbn); + + v_normal = viewNormal; + v_tangent = viewTangent; + v_bitangent = viewBitangent; + + v_texcoord0 = a_texcoord0; +} diff --git a/examples/runtime/shaders/dx11/vs_bump.bin b/examples/runtime/shaders/dx11/vs_bump.bin index 98bd459826c20d5b7ada5e89e2baa7a6254cf317..1105dc45549fb3749197749b69e86789023b0618 100644 GIT binary patch delta 593 zcmZuuJ4gdT5S`8CzQ)`U63J3%(9l2ADM0B&zTSEjf-$O;r&E06ocd2_m{C^3t_%UrR7QV-RJD(FqhS zV^;n&kl;9PMkl$eukBh@@?@%z@&F{tAG9GoxK9u{s;=@_iwy4<8)n z)tQ%j*ZE;8B*?_o-Q`-UlHh`mq#N#5Z0h~Eue2AmGHe&EMgaumoVWTt>^bKwkgb}B2 zaHMG?PCxE6X2JVHpzx_rHe0sKcS=CGaCp70q+I zl}Jy6ZBzda{js*)y^HB?4^dB;V|rjr-R0b2~Hx@SrDoW8Mwkoebj` NgI;jsP6m%|_79>aP{#lO diff --git a/examples/runtime/shaders/dx11/vs_bump_instanced.bin b/examples/runtime/shaders/dx11/vs_bump_instanced.bin new file mode 100644 index 0000000000000000000000000000000000000000..98bd459826c20d5b7ada5e89e2baa7a6254cf317 GIT binary patch literal 2880 zcmb7_PiSLR6vj`Jv`so<%Ag=3@=y^)DYTA%s)M9$nzqnsN)kc^p{+9+Tgi~2Q?)BC zS;&AOx^W|j3zw5BWHGf!mL(ateh7HZ&{1?16r2*`@}vl z%gc72{V4($d1R^Gd1bqO&5n+a;L5EsGG(ksko7>G4EvYEzO6UdFn%CB5?<0$3U(Oy z@9Vv#eMu{gegL;D#bzJz5LpXCS7B!zC zoHJQHz`avo==cZco+IGsj*kIKz|kGou~@*-!Ply_3v;WsUahY*R;p{(m|I&~Tx(ck zabuxct(B>{s+#YFGt_)j3!x@_Au7SXh_&Pa9@ne`Uk~BbJTCm3Aw14Y`1eCNHD~Wi zaLyudsTn`;eX8Kp3|?<;_Uf8n36+M|X?50@%e5zUxFm1y%Hd0DcjdiE-jd(>ro!$` zCcj?SiHm+LoZQf7q?3np$lrBxcAY$3XCALA-f@)p$8U>x+NX75I8F@o8F7f=_-INe z#*RK8V9%*7d*SQTyf^V%IXfBmamK9RwlU>TOl|)Lsn7@I!ry zpFdW7d^blEpWa{W@;~8r$MHQDa<1H+oIQ=FaodfF;4|<9<-MPN*8S=;M!X_5d#!>j zQ_>^(B%-k_Q_{l@Z}nHdm&}7&+y{N8PoD+9=Jag^E4e`{y@vh<_%r4F;yvzEzx$XJD@%set z&*I=YdV3sluRNI4kSU2c*xOR3BxInshqv4>HPTz^AHJv9sMBqJPeWhg-eRLh=lDH^ zztJ>6UO>Ha)gNaplm zF3G|3AvZ8)11H2goYNj#+6VrFJ+?igS^IZ~djQ`t=i%2e?C`LG`S++2zJuOt`qKN| zcO&fvdmYa(;P|4~2)?m-ZD}5Q?{^<~o|n%XAN2ohlzi(vSNDr;K4qh}wC$mk&1)s@ hi~8HCH|84q(x1@cw~z2&cu%Y)5B&WfaXodoe!byYpU_RGglZUOklEiUFmF;0Q6e7xp1R3v=9;nq6j zHc(;UiwLeWZo{p-np+uSUhFGmJkttpa9Q)TC1G=KjoyZho^ zwzE6h%|;*I?oAij_Wa;*wofqZZw~vzhnxMa!C-*P=Rhk(uVBGPfcxPK^Y1q8(XRt~ zxiBdgt#F&ztZ<7sZsah3seJ46t;eck5U{kIz2~LnU{~0<)|!u8o0#X6TJmKPVVrYT z{8?%gBL_<2z_mSh;W?W1I-OhcszdJ%7_*16kS4@s0jRG~N1Wj~aN)U7r?=F3ysl$? zo$k7hbsev1*0FA*QHNfQ`f2(l&QqXBG4}pAA759!hMrQF;Jg6+8JrV?Kg+oUf52bP z1#zvb{QxQb+|<>6q`N~uK^OYwovH6@et1XM{3zDk<%hGl;YXbO)VkV_;(9(!UF}Dl z`~+R7p*{_M^F6=T?=i$NInM1=?@m(@D9_MSew2jDA@IKzix904Erc+O*35%W3W(d#vj@)Dkg3mtG8Gc)0v zZT#!1GY${toAXC_v3R>$9xUH~A3S`yKG>d2Cxhw7H}CdWgRSM4Z;Q_aHZ@L(;}$0_X>sb(7WZ7Q#n!Q3 zt4aMr`qt}PkJZ;8VD*Y?tX|xf&q-mZA97Me)VBrqLZ6mC%Z#~kL=4QBS7zKNKX({Q z<2Z|O%%?czoUp#kfD85o+lwpdv(f1@o=G=X4fmk?9MDcmuOrTQ?!@z_|x`@85_pj>5=x!d_RMF2LF}r>iJ9|tofA7|CEoz>`9@X%^mkr$1wVz@-C|? G0RI3F?9JT( diff --git a/examples/runtime/shaders/dx9/vs_bump_instanced.bin b/examples/runtime/shaders/dx9/vs_bump_instanced.bin new file mode 100644 index 0000000000000000000000000000000000000000..9b24bdf33730ccada1135c333ed7574267c6277f GIT binary patch literal 1083 zcmZWnv2GJV6r9_;^Aae`2O!~sf;1LRMBxqyMG7M&IHp3f5Ckv+j2sB<<`3=*&=skY zkDyIjzTkxJ6H@1x*}c15g6;Lqn|*KIyl20fZb##@Uw;jHKjw#v{hw=5f*7|$u(Miz zT8n@LcgbE>m(@D9_MSew2jDA@IKzix904Erc+O*35%W3W(d#vj@)Dkg3mtG8Gc)0v zZT#!1GY${toAXC_v3R>$9xUH~A3S`yKG>d2Cxhw7H}CdWgRSM4Z;Q_aHZ@L(;}$0_X>sb(7WZ7Q#n!Q3 zt4aMr`qt}PkJZ;8VD*Y?tX|xf&q-mZA97Me)VBrqLZ6mC%Z#~kL=4QBS7zKNKX({Q z<2Z|O%%?czoUp#kfD85o+lwpdv(f1@o=G=X4fmk?9MDcmuOrTQ?!@z_|x`@85_pj>5=x!d_RMF2LF}r>iJ9|tofA7|CEoz>`9@X%^mkr$1wVz@-C|? G0RI3F?9JT( literal 0 HcmV?d00001 diff --git a/examples/runtime/shaders/gles/vs_bump.bin b/examples/runtime/shaders/gles/vs_bump.bin index 176e23f1d3a5e0aa3e54f56fd91efe5bdd2ee49a..58a60d432f0a5fe7d1166272ae1252a18a306b07 100644 GIT binary patch literal 1596 zcmaJ>Np9OP6m7RU1%Yg&08vCz9t5GwqFr!c%g>a;q`Vnb@N=A=%J`||C| zs39yPgGeP#>$0q}!18Del@=ROfano+0eaKzmHAl?38_+*d_E|l3&R#pCQbdmIArmob2SWm^n(EPl%b@RnMk6w?G(+35-Qw z(9|$OT+cAaC4yW+J?;9)i*RA0y2+-&iw5AT%Mn6|CPYP_iJDJ}qSh`3pUa9YSwmse z+Hu;9%I#Ka>7OqrQy2~W%jvAAZUVqy1wex58OzK+HjRMK$uQ!Zplk(~Ff6fM5nEC0 zvy`$GL%wD_?WbkH8XkO66rU7rZ^~YEFkT;3-40kU@p#shH(fOaQ`Qc?`(KQhPGNro Yql)Wf`20*tI~w%Cg3I~|KOE=Fe;vXBd)`LH>@gYg}#0-zB~knmTuS^Yijhuwl4=%?Ha<@!40iT zR-wB)?G_wsRyFM&?FrA(vFI2*-M7u_ddjd4I?`TPy+s|}WT-1nhvsbr3JMQQ!IRVT zrfJ$T@hpOalX^>QkT&41K^57J;Ahqc5YAineB@Nf$q_3`!b!FcCh_zg9KVBuP>&}? z#4W0cKE0NAn$@AR&%rvK~8Mu7J9gNrnt*4@qgh!86qI z(I?}PMlp~KGv@-(ars2%Tm%81p%(7jU2(4)EHc>*w#o8nm}urCn#n|oSK>@33PUp^ zU`yj9LbswBlj7$N=UhmESiKZ}@KDUc30zEwS@>1Yr#iQEIF=I}OHJHoPE+xUJ#n@dLoJ?o}P>plE9*ap)Sgy7nKF0r-h1HaduD&wtt~XBQ zphC^LiZ9o*tqkM%dcKI6TL%C<2MCBFi_GJb%m}Zk&FG#3&eRR}RXB|Xo4jLV^ORs6d0GOUCX&VRcddq60WSsZRb2$j+#9vi0FyPR0Q;)nWaVSut{h`q$m! YYKUFYzvGTc7VP|2fXRDwe+9vZe;e~S?*IS* diff --git a/examples/runtime/shaders/gles/vs_bump_instanced.bin b/examples/runtime/shaders/gles/vs_bump_instanced.bin new file mode 100644 index 0000000000000000000000000000000000000000..176e23f1d3a5e0aa3e54f56fd91efe5bdd2ee49a GIT binary patch literal 1773 zcmaJ?OK#gR5N)?Q1%Yg&0#QUs{=w+7Xct`s2+&Os2#iHJ3~b3zX!%q0Dm_on(UWxe z6G=(wPJT1<=FN}(@$l{A>d)`LH>@gYg}#0-zB~knmTuS^Yijhuwl4=%?Ha<@!40iT zR-wB)?G_wsRyFM&?FrA(vFI2*-M7u_ddjd4I?`TPy+s|}WT-1nhvsbr3JMQQ!IRVT zrfJ$T@hpOalX^>QkT&41K^57J;Ahqc5YAineB@Nf$q_3`!b!FcCh_zg9KVBuP>&}? z#4W0cKE0NAn$@AR&%rvK~8Mu7J9gNrnt*4@qgh!86qI z(I?}PMlp~KGv@-(ars2%Tm%81p%(7jU2(4)EHc>*w#o8nm}urCn#n|oSK>@33PUp^ zU`yj9LbswBlj7$N=UhmESiKZ}@KDUc30zEwS@>1Yr#iQEIF=I}OHJHoPE+xUJ#n@dLoJ?o}P>plE9*ap)Sgy7nKF0r-h1HaduD&wtt~XBQ zphC^LiZ9o*tqkM%dcKI6TL%C<2MCBFi_GJb%m}Zk&FG#3&eRR}RXB|Xo4jLV^ORs6d0GOUCX&VRcddq60WSsZRb2$j+#9vi0FyPR0Q;)nWaVSut{h`q$m! YYKUFYzvGTc7VP|2fXRDwe+9vZe;e~S?*IS* literal 0 HcmV?d00001 diff --git a/examples/runtime/shaders/glsl/vs_bump.bin b/examples/runtime/shaders/glsl/vs_bump.bin index 92ce52295f099465572b620d0d23ed54781c0c74..280a64fb776fd95a9c26239967b29a972f07d43c 100644 GIT binary patch literal 1557 zcmaJ>%WC5=6zy#N6@qT;ff`G49wv0(WnrM3P>kESK|^8(M{yoyer3LAzGJ?mSF&YY z*`hmfU+0|r(95rlqErMs>Da#?8&~6DLLi)dQr9S z=cfMcb*zH6Xs)8#lD2&3q|MKV`ZzJF5{{8Uq%1G*b=_Qa0l4BuhnykphD_zEt@PjN{?p0S!Vzr&fXEQb_}cT5O)Zm>Sa@nIj3D1IQmki~;}Vrzf}U=D#H|crqN>TZ!3$kr(&Y?Q z$ULO7??}zPq^Prt$@jD}ht?pBIy+AFsKS1wmhts=vBGE)-!4}*bsGQ%Cjb(n$XaIc zSvLYcCyR)0g0eMS!mz}yBDSX3=P+e!hJ1QF-KS-XX&ih}6rU9BZpvMCFiwxE?FOut scsy&$byuxm%DTb#|BEHlGc-3aQrzal=Vw#8(V!0&T+UDUCkXDo0A3086aWAK literal 1734 zcmaJ?OHRWu5QS|{VTnzGM3hO=pDOk&k&xIR6a^Y8qc*8hH~k>4!g)9cCt>`H?Z&W6 z-^{#u^K%~`?k;EFUq4q})oy816G)RF*wyr{Y1d?3vYhOSj#m5owt1iX4D+BX+as-) zq^n*t(iQtnvmJn(!U0qCWYyudY1&2NSU3kO>t$850bZl3ay5WoXdh5A*3y?9tGJw; z&|*=tGMfipJpBWQKX4T4@T8=)i*Rf?x9Kt*ONJKg5oOr#GeREJ*VxbnPJq@VjDnAV z$Z4#bMYSqWApVx0Psua6RfVEJgM+~x|J2~v0OOw-92-Vt1KE0m^DTs<{*L#U5Mq(6 z#}3C6qIPA1AtTB|Q0i~=43&Ixtv%8xMw0W)IR{i+?#Z0fxB`f(DZq*~Rn|oLPJ`EJiLWJyoIVu<7np5DZ!j_R2uw(S)EJ=WsnHUQr-c zTMZxJe_0@>q;>U`fxX_4ia~{na~2;@2U8h9d^#NY%#8yAjspfnkwM1sUS!1A)MT{J z0Wx{ReHB)t(I)O#+Z?6YlelHAl!wXp7b{TU;F7^UD3BNBE;@q4lj_93far`oCsQBf oVlozx$quWh%!m;i)W7ZqmqYA|{vEeWqG0R40!_}N`xyimzluUEE&u=k diff --git a/examples/runtime/shaders/glsl/vs_bump_instanced.bin b/examples/runtime/shaders/glsl/vs_bump_instanced.bin new file mode 100644 index 0000000000000000000000000000000000000000..92ce52295f099465572b620d0d23ed54781c0c74 GIT binary patch literal 1734 zcmaJ?OHRWu5QS|{VTnzGM3hO=pDOk&k&xIR6a^Y8qc*8hH~k>4!g)9cCt>`H?Z&W6 z-^{#u^K%~`?k;EFUq4q})oy816G)RF*wyr{Y1d?3vYhOSj#m5owt1iX4D+BX+as-) zq^n*t(iQtnvmJn(!U0qCWYyudY1&2NSU3kO>t$850bZl3ay5WoXdh5A*3y?9tGJw; z&|*=tGMfipJpBWQKX4T4@T8=)i*Rf?x9Kt*ONJKg5oOr#GeREJ*VxbnPJq@VjDnAV z$Z4#bMYSqWApVx0Psua6RfVEJgM+~x|J2~v0OOw-92-Vt1KE0m^DTs<{*L#U5Mq(6 z#}3C6qIPA1AtTB|Q0i~=43&Ixtv%8xMw0W)IR{i+?#Z0fxB`f(DZq*~Rn|oLPJ`EJiLWJyoIVu<7np5DZ!j_R2uw(S)EJ=WsnHUQr-c zTMZxJe_0@>q;>U`fxX_4ia~{na~2;@2U8h9d^#NY%#8yAjspfnkwM1sUS!1A)MT{J z0Wx{ReHB)t(I)O#+Z?6YlelHAl!wXp7b{TU;F7^UD3BNBE;@q4lj_93far`oCsQBf oVlozx$quWh%!m;i)W7ZqmqYA|{vEeWqG0R40!_}N`xyimzluUEE&u=k literal 0 HcmV?d00001 diff --git a/include/bgfx.h b/include/bgfx.h index 756cf2ef..e858efa4 100644 --- a/include/bgfx.h +++ b/include/bgfx.h @@ -226,6 +226,25 @@ #define BGFX_RESET_VSYNC UINT32_C(0x00000080) #define BGFX_RESET_CAPTURE UINT32_C(0x00000100) +/// +#define BGFX_CAPS_TEXTURE_FORMAT_BC1 UINT64_C(0x0000000000000001) +#define BGFX_CAPS_TEXTURE_FORMAT_BC2 UINT64_C(0x0000000000000002) +#define BGFX_CAPS_TEXTURE_FORMAT_BC3 UINT64_C(0x0000000000000004) +#define BGFX_CAPS_TEXTURE_FORMAT_BC4 UINT64_C(0x0000000000000008) +#define BGFX_CAPS_TEXTURE_FORMAT_BC5 UINT64_C(0x0000000000000010) +#define BGFX_CAPS_TEXTURE_FORMAT_ETC1 UINT64_C(0x0000000000000020) +#define BGFX_CAPS_TEXTURE_FORMAT_ETC2 UINT64_C(0x0000000000000040) +#define BGFX_CAPS_TEXTURE_FORMAT_ETC2A UINT64_C(0x0000000000000080) +#define BGFX_CAPS_TEXTURE_FORMAT_ETC2A1 UINT64_C(0x0000000000000100) +#define BGFX_CAPS_TEXTURE_FORMAT_PTC12 UINT64_C(0x0000000000000200) +#define BGFX_CAPS_TEXTURE_FORMAT_PTC14 UINT64_C(0x0000000000000400) +#define BGFX_CAPS_TEXTURE_FORMAT_PTC14A UINT64_C(0x0000000000000800) +#define BGFX_CAPS_TEXTURE_FORMAT_PTC12A UINT64_C(0x0000000000001000) +#define BGFX_CAPS_TEXTURE_FORMAT_PTC22 UINT64_C(0x0000000000002000) +#define BGFX_CAPS_TEXTURE_FORMAT_PTC24 UINT64_C(0x0000000000004000) +#define BGFX_CAPS_TEXTURE_3D UINT64_C(0x0000000000010000) +#define BGFX_CAPS_INSTANCING UINT64_C(0x0000000000020000) + /// #define BGFX_HANDLE(_name) \ struct _name { uint16_t idx; }; \ @@ -419,6 +438,26 @@ namespace bgfx uint32_t size; }; + /// Renderer capabilities. + struct Caps + { + /// Renderer backend type. + RendererType::Enum rendererType; + + /// Supported functionality, it includes emulated functionality. + /// Checking supported and not emulated will give functionality + /// natively supported by renderer. + uint64_t supported; + + /// Emulated functionality. For example some texture compression + /// modes are not natively supported by all renderers. The library + /// internally decompresses texture into supported format. + uint64_t emulated; + + /// Maximum texture size. + uint16_t maxTextureSize; + }; + struct TransientIndexBuffer { uint8_t* data; @@ -568,6 +607,9 @@ namespace bgfx /// singlethreaded renderer this call does frame rendering. void frame(); + /// Returns renderer capabilities. + const Caps* getCaps(); + /// Allocate buffer to pass to bgfx calls. Data will be freed inside bgfx. const Memory* alloc(uint32_t _size); diff --git a/src/bgfx.cpp b/src/bgfx.cpp index e6b8a967..bd2c2eab 100755 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -10,7 +10,9 @@ namespace bgfx #define BGFX_MAIN_THREAD_MAGIC 0x78666762 #if BGFX_CONFIG_MULTITHREADED && !BX_PLATFORM_OSX && !BX_PLATFORM_IOS -# define BGFX_CHECK_MAIN_THREAD() BX_CHECK(BGFX_MAIN_THREAD_MAGIC == s_threadIndex, "Must be called from main thread.") +# define BGFX_CHECK_MAIN_THREAD() \ + BX_CHECK(NULL != s_ctx, "Library is not initialized yet."); \ + BX_CHECK(BGFX_MAIN_THREAD_MAGIC == s_threadIndex, "Must be called from main thread.") # define BGFX_CHECK_RENDER_THREAD() BX_CHECK(BGFX_MAIN_THREAD_MAGIC != s_threadIndex, "Must be called from render thread.") #else # define BGFX_CHECK_MAIN_THREAD() @@ -189,6 +191,8 @@ namespace bgfx CallbackI* g_callback = NULL; bx::ReallocatorI* g_allocator = NULL; + Caps g_caps; + static BX_THREAD uint32_t s_threadIndex = 0; static Context* s_ctx = NULL; @@ -619,6 +623,12 @@ namespace bgfx bx::radixSort64(m_sortKeys, s_ctx->m_tempKeys, m_sortValues, s_ctx->m_tempValues, m_num); } + const Caps* getCaps() + { + BGFX_CHECK_MAIN_THREAD(); + return &g_caps; + } + RendererType::Enum getRendererType() { #if BGFX_CONFIG_RENDERER_DIRECT3D9 @@ -640,6 +650,20 @@ namespace bgfx { BX_TRACE("Init..."); + memset(&g_caps, 0, sizeof(g_caps) ); + g_caps.rendererType = getRendererType(); + g_caps.emulated = 0 + | BGFX_CAPS_TEXTURE_FORMAT_BC1 + | BGFX_CAPS_TEXTURE_FORMAT_BC2 + | BGFX_CAPS_TEXTURE_FORMAT_BC3 + | BGFX_CAPS_TEXTURE_FORMAT_BC4 + | BGFX_CAPS_TEXTURE_FORMAT_BC5 + | BGFX_CAPS_TEXTURE_FORMAT_ETC1 + | BGFX_CAPS_TEXTURE_FORMAT_ETC2 + | BGFX_CAPS_TEXTURE_FORMAT_ETC2A + | BGFX_CAPS_TEXTURE_FORMAT_ETC2A1 + ; + if (NULL != _allocator) { g_allocator = _allocator; @@ -1696,6 +1720,7 @@ namespace bgfx const InstanceDataBuffer* allocInstanceDataBuffer(uint32_t _num, uint16_t _stride) { BGFX_CHECK_MAIN_THREAD(); + BX_CHECK(0 != (g_caps.supported & BGFX_CAPS_INSTANCING), "Instancing is not supported! Use bgfx::getCaps to check backend renderer capabilities."); BX_CHECK(0 < _num, "Requesting 0 instanced data vertices."); return s_ctx->allocInstanceDataBuffer(_num, _stride); } @@ -1823,6 +1848,7 @@ namespace bgfx TextureHandle createTexture3D(uint16_t _width, uint16_t _height, uint16_t _depth, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem) { BGFX_CHECK_MAIN_THREAD(); + BX_CHECK(0 != (g_caps.supported & BGFX_CAPS_TEXTURE_3D), "Texture3D is not supported! Use bgfx::getCaps to check backend renderer capabilities."); #if BGFX_CONFIG_DEBUG if (NULL != _mem) diff --git a/src/bgfx_p.h b/src/bgfx_p.h index da436945..275ce6c6 100755 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -227,6 +227,7 @@ namespace bgfx extern const uint32_t g_uniformTypeSize[UniformType::Count+1]; extern CallbackI* g_callback; extern bx::ReallocatorI* g_allocator; + extern Caps g_caps; void release(const Memory* _mem); const char* getAttribName(Attrib::Enum _attr); diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 87271f56..44fa4286 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -478,6 +478,18 @@ namespace bgfx m_uniformReg.add(getPredefinedUniformName(PredefinedUniform::Enum(ii) ), &m_predefinedUniforms[ii]); } + g_caps.emulated &= ~( 0 + | BGFX_CAPS_TEXTURE_FORMAT_BC1 + | BGFX_CAPS_TEXTURE_FORMAT_BC2 + | BGFX_CAPS_TEXTURE_FORMAT_BC3 + | BGFX_CAPS_TEXTURE_FORMAT_BC4 + ); + g_caps.supported |= ( 0 + | BGFX_CAPS_INSTANCING + | BGFX_CAPS_TEXTURE_3D + ); + g_caps.maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; + postReset(); } diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index 330714b8..d33de628 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -409,6 +409,14 @@ namespace bgfx BX_TRACE("Max fragment shader 2.0 instr. slots: %d", m_caps.PS20Caps.NumInstructionSlots); BX_TRACE("Max fragment shader 3.0 instr. slots: %d", m_caps.MaxPixelShader30InstructionSlots); + g_caps.emulated &= ~( 0 + | BGFX_CAPS_TEXTURE_FORMAT_BC1 + | BGFX_CAPS_TEXTURE_FORMAT_BC2 + | BGFX_CAPS_TEXTURE_FORMAT_BC3 + ); + g_caps.supported |= BGFX_CAPS_TEXTURE_3D; + g_caps.maxTextureSize = bx::uint32_min(m_caps.MaxTextureWidth, m_caps.MaxTextureHeight); + #if BGFX_CONFIG_RENDERER_USE_EXTENSIONS BX_TRACE("Extended formats:"); for (uint32_t ii = 0; ii < ExtendedFormat::Count; ++ii) @@ -434,6 +442,12 @@ namespace bgfx s_textureFormat[TextureFormat::BC4].m_fmt = s_extendedFormats[ExtendedFormat::Ati1].m_supported ? D3DFMT_ATI1 : D3DFMT_UNKNOWN; s_textureFormat[TextureFormat::BC5].m_fmt = s_extendedFormats[ExtendedFormat::Ati2].m_supported ? D3DFMT_ATI2 : D3DFMT_UNKNOWN; + + g_caps.emulated &= ~( 0 + | (D3DFMT_UNKNOWN != s_textureFormat[TextureFormat::BC4].m_fmt ? BGFX_CAPS_TEXTURE_FORMAT_BC4 : 0) + | (D3DFMT_UNKNOWN != s_textureFormat[TextureFormat::BC5].m_fmt ? BGFX_CAPS_TEXTURE_FORMAT_BC5 : 0) + ); + g_caps.supported |= m_instancing ? BGFX_CAPS_INSTANCING : 0; #endif // BGFX_CONFIG_RENDERER_USE_EXTENSIONS uint32_t index = 1; diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index b4100f5a..ad2b8069 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -2210,8 +2210,7 @@ namespace bgfx glGetIntegerv(_pname, &result); GLenum err = glGetError(); BX_WARN(0 == err, "glGetIntegerv(0x%04x, ...) failed with GL error: 0x%04x.", _pname, err); - BX_UNUSED(err); - return result; + return 0 == err ? result : 0; } void Context::rendererInit() @@ -2370,7 +2369,8 @@ namespace bgfx s_textureFormat[TextureFormat::BC4].m_supported = bc45Supported; s_textureFormat[TextureFormat::BC5].m_supported = bc45Supported; - s_textureFormat[TextureFormat::ETC1].m_supported = s_extension[Extension::OES_compressed_ETC1_RGB8_texture].m_supported; + bool etc1Supported = s_extension[Extension::OES_compressed_ETC1_RGB8_texture].m_supported; + s_textureFormat[TextureFormat::ETC1].m_supported = etc1Supported; bool etc2Supported = !!BGFX_CONFIG_RENDERER_OPENGLES3 || s_extension[Extension::ARB_ES3_compatibility].m_supported @@ -2398,6 +2398,17 @@ namespace bgfx s_textureFormat[TextureFormat::PTC22].m_supported = ptc2Supported; s_textureFormat[TextureFormat::PTC24].m_supported = ptc2Supported; + g_caps.emulated &= ~( 0 + | bc123Supported ? BGFX_CAPS_TEXTURE_FORMAT_BC1|BGFX_CAPS_TEXTURE_FORMAT_BC2|BGFX_CAPS_TEXTURE_FORMAT_BC3 : 0 + | bc45Supported ? BGFX_CAPS_TEXTURE_FORMAT_BC4|BGFX_CAPS_TEXTURE_FORMAT_BC5 : 0 + | etc1Supported ? BGFX_CAPS_TEXTURE_FORMAT_ETC1 : 0 + | etc2Supported ? BGFX_CAPS_TEXTURE_FORMAT_ETC2|BGFX_CAPS_TEXTURE_FORMAT_ETC2A|BGFX_CAPS_TEXTURE_FORMAT_ETC2A1 : 0 + | ptc1Supported ? BGFX_CAPS_TEXTURE_FORMAT_PTC12|BGFX_CAPS_TEXTURE_FORMAT_PTC14|BGFX_CAPS_TEXTURE_FORMAT_PTC14A|BGFX_CAPS_TEXTURE_FORMAT_PTC12A : 0 + | ptc2Supported ? BGFX_CAPS_TEXTURE_FORMAT_PTC22|BGFX_CAPS_TEXTURE_FORMAT_PTC24 : 0 + ); + g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3) ? BGFX_CAPS_TEXTURE_3D : 0; + g_caps.maxTextureSize = glGet(GL_MAX_TEXTURE_SIZE); + s_renderCtx->m_vaoSupport = !!BGFX_CONFIG_RENDERER_OPENGLES3 || s_extension[Extension::ARB_vertex_array_object].m_supported || s_extension[Extension::OES_vertex_array_object].m_supported @@ -2485,7 +2496,9 @@ namespace bgfx s_textureFormat[TextureFormat::BC5].m_internalFmt = GL_COMPRESSED_RED_GREEN_RGTC2_EXT; } -#if !BGFX_CONFIG_RENDERER_OPENGLES3 +#if BGFX_CONFIG_RENDERER_OPENGLES3 + g_caps.supported |= BGFX_CAPS_INSTANCING; +#else s_vertexAttribDivisor = stubVertexAttribDivisor; s_drawArraysInstanced = stubDrawArraysInstanced; s_drawElementsInstanced = stubDrawElementsInstanced; @@ -2501,6 +2514,7 @@ namespace bgfx s_vertexAttribDivisor = glVertexAttribDivisor; s_drawArraysInstanced = glDrawArraysInstanced; s_drawElementsInstanced = glDrawElementsInstanced; + g_caps.supported |= BGFX_CAPS_INSTANCING; } } # endif // !BX_PLATFORM_IOS