diff options
author | 2016-08-06 14:20:16 +0200 | |
---|---|---|
committer | 2016-08-06 14:20:16 +0200 | |
commit | 3917850b6197950e5671f4d3b9cb0b9c921b798d (patch) | |
tree | 503b9690868a7c238ba10d73b5c6bece7ca8c338 | |
parent | 057474989c1a92e9e935dbc8cb9d233ba3a4ea3a (diff) |
Update BX and BGFX (nw)
218 files changed, 10997 insertions, 5048 deletions
diff --git a/3rdparty/bgfx/3rdparty/glsl-optimizer/Changelog.md b/3rdparty/bgfx/3rdparty/glsl-optimizer/Changelog.md index 39ce18b2541..92206386f12 100644 --- a/3rdparty/bgfx/3rdparty/glsl-optimizer/Changelog.md +++ b/3rdparty/bgfx/3rdparty/glsl-optimizer/Changelog.md @@ -1,6 +1,23 @@ GLSL optimizer Change Log ========================= +2016 06 +------- + +Fixed: + +* Fixed Metal translation in some cases having wrong precision on constants or constant arrays. + + +2016 05 +------- + +Fixed: + +* Fixed Metal translation in some cases having wrong precision on struct members. +* Fixed Metal translation in some cases emitting struct declarations vs. constant initializers in wrong order. + + 2016 03 ------- diff --git a/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ast_to_hir.cpp b/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ast_to_hir.cpp index c19ca4321ef..1d0fcb37203 100644 --- a/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ast_to_hir.cpp +++ b/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ast_to_hir.cpp @@ -3042,6 +3042,12 @@ process_initializer(ir_variable *var, ast_declaration *decl, ir_dereference *const lhs = new(state) ir_dereference_variable(var); ir_rvalue *rhs = decl->initializer->hir(initializer_instructions, state); + /* Propagate precision qualifier for constant value */ + if (type->qualifier.flags.q.constant) { + ir_constant *constant_value = rhs->constant_expression_value(); + constant_value->set_precision((glsl_precision)type->qualifier.precision); + } + /* Calculate the constant value if this is a const or uniform * declaration. */ diff --git a/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir.cpp b/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir.cpp index 636736e5237..ffb37eed157 100644 --- a/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir.cpp +++ b/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir.cpp @@ -647,8 +647,8 @@ ir_constant::ir_constant() } ir_constant::ir_constant(const struct glsl_type *type, - const ir_constant_data *data) - : ir_rvalue(ir_type_constant, glsl_precision_undefined) + const ir_constant_data *data, glsl_precision precision) + : ir_rvalue(ir_type_constant, precision) { assert((type->base_type >= GLSL_TYPE_UINT) && (type->base_type <= GLSL_TYPE_BOOL)); diff --git a/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir.h b/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir.h index 6d21d0e2e15..953e85e4e86 100644 --- a/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir.h +++ b/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir.h @@ -2161,7 +2161,7 @@ union ir_constant_data { class ir_constant : public ir_rvalue { public: - ir_constant(const struct glsl_type *type, const ir_constant_data *data); + ir_constant(const struct glsl_type *type, const ir_constant_data *data, glsl_precision precision = glsl_precision_undefined); ir_constant(bool b, unsigned vector_elements=1); ir_constant(unsigned int u, unsigned vector_elements=1); ir_constant(int i, unsigned vector_elements=1); diff --git a/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_clone.cpp b/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_clone.cpp index a32a836458d..140e36ff71e 100644 --- a/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_clone.cpp +++ b/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_clone.cpp @@ -330,7 +330,7 @@ ir_constant::clone(void *mem_ctx, struct hash_table *ht) const case GLSL_TYPE_INT: case GLSL_TYPE_FLOAT: case GLSL_TYPE_BOOL: - return new(mem_ctx) ir_constant(this->type, &this->value); + return new(mem_ctx) ir_constant(this->type, &this->value, this->precision); case GLSL_TYPE_STRUCT: { ir_constant *c = new(mem_ctx) ir_constant; @@ -351,6 +351,7 @@ ir_constant::clone(void *mem_ctx, struct hash_table *ht) const ir_constant *c = new(mem_ctx) ir_constant; c->type = this->type; + c->set_precision(this->get_precision()); c->array_elements = ralloc_array(c, ir_constant *, this->type->length); for (unsigned i = 0; i < this->type->length; i++) { c->array_elements[i] = this->array_elements[i]->clone(mem_ctx, NULL); diff --git a/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_print_metal_visitor.cpp b/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_print_metal_visitor.cpp index 9f7071d9564..c7919a4c568 100644 --- a/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_print_metal_visitor.cpp +++ b/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_print_metal_visitor.cpp @@ -99,6 +99,7 @@ struct metal_print_context , inoutStr(ralloc_strdup(buffer, "")) , uniformStr(ralloc_strdup(buffer, "")) , paramsStr(ralloc_strdup(buffer, "")) + , typedeclStr(ralloc_strdup(buffer, "")) , writingParams(false) , matrixCastsDone(false) , matrixConstructorsDone(false) @@ -117,6 +118,7 @@ struct metal_print_context string_buffer inoutStr; string_buffer uniformStr; string_buffer paramsStr; + string_buffer typedeclStr; bool writingParams; bool matrixCastsDone; bool matrixConstructorsDone; @@ -267,7 +269,10 @@ _mesa_print_ir_metal(exec_list *instructions, if (var->data.mode == ir_var_shader_inout) strOut = &ctx.inoutStr; } - + + if (ir->ir_type == ir_type_typedecl) { + strOut = &ctx.typedeclStr; + } ir_print_metal_visitor v (ctx, *strOut, >racker, mode, state); v.loopstate = ls; @@ -293,6 +298,8 @@ _mesa_print_ir_metal(exec_list *instructions, ctx.uniformStr.asprintf_append("};\n"); // emit global array/struct constants + + ctx.prefixStr.asprintf_append("%s", ctx.typedeclStr.c_str()); foreach_in_list_safe(gconst_entry_metal, node, >racker.global_constants) { ir_constant* c = node->ir; @@ -1968,7 +1975,7 @@ ir_print_metal_visitor::visit(ir_typedecl_statement *ir) buffer.asprintf_append (" "); //if (state->es_shader) // buffer.asprintf_append ("%s", get_precision_string(s->fields.structure[j].precision)); //@TODO - print_type(buffer, ir, s->fields.structure[j].type, false); + print_type_precision(buffer, s->fields.structure[j].type, s->fields.structure[j].precision, false); buffer.asprintf_append (" %s", s->fields.structure[j].name); print_type_post(buffer, s->fields.structure[j].type, false); buffer.asprintf_append (";\n"); diff --git a/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/const-precision-inES3.txt b/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/const-precision-inES3.txt new file mode 100644 index 00000000000..a1eb058d651 --- /dev/null +++ b/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/const-precision-inES3.txt @@ -0,0 +1,40 @@ +#version 300 es +#define gl_FragData _glesFragData +layout(location = 0) out mediump vec4 _glesFragData[1]; + +struct v2f { + highp vec4 pos; + mediump vec2 uv; +}; + +struct u2v { + highp vec4 vertex; + mediump vec2 texcoord; +}; + +const mediump vec3[3] ha = vec3[3]( vec3( 1.0, 2.0, 3.0), vec3( 4.0, 5.0, 6.0), vec3( 7.0, 8.0, 9.0)); +const highp vec3[3] fa = vec3[3]( vec3( 11.0, 12.0, 13.0), vec3( 14.0, 15.0, 16.0), vec3( 17.0, 18.0, 19.0)); + +mediump vec4 frag( in v2f i ) { + mediump vec3 h = vec3( 0.0); + highp vec3 f = vec3( 0.0); + highp vec3 p = vec3( i.uv.xy, 1.0); + highp int j = 0; + for ( ; (j < int((i.uv.x * 3.0))); (j++)) { + h += ha[j]; + f += fa[j]; + f += (p * ha[0]); + } + return vec4( h.xy, f.xy); +} + +in mediump vec2 xlv_TEXCOORD0; +void main() { + mediump vec4 xl_retval; + v2f xlt_i; + xlt_i.pos = vec4(0.0); + xlt_i.uv = vec2(xlv_TEXCOORD0); + xl_retval = frag( xlt_i); + gl_FragData[0] = vec4(xl_retval); +} + diff --git a/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/const-precision-outES3.txt b/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/const-precision-outES3.txt new file mode 100644 index 00000000000..6676a2e8857 --- /dev/null +++ b/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/const-precision-outES3.txt @@ -0,0 +1,33 @@ +#version 300 es +layout(location=0) out mediump vec4 _glesFragData[1]; +in mediump vec2 xlv_TEXCOORD0; +void main () +{ + mediump vec4 tmpvar_1; + mediump vec2 tmpvar_2; + tmpvar_2 = xlv_TEXCOORD0; + highp vec3 p_4; + highp vec3 f_5; + mediump vec3 h_6; + h_6 = vec3(0.0, 0.0, 0.0); + f_5 = vec3(0.0, 0.0, 0.0); + mediump vec3 tmpvar_7; + tmpvar_7.z = 1.0; + tmpvar_7.xy = xlv_TEXCOORD0; + p_4 = tmpvar_7; + for (highp int j_3 = 0; j_3 < int((tmpvar_2.x * 3.0)); j_3++) { + h_6 = (h_6 + vec3[3](vec3(1.0, 2.0, 3.0), vec3(4.0, 5.0, 6.0), vec3(7.0, 8.0, 9.0))[j_3]); + f_5 = (f_5 + vec3[3](vec3(11.0, 12.0, 13.0), vec3(14.0, 15.0, 16.0), vec3(17.0, 18.0, 19.0))[j_3]); + f_5 = (f_5 + (p_4 * vec3(1.0, 2.0, 3.0))); + }; + highp vec4 tmpvar_8; + tmpvar_8.xy = h_6.xy; + tmpvar_8.zw = f_5.xy; + tmpvar_1 = tmpvar_8; + _glesFragData[0] = tmpvar_1; +} + + +// stats: 12 alu 0 tex 2 flow +// inputs: 1 +// #0: xlv_TEXCOORD0 (medium float) 2x1 [-1] diff --git a/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/const-precision-outES3Metal.txt b/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/const-precision-outES3Metal.txt new file mode 100644 index 00000000000..78a6ad1bf92 --- /dev/null +++ b/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/const-precision-outES3Metal.txt @@ -0,0 +1,45 @@ +#include <metal_stdlib> +#pragma clang diagnostic ignored "-Wparentheses-equality" +using namespace metal; +constant half3 _xlat_mtl_const1[3] = {float3(1.0, 2.0, 3.0), float3(4.0, 5.0, 6.0), float3(7.0, 8.0, 9.0)}; +constant float3 _xlat_mtl_const2[3] = {float3(11.0, 12.0, 13.0), float3(14.0, 15.0, 16.0), float3(17.0, 18.0, 19.0)}; +struct xlatMtlShaderInput { + half2 xlv_TEXCOORD0; +}; +struct xlatMtlShaderOutput { + half4 _glesFragData_0 [[color(0)]]; +}; +struct xlatMtlShaderUniform { +}; +fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]]) +{ + xlatMtlShaderOutput _mtl_o; + half4 tmpvar_1; + half2 tmpvar_2; + tmpvar_2 = _mtl_i.xlv_TEXCOORD0; + float3 p_4; + float3 f_5; + half3 h_6; + h_6 = half3(float3(0.0, 0.0, 0.0)); + f_5 = float3(0.0, 0.0, 0.0); + half3 tmpvar_7; + tmpvar_7.z = half(1.0); + tmpvar_7.xy = _mtl_i.xlv_TEXCOORD0; + p_4 = float3(tmpvar_7); + for (int j_3 = 0; j_3 < short((tmpvar_2.x * (half)3.0)); j_3++) { + h_6 = (h_6 + _xlat_mtl_const1[j_3]); + f_5 = (f_5 + _xlat_mtl_const2[j_3]); + f_5 = (f_5 + (p_4 * float3(1.0, 2.0, 3.0))); + }; + float4 tmpvar_8; + tmpvar_8.xy = float2(h_6.xy); + tmpvar_8.zw = f_5.xy; + tmpvar_1 = half4(tmpvar_8); + _mtl_o._glesFragData_0 = tmpvar_1; + return _mtl_o; +} + + +// stats: 12 alu 0 tex 2 flow +// inputs: 1 +// #0: xlv_TEXCOORD0 (medium float) 2x1 [-1] diff --git a/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/global-struct-constant-init-metal-inES3.txt b/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/global-struct-constant-init-metal-inES3.txt new file mode 100644 index 00000000000..e6ef84c2bca --- /dev/null +++ b/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/global-struct-constant-init-metal-inES3.txt @@ -0,0 +1,685 @@ +#version 300 es +vec4 xll_texCUBElod(samplerCube s, vec4 coord) { + return textureLod( s, coord.xyz, coord.w); +} +float xll_shadow2D(mediump sampler2DShadow s, vec3 coord) { return texture (s, coord); } +float xll_saturate_f( float x) { + return clamp( x, 0.0, 1.0); +} +vec2 xll_saturate_vf2( vec2 x) { + return clamp( x, 0.0, 1.0); +} +vec3 xll_saturate_vf3( vec3 x) { + return clamp( x, 0.0, 1.0); +} +vec4 xll_saturate_vf4( vec4 x) { + return clamp( x, 0.0, 1.0); +} +mat2 xll_saturate_mf2x2(mat2 m) { + return mat2( clamp(m[0], 0.0, 1.0), clamp(m[1], 0.0, 1.0)); +} +mat3 xll_saturate_mf3x3(mat3 m) { + return mat3( clamp(m[0], 0.0, 1.0), clamp(m[1], 0.0, 1.0), clamp(m[2], 0.0, 1.0)); +} +mat4 xll_saturate_mf4x4(mat4 m) { + return mat4( clamp(m[0], 0.0, 1.0), clamp(m[1], 0.0, 1.0), clamp(m[2], 0.0, 1.0), clamp(m[3], 0.0, 1.0)); +} + +struct v2f_vertex_lit { + highp vec2 uv; + lowp vec4 diff; + lowp vec4 spec; +}; + +struct v2f_img { + highp vec4 pos; + mediump vec2 uv; +}; + +struct appdata_img { + highp vec4 vertex; + mediump vec2 texcoord; +}; + +struct Unity_GlossyEnvironmentData { + mediump float roughness; + mediump vec3 reflUVW; +}; + +struct UnityLight { + mediump vec3 color; + mediump vec3 dir; + mediump float ndotl; +}; + +struct UnityIndirect { + mediump vec3 diffuse; + mediump vec3 specular; +}; + +struct UnityGI { + UnityLight light; + UnityIndirect indirect; +}; + +struct UnityGIInput { + UnityLight light; + highp vec3 worldPos; + mediump vec3 worldViewDir; + mediump float atten; + mediump vec3 ambient; + mediump vec4 lightmapUV; + highp vec4 boxMax[2]; + highp vec4 boxMin[2]; + highp vec4 probePosition[2]; + highp vec4 probeHDR[2]; +}; + +struct SurfaceOutputStandard { + lowp vec3 Albedo; + lowp vec3 Normal; + mediump vec3 Emission; + mediump float Metallic; + mediump float Smoothness; + mediump float Occlusion; + lowp float Alpha; +}; + +struct SurfaceOutputStandardSpecular { + lowp vec3 Albedo; + lowp vec3 Specular; + lowp vec3 Normal; + mediump vec3 Emission; + mediump float Smoothness; + mediump float Occlusion; + lowp float Alpha; +}; + +struct VertexInput { + highp vec4 vertex; + mediump vec3 normal; + highp vec2 uv0; + highp vec2 uv1; +}; + +struct FragmentCommonData { + mediump vec3 diffColor; + mediump vec3 specColor; + mediump float oneMinusReflectivity; + mediump float oneMinusRoughness; + mediump vec3 normalWorld; + mediump vec3 eyeVec; + mediump vec3 posWorld; + mediump float alpha; +}; + +struct VertexOutputForwardBase { + highp vec4 pos; + highp vec4 tex; + mediump vec3 eyeVec; + mediump vec4 tangentToWorldAndParallax[3]; + mediump vec4 ambientOrLightmapUV; + mediump vec4 _ShadowCoord; +}; + +struct VertexOutputForwardAdd { + highp vec4 pos; + highp vec4 tex; + mediump vec3 eyeVec; + mediump vec4 tangentToWorldAndLightDir[3]; + mediump vec4 _ShadowCoord; +}; + +struct VertexOutputDeferred { + highp vec4 pos; + highp vec4 tex; + mediump vec3 eyeVec; + mediump vec4 tangentToWorldAndParallax[3]; + mediump vec4 ambientOrLightmapUV; +}; + +struct VertexInput_VC { + highp vec4 vertex; + lowp vec4 color; + mediump vec3 normal; + highp vec2 uv0; + highp vec2 uv1; +}; + +struct VertexOutputForwardBase_VC { + highp vec4 pos; + highp vec4 tex; + mediump vec3 eyeVec; + mediump vec4 tangentToWorldAndParallax[3]; + mediump vec4 ambientOrLightmapUV; + mediump vec4 _ShadowCoord; + lowp vec4 color; +}; + +struct VertexOutputDeferred_VC { + highp vec4 pos; + lowp vec4 color; + highp vec4 tex; + mediump vec3 eyeVec; + mediump vec4 tangentToWorldAndParallax[3]; + mediump vec4 ambientOrLightmapUV; +}; + +uniform highp vec4 _Time; +uniform highp vec4 _SinTime; +uniform highp vec4 _CosTime; +uniform highp vec4 unity_DeltaTime; + +uniform highp vec3 _WorldSpaceCameraPos; + +uniform highp vec4 _ProjectionParams; + +uniform highp vec4 _ScreenParams; + +uniform highp vec4 _ZBufferParams; + +uniform highp vec4 unity_OrthoParams; + +uniform highp vec4 unity_CameraWorldClipPlanes[6]; + +uniform highp mat4 unity_CameraProjection; +uniform highp mat4 unity_CameraInvProjection; + +uniform mediump vec4 _WorldSpaceLightPos0; + +uniform highp vec4 _LightPositionRange; +uniform highp vec4 unity_4LightPosX0; +uniform highp vec4 unity_4LightPosY0; + +uniform highp vec4 unity_4LightPosZ0; +uniform mediump vec4 unity_4LightAtten0; +uniform mediump vec4 unity_LightColor[8]; + +uniform highp vec4 unity_LightPosition[8]; + +uniform mediump vec4 unity_LightAtten[8]; +uniform highp vec4 unity_SpotDirection[8]; + +uniform mediump vec4 unity_SHAr; +uniform mediump vec4 unity_SHAg; +uniform mediump vec4 unity_SHAb; +uniform mediump vec4 unity_SHBr; + +uniform mediump vec4 unity_SHBg; +uniform mediump vec4 unity_SHBb; +uniform mediump vec4 unity_SHC; + +uniform mediump vec3 unity_LightColor0; +uniform mediump vec3 unity_LightColor1; +uniform mediump vec3 unity_LightColor2; +uniform mediump vec3 unity_LightColor3; + +uniform highp vec4 unity_ShadowSplitSpheres[4]; +uniform highp vec4 unity_ShadowSplitSqRadii; +uniform highp vec4 unity_LightShadowBias; +uniform highp vec4 _LightSplitsNear; + +uniform highp vec4 _LightSplitsFar; +uniform highp mat4 unity_World2Shadow[4]; +uniform mediump vec4 _LightShadowData; +uniform highp vec4 unity_ShadowFadeCenterAndType; + +uniform highp mat4 glstate_matrix_mvp; +uniform highp mat4 glstate_matrix_modelview0; +uniform highp mat4 glstate_matrix_invtrans_modelview0; + +uniform highp mat4 _Object2World; +uniform highp mat4 _World2Object; +uniform highp vec4 unity_LODFade; +uniform highp vec4 unity_WorldTransformParams; + +uniform highp mat4 glstate_matrix_transpose_modelview0; + +uniform highp mat4 glstate_matrix_projection; +uniform lowp vec4 glstate_lightmodel_ambient; + +uniform highp mat4 unity_MatrixV; +uniform highp mat4 unity_MatrixVP; + +uniform lowp vec4 unity_AmbientSky; +uniform lowp vec4 unity_AmbientEquator; +uniform lowp vec4 unity_AmbientGround; + +uniform lowp vec4 unity_FogColor; + +uniform highp vec4 unity_FogParams; + +uniform sampler2D unity_Lightmap; +uniform sampler2D unity_LightmapInd; + +uniform sampler2D unity_DynamicLightmap; +uniform sampler2D unity_DynamicDirectionality; +uniform sampler2D unity_DynamicNormal; + +uniform highp vec4 unity_LightmapST; +uniform highp vec4 unity_DynamicLightmapST; + +uniform samplerCube unity_SpecCube0; +uniform samplerCube unity_SpecCube1; + +uniform highp vec4 unity_SpecCube0_BoxMax; +uniform highp vec4 unity_SpecCube0_BoxMin; +uniform highp vec4 unity_SpecCube0_ProbePosition; +uniform mediump vec4 unity_SpecCube0_HDR; + +uniform highp vec4 unity_SpecCube1_BoxMax; +uniform highp vec4 unity_SpecCube1_BoxMin; +uniform highp vec4 unity_SpecCube1_ProbePosition; +uniform mediump vec4 unity_SpecCube1_HDR; + +uniform lowp vec4 unity_ColorSpaceGrey; +uniform lowp vec4 unity_ColorSpaceDouble; +uniform mediump vec4 unity_ColorSpaceDielectricSpec; +uniform mediump vec4 unity_ColorSpaceLuminance; + +uniform mediump vec4 unity_Lightmap_HDR; + +uniform mediump vec4 unity_DynamicLightmap_HDR; + +uniform lowp vec4 _LightColor0; +uniform lowp vec4 _SpecColor; + +uniform sampler2D unity_NHxRoughness; + +uniform mediump vec4 _Color; +uniform mediump float _Cutoff; +uniform sampler2D _MainTex; + +uniform highp vec4 _MainTex_ST; +uniform sampler2D _DetailAlbedoMap; +uniform highp vec4 _DetailAlbedoMap_ST; + +uniform sampler2D _BumpMap; +uniform mediump float _BumpScale; +uniform sampler2D _DetailMask; + +uniform sampler2D _DetailNormalMap; +uniform mediump float _DetailNormalMapScale; +uniform sampler2D _SpecGlossMap; + +uniform sampler2D _MetallicGlossMap; +uniform mediump float _Metallic; +uniform mediump float _Glossiness; + +uniform sampler2D _OcclusionMap; +uniform mediump float _OcclusionStrength; +uniform sampler2D _ParallaxMap; + +uniform mediump float _Parallax; +uniform mediump float _UVSec; +uniform mediump vec4 _EmissionColor; + +uniform sampler2D _EmissionMap; + +uniform lowp sampler2DShadow _ShadowMapTexture; + +mediump float DotClamped( in mediump vec3 a, in mediump vec3 b ) { + return max( 0.0, dot( a, b)); +} + +mediump float BlinnTerm( in mediump vec3 normal, in mediump vec3 halfDir ) { + return DotClamped( normal, halfDir); +} + +mediump float Pow4( in mediump float x ) { + return (((x * x) * x) * x); +} + +mediump vec3 FresnelLerpFast( in mediump vec3 F0, in mediump vec3 F90, in mediump float cosA ) { + mediump float t = Pow4( (1.0 - cosA)); + return mix( F0, F90, vec3( t)); +} + +bool IsGammaSpace( ) { + return true; +} + +mediump float RoughnessToSpecPower( in mediump float roughness ) { + + mediump float m = max( 0.0001, (roughness * roughness)); + mediump float n = ((2.0 / (m * m)) - 2.0); + n = max( n, 0.0001); + + return n; +} + +mediump vec3 Unity_SafeNormalize( in mediump vec3 inVec ) { + mediump float dp3 = max( 0.001, dot( inVec, inVec)); + return (inVec * inversesqrt(dp3)); +} + +mediump vec4 BRDF2_Unity_PBS( in mediump vec3 diffColor, in mediump vec3 specColor, in mediump float oneMinusReflectivity, in mediump float oneMinusRoughness, in mediump vec3 normal, in mediump vec3 viewDir, in UnityLight light, in UnityIndirect gi ) { + mediump vec3 halfDir = Unity_SafeNormalize( (light.dir + viewDir)); + + mediump float nl = light.ndotl; + mediump float nh = BlinnTerm( normal, halfDir); + mediump float nv = DotClamped( normal, viewDir); + mediump float lh = DotClamped( light.dir, halfDir); + + mediump float roughness = (1.0 - oneMinusRoughness); + mediump float specularPower = RoughnessToSpecPower( roughness); + + mediump float invV = (((lh * lh) * oneMinusRoughness) + (roughness * roughness)); + mediump float invF = lh; + mediump float specular = (((specularPower + 1.0) * pow( nh, specularPower)) / (((8.0 * invV) * invF) + 0.0001)); + if (IsGammaSpace( )){ + specular = sqrt(max( 0.0001, specular)); + } + + mediump float realRoughness = (roughness * roughness); + mediump float surfaceReduction = (( IsGammaSpace( ) ) ? ( 0.28 ) : ( (0.6 - (0.08 * roughness)) )); + + surfaceReduction = (1.0 - ((realRoughness * roughness) * surfaceReduction)); + + mediump float grazingTerm = xll_saturate_f((oneMinusRoughness + (1.0 - oneMinusReflectivity))); + mediump vec3 color = (((((diffColor + (specular * specColor)) * light.color) * nl) + (gi.diffuse * diffColor)) + ((surfaceReduction * gi.specular) * FresnelLerpFast( specColor, vec3( grazingTerm), nv))); + + return vec4( color, 1.0); +} + +mediump vec3 BRDF_Unity_Indirect( in mediump vec3 baseColor, in mediump vec3 specColor, in mediump float oneMinusReflectivity, in mediump float oneMinusRoughness, in mediump vec3 normal, in mediump vec3 viewDir, in mediump float occlusion, in UnityGI gi ) { + mediump vec3 c = vec3( 0.0); + + return c; +} + +mediump vec3 Emission( in highp vec2 uv ) { + return vec3( 0.0); +} + +void ResetUnityLight( out UnityLight outLight ) { + + outLight.color = vec3( 0.0); + outLight.dir = vec3( 0.0); + outLight.ndotl = 0.0; +} + +void ResetUnityGI( out UnityGI outGI ) { + ResetUnityLight( outGI.light); + + outGI.indirect.diffuse = vec3( 0.0); + outGI.indirect.specular = vec3( 0.0); +} + +mediump vec3 LinearToGammaSpace( in mediump vec3 linRGB ) { + linRGB = max( linRGB, vec3( 0.0, 0.0, 0.0)); + + return max( ((1.055 * pow( linRGB, vec3( 0.4166667))) - 0.055), vec3( 0.0)); +} + +mediump vec3 SHEvalLinearL0L1( in mediump vec4 normal ) { + mediump vec3 x; + + x.x = dot( unity_SHAr, normal); + x.y = dot( unity_SHAg, normal); + x.z = dot( unity_SHAb, normal); + + return x; +} + +mediump vec3 ShadeSHPerPixel( in mediump vec3 normal, in mediump vec3 ambient ) { + + mediump vec3 ambient_contrib = vec3( 0.0); + + ambient_contrib = SHEvalLinearL0L1( vec4( normal, 1.0)); + ambient = max( vec3( 0.0, 0.0, 0.0), (ambient + ambient_contrib)); + if (IsGammaSpace( )){ + ambient = LinearToGammaSpace( ambient); + } + + return ambient; +} + +UnityGI UnityGI_Base( in UnityGIInput data, in mediump float occlusion, in mediump vec3 normalWorld ) { + UnityGI o_gi; + ResetUnityGI( o_gi); + + o_gi.light = data.light; + o_gi.light.color *= data.atten; + + o_gi.indirect.diffuse = ShadeSHPerPixel( normalWorld, data.ambient); + + o_gi.indirect.diffuse *= occlusion; + return o_gi; +} + +UnityGI UnityGlobalIllumination( in UnityGIInput data, in mediump float occlusion, in mediump vec3 normalWorld ) { + return UnityGI_Base( data, occlusion, normalWorld); +} + +mediump vec3 DecodeHDR( in mediump vec4 data, in mediump vec4 decodeInstructions ) { + return ((decodeInstructions.x * data.w) * data.xyz); +} + +mediump vec3 DecodeHDR_NoLinearSupportInSM2( in mediump vec4 data, in mediump vec4 decodeInstructions ) { + return DecodeHDR( data, decodeInstructions); +} + +mediump vec3 Unity_GlossyEnvironment( in samplerCube tex, in mediump vec4 hdr, in Unity_GlossyEnvironmentData glossIn ) { + + mediump float roughness = glossIn.roughness; + + roughness = (roughness * (1.7 - (0.7 * roughness))); + + mediump float mip = (roughness * 6.0); + mediump vec4 rgbm = xll_texCUBElod( tex, vec4( glossIn.reflUVW, mip)); + return DecodeHDR_NoLinearSupportInSM2( rgbm, hdr); +} + +mediump vec3 UnityGI_IndirectSpecular( in UnityGIInput data, in mediump float occlusion, in mediump vec3 normalWorld, in Unity_GlossyEnvironmentData glossIn ) { + mediump vec3 specular; + mediump vec3 env0 = Unity_GlossyEnvironment( unity_SpecCube0, data.probeHDR[0], glossIn); + specular = env0; + return (specular * occlusion); +} + +UnityGI UnityGlobalIllumination( in UnityGIInput data, in mediump float occlusion, in mediump vec3 normalWorld, in Unity_GlossyEnvironmentData glossIn ) { + UnityGI o_gi = UnityGI_Base( data, occlusion, normalWorld); + o_gi.indirect.specular = UnityGI_IndirectSpecular( data, occlusion, normalWorld, glossIn); + return o_gi; +} + +UnityGI FragmentGI( in FragmentCommonData s, in mediump float occlusion, in mediump vec4 i_ambientOrLightmapUV, in mediump float atten, in UnityLight light, in bool reflections ) { + UnityGIInput d; + d.light = light; + + d.worldPos = s.posWorld; + d.worldViewDir = (-s.eyeVec); + d.atten = atten; + + d.ambient = i_ambientOrLightmapUV.xyz; + d.lightmapUV = vec4( 0.0); + d.boxMax[0] = unity_SpecCube0_BoxMax; + + d.boxMin[0] = unity_SpecCube0_BoxMin; + d.probePosition[0] = unity_SpecCube0_ProbePosition; + d.probeHDR[0] = unity_SpecCube0_HDR; + + d.boxMax[1] = unity_SpecCube1_BoxMax; + d.boxMin[1] = unity_SpecCube1_BoxMin; + d.probePosition[1] = unity_SpecCube1_ProbePosition; + d.probeHDR[1] = unity_SpecCube1_HDR; + + if (reflections){ + Unity_GlossyEnvironmentData g; + g.roughness = (1.0 - s.oneMinusRoughness); + + g.reflUVW = reflect( s.eyeVec, s.normalWorld); + return UnityGlobalIllumination( d, occlusion, s.normalWorld, g); + } + else{ + return UnityGlobalIllumination( d, occlusion, s.normalWorld); + } +} + +UnityGI FragmentGI( in highp vec3 posWorld, in mediump float occlusion, in mediump vec4 i_ambientOrLightmapUV, in mediump float atten, in mediump float oneMinusRoughness, in mediump vec3 normalWorld, in mediump vec3 eyeVec, in UnityLight light, in bool reflections ) { + FragmentCommonData s = FragmentCommonData(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), 0.0, 0.0, vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), 0.0); + s.oneMinusRoughness = oneMinusRoughness; + s.normalWorld = normalWorld; + s.eyeVec = eyeVec; + s.posWorld = posWorld; + return FragmentGI( s, occlusion, i_ambientOrLightmapUV, atten, light, reflections); +} + +UnityGI FragmentGI( in highp vec3 posWorld, in mediump float occlusion, in mediump vec4 i_ambientOrLightmapUV, in mediump float atten, in mediump float oneMinusRoughness, in mediump vec3 normalWorld, in mediump vec3 eyeVec, in UnityLight light ) { + return FragmentGI( posWorld, occlusion, i_ambientOrLightmapUV, atten, oneMinusRoughness, normalWorld, eyeVec, light, true); +} + +mediump float Alpha( in highp vec2 uv ) { + return (texture( _MainTex, uv).w * _Color.w); +} + +mediump vec3 Albedo( in highp vec4 texcoords ) { + mediump vec3 albedo = (_Color.xyz * texture( _MainTex, texcoords.xy).xyz); + return albedo; +} + +mediump float OneMinusReflectivityFromMetallic( in mediump float metallic ) { + mediump float oneMinusDielectricSpec = unity_ColorSpaceDielectricSpec.w; + return (oneMinusDielectricSpec - (metallic * oneMinusDielectricSpec)); +} + +mediump vec3 DiffuseAndSpecularFromMetallic( in mediump vec3 albedo, in mediump float metallic, out mediump vec3 specColor, out mediump float oneMinusReflectivity ) { + specColor = mix( unity_ColorSpaceDielectricSpec.xyz, albedo, vec3( metallic)); + oneMinusReflectivity = OneMinusReflectivityFromMetallic( metallic); + + return (albedo * oneMinusReflectivity); +} + +mediump vec2 MetallicGloss( in highp vec2 uv ) { + mediump vec2 mg; + + mg = vec2( _Metallic, _Glossiness); + return mg; +} + +FragmentCommonData MetallicSetup( in highp vec4 i_tex ) { + mediump vec2 metallicGloss = MetallicGloss( i_tex.xy); + mediump float metallic = metallicGloss.x; + + mediump float oneMinusRoughness = metallicGloss.y; + mediump float oneMinusReflectivity; + mediump vec3 specColor; + + mediump vec3 diffColor = DiffuseAndSpecularFromMetallic( Albedo( i_tex), metallic, specColor, oneMinusReflectivity); + FragmentCommonData o = FragmentCommonData(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), 0.0, 0.0, vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), 0.0); + o.diffColor = diffColor; + + o.specColor = specColor; + o.oneMinusReflectivity = oneMinusReflectivity; + o.oneMinusRoughness = oneMinusRoughness; + return o; +} + +mediump vec3 NormalizePerPixelNormal( in mediump vec3 n ) { + return normalize(n); +} + +highp vec4 Parallax( in highp vec4 texcoords, in mediump vec3 viewDir ) { + return texcoords; +} + +mediump vec3 PerPixelWorldNormal( in highp vec4 i_tex, in mediump vec4 tangentToWorld[3] ) { + mediump vec3 normalWorld = normalize(tangentToWorld[2].xyz); + return normalWorld; +} + +mediump vec3 PreMultiplyAlpha( in mediump vec3 diffColor, in mediump float alpha, in mediump float oneMinusReflectivity, out mediump float outModifiedAlpha ) { + outModifiedAlpha = alpha; + return diffColor; +} + +FragmentCommonData FragmentSetup( in highp vec4 i_tex, in mediump vec3 i_eyeVec, in mediump vec3 i_viewDirForParallax, in mediump vec4 tangentToWorld[3], in mediump vec3 i_posWorld ) { + i_tex = Parallax( i_tex, i_viewDirForParallax); + + mediump float alpha = Alpha( i_tex.xy); + + FragmentCommonData o = MetallicSetup( i_tex); + o.normalWorld = PerPixelWorldNormal( i_tex, tangentToWorld); + o.eyeVec = NormalizePerPixelNormal( i_eyeVec); + o.posWorld = i_posWorld; + + o.diffColor = PreMultiplyAlpha( o.diffColor, alpha, o.oneMinusReflectivity, o.alpha); + return o; +} + +mediump float LambertTerm( in mediump vec3 normal, in mediump vec3 lightDir ) { + return DotClamped( normal, lightDir); +} + +UnityLight MainLight( in mediump vec3 normalWorld ) { + UnityLight l; + + l.color = _LightColor0.xyz; + l.dir = _WorldSpaceLightPos0.xyz; + l.ndotl = LambertTerm( normalWorld, l.dir); + + return l; +} + +mediump float LerpOneTo( in mediump float b, in mediump float t ) { + mediump float oneMinusT = (1.0 - t); + return (oneMinusT + (b * t)); +} + +mediump float Occlusion( in highp vec2 uv ) { + mediump float occ = texture( _OcclusionMap, uv).y; + return LerpOneTo( occ, _OcclusionStrength); +} + +mediump vec4 OutputForward( in mediump vec4 xlat_varoutput, in mediump float alphaFromSurface ) { + xlat_varoutput.w = 1.0; + return xlat_varoutput; +} + +lowp float unitySampleShadow( in mediump vec4 shadowCoord ) { + lowp float shadow = xll_shadow2D( _ShadowMapTexture, shadowCoord.xyz.xyz); + shadow = (_LightShadowData.x + (shadow * (1.0 - _LightShadowData.x))); + return shadow; +} + +mediump vec4 fragForwardBase_VC( in VertexOutputForwardBase_VC i ) { + FragmentCommonData s = FragmentSetup( i.tex, i.eyeVec, vec3( 0.0, 0.0, 0.0), i.tangentToWorldAndParallax, vec3( 0.0, 0.0, 0.0)); + UnityLight mainLight = MainLight( s.normalWorld); + + mediump float atten = unitySampleShadow( i._ShadowCoord); + mediump float occlusion = Occlusion( i.tex.xy); + UnityGI gi = FragmentGI( s.posWorld, occlusion, i.ambientOrLightmapUV, atten, s.oneMinusRoughness, s.normalWorld, s.eyeVec, mainLight); + + mediump vec4 c = BRDF2_Unity_PBS( s.diffColor, s.specColor, s.oneMinusReflectivity, s.oneMinusRoughness, s.normalWorld, (-s.eyeVec), gi.light, gi.indirect); + c *= i.color; + + c.xyz += BRDF_Unity_Indirect( s.diffColor, s.specColor, s.oneMinusReflectivity, s.oneMinusRoughness, s.normalWorld, (-s.eyeVec), occlusion, gi); + c.xyz += Emission( i.tex.xy); + + return OutputForward( c, (s.alpha * i.color.w)); +} +in highp vec4 xlv_TEXCOORD0; +in mediump vec3 xlv_TEXCOORD1; +in mediump vec4 xlv_TEXCOORD2; +in mediump vec4 xlv_TEXCOORD2_1; +in mediump vec4 xlv_TEXCOORD2_2; +in mediump vec4 xlv_TEXCOORD5; +in mediump vec4 xlv_TEXCOORD6; +in lowp vec4 xlv_COLOR; +out lowp vec4 FragData [1]; +void main() { + mediump vec4 xl_retval; + VertexOutputForwardBase_VC xlt_i; + xlt_i.pos = vec4(0.0); + xlt_i.tex = vec4(xlv_TEXCOORD0); + xlt_i.eyeVec = vec3(xlv_TEXCOORD1); + xlt_i.tangentToWorldAndParallax[0] = vec4(xlv_TEXCOORD2); + xlt_i.tangentToWorldAndParallax[1] = vec4(xlv_TEXCOORD2_1); + xlt_i.tangentToWorldAndParallax[2] = vec4(xlv_TEXCOORD2_2); + xlt_i.ambientOrLightmapUV = vec4(xlv_TEXCOORD5); + xlt_i._ShadowCoord = vec4(xlv_TEXCOORD6); + xlt_i.color = vec4(xlv_COLOR); + xl_retval = fragForwardBase_VC( xlt_i); + FragData[0] = vec4(xl_retval); +} diff --git a/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/global-struct-constant-init-metal-outES3.txt b/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/global-struct-constant-init-metal-outES3.txt new file mode 100644 index 00000000000..3c6034fa529 --- /dev/null +++ b/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/global-struct-constant-init-metal-outES3.txt @@ -0,0 +1,187 @@ +#version 300 es +struct FragmentCommonData { + mediump vec3 diffColor; + mediump vec3 specColor; + mediump float oneMinusReflectivity; + mediump float oneMinusRoughness; + mediump vec3 normalWorld; + mediump vec3 eyeVec; + mediump vec3 posWorld; + mediump float alpha; +}; +uniform mediump vec4 _WorldSpaceLightPos0; +uniform mediump vec4 unity_SHAr; +uniform mediump vec4 unity_SHAg; +uniform mediump vec4 unity_SHAb; +uniform mediump vec4 _LightShadowData; +uniform lowp samplerCube unity_SpecCube0; +uniform mediump vec4 unity_SpecCube0_HDR; +uniform mediump vec4 unity_ColorSpaceDielectricSpec; +uniform lowp vec4 _LightColor0; +uniform mediump vec4 _Color; +uniform sampler2D _MainTex; +uniform mediump float _Metallic; +uniform mediump float _Glossiness; +uniform sampler2D _OcclusionMap; +uniform mediump float _OcclusionStrength; +uniform lowp sampler2DShadow _ShadowMapTexture; +in highp vec4 xlv_TEXCOORD0; +in mediump vec3 xlv_TEXCOORD1; +in mediump vec4 xlv_TEXCOORD2_2; +in mediump vec4 xlv_TEXCOORD5; +in mediump vec4 xlv_TEXCOORD6; +in lowp vec4 xlv_COLOR; +out lowp vec4 FragData[1]; +void main () +{ + mediump vec4 c_1; + mediump float atten_2; + lowp vec4 tmpvar_3; + tmpvar_3 = texture (_MainTex, xlv_TEXCOORD0.xy); + mediump vec2 tmpvar_4; + tmpvar_4.x = _Metallic; + tmpvar_4.y = _Glossiness; + mediump vec3 tmpvar_5; + tmpvar_5 = (_Color.xyz * tmpvar_3.xyz); + mediump vec3 tmpvar_6; + mediump vec3 tmpvar_7; + tmpvar_7 = mix (unity_ColorSpaceDielectricSpec.xyz, tmpvar_5, vec3(_Metallic)); + mediump float tmpvar_8; + tmpvar_8 = (unity_ColorSpaceDielectricSpec.w - (_Metallic * unity_ColorSpaceDielectricSpec.w)); + tmpvar_6 = (tmpvar_5 * tmpvar_8); + mediump vec3 tmpvar_9; + tmpvar_9 = normalize(xlv_TEXCOORD2_2.xyz); + mediump vec3 tmpvar_10; + tmpvar_10 = normalize(xlv_TEXCOORD1); + mediump vec3 tmpvar_11; + tmpvar_11 = _LightColor0.xyz; + lowp float shadow_12; + mediump float tmpvar_13; + tmpvar_13 = texture (_ShadowMapTexture, xlv_TEXCOORD6.xyz); + lowp float tmpvar_14; + tmpvar_14 = tmpvar_13; + shadow_12 = (_LightShadowData.x + (tmpvar_14 * (1.0 - _LightShadowData.x))); + atten_2 = shadow_12; + mediump float occ_15; + lowp float tmpvar_16; + tmpvar_16 = texture (_OcclusionMap, xlv_TEXCOORD0.xy).y; + occ_15 = tmpvar_16; + mediump float tmpvar_17; + tmpvar_17 = ((1.0 - _OcclusionStrength) + (occ_15 * _OcclusionStrength)); + FragmentCommonData s_18; + s_18 = FragmentCommonData(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), 0.0, 0.0, vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), 0.0); + s_18.oneMinusRoughness = tmpvar_4.y; + s_18.normalWorld = tmpvar_9; + s_18.eyeVec = tmpvar_10; + s_18.posWorld = vec3(0.0, 0.0, 0.0); + mediump vec3 tmpvar_19; + mediump vec3 tmpvar_20; + tmpvar_19 = s_18.normalWorld; + tmpvar_20 = s_18.eyeVec; + highp vec4 tmpvar_21; + tmpvar_21 = unity_SpecCube0_HDR; + mediump float tmpvar_22; + tmpvar_22 = (1.0 - s_18.oneMinusRoughness); + mediump vec3 tmpvar_23; + tmpvar_23 = (tmpvar_20 - (2.0 * ( + dot (tmpvar_19, tmpvar_20) + * tmpvar_19))); + mediump vec4 tmpvar_24; + tmpvar_24.w = 1.0; + tmpvar_24.xyz = tmpvar_19; + mediump vec3 x_25; + x_25.x = dot (unity_SHAr, tmpvar_24); + x_25.y = dot (unity_SHAg, tmpvar_24); + x_25.z = dot (unity_SHAb, tmpvar_24); + mediump vec4 hdr_26; + hdr_26 = tmpvar_21; + mediump vec4 tmpvar_27; + tmpvar_27.xyz = tmpvar_23; + tmpvar_27.w = ((tmpvar_22 * (1.7 - + (0.7 * tmpvar_22) + )) * 6.0); + lowp vec4 tmpvar_28; + tmpvar_28 = textureLod (unity_SpecCube0, tmpvar_23, tmpvar_27.w); + mediump vec4 tmpvar_29; + tmpvar_29 = tmpvar_28; + mediump vec3 viewDir_30; + viewDir_30 = -(tmpvar_10); + mediump vec3 tmpvar_31; + mediump vec3 inVec_32; + inVec_32 = (_WorldSpaceLightPos0.xyz + viewDir_30); + tmpvar_31 = (inVec_32 * inversesqrt(max (0.001, + dot (inVec_32, inVec_32) + ))); + mediump float tmpvar_33; + tmpvar_33 = max (0.0, dot (_WorldSpaceLightPos0.xyz, tmpvar_31)); + mediump float tmpvar_34; + tmpvar_34 = (1.0 - _Glossiness); + mediump float tmpvar_35; + tmpvar_35 = max (0.0001, (tmpvar_34 * tmpvar_34)); + mediump float tmpvar_36; + tmpvar_36 = max (((2.0 / + (tmpvar_35 * tmpvar_35) + ) - 2.0), 0.0001); + mediump float x_37; + x_37 = (1.0 - max (0.0, dot (tmpvar_9, viewDir_30))); + mediump vec4 tmpvar_38; + tmpvar_38.w = 1.0; + tmpvar_38.xyz = ((( + ((tmpvar_6 + (sqrt( + max (0.0001, (((tmpvar_36 + 1.0) * pow ( + max (0.0, dot (tmpvar_9, tmpvar_31)) + , tmpvar_36)) / (( + (8.0 * (((tmpvar_33 * tmpvar_33) * _Glossiness) + (tmpvar_34 * tmpvar_34))) + * tmpvar_33) + 0.0001))) + ) * tmpvar_7)) * (tmpvar_11 * atten_2)) + * + max (0.0, dot (tmpvar_9, _WorldSpaceLightPos0.xyz)) + ) + ( + (max (((1.055 * + pow (max (vec3(0.0, 0.0, 0.0), (xlv_TEXCOORD5.xyz + x_25)), vec3(0.4166667, 0.4166667, 0.4166667)) + ) - 0.055), vec3(0.0, 0.0, 0.0)) * tmpvar_17) + * tmpvar_6)) + (( + (1.0 - ((tmpvar_34 * tmpvar_34) * (tmpvar_34 * 0.28))) + * + (((hdr_26.x * tmpvar_29.w) * tmpvar_29.xyz) * tmpvar_17) + ) * mix (tmpvar_7, vec3( + clamp ((_Glossiness + (1.0 - tmpvar_8)), 0.0, 1.0) + ), vec3( + ((x_37 * x_37) * (x_37 * x_37)) + )))); + c_1 = (tmpvar_38 * xlv_COLOR); + c_1.xyz = c_1.xyz; + c_1.xyz = c_1.xyz; + mediump vec4 xlat_varoutput_39; + xlat_varoutput_39.xyz = c_1.xyz; + xlat_varoutput_39.w = 1.0; + FragData[0] = xlat_varoutput_39; +} + + +// stats: 97 alu 4 tex 0 flow +// inputs: 6 +// #0: xlv_TEXCOORD0 (high float) 4x1 [-1] +// #1: xlv_TEXCOORD1 (medium float) 3x1 [-1] +// #2: xlv_TEXCOORD2_2 (medium float) 4x1 [-1] +// #3: xlv_TEXCOORD5 (medium float) 4x1 [-1] +// #4: xlv_TEXCOORD6 (medium float) 4x1 [-1] +// #5: xlv_COLOR (low float) 4x1 [-1] +// uniforms: 12 (total size: 0) +// #0: _WorldSpaceLightPos0 (medium float) 4x1 [-1] +// #1: unity_SHAr (medium float) 4x1 [-1] +// #2: unity_SHAg (medium float) 4x1 [-1] +// #3: unity_SHAb (medium float) 4x1 [-1] +// #4: _LightShadowData (medium float) 4x1 [-1] +// #5: unity_SpecCube0_HDR (medium float) 4x1 [-1] +// #6: unity_ColorSpaceDielectricSpec (medium float) 4x1 [-1] +// #7: _LightColor0 (low float) 4x1 [-1] +// #8: _Color (medium float) 4x1 [-1] +// #9: _Metallic (medium float) 1x1 [-1] +// #10: _Glossiness (medium float) 1x1 [-1] +// #11: _OcclusionStrength (medium float) 1x1 [-1] +// textures: 4 +// #0: unity_SpecCube0 (low cube) 0x0 [-1] +// #1: _MainTex (low 2d) 0x0 [-1] +// #2: _OcclusionMap (low 2d) 0x0 [-1] +// #3: _ShadowMapTexture (low 2dshadow) 0x0 [-1] diff --git a/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/global-struct-constant-init-metal-outES3Metal.txt b/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/global-struct-constant-init-metal-outES3Metal.txt new file mode 100644 index 00000000000..ca71d1d321c --- /dev/null +++ b/3rdparty/bgfx/3rdparty/glsl-optimizer/tests/fragment/global-struct-constant-init-metal-outES3Metal.txt @@ -0,0 +1,199 @@ +#include <metal_stdlib> +#pragma clang diagnostic ignored "-Wparentheses-equality" +using namespace metal; +constexpr sampler _mtl_xl_shadow_sampler(address::clamp_to_edge, filter::linear, compare_func::less); +struct FragmentCommonData { + half3 diffColor; + half3 specColor; + half oneMinusReflectivity; + half oneMinusRoughness; + half3 normalWorld; + half3 eyeVec; + half3 posWorld; + half alpha; +}; +constant FragmentCommonData _xlat_mtl_const1 = {float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), 0.0, 0.0, float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), 0.0}; +struct xlatMtlShaderInput { + float4 xlv_TEXCOORD0; + half3 xlv_TEXCOORD1; + half4 xlv_TEXCOORD2_2; + half4 xlv_TEXCOORD5; + half4 xlv_TEXCOORD6; + half4 xlv_COLOR; +}; +struct xlatMtlShaderOutput { + half4 FragData_0 [[color(0)]]; +}; +struct xlatMtlShaderUniform { + half4 _WorldSpaceLightPos0; + half4 unity_SHAr; + half4 unity_SHAg; + half4 unity_SHAb; + half4 _LightShadowData; + half4 unity_SpecCube0_HDR; + half4 unity_ColorSpaceDielectricSpec; + half4 _LightColor0; + half4 _Color; + half _Metallic; + half _Glossiness; + half _OcclusionStrength; +}; +fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]] + , texturecube<half> unity_SpecCube0 [[texture(0)]], sampler _mtlsmp_unity_SpecCube0 [[sampler(0)]] + , texture2d<half> _MainTex [[texture(1)]], sampler _mtlsmp__MainTex [[sampler(1)]] + , texture2d<half> _OcclusionMap [[texture(2)]], sampler _mtlsmp__OcclusionMap [[sampler(2)]] + , depth2d<float> _ShadowMapTexture [[texture(3)]], sampler _mtlsmp__ShadowMapTexture [[sampler(3)]]) +{ + xlatMtlShaderOutput _mtl_o; + half4 c_1; + half atten_2; + half4 tmpvar_3; + tmpvar_3 = _MainTex.sample(_mtlsmp__MainTex, (float2)(_mtl_i.xlv_TEXCOORD0.xy)); + half2 tmpvar_4; + tmpvar_4.x = _mtl_u._Metallic; + tmpvar_4.y = _mtl_u._Glossiness; + half3 tmpvar_5; + tmpvar_5 = (_mtl_u._Color.xyz * tmpvar_3.xyz); + half3 tmpvar_6; + half3 tmpvar_7; + tmpvar_7 = mix (_mtl_u.unity_ColorSpaceDielectricSpec.xyz, tmpvar_5, half3(_mtl_u._Metallic)); + half tmpvar_8; + tmpvar_8 = (_mtl_u.unity_ColorSpaceDielectricSpec.w - (_mtl_u._Metallic * _mtl_u.unity_ColorSpaceDielectricSpec.w)); + tmpvar_6 = (tmpvar_5 * tmpvar_8); + half3 tmpvar_9; + tmpvar_9 = normalize(_mtl_i.xlv_TEXCOORD2_2.xyz); + half3 tmpvar_10; + tmpvar_10 = normalize(_mtl_i.xlv_TEXCOORD1); + half3 tmpvar_11; + tmpvar_11 = _mtl_u._LightColor0.xyz; + half shadow_12; + half tmpvar_13; + tmpvar_13 = _ShadowMapTexture.sample_compare(_mtl_xl_shadow_sampler, (float2)(_mtl_i.xlv_TEXCOORD6.xyz).xy, (float)(_mtl_i.xlv_TEXCOORD6.xyz).z); + half tmpvar_14; + tmpvar_14 = tmpvar_13; + shadow_12 = (_mtl_u._LightShadowData.x + (tmpvar_14 * ((half)1.0 - _mtl_u._LightShadowData.x))); + atten_2 = shadow_12; + half occ_15; + half tmpvar_16; + tmpvar_16 = _OcclusionMap.sample(_mtlsmp__OcclusionMap, (float2)(_mtl_i.xlv_TEXCOORD0.xy)).y; + occ_15 = tmpvar_16; + half tmpvar_17; + tmpvar_17 = (((half)1.0 - _mtl_u._OcclusionStrength) + (occ_15 * _mtl_u._OcclusionStrength)); + FragmentCommonData s_18; + s_18 = _xlat_mtl_const1; + s_18.oneMinusRoughness = tmpvar_4.y; + s_18.normalWorld = tmpvar_9; + s_18.eyeVec = tmpvar_10; + s_18.posWorld = half3(float3(0.0, 0.0, 0.0)); + half3 tmpvar_19; + half3 tmpvar_20; + tmpvar_19 = s_18.normalWorld; + tmpvar_20 = s_18.eyeVec; + float4 tmpvar_21; + tmpvar_21 = float4(_mtl_u.unity_SpecCube0_HDR); + half tmpvar_22; + tmpvar_22 = ((half)1.0 - s_18.oneMinusRoughness); + half3 tmpvar_23; + tmpvar_23 = (tmpvar_20 - ((half)2.0 * ( + dot (tmpvar_19, tmpvar_20) + * tmpvar_19))); + half4 tmpvar_24; + tmpvar_24.w = half(1.0); + tmpvar_24.xyz = tmpvar_19; + half3 x_25; + x_25.x = dot (_mtl_u.unity_SHAr, tmpvar_24); + x_25.y = dot (_mtl_u.unity_SHAg, tmpvar_24); + x_25.z = dot (_mtl_u.unity_SHAb, tmpvar_24); + half4 hdr_26; + hdr_26 = half4(tmpvar_21); + half4 tmpvar_27; + tmpvar_27.xyz = tmpvar_23; + tmpvar_27.w = ((tmpvar_22 * ((half)1.7 - + ((half)0.7 * tmpvar_22) + )) * (half)6.0); + half4 tmpvar_28; + tmpvar_28 = unity_SpecCube0.sample(_mtlsmp_unity_SpecCube0, (float3)(tmpvar_23), level(tmpvar_27.w)); + half4 tmpvar_29; + tmpvar_29 = tmpvar_28; + half3 viewDir_30; + viewDir_30 = -(tmpvar_10); + half3 tmpvar_31; + half3 inVec_32; + inVec_32 = (_mtl_u._WorldSpaceLightPos0.xyz + viewDir_30); + tmpvar_31 = (inVec_32 * rsqrt(max ((half)0.001, + dot (inVec_32, inVec_32) + ))); + half tmpvar_33; + tmpvar_33 = max ((half)0.0, dot (_mtl_u._WorldSpaceLightPos0.xyz, tmpvar_31)); + half tmpvar_34; + tmpvar_34 = ((half)1.0 - _mtl_u._Glossiness); + half tmpvar_35; + tmpvar_35 = max ((half)0.0001, (tmpvar_34 * tmpvar_34)); + half tmpvar_36; + tmpvar_36 = max ((((half)2.0 / + (tmpvar_35 * tmpvar_35) + ) - (half)2.0), (half)0.0001); + half x_37; + x_37 = ((half)1.0 - max ((half)0.0, dot (tmpvar_9, viewDir_30))); + half4 tmpvar_38; + tmpvar_38.w = half(1.0); + tmpvar_38.xyz = ((( + ((tmpvar_6 + (sqrt( + max ((half)0.0001, (((tmpvar_36 + (half)1.0) * pow ( + max ((half)0.0, dot (tmpvar_9, tmpvar_31)) + , tmpvar_36)) / (( + ((half)8.0 * (((tmpvar_33 * tmpvar_33) * _mtl_u._Glossiness) + (tmpvar_34 * tmpvar_34))) + * tmpvar_33) + (half)0.0001))) + ) * tmpvar_7)) * (tmpvar_11 * atten_2)) + * + max ((half)0.0, dot (tmpvar_9, _mtl_u._WorldSpaceLightPos0.xyz)) + ) + ( + (max ((((half)1.055 * + pow (max ((half3)float3(0.0, 0.0, 0.0), (_mtl_i.xlv_TEXCOORD5.xyz + x_25)), (half3)float3(0.4166667, 0.4166667, 0.4166667)) + ) - (half)0.055), (half3)float3(0.0, 0.0, 0.0)) * tmpvar_17) + * tmpvar_6)) + (( + ((half)1.0 - ((tmpvar_34 * tmpvar_34) * (tmpvar_34 * (half)0.28))) + * + (((hdr_26.x * tmpvar_29.w) * tmpvar_29.xyz) * tmpvar_17) + ) * mix (tmpvar_7, half3( + clamp ((_mtl_u._Glossiness + ((half)1.0 - tmpvar_8)), (half)0.0, (half)1.0) + ), half3( + ((x_37 * x_37) * (x_37 * x_37)) + )))); + c_1 = (tmpvar_38 * _mtl_i.xlv_COLOR); + c_1.xyz = c_1.xyz; + c_1.xyz = c_1.xyz; + half4 xlat_varoutput_39; + xlat_varoutput_39.xyz = c_1.xyz; + xlat_varoutput_39.w = half(1.0); + _mtl_o.FragData_0 = xlat_varoutput_39; + return _mtl_o; +} + + +// stats: 97 alu 4 tex 0 flow +// inputs: 6 +// #0: xlv_TEXCOORD0 (high float) 4x1 [-1] +// #1: xlv_TEXCOORD1 (medium float) 3x1 [-1] +// #2: xlv_TEXCOORD2_2 (medium float) 4x1 [-1] +// #3: xlv_TEXCOORD5 (medium float) 4x1 [-1] +// #4: xlv_TEXCOORD6 (medium float) 4x1 [-1] +// #5: xlv_COLOR (low float) 4x1 [-1] +// uniforms: 12 (total size: 78) +// #0: _WorldSpaceLightPos0 (medium float) 4x1 [-1] loc 0 +// #1: unity_SHAr (medium float) 4x1 [-1] loc 8 +// #2: unity_SHAg (medium float) 4x1 [-1] loc 16 +// #3: unity_SHAb (medium float) 4x1 [-1] loc 24 +// #4: _LightShadowData (medium float) 4x1 [-1] loc 32 +// #5: unity_SpecCube0_HDR (medium float) 4x1 [-1] loc 40 +// #6: unity_ColorSpaceDielectricSpec (medium float) 4x1 [-1] loc 48 +// #7: _LightColor0 (low float) 4x1 [-1] loc 56 +// #8: _Color (medium float) 4x1 [-1] loc 64 +// #9: _Metallic (medium float) 1x1 [-1] loc 72 +// #10: _Glossiness (medium float) 1x1 [-1] loc 74 +// #11: _OcclusionStrength (medium float) 1x1 [-1] loc 76 +// textures: 4 +// #0: unity_SpecCube0 (low cube) 0x0 [-1] loc 0 +// #1: _MainTex (low 2d) 0x0 [-1] loc 1 +// #2: _OcclusionMap (low 2d) 0x0 [-1] loc 2 +// #3: _ShadowMapTexture (low 2dshadow) 0x0 [-1] loc 3 diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp index 6ae5c798648..e3c3b915d2c 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp @@ -131,11 +131,8 @@ ImGui::NewFrame(); // 3) most of your application code here - ImGui::Begin("My window"); - ImGui::Text("Hello, world."); - ImGui::End(); - MyGameUpdate(); // may use ImGui functions - MyGameRender(); // may use ImGui functions + MyGameUpdate(); // may use any ImGui functions, e.g. ImGui::Begin("My window"); ImGui::Text("Hello, world!"); ImGui::End(); + MyGameRender(); // may use any ImGui functions // 4) render & swap video buffers ImGui::Render(); @@ -153,6 +150,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2016/07/30 (1.50) - SameLine(x) with x>0.0f is now relative to left of column/group if any, and not always to left of window. This was sort of always the intent and hopefully breakage should be minimal. - 2016/05/12 (1.49) - title bar (using ImGuiCol_TitleBg/ImGuiCol_TitleBgActive colors) isn't rendered over a window background (ImGuiCol_WindowBg color) anymore. If your TitleBg/TitleBgActive alpha was 1.0f or you are using the default theme it will not affect you. However if your TitleBg/TitleBgActive alpha was <1.0f you need to tweak your custom theme to readjust for the fact that we don't draw a WindowBg background behind the title bar. @@ -391,10 +389,12 @@ e.g. when displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state differently. experiment and see what makes more sense! Q: How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application? - A: You can read the 'io.WantCaptureXXX' flags in the ImGuiIO structure. Preferably read them after calling ImGui::NewFrame() to avoid those flags lagging by one frame. + A: You can read the 'io.WantCaptureXXX' flags in the ImGuiIO structure. Preferably read them after calling ImGui::NewFrame() to avoid those flags lagging by one frame, but either should be fine. When 'io.WantCaptureMouse' or 'io.WantCaptureKeyboard' flags are set you may want to discard/hide the inputs from the rest of your application. When 'io.WantInputsCharacters' is set to may want to notify your OS to popup an on-screen keyboard, if available. ImGui is tracking dragging and widget activity that may occur outside the boundary of a window, so 'io.WantCaptureMouse' is a more accurate and complete than testing for ImGui::IsMouseHoveringAnyWindow(). + (Advanced note: text input releases focus on Return 'KeyDown', so the following Return 'KeyUp' event that your application receive will typically have 'io.WantcaptureKeyboard=false'. + Depending on your application logic it may or not be inconvenient. You might want to track which key-downs were for ImGui (e.g. with an array of bool) and filter out the corresponding key-ups.) Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) A: Use the font atlas to load the TTF file you want: @@ -460,7 +460,7 @@ - doc: add a proper documentation+regression testing system (#435) - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass. - - window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). + - window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis) (#690) - window: auto-fit feedback loop when user relies on any dynamic layout (window width multiplier, column) appears weird to end-user. clarify. - window: allow resizing of child windows (possibly given min/max for each axis?) - window: background options for child windows, border option (disable rounding) @@ -488,9 +488,11 @@ - input text: flag to disable live update of the user buffer (also applies to float/int text input) - input text: resize behavior - field could stretch when being edited? hover tooltip shows more text? - input text: add ImGuiInputTextFlags_EnterToApply? (off #218) + - input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725) - input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc). - input text multi-line: way to dynamically grow the buffer without forcing the user to initially allocate for worse case (follow up on #200) - input text multi-line: line numbers? status bar? (follow up on #200) + - input text multi-line: behave better when user changes input buffer while editing is active (even though it is illegal behavior). namely, the change of buffer can create a scrollbar glitch (#725) - input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position. - input number: optional range min/max for Input*() functions - input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled) @@ -834,10 +836,7 @@ ImGuiIO::ImGuiIO() // Set OS X style defaults based on __APPLE__ compile time flag #ifdef __APPLE__ - WordMovementUsesAltKey = true; // OS X style: Text editing cursor movement using Alt instead of Ctrl - ShortcutsUseSuperKey = true; // OS X style: Shortcuts using Cmd/Super instead of Ctrl - DoubleClickSelectsWord = true; // OS X style: Double click selects by word instead of selecting whole text - MultiSelectUsesSuperKey = true; // OS X style: Multi-selection in lists uses Cmd/Super instead of Ctrl + OSXBehaviors = true; #endif } @@ -868,7 +867,8 @@ void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars) // HELPERS //----------------------------------------------------------------------------- -#define IM_F32_TO_INT8(_VAL) ((int)((_VAL) * 255.0f + 0.5f)) +#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose +#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255 // Play it nice with Windows users. Notepad in 2015 still doesn't display text data with Unix-style \n. #ifdef _WIN32 @@ -899,6 +899,13 @@ int ImStrnicmp(const char* str1, const char* str2, int count) return d; } +void ImStrncpy(char* dst, const char* src, int count) +{ + if (count < 1) return; + strncpy(dst, src, (size_t)count); + dst[count-1] = 0; +} + char* ImStrdup(const char *str) { size_t len = strlen(str) + 1; @@ -997,7 +1004,6 @@ ImU32 ImHash(const void* data, int data_size, ImU32 seed) // - We don't do 'current += 2; continue;' after handling ### to keep the code smaller. if (c == '#' && current[0] == '#' && current[1] == '#') crc = seed; - crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c]; } } @@ -1189,10 +1195,10 @@ ImVec4 ImGui::ColorConvertU32ToFloat4(ImU32 in) ImU32 ImGui::ColorConvertFloat4ToU32(const ImVec4& in) { ImU32 out; - out = ((ImU32)IM_F32_TO_INT8(ImSaturate(in.x))); - out |= ((ImU32)IM_F32_TO_INT8(ImSaturate(in.y))) << 8; - out |= ((ImU32)IM_F32_TO_INT8(ImSaturate(in.z))) << 16; - out |= ((ImU32)IM_F32_TO_INT8(ImSaturate(in.w))) << 24; + out = ((ImU32)IM_F32_TO_INT8_SAT(in.x)); + out |= ((ImU32)IM_F32_TO_INT8_SAT(in.y)) << 8; + out |= ((ImU32)IM_F32_TO_INT8_SAT(in.z)) << 16; + out |= ((ImU32)IM_F32_TO_INT8_SAT(in.w)) << 24; return out; } @@ -1300,7 +1306,7 @@ void ImGuiStorage::Clear() } // std::lower_bound but without the bullshit -static ImVector<ImGuiStorage::Pair>::iterator LowerBound(ImVector<ImGuiStorage::Pair>& data, ImU32 key) +static ImVector<ImGuiStorage::Pair>::iterator LowerBound(ImVector<ImGuiStorage::Pair>& data, ImGuiID key) { ImVector<ImGuiStorage::Pair>::iterator first = data.begin(); ImVector<ImGuiStorage::Pair>::iterator last = data.end(); @@ -1322,7 +1328,7 @@ static ImVector<ImGuiStorage::Pair>::iterator LowerBound(ImVector<ImGuiStorage:: return first; } -int ImGuiStorage::GetInt(ImU32 key, int default_val) const +int ImGuiStorage::GetInt(ImGuiID key, int default_val) const { ImVector<Pair>::iterator it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key); if (it == Data.end() || it->key != key) @@ -1330,12 +1336,12 @@ int ImGuiStorage::GetInt(ImU32 key, int default_val) const return it->val_i; } -bool ImGuiStorage::GetBool(ImU32 key, bool default_val) const +bool ImGuiStorage::GetBool(ImGuiID key, bool default_val) const { return GetInt(key, default_val ? 1 : 0) != 0; } -float ImGuiStorage::GetFloat(ImU32 key, float default_val) const +float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const { ImVector<Pair>::iterator it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key); if (it == Data.end() || it->key != key) @@ -1382,7 +1388,7 @@ void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) } // FIXME-OPT: Need a way to reuse the result of lower_bound when doing GetInt()/SetInt() - not too bad because it only happens on explicit interaction (maximum one a frame) -void ImGuiStorage::SetInt(ImU32 key, int val) +void ImGuiStorage::SetInt(ImGuiID key, int val) { ImVector<Pair>::iterator it = LowerBound(Data, key); if (it == Data.end() || it->key != key) @@ -1393,12 +1399,12 @@ void ImGuiStorage::SetInt(ImU32 key, int val) it->val_i = val; } -void ImGuiStorage::SetBool(ImU32 key, bool val) +void ImGuiStorage::SetBool(ImGuiID key, bool val) { SetInt(key, val ? 1 : 0); } -void ImGuiStorage::SetFloat(ImU32 key, float val) +void ImGuiStorage::SetFloat(ImGuiID key, float val) { ImVector<Pair>::iterator it = LowerBound(Data, key); if (it == Data.end() || it->key != key) @@ -1409,7 +1415,7 @@ void ImGuiStorage::SetFloat(ImU32 key, float val) it->val_f = val; } -void ImGuiStorage::SetVoidPtr(ImU32 key, void* val) +void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val) { ImVector<Pair>::iterator it = LowerBound(Data, key); if (it == Data.end() || it->key != key) @@ -1435,7 +1441,7 @@ ImGuiTextFilter::ImGuiTextFilter(const char* default_filter) { if (default_filter) { - ImFormatString(InputBuf, IM_ARRAYSIZE(InputBuf), "%s", default_filter); + ImStrncpy(InputBuf, default_filter, IM_ARRAYSIZE(InputBuf)); Build(); } else @@ -1617,12 +1623,14 @@ float ImGuiSimpleColumns::CalcExtraSpace(float avail_w) static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height) { - // Setting those fields so that SetScrollHere() can properly function after the end of our clipper usage. - // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list. + // Set cursor position and a few other things so that SetScrollHere() and Columns() can work when seeking cursor. + // FIXME: It is problematic that we have to do that here, because custom/equivalent end-user code would stumble on the same issue. Consider moving within SetCursorXXX functions? ImGui::SetCursorPosY(pos_y); ImGuiWindow* window = ImGui::GetCurrentWindow(); - window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; - window->DC.PrevLineHeight = (line_height - GImGui->Style.ItemSpacing.y); + window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHere() can properly function after the end of our clipper usage. + window->DC.PrevLineHeight = (line_height - GImGui->Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list. + if (window->DC.ColumnsCount > 1) + window->DC.ColumnsCellMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly } // Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1 @@ -1675,8 +1683,9 @@ bool ImGuiListClipper::Step() if (ItemsCount == 1) { ItemsCount = -1; return false; } float items_height = ImGui::GetCursorPosY() - StartPosY; IM_ASSERT(items_height > 0.0f); // If this triggers, it means Item 0 hasn't moved the cursor vertically - ImGui::SetCursorPosY(StartPosY); // Rewind cursor so we can Begin() again, this time with a known height. - Begin(ItemsCount, items_height); + Begin(ItemsCount-1, items_height); + DisplayStart++; + DisplayEnd++; StepNo = 3; return true; } @@ -1700,7 +1709,7 @@ ImGuiWindow::ImGuiWindow(const char* name) Name = ImStrdup(name); ID = ImHash(name, 0); IDStack.push_back(ID); - MoveID = GetID("#MOVE"); + MoveId = GetID("#MOVE"); Flags = 0; IndexWithinParent = 0; @@ -1719,7 +1728,7 @@ ImGuiWindow::ImGuiWindow(const char* name) Collapsed = false; SkipItems = false; BeginCount = 0; - PopupID = 0; + PopupId = 0; AutoFitFramesX = AutoFitFramesY = -1; AutoFitOnlyGrows = false; AutoPosLastDirection = -1; @@ -1768,6 +1777,12 @@ ImGuiID ImGuiWindow::GetID(const void* ptr) return id; } +ImGuiID ImGuiWindow::GetIDNoKeepAlive(const char* str, const char* str_end) +{ + ImGuiID seed = IDStack.back(); + return ImHash(str, str_end ? (int)(str_end - str) : 0, seed); +} + //----------------------------------------------------------------------------- // Internal API exposed in imgui_internal.h //----------------------------------------------------------------------------- @@ -1844,7 +1859,7 @@ void ImGui::ItemSize(const ImRect& bb, float text_offset_y) bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) { ImGuiWindow* window = GetCurrentWindow(); - window->DC.LastItemID = id ? *id : 0; + window->DC.LastItemId = id ? *id : 0; window->DC.LastItemRect = bb; window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false; if (IsClippedEx(bb, id, false)) @@ -1858,7 +1873,7 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) // So that clicking on items with no active id such as Text() still returns true with IsItemHovered() window->DC.LastItemHoveredRect = true; if (g.HoveredRootWindow == window->RootWindow) - if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdAllowOverlap || (g.ActiveId == window->MoveID)) + if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdAllowOverlap || (g.ActiveId == window->MoveId)) if (IsWindowContentHoverable(window)) window->DC.LastItemHoveredAndUsable = true; } @@ -1950,8 +1965,7 @@ float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x) else if (wrap_pos_x > 0.0f) wrap_pos_x += window->Pos.x - window->Scroll.x; // wrap_pos_x is provided is window local space - const float wrap_width = wrap_pos_x > 0.0f ? ImMax(wrap_pos_x - pos.x, 0.00001f) : 0.0f; - return wrap_width; + return ImMax(wrap_pos_x - pos.x, 1.0f); } //----------------------------------------------------------------------------- @@ -2071,7 +2085,6 @@ void ImGui::NewFrame() g.OverlayDrawList.Clear(); g.OverlayDrawList.PushTextureID(g.IO.Fonts->TexID); g.OverlayDrawList.PushClipRectFullScreen(); - g.OverlayDrawList.AddDrawCmd(); // Mark rendering data as invalid to prevent user who may have a handle on it to use it g.RenderDrawData.Valid = false; @@ -2138,7 +2151,7 @@ void ImGui::NewFrame() { KeepAliveID(g.MovedWindowMoveId); IM_ASSERT(g.MovedWindow && g.MovedWindow->RootWindow); - IM_ASSERT(g.MovedWindow->RootWindow->MoveID == g.MovedWindowMoveId); + IM_ASSERT(g.MovedWindow->RootWindow->MoveId == g.MovedWindowMoveId); if (g.IO.MouseDown[0]) { if (!(g.MovedWindow->Flags & ImGuiWindowFlags_NoMove)) @@ -2239,14 +2252,11 @@ void ImGui::NewFrame() window->SizeFull *= scale; } } - else + else if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) { // Scroll - if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) - { - const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5; - SetWindowScrollY(window, window->Scroll.y - g.IO.MouseWheel * window->CalcFontSize() * scroll_lines); - } + const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5; + SetWindowScrollY(window, window->Scroll.y - g.IO.MouseWheel * window->CalcFontSize() * scroll_lines); } } @@ -2264,6 +2274,15 @@ void ImGui::NewFrame() window->Accessed = false; } + // Closing the focused window restore focus to the first active root window in descending z-order + if (g.FocusedWindow && !g.FocusedWindow->WasActive) + for (int i = g.Windows.Size-1; i >= 0; i--) + if (g.Windows[i]->WasActive && !(g.Windows[i]->Flags & ImGuiWindowFlags_ChildWindow)) + { + FocusWindow(g.Windows[i]); + break; + } + // No window should be open at the beginning of the frame. // But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear. g.CurrentWindowStack.resize(0); @@ -2343,7 +2362,7 @@ static ImGuiIniData* FindWindowSettings(const char* name) for (int i = 0; i != g.Settings.Size; i++) { ImGuiIniData* ini = &g.Settings[i]; - if (ini->ID == id) + if (ini->Id == id) return ini; } return NULL; @@ -2354,7 +2373,7 @@ static ImGuiIniData* AddWindowSettings(const char* name) GImGui->Settings.resize(GImGui->Settings.Size + 1); ImGuiIniData* ini = &GImGui->Settings.back(); ini->Name = ImStrdup(name); - ini->ID = ImHash(name, 0); + ini->Id = ImHash(name, 0); ini->Collapsed = false; ini->Pos = ImVec2(FLT_MAX,FLT_MAX); ini->Size = ImVec2(0,0); @@ -2585,7 +2604,7 @@ void ImGui::EndFrame() if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove)) { g.MovedWindow = g.HoveredWindow; - g.MovedWindowMoveId = g.HoveredRootWindow->MoveID; + g.MovedWindowMoveId = g.HoveredRootWindow->MoveId; SetActiveID(g.MovedWindowMoveId, g.HoveredRootWindow); } } @@ -3217,7 +3236,7 @@ bool ImGui::IsItemActive() if (g.ActiveId) { ImGuiWindow* window = GetCurrentWindowRead(); - return g.ActiveId == window->DC.LastItemID; + return g.ActiveId == window->DC.LastItemId; } return false; } @@ -3248,9 +3267,9 @@ bool ImGui::IsItemVisible() void ImGui::SetItemAllowOverlap() { ImGuiContext& g = *GImGui; - if (g.HoveredId == g.CurrentWindow->DC.LastItemID) + if (g.HoveredId == g.CurrentWindow->DC.LastItemId) g.HoveredIdAllowOverlap = true; - if (g.ActiveId == g.CurrentWindow->DC.LastItemID) + if (g.ActiveId == g.CurrentWindow->DC.LastItemId) g.ActiveIdAllowOverlap = true; } @@ -3318,7 +3337,7 @@ void ImGui::EndTooltip() static bool IsPopupOpen(ImGuiID id) { ImGuiContext& g = *GImGui; - const bool is_open = g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].PopupID == id; + const bool is_open = g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].PopupId == id; return is_open; } @@ -3335,7 +3354,7 @@ void ImGui::OpenPopupEx(const char* str_id, bool reopen_existing) ImGuiPopupRef popup_ref = ImGuiPopupRef(id, window, window->GetID("##menus"), g.IO.MousePos); // Tagged as new ref because constructor sets Window to NULL (we are passing the ParentWindow info here) if (g.OpenPopupStack.Size < current_stack_size + 1) g.OpenPopupStack.push_back(popup_ref); - else if (reopen_existing || g.OpenPopupStack[current_stack_size].PopupID != id) + else if (reopen_existing || g.OpenPopupStack[current_stack_size].PopupId != id) { g.OpenPopupStack.resize(current_stack_size+1); g.OpenPopupStack[current_stack_size] = popup_ref; @@ -3411,7 +3430,7 @@ void ImGui::CloseCurrentPopup() { ImGuiContext& g = *GImGui; int popup_idx = g.CurrentPopupStack.Size - 1; - if (popup_idx < 0 || popup_idx > g.OpenPopupStack.Size || g.CurrentPopupStack[popup_idx].PopupID != g.OpenPopupStack[popup_idx].PopupID) + if (popup_idx < 0 || popup_idx > g.OpenPopupStack.Size || g.CurrentPopupStack[popup_idx].PopupId != g.OpenPopupStack[popup_idx].PopupId) return; while (popup_idx > 0 && g.OpenPopupStack[popup_idx].Window && (g.OpenPopupStack[popup_idx].Window->Flags & ImGuiWindowFlags_ChildMenu)) popup_idx--; @@ -3814,11 +3833,11 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (flags & ImGuiWindowFlags_Popup) { ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.CurrentPopupStack.Size]; - window_was_active &= (window->PopupID == popup_ref.PopupID); + window_was_active &= (window->PopupId == popup_ref.PopupId); window_was_active &= (window == popup_ref.Window); popup_ref.Window = window; g.CurrentPopupStack.push_back(popup_ref); - window->PopupID = popup_ref.PopupID; + window->PopupId = popup_ref.PopupId; } const bool window_appearing_after_being_hidden = (window->HiddenFrames == 1); @@ -3901,16 +3920,10 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us else PushClipRect(fullscreen_rect.Min, fullscreen_rect.Max, true); - // New windows appears in front if (!window_was_active) { - window->AutoPosLastDirection = -1; - - if (!(flags & ImGuiWindowFlags_NoFocusOnAppearing)) - if (!(flags & (ImGuiWindowFlags_ChildWindow|ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup)) - FocusWindow(window); - // Popup first latch mouse position, will position itself when it appears next frame + window->AutoPosLastDirection = -1; if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api) window->PosFloat = g.IO.MousePos; } @@ -4087,7 +4100,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (window->ScrollTarget.y < FLT_MAX) { float center_ratio = window->ScrollTargetCenterRatio.y; - window->Scroll.y = window->ScrollTarget.y - ((1.0f - center_ratio) * window->TitleBarHeight()) - (center_ratio * window->SizeFull.y); + window->Scroll.y = window->ScrollTarget.y - ((1.0f - center_ratio) * (window->TitleBarHeight() + window->MenuBarHeight())) - (center_ratio * window->SizeFull.y); window->ScrollTarget.y = FLT_MAX; } window->Scroll = ImMax(window->Scroll, ImVec2(0.0f, 0.0f)); @@ -4213,6 +4226,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us // Setup drawing context window->DC.IndentX = 0.0f + window->WindowPadding.x - window->Scroll.x; + window->DC.GroupOffsetX = 0.0f; window->DC.ColumnsOffsetX = 0.0f; window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.IndentX + window->DC.ColumnsOffsetX, window->TitleBarHeight() + window->MenuBarHeight() + window->WindowPadding.y - window->Scroll.y); window->DC.CursorPos = window->DC.CursorStartPos; @@ -4248,6 +4262,11 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (window->AutoFitFramesY > 0) window->AutoFitFramesY--; + // New windows appears in front (we need to do that AFTER setting DC.CursorStartPos so our initial navigation reference rectangle can start around there) + if (!window_was_active && !(flags & ImGuiWindowFlags_NoFocusOnAppearing)) + if (!(flags & (ImGuiWindowFlags_ChildWindow|ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup)) + FocusWindow(window); + // Title bar if (!(flags & ImGuiWindowFlags_NoTitleBar)) { @@ -4271,7 +4290,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (style.WindowTitleAlign & ImGuiAlign_Center) pad_right = pad_left; if (pad_left) text_min.x += g.FontSize + style.ItemInnerSpacing.x; if (pad_right) text_max.x -= g.FontSize + style.ItemInnerSpacing.x; - RenderTextClipped(text_min, text_max, name, NULL, &text_size, style.WindowTitleAlign, NULL, &clip_max); + ImVec2 clip_min = ImVec2(text_min.x, window->Pos.y); + RenderTextClipped(text_min, text_max, name, NULL, &text_size, style.WindowTitleAlign, &clip_min, &clip_max); } // Save clipped aabb so we can access it in constant-time in FindHoveredWindow() @@ -4913,8 +4933,7 @@ void ImGui::SetWindowFocus(const char* name) { if (name) { - ImGuiWindow* window = FindWindowByName(name); - if (window) + if (ImGuiWindow* window = FindWindowByName(name)) FocusWindow(window); } else @@ -5077,13 +5096,13 @@ ImVec2 ImGui::GetCursorPos() float ImGui::GetCursorPosX() { - ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindow* window = GetCurrentWindowRead(); return window->DC.CursorPos.x - window->Pos.x + window->Scroll.x; } float ImGui::GetCursorPosY() { - ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindow* window = GetCurrentWindowRead(); return window->DC.CursorPos.y - window->Pos.y + window->Scroll.y; } @@ -5124,6 +5143,7 @@ void ImGui::SetCursorScreenPos(const ImVec2& screen_pos) { ImGuiWindow* window = GetCurrentWindow(); window->DC.CursorPos = screen_pos; + window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); } float ImGui::GetScrollX() @@ -5158,7 +5178,7 @@ void ImGui::SetScrollX(float scroll_x) void ImGui::SetScrollY(float scroll_y) { ImGuiWindow* window = GetCurrentWindow(); - window->ScrollTarget.y = scroll_y + window->TitleBarHeight(); // title bar height canceled out when using ScrollTargetRelY + window->ScrollTarget.y = scroll_y + window->TitleBarHeight() + window->MenuBarHeight(); // title bar height canceled out when using ScrollTargetRelY window->ScrollTargetCenterRatio.y = 0.0f; } @@ -5251,9 +5271,10 @@ void ImGui::TextDisabled(const char* fmt, ...) void ImGui::TextWrappedV(const char* fmt, va_list args) { - PushTextWrapPos(0.0f); + bool need_wrap = (GImGui->CurrentWindow->DC.TextWrapPos < 0.0f); // Keep existing wrap position is one ia already set + if (need_wrap) PushTextWrapPos(0.0f); TextV(fmt, args); - PopTextWrapPos(); + if (need_wrap) PopTextWrapPos(); } void ImGui::TextWrapped(const char* fmt, ...) @@ -5316,7 +5337,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) // Lines to render if (line < text_end) { - ImRect line_rect(pos, pos + ImVec2(GetWindowWidth(), line_height)); + ImRect line_rect(pos, pos + ImVec2(FLT_MAX, line_height)); while (line < text_end) { const char* line_end = strchr(line, '\n'); @@ -5360,9 +5381,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) const ImVec2 text_size = CalcTextSize(text_begin, text_end, false, wrap_width); // Account of baseline offset - ImVec2 text_pos = window->DC.CursorPos; - text_pos.y += window->DC.CurrentLineTextBaseOffset; - + ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrentLineTextBaseOffset); ImRect bb(text_pos, text_pos + text_size); ItemSize(text_size); if (!ItemAdd(bb, NULL)) @@ -7405,6 +7424,7 @@ static void STB_TEXTEDIT_DELETECHARS(STB_TEXTEDIT_STRING* obj, int pos, int n) static bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int pos, const ImWchar* new_text, int new_text_len) { const int text_len = obj->CurLenW; + IM_ASSERT(pos <= text_len); if (new_text_len + text_len + 1 > obj->Text.Size) return false; @@ -7612,10 +7632,6 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // NB: we are only allowed to access 'edit_state' if we are the active widget. ImGuiTextEditState& edit_state = g.InputTextState; - const bool is_ctrl_down = io.KeyCtrl; - const bool is_shift_down = io.KeyShift; - const bool is_alt_down = io.KeyAlt; - const bool is_super_down = io.KeySuper; const bool focus_requested = FocusableItemRegister(window, g.ActiveId == id, (flags & (ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_AllowTabInput)) == 0); // Using completion callback disable keyboard tabbing const bool focus_requested_by_code = focus_requested && (window->FocusIdxAllCounter == window->FocusIdxAllRequestCurrent); const bool focus_requested_by_tab = focus_requested && !focus_requested_by_code; @@ -7627,7 +7643,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 g.MouseCursor = ImGuiMouseCursor_TextInput; } const bool user_clicked = hovered && io.MouseClicked[0]; - const bool user_scrolled = is_multiline && g.ActiveId == 0 && edit_state.Id == id && g.ActiveIdPreviousFrame == draw_window->GetID("#SCROLLY"); + const bool user_scrolled = is_multiline && g.ActiveId == 0 && edit_state.Id == id && g.ActiveIdPreviousFrame == draw_window->GetIDNoKeepAlive("#SCROLLY"); bool select_all = (g.ActiveId != id) && (flags & ImGuiInputTextFlags_AutoSelectAll) != 0; if (focus_requested || user_clicked || user_scrolled) @@ -7638,9 +7654,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Take a copy of the initial buffer value (both in original UTF-8 format and converted to wchar) // From the moment we focused we are ignoring the content of 'buf' (unless we are in read-only mode) const int prev_len_w = edit_state.CurLenW; - edit_state.Text.resize(buf_size+1); // wchar count <= utf-8 count. we use +1 to make sure that .Data isn't NULL so it doesn't crash. - edit_state.InitialText.resize(buf_size+1); // utf-8. we use +1 to make sure that .Data isn't NULL so it doesn't crash. - ImFormatString(edit_state.InitialText.Data, edit_state.InitialText.Size, "%s", buf); + edit_state.Text.resize(buf_size+1); // wchar count <= UTF-8 count. we use +1 to make sure that .Data isn't NULL so it doesn't crash. + edit_state.InitialText.resize(buf_size+1); // UTF-8. we use +1 to make sure that .Data isn't NULL so it doesn't crash. + ImStrncpy(edit_state.InitialText.Data, buf, edit_state.InitialText.Size); const char* buf_end = NULL; edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text.Data, edit_state.Text.Size, buf, NULL, &buf_end); edit_state.CurLenA = (int)(buf_end - buf); // We can't get the result from ImFormatString() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8. @@ -7665,7 +7681,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 } if (flags & ImGuiInputTextFlags_AlwaysInsertMode) edit_state.StbState.insert_mode = true; - if (!is_multiline && (focus_requested_by_tab || (user_clicked && is_ctrl_down))) + if (!is_multiline && (focus_requested_by_tab || (user_clicked && io.KeyCtrl))) select_all = true; } SetActiveID(id, window); @@ -7700,15 +7716,16 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 g.ActiveIdAllowOverlap = !io.MouseDown[0]; // Edit in progress - const float mouse_x = (g.IO.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + edit_state.ScrollX; - const float mouse_y = (is_multiline ? (g.IO.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize*0.5f)); + const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + edit_state.ScrollX; + const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize*0.5f)); - if (select_all || (hovered && !io.DoubleClickSelectsWord && io.MouseDoubleClicked[0])) + const bool osx_double_click_selects_words = io.OSXBehaviors; // OS X style: Double click selects by word instead of selecting whole text + if (select_all || (hovered && !osx_double_click_selects_words && io.MouseDoubleClicked[0])) { edit_state.SelectAll(); edit_state.SelectedAllMouseLock = true; } - else if (hovered && io.DoubleClickSelectsWord && io.MouseDoubleClicked[0]) + else if (hovered && osx_double_click_selects_words && io.MouseDoubleClicked[0]) { // Select a word only, OS X style (by simulating keystrokes) edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT); @@ -7728,14 +7745,14 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (edit_state.SelectedAllMouseLock && !io.MouseDown[0]) edit_state.SelectedAllMouseLock = false; - if (g.IO.InputCharacters[0]) + if (io.InputCharacters[0]) { // Process text input (before we check for Return because using some IME will effectively send a Return?) // We ignore CTRL inputs, but need to allow CTRL+ALT as some keyboards (e.g. German) use AltGR - which is Alt+Ctrl - to input certain characters. - if (!(is_ctrl_down && !is_alt_down) && is_editable) + if (!(io.KeyCtrl && !io.KeyAlt) && is_editable) { - for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++) - if (unsigned int c = (unsigned int)g.IO.InputCharacters[n]) + for (int n = 0; n < IM_ARRAYSIZE(io.InputCharacters) && io.InputCharacters[n]; n++) + if (unsigned int c = (unsigned int)io.InputCharacters[n]) { // Insert character if they pass filtering if (!InputTextFilterCharacter(&c, flags, callback, user_data)) @@ -7750,22 +7767,31 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Handle various key-presses bool cancel_edit = false; - const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0); - const bool is_shortcutkey_only = (io.ShortcutsUseSuperKey ? (is_super_down && !is_alt_down && !is_shift_down && !is_ctrl_down) : (is_ctrl_down && !is_alt_down && !is_shift_down && !is_super_down)); - const bool is_wordmove_key_down = (io.WordMovementUsesAltKey ? io.KeyAlt : io.KeyCtrl); - - if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); } - else if (is_multiline && IsKeyPressedMap(ImGuiKey_UpArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, draw_window->Scroll.y - g.FontSize); else edit_state.OnKeyPressed(STB_TEXTEDIT_K_UP | k_mask); } - else if (is_multiline && IsKeyPressedMap(ImGuiKey_DownArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, draw_window->Scroll.y + g.FontSize); else edit_state.OnKeyPressed(STB_TEXTEDIT_K_DOWN| k_mask); } - else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } + const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0); + const bool is_shortcut_key_only = (io.OSXBehaviors ? (io.KeySuper && !io.KeyCtrl) : (io.KeyCtrl && !io.KeySuper)) && !io.KeyAlt && !io.KeyShift; // OS X style: Shortcuts using Cmd/Super instead of Ctrl + const bool is_wordmove_key_down = io.OSXBehaviors ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl + const bool is_startend_key_down = io.OSXBehaviors && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End + + if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetWindowScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) { if (io.KeyCtrl) SetWindowScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } else if (IsKeyPressedMap(ImGuiKey_Delete) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_Backspace) && is_editable) { if (is_ctrl_down && !edit_state.HasSelection()) edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT|STB_TEXTEDIT_K_SHIFT); edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_Backspace) && is_editable) + { + if (!edit_state.HasSelection()) + { + if (is_wordmove_key_down) edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT|STB_TEXTEDIT_K_SHIFT); + else if (io.OSXBehaviors && io.KeySuper && !io.KeyAlt && !io.KeyCtrl) edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT); + } + edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); + } else if (IsKeyPressedMap(ImGuiKey_Enter)) { bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0; - if (!is_multiline || (ctrl_enter_for_new_line && !is_ctrl_down) || (!ctrl_enter_for_new_line && is_ctrl_down)) + if (!is_multiline || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl)) { SetActiveID(0); enter_pressed = true; @@ -7777,30 +7803,30 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 edit_state.OnKeyPressed((int)c); } } - else if ((flags & ImGuiInputTextFlags_AllowTabInput) && IsKeyPressedMap(ImGuiKey_Tab) && !is_ctrl_down && !is_shift_down && !is_alt_down && is_editable) + else if ((flags & ImGuiInputTextFlags_AllowTabInput) && IsKeyPressedMap(ImGuiKey_Tab) && !io.KeyCtrl && !io.KeyShift && !io.KeyAlt && is_editable) { unsigned int c = '\t'; // Insert TAB if (InputTextFilterCharacter(&c, flags, callback, user_data)) edit_state.OnKeyPressed((int)c); } else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveID(0); cancel_edit = true; } - else if (is_shortcutkey_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); } - else if (is_shortcutkey_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); } - else if (is_shortcutkey_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; } - else if (is_shortcutkey_only && !is_password && ((IsKeyPressedMap(ImGuiKey_X) && is_editable) || IsKeyPressedMap(ImGuiKey_C)) && (!is_multiline || edit_state.HasSelection())) + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; } + else if (is_shortcut_key_only && !is_password && ((IsKeyPressedMap(ImGuiKey_X) && is_editable) || IsKeyPressedMap(ImGuiKey_C)) && (!is_multiline || edit_state.HasSelection())) { // Cut, Copy const bool cut = IsKeyPressedMap(ImGuiKey_X); if (cut && !edit_state.HasSelection()) edit_state.SelectAll(); - if (g.IO.SetClipboardTextFn) + if (io.SetClipboardTextFn) { const int ib = edit_state.HasSelection() ? ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end) : 0; const int ie = edit_state.HasSelection() ? ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end) : edit_state.CurLenW; edit_state.TempTextBuffer.resize((ie-ib) * 4 + 1); ImTextStrToUtf8(edit_state.TempTextBuffer.Data, edit_state.TempTextBuffer.Size, edit_state.Text.Data+ib, edit_state.Text.Data+ie); - g.IO.SetClipboardTextFn(edit_state.TempTextBuffer.Data); + io.SetClipboardTextFn(edit_state.TempTextBuffer.Data); } if (cut) @@ -7809,35 +7835,32 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 stb_textedit_cut(&edit_state, &edit_state.StbState); } } - else if (is_shortcutkey_only && IsKeyPressedMap(ImGuiKey_V) && is_editable) + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_V) && is_editable) { // Paste - if (g.IO.GetClipboardTextFn) + if (const char* clipboard = io.GetClipboardTextFn ? io.GetClipboardTextFn() : NULL) { - if (const char* clipboard = g.IO.GetClipboardTextFn()) + // Filter pasted buffer + const int clipboard_len = (int)strlen(clipboard); + ImWchar* clipboard_filtered = (ImWchar*)ImGui::MemAlloc((clipboard_len+1) * sizeof(ImWchar)); + int clipboard_filtered_len = 0; + for (const char* s = clipboard; *s; ) { - // Remove new-line from pasted buffer - const int clipboard_len = (int)strlen(clipboard); - ImWchar* clipboard_filtered = (ImWchar*)ImGui::MemAlloc((clipboard_len+1) * sizeof(ImWchar)); - int clipboard_filtered_len = 0; - for (const char* s = clipboard; *s; ) - { - unsigned int c; - s += ImTextCharFromUtf8(&c, s, NULL); - if (c == 0) - break; - if (c >= 0x10000 || !InputTextFilterCharacter(&c, flags, callback, user_data)) - continue; - clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c; - } - clipboard_filtered[clipboard_filtered_len] = 0; - if (clipboard_filtered_len > 0) // If everything was filtered, ignore the pasting operation - { - stb_textedit_paste(&edit_state, &edit_state.StbState, clipboard_filtered, clipboard_filtered_len); - edit_state.CursorFollow = true; - } - ImGui::MemFree(clipboard_filtered); + unsigned int c; + s += ImTextCharFromUtf8(&c, s, NULL); + if (c == 0) + break; + if (c >= 0x10000 || !InputTextFilterCharacter(&c, flags, callback, user_data)) + continue; + clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c; + } + clipboard_filtered[clipboard_filtered_len] = 0; + if (clipboard_filtered_len > 0) // If everything was filtered, ignore the pasting operation + { + stb_textedit_paste(&edit_state, &edit_state.StbState, clipboard_filtered, clipboard_filtered_len); + edit_state.CursorFollow = true; } + ImGui::MemFree(clipboard_filtered); } } @@ -7846,7 +7869,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Restore initial value if (is_editable) { - ImFormatString(buf, buf_size, "%s", edit_state.InitialText.Data); + ImStrncpy(buf, edit_state.InitialText.Data, buf_size); value_changed = true; } } @@ -7932,28 +7955,33 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Copy back to user buffer if (is_editable && strcmp(edit_state.TempTextBuffer.Data, buf) != 0) { - ImFormatString(buf, buf_size, "%s", edit_state.TempTextBuffer.Data); + ImStrncpy(buf, edit_state.TempTextBuffer.Data, buf_size); value_changed = true; } } } + // Render + // Select which buffer we are going to display. When ImGuiInputTextFlags_NoLiveEdit is set 'buf' might still be the old value. We set buf to NULL to prevent accidental usage from now on. + const char* buf_display = (g.ActiveId == id && is_editable) ? edit_state.TempTextBuffer.Data : buf; buf = NULL; + if (!is_multiline) RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); - // Render const ImVec4 clip_rect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + size.x, frame_bb.Min.y + size.y); // Not using frame_bb.Max because we have adjusted size ImVec2 render_pos = is_multiline ? draw_window->DC.CursorPos : frame_bb.Min + style.FramePadding; ImVec2 text_size(0.f, 0.f); - if (g.ActiveId == id || (edit_state.Id == id && is_multiline && g.ActiveId == draw_window->GetID("#SCROLLY"))) + const bool is_currently_scrolling = (edit_state.Id == id && is_multiline && g.ActiveId == draw_window->GetIDNoKeepAlive("#SCROLLY")); + if (g.ActiveId == id || is_currently_scrolling) { - edit_state.CursorAnim += g.IO.DeltaTime; + edit_state.CursorAnim += io.DeltaTime; - // We need to: - // - Display the text (this can be more easily clipped) + // This is going to be messy. We need to: + // - Display the text (this alone can be more easily clipped) // - Handle scrolling, highlight selection, display cursor (those all requires some form of 1d->2d cursor position calculation) // - Measure text height (for scrollbar) // We are attempting to do most of that in **one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort) + // FIXME: This should occur on buf_display but we'd need to maintain cursor/select_start/select_end for UTF-8. const ImWchar* text_begin = edit_state.Text.Data; ImVec2 cursor_offset, select_start_offset; @@ -8067,7 +8095,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 } } - draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos - render_scroll, GetColorU32(ImGuiCol_Text), buf, buf+edit_state.CurLenA, 0.0f, is_multiline ? NULL : &clip_rect); + draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos - render_scroll, GetColorU32(ImGuiCol_Text), buf_display, buf_display + edit_state.CurLenA, 0.0f, is_multiline ? NULL : &clip_rect); // Draw blinking cursor bool cursor_is_visible = (g.InputTextState.CursorAnim <= 0.0f) || fmodf(g.InputTextState.CursorAnim, 1.20f) <= 0.80f; @@ -8085,8 +8113,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Render text only const char* buf_end = NULL; if (is_multiline) - text_size = ImVec2(size.x, InputTextCalcTextLenAndLineCount(buf, &buf_end) * g.FontSize); // We don't need width - draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos, GetColorU32(ImGuiCol_Text), buf, buf_end, 0.0f, is_multiline ? NULL : &clip_rect); + text_size = ImVec2(size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_end) * g.FontSize); // We don't need width + draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos, GetColorU32(ImGuiCol_Text), buf_display, buf_end, 0.0f, is_multiline ? NULL : &clip_rect); } if (is_multiline) @@ -8094,6 +8122,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 Dummy(text_size + ImVec2(0.0f, g.FontSize)); // Always add room to scroll an extra line EndChildFrame(); EndGroup(); + if (g.ActiveId == id || is_currently_scrolling) // Set LastItemId which was lost by EndChild/EndGroup, so user can use IsItemActive() + window->DC.LastItemId = g.ActiveId; } if (is_password) @@ -8101,7 +8131,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Log as text if (g.LogEnabled && !is_password) - LogRenderedText(render_pos, buf, NULL); + LogRenderedText(render_pos, buf_display, NULL); if (label_size.x > 0) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); @@ -8115,14 +8145,12 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) { IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline() - bool ret = InputTextEx(label, buf, (int)buf_size, ImVec2(0,0), flags, callback, user_data); - return ret; + return InputTextEx(label, buf, (int)buf_size, ImVec2(0,0), flags, callback, user_data); } bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) { - bool ret = InputTextEx(label, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data); - return ret; + return InputTextEx(label, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data); } // NB: scalar_format here must be a simple "%xx" format string with no prefix/suffix (unlike the Drag/Slider functions "display_format" argument) @@ -8856,7 +8884,7 @@ bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_borde RenderFrame(bb.Min, bb.Max, GetColorU32(col), outline_border, style.FrameRounding); if (hovered) - SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col.x, col.y, col.z, col.w, IM_F32_TO_INT8(col.x), IM_F32_TO_INT8(col.y), IM_F32_TO_INT8(col.z), IM_F32_TO_INT8(col.z)); + SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col.x, col.y, col.z, col.w, IM_F32_TO_INT8_SAT(col.x), IM_F32_TO_INT8_SAT(col.y), IM_F32_TO_INT8_SAT(col.z), IM_F32_TO_INT8_SAT(col.z)); return pressed; } @@ -8897,7 +8925,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) if (edit_mode == ImGuiColorEditMode_HSV) ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]); - int i[4] = { IM_F32_TO_INT8(f[0]), IM_F32_TO_INT8(f[1]), IM_F32_TO_INT8(f[2]), IM_F32_TO_INT8(f[3]) }; + int i[4] = { IM_F32_TO_INT8_UNBOUND(f[0]), IM_F32_TO_INT8_UNBOUND(f[1]), IM_F32_TO_INT8_UNBOUND(f[2]), IM_F32_TO_INT8_UNBOUND(f[3]) }; int components = alpha ? 4 : 3; bool value_changed = false; @@ -8974,7 +9002,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) // Recreate our own tooltip over's ColorButton() one because we want to display correct alpha here if (IsItemHovered()) - SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col[0], col[1], col[2], col[3], IM_F32_TO_INT8(col[0]), IM_F32_TO_INT8(col[1]), IM_F32_TO_INT8(col[2]), IM_F32_TO_INT8(col[3])); + SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col[0], col[1], col[2], col[3], IM_F32_TO_INT8_SAT(col[0]), IM_F32_TO_INT8_SAT(col[1]), IM_F32_TO_INT8_SAT(col[2]), IM_F32_TO_INT8_SAT(col[3])); if (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelectShowButton) { @@ -9095,7 +9123,8 @@ void ImGui::BeginGroup() group_data.BackupLogLinePosY = window->DC.LogLinePosY; group_data.AdvanceCursor = true; - window->DC.IndentX = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffsetX; + window->DC.GroupOffsetX = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffsetX; + window->DC.IndentX = window->DC.GroupOffsetX; window->DC.CursorMaxPos = window->DC.CursorPos; window->DC.CurrentLineHeight = 0.0f; window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; @@ -9119,6 +9148,7 @@ void ImGui::EndGroup() window->DC.CurrentLineHeight = group_data.BackupCurrentLineHeight; window->DC.CurrentLineTextBaseOffset = group_data.BackupCurrentLineTextBaseOffset; window->DC.IndentX = group_data.BackupIndentX; + window->DC.GroupOffsetX = window->DC.IndentX; window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; if (group_data.AdvanceCursor) @@ -9135,7 +9165,7 @@ void ImGui::EndGroup() // Gets back to previous line and continue with horizontal layout // pos_x == 0 : follow right after previous item -// pos_x != 0 : align to specified x position +// pos_x != 0 : align to specified x position (relative to window/group left) // spacing_w < 0 : use default spacing if pos_x == 0, no spacing if pos_x != 0 // spacing_w >= 0 : enforce spacing amount void ImGui::SameLine(float pos_x, float spacing_w) @@ -9148,7 +9178,7 @@ void ImGui::SameLine(float pos_x, float spacing_w) if (pos_x != 0.0f) { if (spacing_w < 0.0f) spacing_w = 0.0f; - window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + pos_x + spacing_w; + window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + pos_x + spacing_w + window->DC.GroupOffsetX + window->DC.ColumnsOffsetX; window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y; } else @@ -9175,37 +9205,34 @@ void ImGui::NewLine() void ImGui::NextColumn() { ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) + if (window->SkipItems || window->DC.ColumnsCount <= 1) return; ImGuiContext& g = *GImGui; - if (window->DC.ColumnsCount > 1) - { - PopItemWidth(); - PopClipRect(); - - window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); - if (++window->DC.ColumnsCurrent < window->DC.ColumnsCount) - { - // Columns 1+ cancel out IndentX - window->DC.ColumnsOffsetX = GetColumnOffset(window->DC.ColumnsCurrent) - window->DC.IndentX + g.Style.ItemSpacing.x; - window->DrawList->ChannelsSetCurrent(window->DC.ColumnsCurrent); - } - else - { - window->DC.ColumnsCurrent = 0; - window->DC.ColumnsOffsetX = 0.0f; - window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY; - window->DrawList->ChannelsSetCurrent(0); - } - window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); - window->DC.CursorPos.y = window->DC.ColumnsCellMinY; - window->DC.CurrentLineHeight = 0.0f; - window->DC.CurrentLineTextBaseOffset = 0.0f; + PopItemWidth(); + PopClipRect(); - PushColumnClipRect(); - PushItemWidth(GetColumnWidth() * 0.65f); // FIXME: Move on columns setup + window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); + if (++window->DC.ColumnsCurrent < window->DC.ColumnsCount) + { + // Columns 1+ cancel out IndentX + window->DC.ColumnsOffsetX = GetColumnOffset(window->DC.ColumnsCurrent) - window->DC.IndentX + g.Style.ItemSpacing.x; + window->DrawList->ChannelsSetCurrent(window->DC.ColumnsCurrent); + } + else + { + window->DC.ColumnsCurrent = 0; + window->DC.ColumnsOffsetX = 0.0f; + window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY; + window->DrawList->ChannelsSetCurrent(0); } + window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); + window->DC.CursorPos.y = window->DC.ColumnsCellMinY; + window->DC.CurrentLineHeight = 0.0f; + window->DC.CurrentLineTextBaseOffset = 0.0f; + + PushColumnClipRect(); + PushItemWidth(GetColumnWidth() * 0.65f); // FIXME: Move on columns setup } int ImGui::GetColumnIndex() @@ -9227,7 +9254,7 @@ static float GetDraggedColumnOffset(int column_index) ImGuiContext& g = *GImGui; ImGuiWindow* window = ImGui::GetCurrentWindowRead(); IM_ASSERT(column_index > 0); // We cannot drag column 0. If you get this assert you may have a conflict between the ID of your columns and another widgets. - IM_ASSERT(g.ActiveId == window->DC.ColumnsSetID + ImGuiID(column_index)); + IM_ASSERT(g.ActiveId == window->DC.ColumnsSetId + ImGuiID(column_index)); float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x - window->Pos.x; x = ImClamp(x, ImGui::GetColumnOffset(column_index-1)+g.Style.ColumnsMinSpacing, ImGui::GetColumnOffset(column_index+1)-g.Style.ColumnsMinSpacing); @@ -9244,7 +9271,7 @@ float ImGui::GetColumnOffset(int column_index) if (g.ActiveId) { - const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(column_index); + const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index); if (g.ActiveId == column_id) return GetDraggedColumnOffset(column_index); } @@ -9265,7 +9292,7 @@ void ImGui::SetColumnOffset(int column_index, float offset) const float t = (offset - window->DC.ColumnsMinX) / (window->DC.ColumnsMaxX - window->DC.ColumnsMinX); window->DC.ColumnsData[column_index].OffsetNorm = t; - const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(column_index); + const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index); window->DC.StateStorage->SetFloat(column_id, t); } @@ -9316,7 +9343,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border) for (int i = 1; i < window->DC.ColumnsCount; i++) { float x = window->Pos.x + GetColumnOffset(i); - const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(i); + const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(i); const ImRect column_rect(ImVec2(x-4,y1),ImVec2(x+4,y2)); if (IsClippedEx(column_rect, &column_id, false)) continue; @@ -9334,7 +9361,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border) if (held) { if (g.ActiveIdIsJustActivated) - g.ActiveIdClickOffset.x -= 4; // Store from center of column line + g.ActiveIdClickOffset.x -= 4; // Store from center of column line (we used a 8 wide rect for columns clicking) x = GetDraggedColumnOffset(i); SetColumnOffset(i, x); } @@ -9344,7 +9371,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border) // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget. // In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer. PushID(0x11223347 + (id ? 0 : columns_count)); - window->DC.ColumnsSetID = window->GetID(id ? id : "columns"); + window->DC.ColumnsSetId = window->GetID(id ? id : "columns"); PopID(); // Set state for first column @@ -9366,7 +9393,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border) window->DC.ColumnsData.resize(columns_count + 1); for (int column_index = 0; column_index < columns_count + 1; column_index++) { - const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(column_index); + const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index); KeepAliveID(column_id); const float default_t = column_index / (float)window->DC.ColumnsCount; const float t = window->DC.StateStorage->GetFloat(column_id, default_t); // Cheaply store our floating point value inside the integer (could store an union into the map?) @@ -9467,7 +9494,7 @@ void ImGui::ValueColor(const char* prefix, const ImVec4& v) ColorButton(v, true); } -void ImGui::ValueColor(const char* prefix, unsigned int v) +void ImGui::ValueColor(const char* prefix, ImU32 v) { Text("%s: %08X", prefix, v); SameLine(); @@ -9499,12 +9526,8 @@ void ImGui::ValueColor(const char* prefix, unsigned int v) static const char* GetClipboardTextFn_DefaultImpl() { - static char* buf_local = NULL; - if (buf_local) - { - ImGui::MemFree(buf_local); - buf_local = NULL; - } + static ImVector<char> buf_local; + buf_local.clear(); if (!OpenClipboard(NULL)) return NULL; HANDLE wbuf_handle = GetClipboardData(CF_UNICODETEXT); @@ -9513,19 +9536,18 @@ static const char* GetClipboardTextFn_DefaultImpl() if (ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle)) { int buf_len = ImTextCountUtf8BytesFromStr(wbuf_global, NULL) + 1; - buf_local = (char*)ImGui::MemAlloc(buf_len * sizeof(char)); - ImTextStrToUtf8(buf_local, buf_len, wbuf_global, NULL); + buf_local.resize(buf_len); + ImTextStrToUtf8(buf_local.Data, buf_len, wbuf_global, NULL); } GlobalUnlock(wbuf_handle); CloseClipboard(); - return buf_local; + return buf_local.Data; } static void SetClipboardTextFn_DefaultImpl(const char* text) { if (!OpenClipboard(NULL)) return; - const int wbuf_length = ImTextCountCharsFromUtf8(text, NULL) + 1; HGLOBAL wbuf_handle = GlobalAlloc(GMEM_MOVEABLE, (SIZE_T)wbuf_length * sizeof(ImWchar)); if (wbuf_handle == NULL) @@ -9564,7 +9586,7 @@ static void SetClipboardTextFn_DefaultImpl(const char* text) #endif // Win32 API IME support (for Asian languages, etc.) -#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS) +#if defined(_WIN32) && !defined(__GNUC__) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS) #include <imm.h> #ifdef _MSC_VER @@ -9681,6 +9703,8 @@ void ImGui::ShowMetricsWindow(bool* p_open) if (!ImGui::TreeNode(window, "%s '%s', %d @ 0x%p", label, window->Name, window->Active || window->WasActive, window)) return; NodeDrawList(window->DrawList, "DrawList"); + ImGui::BulletText("Size: (%.1f,%.1f), SizeContents (%.1f,%.1f)", window->Size.x, window->Size.y, window->SizeContents.x, window->SizeContents.y); + ImGui::BulletText("Scroll: (%.2f,%.2f)", window->Scroll.x, window->Scroll.y); if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows"); ImGui::BulletText("Storage: %d bytes", window->StateStorage.Data.Size * (int)sizeof(ImGuiStorage::Pair)); @@ -9701,7 +9725,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) for (int i = 0; i < g.OpenPopupStack.Size; i++) { ImGuiWindow* window = g.OpenPopupStack[i].Window; - ImGui::BulletText("PopupID: %08x, Window: '%s'%s%s", g.OpenPopupStack[i].PopupID, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? " ChildWindow" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? " ChildMenu" : ""); + ImGui::BulletText("PopupID: %08x, Window: '%s'%s%s", g.OpenPopupStack[i].PopupId, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? " ChildWindow" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? " ChildMenu" : ""); } ImGui::TreePop(); } diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h index 97411beb216..6a1ed055964 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h @@ -62,11 +62,11 @@ struct ImGuiSizeConstraintCallbackData;// Structure used to constraint window si struct ImGuiListClipper; // Helper to manually clip large list of items struct ImGuiContext; // ImGui context (opaque) -// Enumerations (declared as int for compatibility and to not pollute the top of this file) -typedef unsigned int ImU32; +// Typedefs and Enumerations (declared as int for compatibility and to not pollute the top of this file) +typedef unsigned int ImU32; // 32-bit unsigned integer (typically used to store packed colors) +typedef unsigned int ImGuiID; // unique ID used by widgets (typically hashed from a stack of string) typedef unsigned short ImWchar; // character for keyboard input/display typedef void* ImTextureID; // user data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp) -typedef ImU32 ImGuiID; // unique ID used by widgets (typically hashed from a stack of string) typedef int ImGuiCol; // a color identifier for styling // enum ImGuiCol_ typedef int ImGuiStyleVar; // a variable identifier for styling // enum ImGuiStyleVar_ typedef int ImGuiKey; // a key identifier (ImGui-side enum) // enum ImGuiKey_ @@ -352,7 +352,7 @@ namespace ImGui IMGUI_API void Value(const char* prefix, unsigned int v); IMGUI_API void Value(const char* prefix, float v, const char* float_format = NULL); IMGUI_API void ValueColor(const char* prefix, const ImVec4& v); - IMGUI_API void ValueColor(const char* prefix, unsigned int v); + IMGUI_API void ValueColor(const char* prefix, ImU32 v); // Tooltips IMGUI_API void SetTooltip(const char* fmt, ...) IM_PRINTFARGS(1); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). last call wins @@ -694,9 +694,9 @@ enum ImGuiMouseCursor_ enum ImGuiSetCond_ { ImGuiSetCond_Always = 1 << 0, // Set the variable - ImGuiSetCond_Once = 1 << 1, // Only set the variable on the first call per runtime session - ImGuiSetCond_FirstUseEver = 1 << 2, // Only set the variable if the window doesn't exist in the .ini file - ImGuiSetCond_Appearing = 1 << 3 // Only set the variable if the window is appearing after being inactive (or the first time) + ImGuiSetCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call with succeed) + ImGuiSetCond_FirstUseEver = 1 << 2, // Set the variable if the window has no saved data (if doesn't exist in the .ini file) + ImGuiSetCond_Appearing = 1 << 3 // Set the variable if the window is appearing after being hidden/inactive (or the first time) }; struct ImGuiStyle @@ -758,10 +758,7 @@ struct ImGuiIO ImVec2 DisplayVisibleMax; // <unset> (0.0f,0.0f) // If the values are the same, we defaults to Min=(0.0f) and Max=DisplaySize // Advanced/subtle behaviors - bool WordMovementUsesAltKey; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl - bool ShortcutsUseSuperKey; // = defined(__APPLE__) // OS X style: Shortcuts using Cmd/Super instead of Ctrl - bool DoubleClickSelectsWord; // = defined(__APPLE__) // OS X style: Double click selects by word instead of selecting whole text - bool MultiSelectUsesSuperKey; // = defined(__APPLE__) // OS X style: Multi-selection in lists uses Cmd/Super instead of Ctrl [unused yet] + bool OSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl //------------------------------------------------------------------ // User Functions @@ -888,7 +885,8 @@ public: if (new_capacity <= Capacity) return; T* new_data = (value_type*)ImGui::MemAlloc((size_t)new_capacity * sizeof(value_type)); memset(&new_data[Size], 0, (size_t)(new_capacity - Size) * sizeof(value_type)); // BK - clear garbage so that 0 initialized ImString works properly. - memcpy(new_data, Data, (size_t)Size * sizeof(value_type)); + if (Data) + memcpy(new_data, Data, (size_t)Size * sizeof(value_type)); ImGui::MemFree(Data); Data = new_data; Capacity = new_capacity; @@ -1272,7 +1270,7 @@ struct ImFontConfig int FontNo; // 0 // Index of font within TTF file float SizePixels; // // Size in pixels for rasterizer int OversampleH, OversampleV; // 3, 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis. - bool PixelSnapH; // false // Align every character to pixel boundary (if enabled, set OversampleH/V to 1) + bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1. ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs const ImWchar* GlyphRanges; // // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). @@ -1325,6 +1323,7 @@ struct ImFontAtlas IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs IMGUI_API const ImWchar* GetGlyphRangesChinese(); // Japanese + full set of about 21000 CJK Unified Ideographs IMGUI_API const ImWchar* GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters + IMGUI_API const ImWchar* GetGlyphRangesThai(); // Default + Thai characters // Members // (Access texture data via GetTexData*() calls which will setup a default font for you.) diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp index 62bbd8c3bc5..67846e7ab1b 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp @@ -1020,24 +1020,24 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Text("Hello\nWorld"); ImGui::SameLine(); ImGui::Text("One\nTwo\nThree"); - ImGui::Button("HOP"); ImGui::SameLine(); + ImGui::Button("HOP##1"); ImGui::SameLine(); ImGui::Text("Banana"); ImGui::SameLine(); ImGui::Text("Hello\nWorld"); ImGui::SameLine(); ImGui::Text("Banana"); - ImGui::Button("HOP"); ImGui::SameLine(); + ImGui::Button("HOP##2"); ImGui::SameLine(); ImGui::Text("Hello\nWorld"); ImGui::SameLine(); ImGui::Text("Banana"); - ImGui::Button("TEST"); ImGui::SameLine(); + ImGui::Button("TEST##1"); ImGui::SameLine(); ImGui::Text("TEST"); ImGui::SameLine(); - ImGui::SmallButton("TEST"); + ImGui::SmallButton("TEST##2"); ImGui::AlignFirstTextHeightToWidgets(); // If your line starts with text, call this to align it to upcoming widgets. ImGui::Text("Text aligned to Widget"); ImGui::SameLine(); - ImGui::Button("Widget"); ImGui::SameLine(); + ImGui::Button("Widget##1"); ImGui::SameLine(); ImGui::Text("Widget"); ImGui::SameLine(); - ImGui::SmallButton("Widget"); + ImGui::SmallButton("Widget##2"); // Tree const float spacing = ImGui::GetStyle().ItemInnerSpacing.x; @@ -1415,9 +1415,9 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::InputFloat("blue", &bar, 0.05f, 0, 3); ImGui::NextColumn(); - if (ImGui::CollapsingHeader("Category A")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn(); - if (ImGui::CollapsingHeader("Category B")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn(); - if (ImGui::CollapsingHeader("Category C")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn(); + if (ImGui::CollapsingHeader("Category A")) ImGui::Text("Blah blah blah"); ImGui::NextColumn(); + if (ImGui::CollapsingHeader("Category B")) ImGui::Text("Blah blah blah"); ImGui::NextColumn(); + if (ImGui::CollapsingHeader("Category C")) ImGui::Text("Blah blah blah"); ImGui::NextColumn(); ImGui::Columns(1); ImGui::Separator(); ImGui::TreePop(); @@ -1873,9 +1873,9 @@ static void ShowExampleAppConstrainedResize(bool* p_open) "Custom: Fixed Steps (100)", }; ImGui::Combo("Constraint", &type, desc, IM_ARRAYSIZE(desc)); - if (ImGui::Button("200x200")) { ImGui::SetWindowSize(ImVec2(200,200)); } ImGui::SameLine(); - if (ImGui::Button("500x500")) { ImGui::SetWindowSize(ImVec2(500,500)); } ImGui::SameLine(); - if (ImGui::Button("800x200")) { ImGui::SetWindowSize(ImVec2(800,200)); } + if (ImGui::Button("200x200")) ImGui::SetWindowSize(ImVec2(200,200)); ImGui::SameLine(); + if (ImGui::Button("500x500")) ImGui::SetWindowSize(ImVec2(500,500)); ImGui::SameLine(); + if (ImGui::Button("800x200")) ImGui::SetWindowSize(ImVec2(800,200)); for (int i = 0; i < 10; i++) ImGui::Text("Hello, sailor! Making this line long enough for the example."); } @@ -2088,8 +2088,8 @@ struct ExampleAppConsole // TODO: display items starting from the bottom if (ImGui::SmallButton("Add Dummy Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine(); - if (ImGui::SmallButton("Add Dummy Error")) { AddLog("[error] something went wrong"); } ImGui::SameLine(); - if (ImGui::SmallButton("Clear")) { ClearLog(); } ImGui::SameLine(); + if (ImGui::SmallButton("Add Dummy Error")) AddLog("[error] something went wrong"); ImGui::SameLine(); + if (ImGui::SmallButton("Clear")) ClearLog(); ImGui::SameLine(); if (ImGui::SmallButton("Scroll to bottom")) ScrollToBottom = true; //static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); } @@ -2143,7 +2143,7 @@ struct ExampleAppConsole if (ImGui::InputText("Input", InputBuf, IM_ARRAYSIZE(InputBuf), ImGuiInputTextFlags_EnterReturnsTrue|ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_CallbackHistory, &TextEditCallbackStub, (void*)this)) { char* input_end = InputBuf+strlen(InputBuf); - while (input_end > InputBuf && input_end[-1] == ' ') { input_end--; } *input_end = 0; + while (input_end > InputBuf && input_end[-1] == ' ') input_end--; *input_end = 0; if (InputBuf[0]) ExecCommand(InputBuf); strcpy(InputBuf, ""); diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp index 026f7f7e101..5721873aed3 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp @@ -19,10 +19,10 @@ #include <stdio.h> // vsnprintf, sscanf, printf #if !defined(alloca) -#if defined(_WIN32) +#ifdef _WIN32 #include <malloc.h> // alloca -#elif defined(__FreeBSD__) || defined(__DragonFly__) -#include <stdlib.h> // alloca +#elif (defined(__FreeBSD__) || defined(FreeBSD_kernel) || defined(__DragonFly__)) && !defined(__GLIBC__) +#include <stdlib.h> // alloca. FreeBSD uses stdlib.h unless GLIBC #else #include <alloca.h> // alloca #endif @@ -199,7 +199,7 @@ void ImDrawList::UpdateClipRect() // Try to merge with previous command if it matches, else use current command ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL; - if (prev_cmd && memcmp(&prev_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) == 0 && prev_cmd->TextureId == GetCurrentTextureId() && prev_cmd->UserCallback == NULL) + if (curr_cmd->ElemCount == 0 && prev_cmd && memcmp(&prev_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) == 0 && prev_cmd->TextureId == GetCurrentTextureId() && prev_cmd->UserCallback == NULL) CmdBuffer.pop_back(); else curr_cmd->ClipRect = curr_clip_rect; @@ -1654,6 +1654,17 @@ const ImWchar* ImFontAtlas::GetGlyphRangesCyrillic() return &ranges[0]; } +const ImWchar* ImFontAtlas::GetGlyphRangesThai() +{ + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + 0x0E00, 0x0E7F, // Thai + 0, + }; + return &ranges[0]; +} + //----------------------------------------------------------------------------- // ImFont //----------------------------------------------------------------------------- diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h index 28fb93e98d2..7b59bb63f66 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h @@ -312,7 +312,7 @@ struct IMGUI_API ImGuiTextEditState struct ImGuiIniData { char* Name; - ImGuiID ID; + ImGuiID Id; ImVec2 Pos; ImVec2 Size; bool Collapsed; @@ -331,13 +331,13 @@ struct ImGuiMouseCursorData // Storage for current popup stack struct ImGuiPopupRef { - ImGuiID PopupID; // Set on OpenPopup() + ImGuiID PopupId; // Set on OpenPopup() ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() ImGuiWindow* ParentWindow; // Set on OpenPopup() ImGuiID ParentMenuSet; // Set on OpenPopup() ImVec2 MousePosOnOpen; // Copy of mouse position at the time of opening popup - ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupID = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; } + ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; } }; // Main state for ImGui @@ -481,7 +481,7 @@ struct ImGuiContext ScalarAsInputTextId = 0; DragCurrentValue = 0.0f; DragLastMouseDelta = ImVec2(0.0f, 0.0f); - DragSpeedDefaultRatio = 0.01f; + DragSpeedDefaultRatio = 1.0f / 100.0f; DragSpeedScaleSlow = 0.01f; DragSpeedScaleFast = 10.0f; ScrollbarClickDeltaToGrabCenter = ImVec2(0.0f, 0.0f); @@ -522,7 +522,7 @@ struct IMGUI_API ImGuiDrawContext float PrevLineTextBaseOffset; float LogLinePosY; int TreeDepth; - ImGuiID LastItemID; + ImGuiID LastItemId; ImRect LastItemRect; bool LastItemHoveredAndUsable; // Item rectangle is hovered, and its window is currently interactable with (not blocked by a popup preventing access to the window) bool LastItemHoveredRect; // Item rectangle is hovered, but its window may or not be currently interactable with (might be blocked by a popup preventing access to the window) @@ -546,6 +546,7 @@ struct IMGUI_API ImGuiDrawContext int StackSizesBackup[6]; // Store size of various stacks for asserting float IndentX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) + float GroupOffsetX; float ColumnsOffsetX; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API. int ColumnsCurrent; int ColumnsCount; @@ -555,7 +556,7 @@ struct IMGUI_API ImGuiDrawContext float ColumnsCellMinY; float ColumnsCellMaxY; bool ColumnsShowBorders; - ImGuiID ColumnsSetID; + ImGuiID ColumnsSetId; ImVector<ImGuiColumnData> ColumnsData; ImGuiDrawContext() @@ -565,7 +566,7 @@ struct IMGUI_API ImGuiDrawContext CurrentLineTextBaseOffset = PrevLineTextBaseOffset = 0.0f; LogLinePosY = -1.0f; TreeDepth = 0; - LastItemID = 0; + LastItemId = 0; LastItemRect = ImRect(0.0f,0.0f,0.0f,0.0f); LastItemHoveredAndUsable = LastItemHoveredRect = false; MenuBarAppending = false; @@ -587,7 +588,7 @@ struct IMGUI_API ImGuiDrawContext ColumnsStartPosY = 0.0f; ColumnsCellMinY = ColumnsCellMaxY = 0.0f; ColumnsShowBorders = true; - ColumnsSetID = 0; + ColumnsSetId = 0; } }; @@ -606,7 +607,7 @@ struct IMGUI_API ImGuiWindow ImVec2 SizeContentsExplicit; // Size of contents explicitly set by the user via SetNextWindowContentSize() ImRect ContentsRegionRect; // Maximum visible content position in window coordinates. ~~ (SizeContentsExplicit ? SizeContentsExplicit : Size - ScrollbarSizes) - CursorStartPos, per axis ImVec2 WindowPadding; // Window padding at the time of begin. We need to lock it, in particular manipulation of the ShowBorder would have an effect - ImGuiID MoveID; // == window->GetID("#MOVE") + ImGuiID MoveId; // == window->GetID("#MOVE") ImVec2 Scroll; ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change) ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered @@ -619,7 +620,7 @@ struct IMGUI_API ImGuiWindow bool Collapsed; // Set when collapsing window to become only title-bar bool SkipItems; // == Visible && !Collapsed int BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) - ImGuiID PopupID; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) + ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) int AutoFitFramesX, AutoFitFramesY; bool AutoFitOnlyGrows; int AutoPosLastDirection; @@ -643,7 +644,7 @@ struct IMGUI_API ImGuiWindow ImGuiWindow* RootNonPopupWindow; // If we are a child window, this is pointing to the first non-child non-popup parent window. Else point to ourself. ImGuiWindow* ParentWindow; // If we are a child window, this is pointing to our parent window. Else point to NULL. - // Focus + // Navigation / Focus int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister() int FocusIdxTabCounter; // (same, but only count widgets which you can Tab through) int FocusIdxAllRequestCurrent; // Item being requested for focus @@ -657,6 +658,7 @@ public: ImGuiID GetID(const char* str, const char* str_end = NULL); ImGuiID GetID(const void* ptr); + ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL); ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x+Size.x, Pos.y+Size.y); } float CalcFontSize() const { return GImGui->FontBaseSize * FontWindowScale; } diff --git a/3rdparty/bgfx/3rdparty/remotery/lib/Remotery.c b/3rdparty/bgfx/3rdparty/remotery/lib/Remotery.c index 6b3a35695f2..3acc72fa336 100644 --- a/3rdparty/bgfx/3rdparty/remotery/lib/Remotery.c +++ b/3rdparty/bgfx/3rdparty/remotery/lib/Remotery.c @@ -1,5 +1,5 @@ // -// Copyright 2014 Celtoys Ltd +// Copyright 2014-2016 Celtoys Ltd // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -128,8 +128,11 @@ static rmtBool g_SettingsInitialized = RMT_FALSE; #endif - -#define RMT_UNREFERENCED_PARAMETER(i) (void)(1 ? (void)0 : ((void)i)) +#if 0 //def _MSC_VER + #define RMT_UNREFERENCED_PARAMETER(i) assert(i == 0 || i != 0); // To fool warning C4100 on warning level 4 +#else + #define RMT_UNREFERENCED_PARAMETER(i) (void)(1 ? (void)0 : ((void)i)) +#endif #if RMT_USE_CUDA @@ -173,9 +176,9 @@ static void rmtFree( void* ptr ) g_Settings.free( g_Settings.mm_context, ptr ); } - +#if RMT_USE_OPENGL // DLL/Shared Library functions -void* rmtLoadLibrary(const char* path) +static void* rmtLoadLibrary(const char* path) { #if defined(RMT_PLATFORM_WINDOWS) return (void*)LoadLibraryA(path); @@ -198,14 +201,21 @@ static void rmtFreeLibrary(void* handle) static void* rmtGetProcAddress(void* handle, const char* symbol) { #if defined(RMT_PLATFORM_WINDOWS) + #ifdef _MSC_VER + #pragma warning(push) + #pragma warning(disable:4152) // C4152: nonstandard extension, function/data pointer conversion in expression + #endif return GetProcAddress((HMODULE)handle, (LPCSTR)symbol); + #ifdef _MSC_VER + #pragma warning(pop) + #endif #elif defined(RMT_PLATFORM_POSIX) return dlsym(handle, symbol); #else return NULL; #endif } - +#endif /* ------------------------------------------------------------------------------------------------------------------------ @@ -856,8 +866,9 @@ static void VirtualMirrorBuffer_Destructor(VirtualMirrorBuffer* buffer) */ -typedef struct Thread Thread; -typedef rmtError(*ThreadProc)(Thread* thread); +struct Thread; +typedef rmtError(*ThreadProc)(struct Thread* thread); + typedef struct Thread { @@ -883,9 +894,6 @@ typedef struct Thread } Thread; -typedef rmtError (*ThreadProc)(Thread* thread); - - #if defined(RMT_PLATFORM_WINDOWS) static DWORD WINAPI ThreadProcWindows(LPVOID lpParameter) @@ -1046,6 +1054,7 @@ static void Thread_Destructor(Thread* thread) // NOTE: Microsoft also has its own version of these functions so I'm do some hacky PP to remove them #define strnlen_s strnlen_s_safe_c #define strncat_s strncat_s_safe_c +#define strcpy_s strcpy_s_safe_c #define RSIZE_MAX_STR (4UL << 10) /* 4KB */ @@ -1066,7 +1075,7 @@ static void Thread_Destructor(Thread* thread) typedef int errno_t; #endif -#if !defined(_WIN64) && !defined(__APPLE__) || defined(__MINGW32__) +#if (!defined(_WIN64) && !defined(__APPLE__)) || (defined(__MINGW32__) && !defined(RSIZE_T_DEFINED)) typedef unsigned int rsize_t; #endif @@ -1299,6 +1308,79 @@ strncat_s (char *dest, rsize_t dmax, const char *src, rsize_t slen) } +errno_t +strcpy_s(char *dest, rsize_t dmax, const char *src) +{ + const char *overlap_bumper; + + if (dest == NULL) { + return RCNEGATE(ESNULLP); + } + + if (dmax == 0) { + return RCNEGATE(ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + return RCNEGATE(ESLEMAX); + } + + if (src == NULL) { + *dest = '\0'; + return RCNEGATE(ESNULLP); + } + + if (dest == src) { + return RCNEGATE(EOK); + } + + /* hold base of dest in case src was not copied */ + if (dest < src) { + overlap_bumper = src; + + while (dmax > 0) { + if (dest == overlap_bumper) { + return RCNEGATE(ESOVRLP); + } + + *dest = *src; + if (*dest == '\0') { + return RCNEGATE(EOK); + } + + dmax--; + dest++; + src++; + } + + } + else { + overlap_bumper = dest; + + while (dmax > 0) { + if (src == overlap_bumper) { + return RCNEGATE(ESOVRLP); + } + + *dest = *src; + if (*dest == '\0') { + return RCNEGATE(EOK); + } + + dmax--; + dest++; + src++; + } + } + + /* + * the entire src must have been copied, if not reset dest + * to null the string. + */ + return RCNEGATE(ESNOSPC); +} + + /* very simple integer to hex */ static const char* hex_encoding_table = "0123456789ABCDEF"; @@ -1681,10 +1763,11 @@ static void TCPSocket_Destructor(TCPSocket* tcp_socket) } -static rmtError TCPSocket_RunServer(TCPSocket* tcp_socket, rmtU16 port) +static rmtError TCPSocket_RunServer(TCPSocket* tcp_socket, rmtU16 port, rmtBool limit_connections_to_localhost) { SOCKET s = INVALID_SOCKET; struct sockaddr_in sin; + int enable = 1; #ifdef RMT_PLATFORM_WINDOWS u_long nonblock = 1; #endif @@ -1697,9 +1780,23 @@ static rmtError TCPSocket_RunServer(TCPSocket* tcp_socket, rmtU16 port) if (s == SOCKET_ERROR) return RMT_ERROR_SOCKET_CREATE_FAIL; + // set SO_REUSEADDR so binding doesn't fail when restarting the application + // (otherwise the same port can't be reused within TIME_WAIT) + // I'm not checking for errors because if this fails (unlikely) we might still + // be able to bind to the socket anyway + #ifdef RMT_PLATFORM_POSIX + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)); + #elif defined(RMT_PLATFORM_WINDOWS) + // windows also needs SO_EXCLUSEIVEADDRUSE, + // see http://www.andy-pearce.com/blog/posts/2013/Feb/so_reuseaddr-on-windows/ + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&enable, sizeof(enable)); + enable = 1; + setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *)&enable, sizeof(enable)); + #endif + // Bind the socket to the incoming port sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_addr.s_addr = htonl(limit_connections_to_localhost ? INADDR_LOOPBACK : INADDR_ANY); sin.sin_port = htons(port); if (bind(s, (struct sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR) return RMT_ERROR_SOCKET_BIND_FAIL; @@ -1816,6 +1913,18 @@ static rmtError TCPSocket_AcceptConnection(TCPSocket* tcp_socket, TCPSocket** cl if (s == SOCKET_ERROR) return RMT_ERROR_SOCKET_ACCEPT_FAIL; +#ifdef SO_NOSIGPIPE + // On POSIX systems, send() may send a SIGPIPE signal when writing to an + // already closed connection. By setting this option, we prevent the + // signal from being emitted and send will instead return an error and set + // errno to EPIPE. + // + // This is supported on BSD platforms and not on Linux. + { + int flag = 1; + setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, &flag, sizeof(flag)); + } +#endif // Create a client socket for the new connection assert(client_socket != NULL); New_0(TCPSocket, *client_socket); @@ -1871,7 +1980,14 @@ static rmtError TCPSocket_Send(TCPSocket* tcp_socket, const void* data, rmtU32 l while (cur_data < end_data) { // Attempt to send the remaining chunk of data - int bytes_sent = (int)send(tcp_socket->socket, cur_data, (int)(end_data - cur_data), 0); + int bytes_sent; + int send_flags = 0; +#ifdef MSG_NOSIGNAL + // On Linux this prevents send from emitting a SIGPIPE signal + // Equivalent on BSD to the SO_NOSIGPIPE option. + send_flags = MSG_NOSIGNAL; +#endif + bytes_sent = (int)send(tcp_socket->socket, cur_data, (int)(end_data - cur_data), send_flags); if (bytes_sent == SOCKET_ERROR || bytes_sent == 0) { @@ -2371,9 +2487,10 @@ typedef struct union { - rmtU8 data_mask[4]; - rmtU32 data_mask_u32; - }; + rmtU8 mask[4]; + rmtU32 mask_u32; + } data; + } WebSocket; @@ -2536,10 +2653,10 @@ static rmtError WebSocket_Constructor(WebSocket* web_socket, TCPSocket* tcp_sock web_socket->mode = WEBSOCKET_NONE; web_socket->frame_bytes_remaining = 0; web_socket->mask_offset = 0; - web_socket->data_mask[0] = 0; - web_socket->data_mask[1] = 0; - web_socket->data_mask[2] = 0; - web_socket->data_mask[3] = 0; + web_socket->data.mask[0] = 0; + web_socket->data.mask[1] = 0; + web_socket->data.mask[2] = 0; + web_socket->data.mask[3] = 0; // Caller can optionally specify which TCP socket to use if (web_socket->tcp_socket == NULL) @@ -2555,12 +2672,12 @@ static void WebSocket_Destructor(WebSocket* web_socket) } -static rmtError WebSocket_RunServer(WebSocket* web_socket, rmtU32 port, enum WebSocketMode mode) +static rmtError WebSocket_RunServer(WebSocket* web_socket, rmtU16 port, rmtBool limit_connections_to_localhost, enum WebSocketMode mode) { // Create the server's listening socket assert(web_socket != NULL); web_socket->mode = mode; - return TCPSocket_RunServer(web_socket->tcp_socket, (rmtU16)port); + return TCPSocket_RunServer(web_socket->tcp_socket, port, limit_connections_to_localhost); } @@ -2728,7 +2845,7 @@ static rmtError ReceiveFrameHeader(WebSocket* web_socket) mask_present = (msg_header[1] & 0x80) != 0 ? RMT_TRUE : RMT_FALSE; if (mask_present) { - error = TCPSocket_Receive(web_socket->tcp_socket, web_socket->data_mask, 4, 20); + error = TCPSocket_Receive(web_socket->tcp_socket, web_socket->data.mask, 4, 20); if (error != RMT_ERROR_NONE) return error; } @@ -2790,12 +2907,12 @@ static rmtError WebSocket_Receive(WebSocket* web_socket, void* data, rmtU32* msg } // Apply data mask - if (web_socket->data_mask_u32 != 0) + if (web_socket->data.mask_u32 != 0) { rmtU32 i; for (i = 0; i < bytes_to_read; i++) { - *((rmtU8*)cur_data + i) ^= web_socket->data_mask[web_socket->mask_offset & 3]; + *((rmtU8*)cur_data + i) ^= web_socket->data.mask[web_socket->mask_offset & 3]; web_socket->mask_offset++; } } @@ -2892,11 +3009,20 @@ static void MessageQueue_Destructor(MessageQueue* queue) } +static rmtU32 MessageQueue_SizeForPayload(rmtU32 payload_size) +{ + // Add message header and align for ARM platforms + rmtU32 size = sizeof(Message) + payload_size; + size = (size + 3) & ~3U; + return size; +} + + static Message* MessageQueue_AllocMessage(MessageQueue* queue, rmtU32 payload_size, struct ThreadSampler* thread_sampler) { Message* msg; - rmtU32 write_size = sizeof(Message) + payload_size; + rmtU32 write_size = MessageQueue_SizeForPayload(payload_size); assert(queue != NULL); @@ -2926,9 +3052,8 @@ static Message* MessageQueue_AllocMessage(MessageQueue* queue, rmtU32 payload_si } -static void MessageQueue_CommitMessage(MessageQueue* queue, Message* message, MessageID id) +static void MessageQueue_CommitMessage(Message* message, MessageID id) { - assert(queue != NULL); assert(message != NULL); // Ensure message writes complete before commit @@ -2937,8 +3062,6 @@ static void MessageQueue_CommitMessage(MessageQueue* queue, Message* message, Me // Setting the message ID signals to the consumer that the message is ready assert(message->id == MsgID_NotReady); message->id = id; - - RMT_UNREFERENCED_PARAMETER(queue); } @@ -2981,7 +3104,7 @@ static void MessageQueue_ConsumeNextMessage(MessageQueue* queue, Message* messag // the read position so that a winning thread's allocation will inherit the "not ready" state. // // This costs some write bandwidth and has the potential to flush cache to other cores. - message_size = sizeof(Message) + message->payload_size; + message_size = MessageQueue_SizeForPayload(message->payload_size); memset(message, MsgID_NotReady, message_size); // Ensure clear completes before advancing the read position @@ -3009,31 +3132,33 @@ typedef struct rmtU32 last_ping_time; rmtU16 port; + rmtBool limit_connections_to_localhost; } Server; -static rmtError Server_CreateListenSocket(Server* server, rmtU16 port) +static rmtError Server_CreateListenSocket(Server* server, rmtU16 port, rmtBool limit_connections_to_localhost) { rmtError error = RMT_ERROR_NONE; New_1(WebSocket, server->listen_socket, NULL); if (error == RMT_ERROR_NONE) - error = WebSocket_RunServer(server->listen_socket, port, WEBSOCKET_TEXT); + error = WebSocket_RunServer(server->listen_socket, port, limit_connections_to_localhost, WEBSOCKET_TEXT); return error; } -static rmtError Server_Constructor(Server* server, rmtU16 port) +static rmtError Server_Constructor(Server* server, rmtU16 port, rmtBool limit_connections_to_localhost) { assert(server != NULL); server->listen_socket = NULL; server->client_socket = NULL; server->last_ping_time = 0; server->port = port; + server->limit_connections_to_localhost = limit_connections_to_localhost; // Create the listening WebSocket - return Server_CreateListenSocket(server, port); + return Server_CreateListenSocket(server, port, limit_connections_to_localhost); } @@ -3129,7 +3254,7 @@ static void Server_Update(Server* server) // Recreate the listening socket if it's been destroyed earlier if (server->listen_socket == NULL) - Server_CreateListenSocket(server, server->port); + Server_CreateListenSocket(server, server->port, server->limit_connections_to_localhost); if (server->listen_socket != NULL && server->client_socket == NULL) { @@ -3303,6 +3428,9 @@ static rmtError json_CloseArray(Buffer* buffer) +#define SAMPLE_NAME_LEN 128 + + enum SampleType { SampleType_CPU, @@ -3324,7 +3452,7 @@ typedef struct Sample rmtU32 size_bytes; // Sample name and unique hash - rmtPStr name; + char name[SAMPLE_NAME_LEN]; rmtU32 name_hash; // Unique, persistent ID among all samples @@ -3343,9 +3471,10 @@ typedef struct Sample // This is also mixed with the callstack hash to allow consistent addressing of any point in the tree rmtU32 nb_children; - // Start and end of the sample in microseconds + // Sample end points and length in microseconds rmtU64 us_start; rmtU64 us_end; + rmtU64 us_length; } Sample; @@ -3358,7 +3487,7 @@ static rmtError Sample_Constructor(Sample* sample) sample->type = SampleType_CPU; sample->size_bytes = sizeof(Sample); - sample->name = NULL; + sample->name[0] = 0; sample->name_hash = 0; sample->unique_id = 0; sample->unique_id_html_colour[0] = '#'; @@ -3371,6 +3500,7 @@ static rmtError Sample_Constructor(Sample* sample) sample->nb_children = 0; sample->us_start = 0; sample->us_end = 0; + sample->us_length = 0; return RMT_ERROR_NONE; } @@ -3384,7 +3514,10 @@ static void Sample_Destructor(Sample* sample) static void Sample_Prepare(Sample* sample, rmtPStr name, rmtU32 name_hash, Sample* parent) { - sample->name = name; + // Copy sample name away for two reasons: + // 1. It allows dynamic sprintf-style strings to be transient + // 2. The Remotery thread can still inspect the sample even when the source module has been unloaded + strcpy_s(sample->name, sizeof(sample->name), name); sample->name_hash = name_hash; sample->unique_id = 0; sample->parent = parent; @@ -3394,6 +3527,7 @@ static void Sample_Prepare(Sample* sample, rmtPStr name, rmtU32 name_hash, Sampl sample->nb_children = 0; sample->us_start = 0; sample->us_end = 0; + sample->us_length = 0; } @@ -3416,7 +3550,7 @@ static rmtError json_Sample(Buffer* buffer, Sample* sample) JSON_ERROR_CHECK(json_Comma(buffer)); JSON_ERROR_CHECK(json_FieldU64(buffer, "us_start", sample->us_start)); JSON_ERROR_CHECK(json_Comma(buffer)); - JSON_ERROR_CHECK(json_FieldU64(buffer, "us_length", maxS64(sample->us_end - sample->us_start, 0))); + JSON_ERROR_CHECK(json_FieldU64(buffer, "us_length", maxS64(sample->us_length, 0))); if (sample->first_child != NULL) { @@ -3524,7 +3658,7 @@ static rmtU32 HashCombine(rmtU32 hash_a, rmtU32 hash_b) } -static rmtError SampleTree_Push(SampleTree* tree, rmtPStr name, rmtU32 name_hash, Sample** sample) +static rmtError SampleTree_Push(SampleTree* tree, rmtPStr name, rmtU32 name_hash, rmtU32 flags, Sample** sample) { Sample* parent; rmtError error; @@ -3535,11 +3669,21 @@ static rmtError SampleTree_Push(SampleTree* tree, rmtPStr name, rmtU32 name_hash assert(tree->current_parent != NULL); parent = tree->current_parent; - if (parent->last_child != NULL && parent->last_child->name_hash == name_hash) + if ((flags & RMTSF_Aggregate) != 0) { - // TODO: Collapse siblings with flag exception? - // Note that above check is not enough - requires a linear search + // Linear search for previous instance of this sample name + Sample* sibling; + for (sibling = parent->first_child; sibling != NULL; sibling = sibling->next_sibling) + { + if (sibling->name_hash == name_hash) + { + tree->current_parent = sibling; + *sample = sibling; + return RMT_ERROR_NONE; + } + } } + if (parent->name_hash == name_hash) { // TODO: Collapse recursion on flag? @@ -3657,7 +3801,7 @@ static void AddSampleTreeMessage(MessageQueue* queue, Sample* sample, ObjectAllo payload->root_sample = sample; payload->allocator = allocator; payload->thread_name = thread_name; - MessageQueue_CommitMessage(queue, message, MsgID_SampleTree); + MessageQueue_CommitMessage(message, MsgID_SampleTree); } @@ -3686,8 +3830,6 @@ typedef struct ThreadSampler } ThreadSampler; -static rmtS32 countThreads = 0; - static rmtError ThreadSampler_Constructor(ThreadSampler* thread_sampler) { rmtError error; @@ -3705,8 +3847,11 @@ static rmtError ThreadSampler_Constructor(ThreadSampler* thread_sampler) #if defined(RMT_PLATFORM_LINUX) && RMT_USE_POSIX_THREADNAMES prctl(PR_GET_NAME,thread_sampler->name,0,0,0); #else - strncat_s(thread_sampler->name, sizeof(thread_sampler->name), "Thread", 6); - itoahex_s(thread_sampler->name + 6, sizeof(thread_sampler->name) - 6, AtomicAdd(&countThreads, 1)); + { + static rmtS32 countThreads = 0; + strncat_s(thread_sampler->name, sizeof(thread_sampler->name), "Thread", 6); + itoahex_s(thread_sampler->name + 6, sizeof(thread_sampler->name) - 6, AtomicAdd(&countThreads, 1)); + } #endif // Create the CPU sample tree only - the rest are created on-demand as they need @@ -3729,10 +3874,9 @@ static void ThreadSampler_Destructor(ThreadSampler* ts) } -static rmtError ThreadSampler_Push(ThreadSampler* ts, SampleTree* tree, rmtPStr name, rmtU32 name_hash, Sample** sample) +static rmtError ThreadSampler_Push(SampleTree* tree, rmtPStr name, rmtU32 name_hash, rmtU32 flags, Sample** sample) { - RMT_UNREFERENCED_PARAMETER(ts); - return SampleTree_Push(tree, name, name_hash, sample); + return SampleTree_Push(tree, name, name_hash, flags, sample); } @@ -3967,7 +4111,7 @@ static rmtError Remotery_SendSampleTreeMessage(Remotery* rmt, Message* message) { // If these CUDA samples aren't ready yet, stick them to the back of the queue and continue rmtBool are_samples_ready; - rmt_BeginCPUSample(AreCUDASamplesReady); + rmt_BeginCPUSample(AreCUDASamplesReady, 0); are_samples_ready = AreCUDASamplesReady(sample); rmt_EndCPUSample(); if (!are_samples_ready) @@ -3977,7 +4121,7 @@ static rmtError Remotery_SendSampleTreeMessage(Remotery* rmt, Message* message) } // Retrieve timing of all CUDA samples - rmt_BeginCPUSample(GetCUDASampleTimes); + rmt_BeginCPUSample(GetCUDASampleTimes, 0); GetCUDASampleTimes(sample->parent, sample); rmt_EndCPUSample(); } @@ -4082,13 +4226,13 @@ static rmtError Remotery_ThreadMain(Thread* thread) while (thread->request_exit == RMT_FALSE) { - rmt_BeginCPUSample(Wakeup); + rmt_BeginCPUSample(Wakeup, 0); - rmt_BeginCPUSample(ServerUpdate); + rmt_BeginCPUSample(ServerUpdate, 0); Server_Update(rmt->server); rmt_EndCPUSample(); - rmt_BeginCPUSample(ConsumeMessageQueue); + rmt_BeginCPUSample(ConsumeMessageQueue, 0); Remotery_ConsumeMessageQueue(rmt); rmt_EndCPUSample(); @@ -4129,6 +4273,23 @@ static rmtError Remotery_Constructor(Remotery* rmt) rmt->json_buf = NULL; rmt->thread = NULL; + #if RMT_USE_CUDA + rmt->cuda.CtxSetCurrent = NULL; + rmt->cuda.EventCreate = NULL; + rmt->cuda.EventDestroy = NULL; + rmt->cuda.EventElapsedTime = NULL; + rmt->cuda.EventQuery = NULL; + rmt->cuda.EventRecord = NULL; + #endif + + #if RMT_USE_D3D11 + rmt->d3d11 = NULL; + #endif + + #if RMT_USE_OPENGL + rmt->opengl = NULL; + #endif + // Kick-off the timer usTimer_Init(&rmt->timer); @@ -4138,7 +4299,7 @@ static rmtError Remotery_Constructor(Remotery* rmt) return error; // Create the server - New_1( Server, rmt->server, g_Settings.port ); + New_2(Server, rmt->server, g_Settings.port, g_Settings.limit_connections_to_localhost); if (error != RMT_ERROR_NONE) return error; @@ -4152,26 +4313,13 @@ static rmtError Remotery_Constructor(Remotery* rmt) if (error != RMT_ERROR_NONE) return error; - #if RMT_USE_CUDA - - rmt->cuda.CtxSetCurrent = NULL; - rmt->cuda.EventCreate = NULL; - rmt->cuda.EventDestroy = NULL; - rmt->cuda.EventElapsedTime = NULL; - rmt->cuda.EventQuery = NULL; - rmt->cuda.EventRecord = NULL; - - #endif - #if RMT_USE_D3D11 - rmt->d3d11 = NULL; error = D3D11_Create(&rmt->d3d11); if (error != RMT_ERROR_NONE) return error; #endif #if RMT_USE_OPENGL - rmt->opengl = NULL; error = OpenGL_Create(&rmt->opengl); if (error != RMT_ERROR_NONE) return error; @@ -4198,11 +4346,11 @@ static void Remotery_Destructor(Remotery* rmt) // Join the remotery thread before clearing the global object as the thread is profiling itself Delete(Thread, rmt->thread); - // Ensure this is the module that created it - assert(g_RemoteryCreated == RMT_TRUE); - assert(g_Remotery == rmt); - g_Remotery = NULL; - g_RemoteryCreated = RMT_FALSE; + if (g_RemoteryCreated) + { + g_Remotery = NULL; + g_RemoteryCreated = RMT_FALSE; + } #if RMT_USE_D3D11 Delete(D3D11, rmt->d3d11); @@ -4324,6 +4472,7 @@ RMT_API rmtSettings* _rmt_Settings(void) if( g_SettingsInitialized == RMT_FALSE ) { g_Settings.port = 0x4597; + g_Settings.limit_connections_to_localhost = RMT_FALSE; g_Settings.msSleepBetweenServerUpdates = 10; g_Settings.messageQueueSizeInBytes = 64 * 1024; g_Settings.maxNbMessagesPerUpdate = 100; @@ -4357,6 +4506,9 @@ RMT_API rmtError _rmt_CreateGlobalInstance(Remotery** remotery) RMT_API void _rmt_DestroyGlobalInstance(Remotery* remotery) { + // Ensure this is the module that created it + assert(g_RemoteryCreated == RMT_TRUE); + assert(g_Remotery == remotery); Delete(Remotery, remotery); } @@ -4460,7 +4612,7 @@ static rmtBool QueueLine(MessageQueue* queue, char* text, rmtU32 size, struct Th // Copy the text and commit the message memcpy(message->payload, text, size); - MessageQueue_CommitMessage(queue, message, MsgID_LogText); + MessageQueue_CommitMessage(message, MsgID_LogText); return RMT_TRUE; } @@ -4554,7 +4706,7 @@ static rmtU32 GetNameHash(rmtPStr name, rmtU32* hash_cache) } -RMT_API void _rmt_BeginCPUSample(rmtPStr name, rmtU32* hash_cache) +RMT_API void _rmt_BeginCPUSample(rmtPStr name, rmtU32 flags, rmtU32* hash_cache) { // 'hash_cache' stores a pointer to a sample name's hash value. Internally this is used to identify unique callstacks and it // would be ideal that it's not recalculated each time the sample is used. This can be statically cached at the point @@ -4573,8 +4725,14 @@ RMT_API void _rmt_BeginCPUSample(rmtPStr name, rmtU32* hash_cache) { Sample* sample; rmtU32 name_hash = GetNameHash(name, hash_cache); - if (ThreadSampler_Push(ts, ts->sample_trees[SampleType_CPU], name, name_hash, &sample) == RMT_ERROR_NONE) - sample->us_start = usTimer_Get(&g_Remotery->timer); + if (ThreadSampler_Push(ts->sample_trees[SampleType_CPU], name, name_hash, flags, &sample) == RMT_ERROR_NONE) + { + // If this is an aggregate sample, store the time in 'end' as we want to preserve 'start' + if (sample->us_length != 0) + sample->us_end = usTimer_Get(&g_Remotery->timer); + else + sample->us_start = usTimer_Get(&g_Remotery->timer); + } } } @@ -4589,6 +4747,21 @@ RMT_API void _rmt_EndCPUSample(void) if (Remotery_GetThreadSampler(g_Remotery, &ts) == RMT_ERROR_NONE) { Sample* sample = ts->sample_trees[SampleType_CPU]->current_parent; + + rmtU64 us_end = usTimer_Get(&g_Remotery->timer); + + // Is this an aggregate sample? + if (sample->us_length != 0) + { + sample->us_length += (us_end - sample->us_end); + sample->us_end = us_end; + } + else + { + sample->us_end = us_end; + sample->us_length = (us_end - sample->us_start); + } + sample->us_end = usTimer_Get(&g_Remotery->timer); ThreadSampler_Pop(ts, g_Remotery->mq_to_rmt_thread, sample); } @@ -4794,6 +4967,7 @@ static rmtBool GetCUDASampleTimes(Sample* root_sample, Sample* sample) // Convert to microseconds and add to the sample sample->us_start = (rmtU64)(ms_start * 1000); sample->us_end = (rmtU64)(ms_end * 1000); + sample->us_length = sample->us_end - sample->us_start; // Get child sample times for (child = sample->first_child; child != NULL; child = child->next_sibling) @@ -4847,7 +5021,7 @@ RMT_API void _rmt_BeginCUDASample(rmtPStr name, rmtU32* hash_cache, void* stream } // Push the same and record its event - if (ThreadSampler_Push(ts, *cuda_tree, name, name_hash, &sample) == RMT_ERROR_NONE) + if (ThreadSampler_Push(*cuda_tree, name, name_hash, 0, &sample) == RMT_ERROR_NONE) { CUDASample* cuda_sample = (CUDASample*)sample; CUDAEventRecord(cuda_sample->event_start, stream); @@ -5233,7 +5407,7 @@ RMT_API void _rmt_BeginD3D11Sample(rmtPStr name, rmtU32* hash_cache) New_3(ObjectAllocator, d3d11->timestamp_allocator, sizeof(D3D11Timestamp), (ObjConstructor)D3D11Timestamp_Constructor, (ObjDestructor)D3D11Timestamp_Destructor); // Push the sample - if (ThreadSampler_Push(ts, *d3d_tree, name, name_hash, &sample) == RMT_ERROR_NONE) + if (ThreadSampler_Push(*d3d_tree, name, name_hash, 0, &sample) == RMT_ERROR_NONE) { D3D11Sample* d3d_sample = (D3D11Sample*)sample; @@ -5273,6 +5447,8 @@ static rmtBool GetD3D11SampleTimes(Sample* sample, rmtU64* out_first_timestamp) d3d11->last_error = result; return RMT_FALSE; } + + sample->us_length = sample->us_end - sample->us_start; } // Get child sample times @@ -5296,7 +5472,7 @@ static void UpdateD3D11Frame(void) d3d11 = g_Remotery->d3d11; assert(d3d11 != NULL); - rmt_BeginCPUSample(rmt_UpdateD3D11Frame); + rmt_BeginCPUSample(rmt_UpdateD3D11Frame, 0); // Process all messages in the D3D queue for (;;) @@ -5506,8 +5682,7 @@ static void* rmtglGetProcAddress(OpenGL* opengl, const char* symbol) #elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) - extern void* nsglGetProcAddress(const GLubyte* _name); - return nsglGetProcAddress((const GLubyte*)symbol); + return NSGLGetProcAddress((const GLubyte*)symbol); #elif defined(RMT_PLATFORM_LINUX) @@ -5820,7 +5995,7 @@ RMT_API void _rmt_BeginOpenGLSample(rmtPStr name, rmtU32* hash_cache) New_3(ObjectAllocator, opengl->timestamp_allocator, sizeof(OpenGLTimestamp), (ObjConstructor)OpenGLTimestamp_Constructor, (ObjDestructor)OpenGLTimestamp_Destructor); // Push the sample - if (ThreadSampler_Push(ts, *ogl_tree, name, name_hash, &sample) == RMT_ERROR_NONE) + if (ThreadSampler_Push(*ogl_tree, name, name_hash, 0, &sample) == RMT_ERROR_NONE) { OpenGLSample* ogl_sample = (OpenGLSample*)sample; @@ -5845,6 +6020,8 @@ static rmtBool GetOpenGLSampleTimes(Sample* sample, rmtU64* out_first_timestamp) { if (!OpenGLTimestamp_GetData(ogl_sample->timestamp, &sample->us_start, &sample->us_end, out_first_timestamp)) return RMT_FALSE; + + sample->us_length = sample->us_end - sample->us_start; } // Get child sample times @@ -5868,7 +6045,7 @@ static void UpdateOpenGLFrame(void) opengl = g_Remotery->opengl; assert(opengl != NULL); - rmt_BeginCPUSample(rmt_UpdateOpenGLFrame); + rmt_BeginCPUSample(rmt_UpdateOpenGLFrame, 0); // Process all messages in the OpenGL queue while (1) diff --git a/3rdparty/bgfx/3rdparty/remotery/lib/Remotery.h b/3rdparty/bgfx/3rdparty/remotery/lib/Remotery.h index 20836f68610..141aeb9315f 100644 --- a/3rdparty/bgfx/3rdparty/remotery/lib/Remotery.h +++ b/3rdparty/bgfx/3rdparty/remotery/lib/Remotery.h @@ -82,17 +82,6 @@ documented just below this comment. */ - -// Compiler identification -#if defined(_MSC_VER) - #define RMT_COMPILER_MSVC -#elif defined(__GNUC__) - #define RMT_COMPILER_GNUC -#elif defined(__clang__) - #define RMT_COMPILER_CLANG -#endif - - // Platform identification #if defined(_WINDOWS) || defined(_WIN32) #define RMT_PLATFORM_WINDOWS @@ -254,6 +243,15 @@ typedef enum rmtError } rmtError; +typedef enum rmtSampleFlags +{ + // Default behaviour + RMTSF_None = 0, + + // Search parent for same-named samples and merge timing instead of adding a new sample + RMTSF_Aggregate = 1, +} rmtSampleFlags; + /* ------------------------------------------------------------------------------------------------------------------------ @@ -289,14 +287,14 @@ typedef enum rmtError #define rmt_LogText(text) \ RMT_OPTIONAL(RMT_ENABLED, _rmt_LogText(text)) -#define rmt_BeginCPUSample(name) \ +#define rmt_BeginCPUSample(name, flags) \ RMT_OPTIONAL(RMT_ENABLED, { \ static rmtU32 rmt_sample_hash_##name = 0; \ - _rmt_BeginCPUSample(#name, &rmt_sample_hash_##name); \ + _rmt_BeginCPUSample(#name, flags, &rmt_sample_hash_##name); \ }) -#define rmt_BeginCPUSampleDynamic(namestr) \ - RMT_OPTIONAL(RMT_ENABLED, _rmt_BeginCPUSample(namestr, NULL)) +#define rmt_BeginCPUSampleDynamic(namestr, flags) \ + RMT_OPTIONAL(RMT_ENABLED, _rmt_BeginCPUSample(namestr, flags, NULL)) #define rmt_EndCPUSample() \ RMT_OPTIONAL(RMT_ENABLED, _rmt_EndCPUSample()) @@ -312,8 +310,15 @@ typedef void (*rmtInputHandlerPtr)(const char* text, void* context); // Struture to fill in to modify Remotery default settings typedef struct rmtSettings { + // Which port to listen for incoming connections on rmtU16 port; + // Only allow connections on localhost? + // For dev builds you may want to access your game from other devices but if + // you distribute a game to your players with Remotery active, probably best + // to limit connections to localhost. + rmtBool limit_connections_to_localhost; + // How long to sleep between server updates, hopefully trying to give // a little CPU back to other threads. rmtU32 msSleepBetweenServerUpdates; @@ -485,8 +490,8 @@ struct rmt_EndOpenGLSampleOnScopeExit // Pairs a call to rmt_Begin<TYPE>Sample with its call to rmt_End<TYPE>Sample when leaving scope -#define rmt_ScopedCPUSample(name) \ - RMT_OPTIONAL(RMT_ENABLED, rmt_BeginCPUSample(name)); \ +#define rmt_ScopedCPUSample(name, flags) \ + RMT_OPTIONAL(RMT_ENABLED, rmt_BeginCPUSample(name, flags)); \ RMT_OPTIONAL(RMT_ENABLED, rmt_EndCPUSampleOnScopeExit rmt_ScopedCPUSample##name); #define rmt_ScopedCUDASample(name, stream) \ RMT_OPTIONAL(RMT_USE_CUDA, rmt_BeginCUDASample(name, stream)); \ @@ -525,7 +530,7 @@ RMT_API void _rmt_SetGlobalInstance(Remotery* remotery); RMT_API Remotery* _rmt_GetGlobalInstance(void); RMT_API void _rmt_SetCurrentThreadName(rmtPStr thread_name); RMT_API void _rmt_LogText(rmtPStr text); -RMT_API void _rmt_BeginCPUSample(rmtPStr name, rmtU32* hash_cache); +RMT_API void _rmt_BeginCPUSample(rmtPStr name, rmtU32 flags, rmtU32* hash_cache); RMT_API void _rmt_EndCPUSample(void); #if RMT_USE_CUDA diff --git a/3rdparty/bgfx/3rdparty/remotery/readme.md b/3rdparty/bgfx/3rdparty/remotery/readme.md index 99cbdf9ad7f..143f58247b7 100644 --- a/3rdparty/bgfx/3rdparty/remotery/readme.md +++ b/3rdparty/bgfx/3rdparty/remotery/readme.md @@ -54,14 +54,14 @@ See the sample directory for further examples. A quick example: // Explicit begin/end for C { - rmt_BeginCPUSample(LogText); + rmt_BeginCPUSample(LogText, 0); rmt_LogText("Time me, please!"); rmt_EndCPUSample(); } // Scoped begin/end for C++ { - rmt_ScopedCPUSample(LogText); + rmt_ScopedCPUSample(LogText, 0); rmt_LogText("Time me, too!"); } diff --git a/3rdparty/bgfx/3rdparty/remotery/sample/sample.c b/3rdparty/bgfx/3rdparty/remotery/sample/sample.c index 3339fa35f60..f579e1c1f99 100644 --- a/3rdparty/bgfx/3rdparty/remotery/sample/sample.c +++ b/3rdparty/bgfx/3rdparty/remotery/sample/sample.c @@ -1,12 +1,14 @@ #include <stdlib.h> #include <math.h> +#include <signal.h> +#include <stdio.h> #include "Remotery.h" double delay() { int i, end; double j = 0; - rmt_BeginCPUSample(delay); + rmt_BeginCPUSample(delay, 0); for( i = 0, end = rand()/100; i < end; ++i ) { j += sin(i); } @@ -14,20 +16,30 @@ double delay() { return j; } +int sig = 0; + +/// Allow to close cleanly with ctrl + c +void sigintHandler(int sig_num) { + sig = sig_num; + printf("Interrupted\n"); +} + +int main( ) { + signal(SIGINT, sigintHandler); -int main( int argc, const char **argv ) { Remotery *rmt; if( RMT_ERROR_NONE != rmt_CreateGlobalInstance(&rmt) ) { return -1; } - for(;;) { + while (sig == 0) { rmt_LogText("start profiling"); delay(); rmt_LogText("end profiling"); } rmt_DestroyGlobalInstance(rmt); + printf("Cleaned up and quit\n"); return 0; } diff --git a/3rdparty/bgfx/3rdparty/remotery/vis/Code/Console.js b/3rdparty/bgfx/3rdparty/remotery/vis/Code/Console.js index 06f5e55a8cc..a18f3dce49e 100644 --- a/3rdparty/bgfx/3rdparty/remotery/vis/Code/Console.js +++ b/3rdparty/bgfx/3rdparty/remotery/vis/Code/Console.js @@ -19,7 +19,16 @@ Console = (function() // This accumulates log text as fast as is required this.PageTextBuffer = ""; + this.LastPageTextBufferLen = 0; this.AppTextBuffer = ""; + this.LastAppTextBufferLen = 0; + + // Setup command history control + this.CommandHistory = LocalStore.Get("App", "Global", "CommandHistory", [ ]); + this.CommandIndex = 0; + this.MaxNbCommands = 200; + DOM.Event.AddHandler(this.UserInput.EditNode, "keydown", Bind(OnKeyPress, this)); + DOM.Event.AddHandler(this.UserInput.EditNode, "focus", Bind(OnFocus, this)); // At a much lower frequency this will update the console window window.setInterval(Bind(UpdateHTML, this), 500); @@ -91,13 +100,21 @@ Console = (function() { // Reset the current text buffer as html - var page_node = self.PageContainer.Node; - page_node.innerHTML = self.PageTextBuffer; - page_node.scrollTop = page_node.scrollHeight; - - var app_node = self.AppContainer.Node; - app_node.innerHTML = self.AppTextBuffer; - app_node.scrollTop = app_node.scrollHeight; + if (self.LastPageTextBufferLen != self.PageTextBuffer.length) + { + var page_node = self.PageContainer.Node; + page_node.innerHTML = self.PageTextBuffer; + page_node.scrollTop = page_node.scrollHeight; + self.LastPageTextBufferLen = self.PageTextBuffer.length; + } + + if (self.LastAppTextBufferLen != self.AppTextBuffer.length) + { + var app_node = self.AppContainer.Node; + app_node.innerHTML = self.AppTextBuffer; + app_node.scrollTop = app_node.scrollHeight; + self.LastAppTextBufferLen = self.AppTextBuffer.length; + } } @@ -110,6 +127,64 @@ Console = (function() // Emit to console and clear self.Log("> " + msg); self.UserInput.SetValue(""); + + // Keep track of recently issued commands, with an upper bound + self.CommandHistory.push(msg); + var extra_commands = self.CommandHistory.length - self.MaxNbCommands; + if (extra_commands > 0) + self.CommandHistory.splice(0, extra_commands); + + // Set command history index to the most recent command + self.CommandIndex = self.CommandHistory.length; + + // Backup to local store + LocalStore.Set("App", "Global", "CommandHistory", self.CommandHistory); + + // Keep focus with the edit box + return true; + } + + + function OnKeyPress(self, evt) + { + evt = DOM.Event.Get(evt); + + if (evt.keyCode == Keyboard.Codes.UP) + { + if (self.CommandHistory.length > 0) + { + // Cycle backwards through the command history + self.CommandIndex--; + if (self.CommandIndex < 0) + self.CommandIndex = self.CommandHistory.length - 1; + var command = self.CommandHistory[self.CommandIndex]; + self.UserInput.SetValue(command); + } + + // Stops default behaviour of moving cursor to the beginning + DOM.Event.StopDefaultAction(evt); + } + + else if (evt.keyCode == Keyboard.Codes.DOWN) + { + if (self.CommandHistory.length > 0) + { + // Cycle fowards through the command history + self.CommandIndex = (self.CommandIndex + 1) % self.CommandHistory.length; + var command = self.CommandHistory[self.CommandIndex]; + self.UserInput.SetValue(command); + } + + // Stops default behaviour of moving cursor to the end + DOM.Event.StopDefaultAction(evt); + } + } + + + function OnFocus(self) + { + // Reset command index on focus + self.CommandIndex = self.CommandHistory.length; } diff --git a/3rdparty/bgfx/3rdparty/remotery/vis/Code/Remotery.js b/3rdparty/bgfx/3rdparty/remotery/vis/Code/Remotery.js index 31fe09dc239..5030f8802bb 100644 --- a/3rdparty/bgfx/3rdparty/remotery/vis/Code/Remotery.js +++ b/3rdparty/bgfx/3rdparty/remotery/vis/Code/Remotery.js @@ -92,6 +92,9 @@ Remotery = (function() // Update and disconnect, relying on auto-connect to reconnect self.ConnectionAddress = node.value; self.Server.Disconnect(); + + // Give input focus away + return false; } diff --git a/3rdparty/bgfx/3rdparty/remotery/vis/Styles/Remotery.css b/3rdparty/bgfx/3rdparty/remotery/vis/Styles/Remotery.css index 836dd68d734..995095f417e 100644 --- a/3rdparty/bgfx/3rdparty/remotery/vis/Styles/Remotery.css +++ b/3rdparty/bgfx/3rdparty/remotery/vis/Styles/Remotery.css @@ -67,6 +67,7 @@ body color: #BBB; font: 9px Verdana; margin: 2px; + white-space: pre; } diff --git a/3rdparty/bgfx/3rdparty/remotery/vis/extern/BrowserLib/WindowManager/Code/EditBox.js b/3rdparty/bgfx/3rdparty/remotery/vis/extern/BrowserLib/WindowManager/Code/EditBox.js index b78c9725d53..fd0a039450c 100644 --- a/3rdparty/bgfx/3rdparty/remotery/vis/extern/BrowserLib/WindowManager/Code/EditBox.js +++ b/3rdparty/bgfx/3rdparty/remotery/vis/extern/BrowserLib/WindowManager/Code/EditBox.js @@ -27,11 +27,12 @@ WM.EditBox = (function() this.SetPosition(x, y); this.SetSize(w, h); + this.PreviousValue = ""; + // Hook up the event handlers DOM.Event.AddHandler(this.EditNode, "focus", Bind(OnFocus, this)); DOM.Event.AddHandler(this.EditNode, "keypress", Bind(OnKeyPress, this)); DOM.Event.AddHandler(this.EditNode, "keydown", Bind(OnKeyDown, this)); - DOM.Event.AddHandler(this.EditNode, "change", Bind(OnChange, this)); } @@ -88,9 +89,12 @@ WM.EditBox = (function() function OnKeyPress(self, evt) { // Allow enter to confirm the text only when there's data - if (evt.keyCode == 13 && self.EditNode.value != "") + if (evt.keyCode == 13 && self.EditNode.value != "" && self.ChangeHandler) { - self.EditNode.blur(); + var focus = self.ChangeHandler(self.EditNode); + if (!focus) + self.EditNode.blur(); + self.PreviousValue = ""; } } @@ -100,18 +104,16 @@ WM.EditBox = (function() // Allow escape to cancel any text changes if (evt.keyCode == 27) { - self.EditNode.value = self.PreviousValue; + // On initial edit of the input, escape should NOT replace with the empty string + if (self.PreviousValue != "") + { + self.EditNode.value = self.PreviousValue; + } + self.EditNode.blur(); } } - function OnChange(self, evt) - { - if (self.ChangeHandler) - self.ChangeHandler(self.EditNode); - } - - return EditBox; })(); diff --git a/3rdparty/bgfx/3rdparty/remotery/vis/index.html b/3rdparty/bgfx/3rdparty/remotery/vis/index.html index 7d1620d5aca..b761290559a 100644 --- a/3rdparty/bgfx/3rdparty/remotery/vis/index.html +++ b/3rdparty/bgfx/3rdparty/remotery/vis/index.html @@ -17,6 +17,7 @@ <script type="text/javascript" src="extern/BrowserLib/Core/Code/Convert.js"></script> <script type="text/javascript" src="extern/BrowserLib/Core/Code/LocalStore.js"></script> <script type="text/javascript" src="extern/BrowserLib/Core/Code/Mouse.js"></script> + <script type="text/javascript" src="extern/BrowserLib/Core/Code/Keyboard.js"></script> <!-- User Interface Window Manager --> <script type="text/javascript" src="extern/BrowserLib/WindowManager/Code/WindowManager.js"></script> diff --git a/3rdparty/bgfx/3rdparty/renderdoc/renderdoc_app.h b/3rdparty/bgfx/3rdparty/renderdoc/renderdoc_app.h index 67c179ad0a9..a392cecbbd7 100644 --- a/3rdparty/bgfx/3rdparty/renderdoc/renderdoc_app.h +++ b/3rdparty/bgfx/3rdparty/renderdoc/renderdoc_app.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -29,11 +29,13 @@ #endif #if defined(WIN32) - #define RENDERDOC_CC __cdecl +#define RENDERDOC_CC __cdecl #elif defined(__linux__) - #define RENDERDOC_CC +#define RENDERDOC_CC +#elif defined(__APPLE__) +#define RENDERDOC_CC #else - #error "Unknown platform" +#error "Unknown platform" #endif #ifdef __cplusplus @@ -45,137 +47,144 @@ extern "C" { // This is a GUID/magic value used for when applications pass a path where shader debug // information can be found to match up with a stripped shader. -// the define can be used like so: const GUID RENDERDOC_ShaderDebugMagicValue = RENDERDOC_ShaderDebugMagicValue_value -#define RENDERDOC_ShaderDebugMagicValue_struct { 0xeab25520, 0x6670, 0x4865, 0x84, 0x29, 0x6c, 0x8, 0x51, 0x54, 0x00, 0xff } +// the define can be used like so: const GUID RENDERDOC_ShaderDebugMagicValue = +// RENDERDOC_ShaderDebugMagicValue_value +#define RENDERDOC_ShaderDebugMagicValue_struct \ + { \ + 0xeab25520, 0x6670, 0x4865, 0x84, 0x29, 0x6c, 0x8, 0x51, 0x54, 0x00, 0xff \ + } // as an alternative when you want a byte array (assuming x86 endianness): -#define RENDERDOC_ShaderDebugMagicValue_bytearray { 0x20, 0x55, 0xb2, 0xea, 0x70, 0x66, 0x65, 0x48, 0x84, 0x29, 0x6c, 0x8, 0x51, 0x54, 0x00, 0xff } - +#define RENDERDOC_ShaderDebugMagicValue_bytearray \ + { \ + 0x20, 0x55, 0xb2, 0xea, 0x70, 0x66, 0x65, 0x48, 0x84, 0x29, 0x6c, 0x8, 0x51, 0x54, 0x00, 0xff \ + } + // truncated version when only a uint64_t is available (e.g. Vulkan tags): #define RENDERDOC_ShaderDebugMagicValue_truncated 0x48656670eab25520ULL ////////////////////////////////////////////////////////////////////////////////////////////////// // RenderDoc capture options -// +// -typedef enum -{ - // Allow the application to enable vsync - // - // Default - enabled - // - // 1 - The application can enable or disable vsync at will - // 0 - vsync is force disabled - eRENDERDOC_Option_AllowVSync = 0, - - // Allow the application to enable fullscreen - // - // Default - enabled - // - // 1 - The application can enable or disable fullscreen at will - // 0 - fullscreen is force disabled - eRENDERDOC_Option_AllowFullscreen = 1, - - // Record API debugging events and messages - // - // Default - disabled - // - // 1 - Enable built-in API debugging features and records the results into - // the capture logfile, which is matched up with events on replay - // 0 - no API debugging is forcibly enabled - eRENDERDOC_Option_DebugDeviceMode = 2, - - // Capture CPU callstacks for API events - // - // Default - disabled - // - // 1 - Enables capturing of callstacks - // 0 - no callstacks are captured - eRENDERDOC_Option_CaptureCallstacks = 3, - - // When capturing CPU callstacks, only capture them from drawcalls. - // This option does nothing without the above option being enabled - // - // Default - disabled - // - // 1 - Only captures callstacks for drawcall type API events. - // Ignored if CaptureCallstacks is disabled - // 0 - Callstacks, if enabled, are captured for every event. - eRENDERDOC_Option_CaptureCallstacksOnlyDraws = 4, - - // Specify a delay in seconds to wait for a debugger to attach, after - // creating or injecting into a process, before continuing to allow it to run. - // - // 0 indicates no delay, and the process will run immediately after injection - // - // Default - 0 seconds - // - eRENDERDOC_Option_DelayForDebugger = 5, - - // Verify any writes to mapped buffers, by checking the memory after the - // bounds of the returned pointer to detect any modification. - // - // Default - disabled - // - // 1 - Verify any writes to mapped buffers - // 0 - No verification is performed, and overwriting bounds may cause - // crashes or corruption in RenderDoc - eRENDERDOC_Option_VerifyMapWrites = 6, - - // Hooks any system API calls that create child processes, and injects - // RenderDoc into them recursively with the same options. - // - // Default - disabled - // - // 1 - Hooks into spawned child processes - // 0 - Child processes are not hooked by RenderDoc - eRENDERDOC_Option_HookIntoChildren = 7, - - // By default RenderDoc only includes resources in the final logfile necessary - // for that frame, this allows you to override that behaviour. - // - // Default - disabled - // - // 1 - all live resources at the time of capture are included in the log - // and available for inspection - // 0 - only the resources referenced by the captured frame are included - eRENDERDOC_Option_RefAllResources = 8, - - // By default RenderDoc skips saving initial states for resources where the - // previous contents don't appear to be used, assuming that writes before - // reads indicate previous contents aren't used. - // - // Default - disabled - // - // 1 - initial contents at the start of each captured frame are saved, even if - // they are later overwritten or cleared before being used. - // 0 - unless a read is detected, initial contents will not be saved and will - // appear as black or empty data. - eRENDERDOC_Option_SaveAllInitials = 9, - - // In APIs that allow for the recording of command lists to be replayed later, - // RenderDoc may choose to not capture command lists before a frame capture is - // triggered, to reduce overheads. This means any command lists recorded once - // and replayed many times will not be available and may cause a failure to - // capture. - // - // Note this is only true for APIs where multithreading is difficult or - // discouraged. Newer APIs like Vulkan and D3D12 will ignore this option - // and always capture all command lists since the API is heavily oriented - // around it and the overheads have been reduced by API design. - // - // 1 - All command lists are captured from the start of the application - // 0 - Command lists are only captured if their recording begins during - // the period when a frame capture is in progress. - eRENDERDOC_Option_CaptureAllCmdLists = 10, - - // Mute API debugging output when the debug device mode option is enabled - // - // Default - enabled - // - // 1 - Mute any API debug messages from being displayed or passed through - // 0 - API debugging is displayed as normal - eRENDERDOC_Option_DebugOutputMute = 11, +typedef enum { + // Allow the application to enable vsync + // + // Default - enabled + // + // 1 - The application can enable or disable vsync at will + // 0 - vsync is force disabled + eRENDERDOC_Option_AllowVSync = 0, + + // Allow the application to enable fullscreen + // + // Default - enabled + // + // 1 - The application can enable or disable fullscreen at will + // 0 - fullscreen is force disabled + eRENDERDOC_Option_AllowFullscreen = 1, + + // Record API debugging events and messages + // + // Default - disabled + // + // 1 - Enable built-in API debugging features and records the results into + // the capture logfile, which is matched up with events on replay + // 0 - no API debugging is forcibly enabled + eRENDERDOC_Option_APIValidation = 2, + eRENDERDOC_Option_DebugDeviceMode = 2, // deprecated name of this enum + + // Capture CPU callstacks for API events + // + // Default - disabled + // + // 1 - Enables capturing of callstacks + // 0 - no callstacks are captured + eRENDERDOC_Option_CaptureCallstacks = 3, + + // When capturing CPU callstacks, only capture them from drawcalls. + // This option does nothing without the above option being enabled + // + // Default - disabled + // + // 1 - Only captures callstacks for drawcall type API events. + // Ignored if CaptureCallstacks is disabled + // 0 - Callstacks, if enabled, are captured for every event. + eRENDERDOC_Option_CaptureCallstacksOnlyDraws = 4, + + // Specify a delay in seconds to wait for a debugger to attach, after + // creating or injecting into a process, before continuing to allow it to run. + // + // 0 indicates no delay, and the process will run immediately after injection + // + // Default - 0 seconds + // + eRENDERDOC_Option_DelayForDebugger = 5, + + // Verify any writes to mapped buffers, by checking the memory after the + // bounds of the returned pointer to detect any modification. + // + // Default - disabled + // + // 1 - Verify any writes to mapped buffers + // 0 - No verification is performed, and overwriting bounds may cause + // crashes or corruption in RenderDoc + eRENDERDOC_Option_VerifyMapWrites = 6, + + // Hooks any system API calls that create child processes, and injects + // RenderDoc into them recursively with the same options. + // + // Default - disabled + // + // 1 - Hooks into spawned child processes + // 0 - Child processes are not hooked by RenderDoc + eRENDERDOC_Option_HookIntoChildren = 7, + + // By default RenderDoc only includes resources in the final logfile necessary + // for that frame, this allows you to override that behaviour. + // + // Default - disabled + // + // 1 - all live resources at the time of capture are included in the log + // and available for inspection + // 0 - only the resources referenced by the captured frame are included + eRENDERDOC_Option_RefAllResources = 8, + + // By default RenderDoc skips saving initial states for resources where the + // previous contents don't appear to be used, assuming that writes before + // reads indicate previous contents aren't used. + // + // Default - disabled + // + // 1 - initial contents at the start of each captured frame are saved, even if + // they are later overwritten or cleared before being used. + // 0 - unless a read is detected, initial contents will not be saved and will + // appear as black or empty data. + eRENDERDOC_Option_SaveAllInitials = 9, + + // In APIs that allow for the recording of command lists to be replayed later, + // RenderDoc may choose to not capture command lists before a frame capture is + // triggered, to reduce overheads. This means any command lists recorded once + // and replayed many times will not be available and may cause a failure to + // capture. + // + // Note this is only true for APIs where multithreading is difficult or + // discouraged. Newer APIs like Vulkan and D3D12 will ignore this option + // and always capture all command lists since the API is heavily oriented + // around it and the overheads have been reduced by API design. + // + // 1 - All command lists are captured from the start of the application + // 0 - Command lists are only captured if their recording begins during + // the period when a frame capture is in progress. + eRENDERDOC_Option_CaptureAllCmdLists = 10, + + // Mute API debugging output when the API validation mode option is enabled + // + // Default - enabled + // + // 1 - Mute any API debug messages from being displayed or passed through + // 0 - API debugging is displayed as normal + eRENDERDOC_Option_DebugOutputMute = 11, } RENDERDOC_CaptureOption; @@ -183,140 +192,135 @@ typedef enum // // Returns 1 if the option and value are valid // Returns 0 if either is invalid and the option is unchanged -typedef int (RENDERDOC_CC *pRENDERDOC_SetCaptureOptionU32)(RENDERDOC_CaptureOption opt, uint32_t val); -typedef int (RENDERDOC_CC *pRENDERDOC_SetCaptureOptionF32)(RENDERDOC_CaptureOption opt, float val); +typedef int(RENDERDOC_CC *pRENDERDOC_SetCaptureOptionU32)(RENDERDOC_CaptureOption opt, uint32_t val); +typedef int(RENDERDOC_CC *pRENDERDOC_SetCaptureOptionF32)(RENDERDOC_CaptureOption opt, float val); // Gets the current value of an option as a uint32_t // // If the option is invalid, 0xffffffff is returned -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetCaptureOptionU32)(RENDERDOC_CaptureOption opt); +typedef uint32_t(RENDERDOC_CC *pRENDERDOC_GetCaptureOptionU32)(RENDERDOC_CaptureOption opt); // Gets the current value of an option as a float // // If the option is invalid, -FLT_MAX is returned -typedef float (RENDERDOC_CC *pRENDERDOC_GetCaptureOptionF32)(RENDERDOC_CaptureOption opt); - -typedef enum -{ - // '0' - '9' matches ASCII values - eRENDERDOC_Key_0 = 0x30, - eRENDERDOC_Key_1 = 0x31, - eRENDERDOC_Key_2 = 0x32, - eRENDERDOC_Key_3 = 0x33, - eRENDERDOC_Key_4 = 0x34, - eRENDERDOC_Key_5 = 0x35, - eRENDERDOC_Key_6 = 0x36, - eRENDERDOC_Key_7 = 0x37, - eRENDERDOC_Key_8 = 0x38, - eRENDERDOC_Key_9 = 0x39, - - // 'A' - 'Z' matches ASCII values - eRENDERDOC_Key_A = 0x41, - eRENDERDOC_Key_B = 0x42, - eRENDERDOC_Key_C = 0x43, - eRENDERDOC_Key_D = 0x44, - eRENDERDOC_Key_E = 0x45, - eRENDERDOC_Key_F = 0x46, - eRENDERDOC_Key_G = 0x47, - eRENDERDOC_Key_H = 0x48, - eRENDERDOC_Key_I = 0x49, - eRENDERDOC_Key_J = 0x4A, - eRENDERDOC_Key_K = 0x4B, - eRENDERDOC_Key_L = 0x4C, - eRENDERDOC_Key_M = 0x4D, - eRENDERDOC_Key_N = 0x4E, - eRENDERDOC_Key_O = 0x4F, - eRENDERDOC_Key_P = 0x50, - eRENDERDOC_Key_Q = 0x51, - eRENDERDOC_Key_R = 0x52, - eRENDERDOC_Key_S = 0x53, - eRENDERDOC_Key_T = 0x54, - eRENDERDOC_Key_U = 0x55, - eRENDERDOC_Key_V = 0x56, - eRENDERDOC_Key_W = 0x57, - eRENDERDOC_Key_X = 0x58, - eRENDERDOC_Key_Y = 0x59, - eRENDERDOC_Key_Z = 0x5A, - - // leave the rest of the ASCII range free - // in case we want to use it later - eRENDERDOC_Key_NonPrintable = 0x100, - - eRENDERDOC_Key_Divide, - eRENDERDOC_Key_Multiply, - eRENDERDOC_Key_Subtract, - eRENDERDOC_Key_Plus, - - eRENDERDOC_Key_F1, - eRENDERDOC_Key_F2, - eRENDERDOC_Key_F3, - eRENDERDOC_Key_F4, - eRENDERDOC_Key_F5, - eRENDERDOC_Key_F6, - eRENDERDOC_Key_F7, - eRENDERDOC_Key_F8, - eRENDERDOC_Key_F9, - eRENDERDOC_Key_F10, - eRENDERDOC_Key_F11, - eRENDERDOC_Key_F12, - - eRENDERDOC_Key_Home, - eRENDERDOC_Key_End, - eRENDERDOC_Key_Insert, - eRENDERDOC_Key_Delete, - eRENDERDOC_Key_PageUp, - eRENDERDOC_Key_PageDn, - - eRENDERDOC_Key_Backspace, - eRENDERDOC_Key_Tab, - eRENDERDOC_Key_PrtScrn, - eRENDERDOC_Key_Pause, - - eRENDERDOC_Key_Max, +typedef float(RENDERDOC_CC *pRENDERDOC_GetCaptureOptionF32)(RENDERDOC_CaptureOption opt); + +typedef enum { + // '0' - '9' matches ASCII values + eRENDERDOC_Key_0 = 0x30, + eRENDERDOC_Key_1 = 0x31, + eRENDERDOC_Key_2 = 0x32, + eRENDERDOC_Key_3 = 0x33, + eRENDERDOC_Key_4 = 0x34, + eRENDERDOC_Key_5 = 0x35, + eRENDERDOC_Key_6 = 0x36, + eRENDERDOC_Key_7 = 0x37, + eRENDERDOC_Key_8 = 0x38, + eRENDERDOC_Key_9 = 0x39, + + // 'A' - 'Z' matches ASCII values + eRENDERDOC_Key_A = 0x41, + eRENDERDOC_Key_B = 0x42, + eRENDERDOC_Key_C = 0x43, + eRENDERDOC_Key_D = 0x44, + eRENDERDOC_Key_E = 0x45, + eRENDERDOC_Key_F = 0x46, + eRENDERDOC_Key_G = 0x47, + eRENDERDOC_Key_H = 0x48, + eRENDERDOC_Key_I = 0x49, + eRENDERDOC_Key_J = 0x4A, + eRENDERDOC_Key_K = 0x4B, + eRENDERDOC_Key_L = 0x4C, + eRENDERDOC_Key_M = 0x4D, + eRENDERDOC_Key_N = 0x4E, + eRENDERDOC_Key_O = 0x4F, + eRENDERDOC_Key_P = 0x50, + eRENDERDOC_Key_Q = 0x51, + eRENDERDOC_Key_R = 0x52, + eRENDERDOC_Key_S = 0x53, + eRENDERDOC_Key_T = 0x54, + eRENDERDOC_Key_U = 0x55, + eRENDERDOC_Key_V = 0x56, + eRENDERDOC_Key_W = 0x57, + eRENDERDOC_Key_X = 0x58, + eRENDERDOC_Key_Y = 0x59, + eRENDERDOC_Key_Z = 0x5A, + + // leave the rest of the ASCII range free + // in case we want to use it later + eRENDERDOC_Key_NonPrintable = 0x100, + + eRENDERDOC_Key_Divide, + eRENDERDOC_Key_Multiply, + eRENDERDOC_Key_Subtract, + eRENDERDOC_Key_Plus, + + eRENDERDOC_Key_F1, + eRENDERDOC_Key_F2, + eRENDERDOC_Key_F3, + eRENDERDOC_Key_F4, + eRENDERDOC_Key_F5, + eRENDERDOC_Key_F6, + eRENDERDOC_Key_F7, + eRENDERDOC_Key_F8, + eRENDERDOC_Key_F9, + eRENDERDOC_Key_F10, + eRENDERDOC_Key_F11, + eRENDERDOC_Key_F12, + + eRENDERDOC_Key_Home, + eRENDERDOC_Key_End, + eRENDERDOC_Key_Insert, + eRENDERDOC_Key_Delete, + eRENDERDOC_Key_PageUp, + eRENDERDOC_Key_PageDn, + + eRENDERDOC_Key_Backspace, + eRENDERDOC_Key_Tab, + eRENDERDOC_Key_PrtScrn, + eRENDERDOC_Key_Pause, + + eRENDERDOC_Key_Max, } RENDERDOC_InputButton; // Sets which key or keys can be used to toggle focus between multiple windows // // If keys is NULL or num is 0, toggle keys will be disabled -typedef void (RENDERDOC_CC *pRENDERDOC_SetFocusToggleKeys)(RENDERDOC_InputButton *keys, int num); +typedef void(RENDERDOC_CC *pRENDERDOC_SetFocusToggleKeys)(RENDERDOC_InputButton *keys, int num); // Sets which key or keys can be used to capture the next frame // // If keys is NULL or num is 0, captures keys will be disabled -typedef void (RENDERDOC_CC *pRENDERDOC_SetCaptureKeys)(RENDERDOC_InputButton *keys, int num); +typedef void(RENDERDOC_CC *pRENDERDOC_SetCaptureKeys)(RENDERDOC_InputButton *keys, int num); -typedef enum -{ - // This single bit controls whether the overlay is enabled or disabled globally - eRENDERDOC_Overlay_Enabled = 0x1, +typedef enum { + // This single bit controls whether the overlay is enabled or disabled globally + eRENDERDOC_Overlay_Enabled = 0x1, - // Show the average framerate over several seconds as well as min/max - eRENDERDOC_Overlay_FrameRate = 0x2, + // Show the average framerate over several seconds as well as min/max + eRENDERDOC_Overlay_FrameRate = 0x2, - // Show the current frame number - eRENDERDOC_Overlay_FrameNumber = 0x4, + // Show the current frame number + eRENDERDOC_Overlay_FrameNumber = 0x4, - // Show a list of recent captures, and how many captures have been made - eRENDERDOC_Overlay_CaptureList = 0x8, + // Show a list of recent captures, and how many captures have been made + eRENDERDOC_Overlay_CaptureList = 0x8, - // Default values for the overlay mask - eRENDERDOC_Overlay_Default = - (eRENDERDOC_Overlay_Enabled| - eRENDERDOC_Overlay_FrameRate| - eRENDERDOC_Overlay_FrameNumber| - eRENDERDOC_Overlay_CaptureList), + // Default values for the overlay mask + eRENDERDOC_Overlay_Default = (eRENDERDOC_Overlay_Enabled | eRENDERDOC_Overlay_FrameRate | + eRENDERDOC_Overlay_FrameNumber | eRENDERDOC_Overlay_CaptureList), - // Enable all bits - eRENDERDOC_Overlay_All = ~0U, + // Enable all bits + eRENDERDOC_Overlay_All = ~0U, - // Disable all bits - eRENDERDOC_Overlay_None = 0, + // Disable all bits + eRENDERDOC_Overlay_None = 0, } RENDERDOC_OverlayBits; // returns the overlay bits that have been set -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetOverlayBits)(); +typedef uint32_t(RENDERDOC_CC *pRENDERDOC_GetOverlayBits)(); // sets the overlay bits with an and & or mask -typedef void (RENDERDOC_CC *pRENDERDOC_MaskOverlayBits)(uint32_t And, uint32_t Or); +typedef void(RENDERDOC_CC *pRENDERDOC_MaskOverlayBits)(uint32_t And, uint32_t Or); // this function will attempt to shut down RenderDoc. // @@ -324,14 +328,14 @@ typedef void (RENDERDOC_CC *pRENDERDOC_MaskOverlayBits)(uint32_t And, uint32_t O // the dll is loaded, before any API work happens. RenderDoc will remove its // injected hooks and shut down. Behaviour is undefined if this is called // after any API functions have been called. -typedef void (RENDERDOC_CC *pRENDERDOC_Shutdown)(); +typedef void(RENDERDOC_CC *pRENDERDOC_Shutdown)(); // This function will unload RenderDoc's crash handler. // // If you use your own crash handler and don't want RenderDoc's handler to // intercede, you can call this function to unload it and any unhandled // exceptions will pass to the next handler. -typedef void (RENDERDOC_CC *pRENDERDOC_UnloadCrashHandler)(); +typedef void(RENDERDOC_CC *pRENDERDOC_UnloadCrashHandler)(); // Sets the logfile path template // @@ -350,13 +354,13 @@ typedef void (RENDERDOC_CC *pRENDERDOC_UnloadCrashHandler)(); // // Capture #1 -> my_captures/example_frame123.rdc // Capture #2 -> my_captures/example_frame456.rdc -typedef void (RENDERDOC_CC *pRENDERDOC_SetLogFilePathTemplate)(const char *pathtemplate); +typedef void(RENDERDOC_CC *pRENDERDOC_SetLogFilePathTemplate)(const char *pathtemplate); // returns the current logfile template, see SetLogFileTemplate above, as a UTF-8 string -typedef const char* (RENDERDOC_CC *pRENDERDOC_GetLogFilePathTemplate)(); +typedef const char *(RENDERDOC_CC *pRENDERDOC_GetLogFilePathTemplate)(); // returns the number of captures that have been made -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetNumCaptures)(); +typedef uint32_t(RENDERDOC_CC *pRENDERDOC_GetNumCaptures)(); // This function returns the details of a capture, by index. New captures are added // to the end of the list. @@ -372,13 +376,11 @@ typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetNumCaptures)(); // // Note: when captures are deleted in the UI they will remain in this list, so the // logfile path may not exist anymore. -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetCapture)(uint32_t idx, char *logfile, uint32_t *pathlength, uint64_t *timestamp); - -// capture the next frame on whichever window and API is currently considered active -typedef void (RENDERDOC_CC *pRENDERDOC_TriggerCapture)(); +typedef uint32_t(RENDERDOC_CC *pRENDERDOC_GetCapture)(uint32_t idx, char *logfile, + uint32_t *pathlength, uint64_t *timestamp); // returns 1 if the RenderDoc UI is connected to this application, 0 otherwise -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_IsRemoteAccessConnected)(); +typedef uint32_t(RENDERDOC_CC *pRENDERDOC_IsRemoteAccessConnected)(); // This function will launch the Replay UI associated with the RenderDoc library injected // into the running application. @@ -389,12 +391,13 @@ typedef uint32_t (RENDERDOC_CC *pRENDERDOC_IsRemoteAccessConnected)(); // if cmdline is NULL, the command line will be empty. // // returns the PID of the replay UI if successful, 0 if not successful. -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_LaunchReplayUI)(uint32_t connectRemoteAccess, const char *cmdline); +typedef uint32_t(RENDERDOC_CC *pRENDERDOC_LaunchReplayUI)(uint32_t connectRemoteAccess, + const char *cmdline); // RenderDoc can return a higher version than requested if it's backwards compatible, // this function returns the actual version returned. If a parameter is NULL, it will be // ignored and the others will be filled out. -typedef void (RENDERDOC_CC *pRENDERDOC_GetAPIVersion)(int *major, int *minor, int *patch); +typedef void(RENDERDOC_CC *pRENDERDOC_GetAPIVersion)(int *major, int *minor, int *patch); ////////////////////////////////////////////////////////////////////////// // Capturing functions @@ -403,16 +406,23 @@ typedef void (RENDERDOC_CC *pRENDERDOC_GetAPIVersion)(int *major, int *minor, in // A device pointer is a pointer to the API's root handle. // // This would be an ID3D11Device, HGLRC/GLXContext, ID3D12Device, etc -typedef void* RENDERDOC_DevicePointer; +typedef void *RENDERDOC_DevicePointer; // A window handle is the OS's native window handle // // This would be an HWND, GLXDrawable, etc -typedef void* RENDERDOC_WindowHandle; +typedef void *RENDERDOC_WindowHandle; // This sets the RenderDoc in-app overlay in the API/window pair as 'active' and it will // respond to keypresses. Neither parameter can be NULL -typedef void (RENDERDOC_CC *pRENDERDOC_SetActiveWindow)(RENDERDOC_DevicePointer device, RENDERDOC_WindowHandle wndHandle); +typedef void(RENDERDOC_CC *pRENDERDOC_SetActiveWindow)(RENDERDOC_DevicePointer device, + RENDERDOC_WindowHandle wndHandle); + +// capture the next frame on whichever window and API is currently considered active +typedef void(RENDERDOC_CC *pRENDERDOC_TriggerCapture)(); + +// capture the next N frames on whichever window and API is currently considered active +typedef void(RENDERDOC_CC *pRENDERDOC_TriggerMultiFrameCapture)(uint32_t numFrames); // When choosing either a device pointer or a window handle to capture, you can pass NULL. // Passing NULL specifies a 'wildcard' match against anything. This allows you to specify @@ -432,24 +442,26 @@ typedef void (RENDERDOC_CC *pRENDERDOC_SetActiveWindow)(RENDERDOC_DevicePointer // // The results are undefined (including crashes) if two captures are started overlapping, // even on separate devices and/oror windows. -typedef void (RENDERDOC_CC *pRENDERDOC_StartFrameCapture)(RENDERDOC_DevicePointer device, RENDERDOC_WindowHandle wndHandle); +typedef void(RENDERDOC_CC *pRENDERDOC_StartFrameCapture)(RENDERDOC_DevicePointer device, + RENDERDOC_WindowHandle wndHandle); // Returns whether or not a frame capture is currently ongoing anywhere. // // This will return 1 if a capture is ongoing, and 0 if there is no capture running -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_IsFrameCapturing)(); +typedef uint32_t(RENDERDOC_CC *pRENDERDOC_IsFrameCapturing)(); // Ends capturing immediately. // // This will return 1 if the capture succeeded, and 0 if there was an error capturing. -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_EndFrameCapture)(RENDERDOC_DevicePointer device, RENDERDOC_WindowHandle wndHandle); +typedef uint32_t(RENDERDOC_CC *pRENDERDOC_EndFrameCapture)(RENDERDOC_DevicePointer device, + RENDERDOC_WindowHandle wndHandle); ////////////////////////////////////////////////////////////////////////////////////////////////// // RenderDoc API versions -// +// // RenderDoc uses semantic versioning (http://semver.org/). -// +// // MAJOR version is incremented when incompatible API changes happen. // MINOR version is incremented when functionality is added in a backwards-compatible manner. // PATCH version is incremented when backwards-compatible bug fixes happen. @@ -457,10 +469,11 @@ typedef uint32_t (RENDERDOC_CC *pRENDERDOC_EndFrameCapture)(RENDERDOC_DevicePoin // Note that this means the API returned can be higher than the one you might have requested. // e.g. if you are running against a newer RenderDoc that supports 1.0.1, it will be returned // instead of 1.0.0. You can check this with the GetAPIVersion entry point -typedef enum -{ - eRENDERDOC_API_Version_1_0_0 = 10000, // RENDERDOC_API_1_0_0 = 1 00 00 - eRENDERDOC_API_Version_1_0_1 = 10001, // RENDERDOC_API_1_0_1 = 1 00 01 +typedef enum { + eRENDERDOC_API_Version_1_0_0 = 10000, // RENDERDOC_API_1_0_0 = 1 00 00 + eRENDERDOC_API_Version_1_0_1 = 10001, // RENDERDOC_API_1_0_1 = 1 00 01 + eRENDERDOC_API_Version_1_0_2 = 10002, // RENDERDOC_API_1_0_2 = 1 00 02 + eRENDERDOC_API_Version_1_1_0 = 10100, // RENDERDOC_API_1_1_0 = 1 01 00 } RENDERDOC_Version; // API version changelog: @@ -468,52 +481,59 @@ typedef enum // 1.0.0 - initial release // 1.0.1 - Bugfix: IsFrameCapturing() was returning false for captures that were triggered // by keypress or TriggerCapture, instead of Start/EndFrameCapture. +// 1.0.2 - Refactor: Renamed eRENDERDOC_Option_DebugDeviceMode to eRENDERDOC_Option_APIValidation +// 1.1.0 - Add feature: TriggerMultiFrameCapture(). Backwards compatible with 1.0.x since the new +// function pointer is added to the end of the struct, the original layout is identical -// eRENDERDOC_API_Version_1_0_1 +// eRENDERDOC_API_Version_1_1_0 typedef struct { - pRENDERDOC_GetAPIVersion GetAPIVersion; + pRENDERDOC_GetAPIVersion GetAPIVersion; + + pRENDERDOC_SetCaptureOptionU32 SetCaptureOptionU32; + pRENDERDOC_SetCaptureOptionF32 SetCaptureOptionF32; - pRENDERDOC_SetCaptureOptionU32 SetCaptureOptionU32; - pRENDERDOC_SetCaptureOptionF32 SetCaptureOptionF32; + pRENDERDOC_GetCaptureOptionU32 GetCaptureOptionU32; + pRENDERDOC_GetCaptureOptionF32 GetCaptureOptionF32; - pRENDERDOC_GetCaptureOptionU32 GetCaptureOptionU32; - pRENDERDOC_GetCaptureOptionF32 GetCaptureOptionF32; + pRENDERDOC_SetFocusToggleKeys SetFocusToggleKeys; + pRENDERDOC_SetCaptureKeys SetCaptureKeys; - pRENDERDOC_SetFocusToggleKeys SetFocusToggleKeys; - pRENDERDOC_SetCaptureKeys SetCaptureKeys; + pRENDERDOC_GetOverlayBits GetOverlayBits; + pRENDERDOC_MaskOverlayBits MaskOverlayBits; - pRENDERDOC_GetOverlayBits GetOverlayBits; - pRENDERDOC_MaskOverlayBits MaskOverlayBits; + pRENDERDOC_Shutdown Shutdown; + pRENDERDOC_UnloadCrashHandler UnloadCrashHandler; - pRENDERDOC_Shutdown Shutdown; - pRENDERDOC_UnloadCrashHandler UnloadCrashHandler; + pRENDERDOC_SetLogFilePathTemplate SetLogFilePathTemplate; + pRENDERDOC_GetLogFilePathTemplate GetLogFilePathTemplate; - pRENDERDOC_SetLogFilePathTemplate SetLogFilePathTemplate; - pRENDERDOC_GetLogFilePathTemplate GetLogFilePathTemplate; + pRENDERDOC_GetNumCaptures GetNumCaptures; + pRENDERDOC_GetCapture GetCapture; - pRENDERDOC_GetNumCaptures GetNumCaptures; - pRENDERDOC_GetCapture GetCapture; + pRENDERDOC_TriggerCapture TriggerCapture; - pRENDERDOC_TriggerCapture TriggerCapture; + pRENDERDOC_IsRemoteAccessConnected IsRemoteAccessConnected; + pRENDERDOC_LaunchReplayUI LaunchReplayUI; - pRENDERDOC_IsRemoteAccessConnected IsRemoteAccessConnected; - pRENDERDOC_LaunchReplayUI LaunchReplayUI; + pRENDERDOC_SetActiveWindow SetActiveWindow; - pRENDERDOC_SetActiveWindow SetActiveWindow; + pRENDERDOC_StartFrameCapture StartFrameCapture; + pRENDERDOC_IsFrameCapturing IsFrameCapturing; + pRENDERDOC_EndFrameCapture EndFrameCapture; - pRENDERDOC_StartFrameCapture StartFrameCapture; - pRENDERDOC_IsFrameCapturing IsFrameCapturing; - pRENDERDOC_EndFrameCapture EndFrameCapture; -} RENDERDOC_API_1_0_1; + pRENDERDOC_TriggerMultiFrameCapture TriggerMultiFrameCapture; +} RENDERDOC_API_1_1_0; -typedef RENDERDOC_API_1_0_1 RENDERDOC_API_1_0_0; +typedef RENDERDOC_API_1_1_0 RENDERDOC_API_1_0_0; +typedef RENDERDOC_API_1_1_0 RENDERDOC_API_1_0_1; +typedef RENDERDOC_API_1_1_0 RENDERDOC_API_1_0_2; ////////////////////////////////////////////////////////////////////////////////////////////////// // RenderDoc API entry point -// +// // This entry point can be obtained via GetProcAddress/dlsym if RenderDoc is available. -// +// // The name is the same as the typedef - "RENDERDOC_GetAPI" // // This function is not thread safe, and should not be called on multiple threads at once. @@ -531,8 +551,8 @@ typedef RENDERDOC_API_1_0_1 RENDERDOC_API_1_0_0; // 1 - if the outAPIPointers has been filled with a pointer to the API struct requested // 0 - if the requested version is not supported or the arguments are invalid. // -typedef int (RENDERDOC_CC *pRENDERDOC_GetAPI)(RENDERDOC_Version version, void **outAPIPointers); +typedef int(RENDERDOC_CC *pRENDERDOC_GetAPI)(RENDERDOC_Version version, void **outAPIPointers); #ifdef __cplusplus -} // extern "C" +} // extern "C" #endif diff --git a/3rdparty/bgfx/3rdparty/stb/stb_image.c b/3rdparty/bgfx/3rdparty/stb/stb_image.c index 16e04103441..ad26b74f55d 100644 --- a/3rdparty/bgfx/3rdparty/stb/stb_image.c +++ b/3rdparty/bgfx/3rdparty/stb/stb_image.c @@ -1375,18 +1375,18 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r // convert source image with img_n components to one with req_comp components; // avoid switch per pixel, so use switch per scanline and massive macros switch (COMBO(img_n, req_comp)) { - CASE(1,2) { dest[0]=src[0]; dest[1]=255; } break; - CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=255; } break; - CASE(2,1) { dest[0]=src[0]; } break; - CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; - CASE(3,4) { dest[0]=src[0]; dest[1]=src[1]; dest[2]=src[2]; dest[3]=255; } break; - CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; - CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = 255; } break; - CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; - CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break; - CASE(4,3) { dest[0]=src[0]; dest[1]=src[1]; dest[2]=src[2]; } break; + CASE(1,2) dest[0]=src[0], dest[1]=255; break; + CASE(1,3) dest[0]=dest[1]=dest[2]=src[0]; break; + CASE(1,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; break; + CASE(2,1) dest[0]=src[0]; break; + CASE(2,3) dest[0]=dest[1]=dest[2]=src[0]; break; + CASE(2,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; break; + CASE(3,4) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; break; + CASE(3,1) dest[0]=stbi__compute_y(src[0],src[1],src[2]); break; + CASE(3,2) dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; break; + CASE(4,1) dest[0]=stbi__compute_y(src[0],src[1],src[2]); break; + CASE(4,2) dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; break; + CASE(4,3) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; break; default: STBI_ASSERT(0); } #undef CASE @@ -4101,12 +4101,12 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r switch (filter) { // "none" filter turns into a memcpy here; make that explicit. case STBI__F_none: memcpy(cur, raw, nk); break; - CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break; - CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; - CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break; - CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break; - CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break; - CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break; + CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); break; + CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; + CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); break; + CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); break; + CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); break; + CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); break; } #undef CASE raw += nk; @@ -4117,13 +4117,13 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ for (k=0; k < filter_bytes; ++k) switch (filter) { - CASE(STBI__F_none) { cur[k] = raw[k]; } break; - CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break; - CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; - CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break; - CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break; - CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break; - CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break; + CASE(STBI__F_none) cur[k] = raw[k]; break; + CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); break; + CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; + CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); break; + CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); break; + CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); break; + CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); break; } #undef CASE diff --git a/3rdparty/bgfx/README.md b/3rdparty/bgfx/README.md index 5e45925d013..9f5c27d2059 100644 --- a/3rdparty/bgfx/README.md +++ b/3rdparty/bgfx/README.md @@ -139,7 +139,6 @@ https://github.com/mamedev/mame MAME - Multiple Arcade Machine Emulator https://blackshift.itch.io/blackshift - Blackshift is a grid-based, space-themed action puzzle game which isn't afraid of complexity — think Chip's Challenge on crack. -https://www.youtube.com/watch?v=PUl8612Y-ds <a href="http://www.youtube.com/watch?feature=player_embedded&v=PUl8612Y-ds " target="_blank"><img src="http://img.youtube.com/vi/PUl8612Y-ds/0.jpg" alt="Blackshift Trailer, May 2016" @@ -150,7 +149,15 @@ with Linearly Transformed Cosines, Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt, ACM SIGGRAPH 2016 <a href="http://www.youtube.com/watch?feature=player_embedded&v=ZLRgEN7AQgM " target="_blank"><img src="http://img.youtube.com/vi/ZLRgEN7AQgM/0.jpg" -alt="Real-Time Polygonal-Light Shading with Linearly Transformed Cosines " +alt="Real-Time Polygonal-Light Shading with Linearly Transformed Cosines" +width="640" height="480" border="0" /></a> + +http://www.dogbytegames.com/dead_venture.html - Dead Venture is a new Drive 'N +Gun game where you help a handful of survivals reach the safe haven: a military +base on a far island. +<a href="http://www.youtube.com/watch?feature=player_embedded&v=CgMr1g12yXw +" target="_blank"><img src="http://img.youtube.com/vi/CgMr1g12yXw/0.jpg" +alt="Dead Venture - Gameplay Teaser (iOS / Android)" width="640" height="480" border="0" /></a> [License (BSD 2-clause)](https://bkaradzic.github.io/bgfx/license.html) diff --git a/3rdparty/bgfx/examples/14-shadowvolumes/shadowvolumes.cpp b/3rdparty/bgfx/examples/14-shadowvolumes/shadowvolumes.cpp index 8b08dec93cb..3ebe122d776 100644 --- a/3rdparty/bgfx/examples/14-shadowvolumes/shadowvolumes.cpp +++ b/3rdparty/bgfx/examples/14-shadowvolumes/shadowvolumes.cpp @@ -23,7 +23,7 @@ using namespace std::tr1; #include <bx/timer.h> #include <bx/allocator.h> #include <bx/hash.h> -#include <bx/float4_t.h> +#include <bx/simd_t.h> #include <bx/fpumath.h> #include <bx/crtimpl.h> #include "entry/entry.h" @@ -1513,9 +1513,9 @@ void shadowVolumeCreate(ShadowVolume& _shadowVolume using namespace bx; - const float4_t lx = float4_splat(_light[0]); - const float4_t ly = float4_splat(_light[1]); - const float4_t lz = float4_splat(_light[2]); + const simd128_t lx = simd_splat(_light[0]); + const simd128_t ly = simd_splat(_light[1]); + const simd128_t lz = simd_splat(_light[2]); for (; ii < numEdgesRounded; ii+=2) { @@ -1524,47 +1524,47 @@ void shadowVolumeCreate(ShadowVolume& _shadowVolume const Plane* edgePlane0 = &edgePlanes[ii*2]; const Plane* edgePlane1 = &edgePlanes[ii*2 + 2]; - const float4_t reverse = - float4_ild(edge0.m_faceReverseOrder[0] + const simd128_t reverse = + simd_ild(edge0.m_faceReverseOrder[0] , edge1.m_faceReverseOrder[0] , edge0.m_faceReverseOrder[1] , edge1.m_faceReverseOrder[1] ); - const float4_t p00 = float4_ld(edgePlane0[0].m_plane); - const float4_t p10 = float4_ld(edgePlane1[0].m_plane); - const float4_t p01 = float4_ld(edgePlane0[1].m_plane); - const float4_t p11 = float4_ld(edgePlane1[1].m_plane); - - const float4_t xxyy0 = float4_shuf_xAyB(p00, p01); - const float4_t zzww0 = float4_shuf_zCwD(p00, p01); - const float4_t xxyy1 = float4_shuf_xAyB(p10, p11); - const float4_t zzww1 = float4_shuf_zCwD(p10, p11); - - const float4_t vX = float4_shuf_xAyB(xxyy0, xxyy1); - const float4_t vY = float4_shuf_zCwD(xxyy0, xxyy1); - const float4_t vZ = float4_shuf_xAyB(zzww0, zzww1); - const float4_t vW = float4_shuf_zCwD(zzww0, zzww1); - - const float4_t r0 = float4_mul(vX, lx); - const float4_t r1 = float4_mul(vY, ly); - const float4_t r2 = float4_mul(vZ, lz); - - const float4_t dot = float4_add(r0, float4_add(r1, r2) ); - const float4_t f = float4_add(dot, vW); - - const float4_t zero = float4_zero(); - const float4_t mask = float4_cmpgt(f, zero); - const float4_t onef = float4_splat(1.0f); - const float4_t tmp0 = float4_and(mask, onef); - const float4_t tmp1 = float4_ftoi(tmp0); - const float4_t tmp2 = float4_xor(tmp1, reverse); - const float4_t tmp3 = float4_sll(tmp2, 1); - const float4_t onei = float4_isplat(1); - const float4_t tmp4 = float4_isub(tmp3, onei); + const simd128_t p00 = simd_ld(edgePlane0[0].m_plane); + const simd128_t p10 = simd_ld(edgePlane1[0].m_plane); + const simd128_t p01 = simd_ld(edgePlane0[1].m_plane); + const simd128_t p11 = simd_ld(edgePlane1[1].m_plane); + + const simd128_t xxyy0 = simd_shuf_xAyB(p00, p01); + const simd128_t zzww0 = simd_shuf_zCwD(p00, p01); + const simd128_t xxyy1 = simd_shuf_xAyB(p10, p11); + const simd128_t zzww1 = simd_shuf_zCwD(p10, p11); + + const simd128_t vX = simd_shuf_xAyB(xxyy0, xxyy1); + const simd128_t vY = simd_shuf_zCwD(xxyy0, xxyy1); + const simd128_t vZ = simd_shuf_xAyB(zzww0, zzww1); + const simd128_t vW = simd_shuf_zCwD(zzww0, zzww1); + + const simd128_t r0 = simd_mul(vX, lx); + const simd128_t r1 = simd_mul(vY, ly); + const simd128_t r2 = simd_mul(vZ, lz); + + const simd128_t dot = simd_add(r0, simd_add(r1, r2) ); + const simd128_t f = simd_add(dot, vW); + + const simd128_t zero = simd_zero(); + const simd128_t mask = simd_cmpgt(f, zero); + const simd128_t onef = simd_splat(1.0f); + const simd128_t tmp0 = simd_and(mask, onef); + const simd128_t tmp1 = simd_ftoi(tmp0); + const simd128_t tmp2 = simd_xor(tmp1, reverse); + const simd128_t tmp3 = simd_sll(tmp2, 1); + const simd128_t onei = simd_isplat(1); + const simd128_t tmp4 = simd_isub(tmp3, onei); BX_ALIGN_DECL_16(int32_t res[4]); - float4_st(&res, tmp4); + simd_st(&res, tmp4); for (uint16_t jj = 0; jj < 2; ++jj) { diff --git a/3rdparty/bgfx/examples/15-shadowmaps-simple/fs_sms_shadow.sc b/3rdparty/bgfx/examples/15-shadowmaps-simple/fs_sms_shadow.sc index 3cdf1973f2e..cfaf3412c17 100644 --- a/3rdparty/bgfx/examples/15-shadowmaps-simple/fs_sms_shadow.sc +++ b/3rdparty/bgfx/examples/15-shadowmaps-simple/fs_sms_shadow.sc @@ -7,5 +7,4 @@ void main() { - gl_FragColor = vec4_splat(0.0); } diff --git a/3rdparty/bgfx/examples/18-ibl/fs_ibl_mesh.sc b/3rdparty/bgfx/examples/18-ibl/fs_ibl_mesh.sc index 28aa831331f..836400b9ed0 100644 --- a/3rdparty/bgfx/examples/18-ibl/fs_ibl_mesh.sc +++ b/3rdparty/bgfx/examples/18-ibl/fs_ibl_mesh.sc @@ -11,9 +11,9 @@ $input v_view, v_normal SAMPLERCUBE(s_texCube, 0); SAMPLERCUBE(s_texCubeIrr, 1); -vec3 calcFresnel(vec3 _cspec, float _dot) +vec3 calcFresnel(vec3 _cspec, float _dot, float _strength) { - return _cspec + (1.0 - _cspec)*pow(1.0 - _dot, 5.0); + return _cspec + (1.0 - _cspec)*pow(1.0 - _dot, 5.0) * _strength; } vec3 calcLambert(vec3 _cdiff, float _ndotl) @@ -50,35 +50,28 @@ void main() float hdotv = clamp(dot(hh, vv), 0.0, 1.0); // Material params. - vec3 albedo = u_rgbDiff.xyz; - float reflectivity = u_reflectivity; - float gloss = u_glossiness; + vec3 inAlbedo = u_rgbDiff.xyz; + float inReflectivity = u_reflectivity; + float inGloss = u_glossiness; // Reflection. vec3 refl; if (0.0 == u_metalOrSpec) // Metalness workflow. { - refl = mix(vec3_splat(0.04), albedo, reflectivity); + refl = mix(vec3_splat(0.04), inAlbedo, inReflectivity); } else // Specular workflow. { - refl = u_rgbSpec.xyz * vec3_splat(reflectivity); + refl = u_rgbSpec.xyz * vec3_splat(inReflectivity); } - vec3 dirF0 = calcFresnel(refl, hdotv); - vec3 envF0 = calcFresnel(refl, ndotv); + vec3 albedo = inAlbedo * (1.0 - inReflectivity); + vec3 dirFresnel = calcFresnel(refl, hdotv, inGloss); + vec3 envFresnel = calcFresnel(refl, ndotv, inGloss); - // Direct lighting. - vec3 dirSpec = dirF0; - vec3 dirDiff = albedo * 1.0-dirF0; - - vec3 lambert = u_doDiffuse * calcLambert(dirDiff, ndotl); - vec3 blinn = u_doSpecular * calcBlinn(dirSpec, ndoth, ndotl, specPwr(gloss)); + vec3 lambert = u_doDiffuse * calcLambert(albedo * (1.0 - dirFresnel), ndotl); + vec3 blinn = u_doSpecular * calcBlinn(dirFresnel, ndoth, ndotl, specPwr(inGloss)); vec3 direct = (lambert + blinn)*clight; - // Indirect lighting. - vec3 envSpec = envF0; - vec3 envDiff = albedo * 1.0-envF0; - // Note: Environment textures are filtered with cmft: https://github.com/dariomanesku/cmft // Params used: // --excludeBase true //!< First level mip is not filtered. @@ -86,7 +79,7 @@ void main() // --glossScale 10 //!< Spec power scale. See: specPwr(). // --glossBias 2 //!< Spec power bias. See: specPwr(). // --edgeFixup warp //!< This must be used on DirectX9. When fileted with 'warp', fixCubeLookup() should be used. - float mip = 1.0 + 5.0*(1.0 - gloss); // Use mip levels [1..6] for radiance. + float mip = 1.0 + 5.0*(1.0 - inGloss); // Use mip levels [1..6] for radiance. mat4 mtx; mtx[0] = u_mtx0; @@ -98,9 +91,11 @@ void main() vec3 cubeN = normalize(instMul(mtx, vec4(nn, 0.0)).xyz); cubeR = fixCubeLookup(cubeR, mip, 256.0); - vec3 radiance = u_doDiffuseIbl * envSpec * toLinear(textureCubeLod(s_texCube, cubeR, mip).xyz); - vec3 irradiance = u_doSpecularIbl * envDiff * toLinear(textureCube(s_texCubeIrr, cubeN).xyz); - vec3 indirect = radiance + irradiance; + vec3 radiance = toLinear(textureCubeLod(s_texCube, cubeR, mip).xyz); + vec3 irradiance = toLinear(textureCube(s_texCubeIrr, cubeN).xyz); + vec3 envDiffuse = albedo * irradiance * u_doDiffuseIbl; + vec3 envSpecular = envFresnel * radiance * u_doSpecularIbl; + vec3 indirect = envDiffuse + envSpecular; // Color. vec3 color = direct + indirect; diff --git a/3rdparty/bgfx/examples/18-ibl/ibl.cpp b/3rdparty/bgfx/examples/18-ibl/ibl.cpp index c21b729ae46..06f280f1c64 100644 --- a/3rdparty/bgfx/examples/18-ibl/ibl.cpp +++ b/3rdparty/bgfx/examples/18-ibl/ibl.cpp @@ -731,7 +731,7 @@ int _main_(int _argc, char** _argv) camera.envViewMtx(mtxEnvView); float mtxEnvRot[16]; bx::mtxRotateY(mtxEnvRot, settings.m_envRotCurr); - bx::mtxMul(uniforms.m_mtx, mtxEnvView, mtxEnvRot); + bx::mtxMul(uniforms.m_mtx, mtxEnvView, mtxEnvRot); // Used for Skybox. // Submit view 0. bgfx::setTexture(0, s_texCube, lightProbes[currentLightProbe].m_tex); @@ -742,6 +742,7 @@ int _main_(int _argc, char** _argv) bgfx::submit(0, programSky); // Submit view 1. + memcpy(uniforms.m_mtx, mtxEnvRot, 16*sizeof(float)); // Used for IBL. if (0 == settings.m_meshSelection) { // Submit bunny. @@ -749,6 +750,7 @@ int _main_(int _argc, char** _argv) bx::mtxSRT(mtx, 1.0f, 1.0f, 1.0f, 0.0f, bx::pi, 0.0f, 0.0f, -0.80f, 0.0f); bgfx::setTexture(0, s_texCube, lightProbes[currentLightProbe].m_tex); bgfx::setTexture(1, s_texCubeIrr, lightProbes[currentLightProbe].m_texIrr); + uniforms.submit(); meshSubmit(meshBunny, 1, programMesh, mtx); } else diff --git a/3rdparty/bgfx/examples/18-ibl/vs_ibl_skybox.sc b/3rdparty/bgfx/examples/18-ibl/vs_ibl_skybox.sc index b83fdd19e25..f3a15e0c73f 100644 --- a/3rdparty/bgfx/examples/18-ibl/vs_ibl_skybox.sc +++ b/3rdparty/bgfx/examples/18-ibl/vs_ibl_skybox.sc @@ -15,9 +15,9 @@ void main() { gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) ); - float fov = 45.0; + float fov = radians(45.0); float height = tan(fov*0.5); - float aspect = height*(4.0/3.0); + float aspect = height*(u_viewRect.z / u_viewRect.w); vec2 tex = (2.0*a_texcoord0-1.0) * vec2(aspect, height); mat4 mtx; diff --git a/3rdparty/bgfx/examples/19-oit/oit.cpp b/3rdparty/bgfx/examples/19-oit/oit.cpp index b9bbd041934..78c600331dd 100644 --- a/3rdparty/bgfx/examples/19-oit/oit.cpp +++ b/3rdparty/bgfx/examples/19-oit/oit.cpp @@ -410,6 +410,14 @@ class ExampleOIT : public entry::AppI | BGFX_STATE_MSAA ; + const uint64_t stateNoDepth = 0 + | BGFX_STATE_CULL_CW + | BGFX_STATE_RGB_WRITE + | BGFX_STATE_ALPHA_WRITE + | BGFX_STATE_DEPTH_TEST_ALWAYS + | BGFX_STATE_MSAA + ; + bgfx::ProgramHandle program = BGFX_INVALID_HANDLE; switch (m_mode) { @@ -428,7 +436,7 @@ class ExampleOIT : public entry::AppI program = m_wbSeparatePass; // Set render states. - bgfx::setState(state + bgfx::setState(stateNoDepth | BGFX_STATE_BLEND_FUNC_SEPARATE(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ZERO, BGFX_STATE_BLEND_INV_SRC_ALPHA) ); break; @@ -438,7 +446,7 @@ class ExampleOIT : public entry::AppI program = m_wbPass; // Set render states. - bgfx::setState(state + bgfx::setState(stateNoDepth | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE) | BGFX_STATE_BLEND_INDEPENDENT , 0 diff --git a/3rdparty/bgfx/examples/21-deferred/fs_deferred_light.sc b/3rdparty/bgfx/examples/21-deferred/fs_deferred_light.sc index 81f9ad25984..42571157767 100644 --- a/3rdparty/bgfx/examples/21-deferred/fs_deferred_light.sc +++ b/3rdparty/bgfx/examples/21-deferred/fs_deferred_light.sc @@ -56,11 +56,11 @@ vec3 calcLight(int _idx, vec3 _wpos, vec3 _normal, vec3 _view) float toClipSpaceDepth(float _depthTextureZ) { -#if BGFX_SHADER_LANGUAGE_HLSL +#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL return _depthTextureZ; #else return _depthTextureZ * 2.0 - 1.0; -#endif // BGFX_SHADER_LANGUAGE_HLSL +#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL } vec3 clipToWorld(mat4 _invViewProj, vec3 _clipPos) @@ -76,9 +76,9 @@ void main() float depth = toClipSpaceDepth(deviceDepth); vec3 clip = vec3(v_texcoord0 * 2.0 - 1.0, depth); -#if BGFX_SHADER_LANGUAGE_HLSL +#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL clip.y = -clip.y; -#endif // BGFX_SHADER_LANGUAGE_HLSL +#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL vec3 wpos = clipToWorld(u_mtx, clip); vec3 view = mul(u_view, vec4(wpos, 0.0) ).xyz; diff --git a/3rdparty/bgfx/examples/29-debugdraw/debugdraw.cpp b/3rdparty/bgfx/examples/29-debugdraw/debugdraw.cpp index 4efcd80b882..a1ffa395bed 100644 --- a/3rdparty/bgfx/examples/29-debugdraw/debugdraw.cpp +++ b/3rdparty/bgfx/examples/29-debugdraw/debugdraw.cpp @@ -152,12 +152,12 @@ class DebugDrawApp : public entry::AppI ddDraw(sphere); ddSetWireframe(false); - ddSetColor(0xf0ffc0ff); + ddSetColor(0xc0ffc0ff); sphere.m_center[0] = -2.0f; ddSetLod(2); ddDraw(sphere); - ddSetColor(0xc0f0ffff); + ddSetColor(0xa0f0ffff); sphere.m_center[0] = -4.0f; ddSetLod(1); ddDraw(sphere); @@ -198,6 +198,12 @@ class DebugDrawApp : public entry::AppI float to[3] = { -11.0f, 4.0f, 0.0f }; ddDrawCylinder(from, to, 0.5f ); } + + { + float from[3] = { 0.0f, 7.0f, 0.0f }; + float to[3] = { -6.0f, 7.0f, 0.0f }; + ddDrawCylinder(from, to, 0.5f, true); + } ddPop(); ddDrawOrb(-11.0f, 0.0f, 0.0f, 1.0f); diff --git a/3rdparty/bgfx/examples/29-debugdraw/screenshot.png b/3rdparty/bgfx/examples/29-debugdraw/screenshot.png Binary files differnew file mode 100644 index 00000000000..f00864eda50 --- /dev/null +++ b/3rdparty/bgfx/examples/29-debugdraw/screenshot.png diff --git a/3rdparty/bgfx/examples/30-picking/fs_picking_id.sc b/3rdparty/bgfx/examples/30-picking/fs_picking_id.sc new file mode 100644 index 00000000000..899371379db --- /dev/null +++ b/3rdparty/bgfx/examples/30-picking/fs_picking_id.sc @@ -0,0 +1,16 @@ +$input v_pos, v_view, v_normal, v_color0 + +/* + * Copyright 2011-2016 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "../common/common.sh" + +uniform vec4 u_id; + +void main() +{ + gl_FragColor.xyz = u_id.xyz; // This is dumb, should use u8 texture + gl_FragColor.w = 1.0; +} diff --git a/3rdparty/bgfx/examples/30-picking/fs_picking_shaded.sc b/3rdparty/bgfx/examples/30-picking/fs_picking_shaded.sc new file mode 100644 index 00000000000..668b8014251 --- /dev/null +++ b/3rdparty/bgfx/examples/30-picking/fs_picking_shaded.sc @@ -0,0 +1,44 @@ +$input v_pos, v_view, v_normal, v_color0 + +/* + * Copyright 2011-2016 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "../common/common.sh" + +vec2 blinn(vec3 _lightDir, vec3 _normal, vec3 _viewDir) +{ + float ndotl = dot(_normal, _lightDir); + vec3 reflected = _lightDir - 2.0*ndotl*_normal; // reflect(_lightDir, _normal); + float rdotv = dot(reflected, _viewDir); + return vec2(ndotl, rdotv); +} + +float fresnel(float _ndotl, float _bias, float _pow) +{ + float facing = (1.0 - _ndotl); + return max(_bias + (1.0 - _bias) * pow(facing, _pow), 0.0); +} + +vec4 lit(float _ndotl, float _rdotv, float _m) +{ + float diff = max(0.0, _ndotl); + float spec = step(0.0, _ndotl) * max(0.0, _rdotv * _m); + return vec4(1.0, diff, spec, 1.0); +} + +void main() +{ + vec3 lightDir = vec3(0.0, 0.0, -1.0); + vec3 normal = normalize(v_normal); + vec3 view = normalize(v_view); + vec2 bln = blinn(lightDir, normal, view); + vec4 lc = lit(bln.x, bln.y, 1.0); + float fres = fresnel(bln.x, 0.2, 5.0); + + vec3 color = v_color0.xyz; + + gl_FragColor.xyz = pow(vec3(0.07, 0.06, 0.08) + color*lc.y + fres*pow(lc.z, 128.0), vec3_splat(1.0/2.2) ); + gl_FragColor.w = 1.0; +} diff --git a/3rdparty/bgfx/examples/30-picking/makefile b/3rdparty/bgfx/examples/30-picking/makefile new file mode 100644 index 00000000000..e6278cb66dc --- /dev/null +++ b/3rdparty/bgfx/examples/30-picking/makefile @@ -0,0 +1,18 @@ +# +# Copyright 2011-2016 Branimir Karadzic. All rights reserved. +# License: http://www.opensource.org/licenses/BSD-2-Clause +# + +BGFX_DIR=../.. +RUNTIME_DIR=$(BGFX_DIR)/examples/runtime +BUILD_DIR=../../.build + +include $(BGFX_DIR)/scripts/shader.mk + +rebuild: + @make -s --no-print-directory TARGET=0 clean all + @make -s --no-print-directory TARGET=1 clean all + @make -s --no-print-directory TARGET=2 clean all + @make -s --no-print-directory TARGET=3 clean all + @make -s --no-print-directory TARGET=4 clean all + @make -s --no-print-directory TARGET=5 clean all diff --git a/3rdparty/bgfx/examples/30-picking/picking.cpp b/3rdparty/bgfx/examples/30-picking/picking.cpp new file mode 100644 index 00000000000..b6419a884bc --- /dev/null +++ b/3rdparty/bgfx/examples/30-picking/picking.cpp @@ -0,0 +1,423 @@ +/* + * Copyright 2016 Joseph Cherlin. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "common.h" +#include "bgfx_utils.h" +#include "imgui/imgui.h" +#include <bx/rng.h> +#include <map> + +#define RENDER_PASS_SHADING 0 // Default forward rendered geo with simple shading +#define RENDER_PASS_ID 1 // ID buffer for picking +#define RENDER_PASS_BLIT 2 // Blit GPU render target to CPU texture + +#define ID_DIM 8 // Size of the ID buffer + +class ExamplePicking : public entry::AppI +{ + void init(int _argc, char** _argv) BX_OVERRIDE + { + Args args(_argc, _argv); + + m_width = 1280; + m_height = 720; + m_debug = BGFX_DEBUG_TEXT; + m_reset = BGFX_RESET_VSYNC; + + bgfx::init(args.m_type, args.m_pciId); + + bgfx::reset(m_width, m_height, m_reset); + + // Enable debug text. + bgfx::setDebug(m_debug); + + // Set up screen clears + bgfx::setViewClear(RENDER_PASS_SHADING + , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH + , 0x303030ff + , 1.0f + , 0 + ); + + // ID buffer clears to black, which represnts clicking on nothing (background) + bgfx::setViewClear(RENDER_PASS_ID + , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH + , 0x000000ff + , 1.0f + , 0 + ); + + // Create uniforms + u_tint = bgfx::createUniform("u_tint", bgfx::UniformType::Vec4); // Tint for when you click on items + u_id = bgfx::createUniform("u_id", bgfx::UniformType::Vec4); // ID for drawing into ID buffer + + // Create program from shaders. + m_shadingProgram = loadProgram("vs_picking_shaded", "fs_picking_shaded"); // Blinn shading + m_idProgram = loadProgram("vs_picking_shaded", "fs_picking_id"); // Shader for drawing into ID buffer + + static const char* meshPaths[] = + { + "meshes/orb.bin", + "meshes/column.bin", + "meshes/bunny.bin", + "meshes/cube.bin", + "meshes/tree.bin", + "meshes/hollowcube.bin", + }; + + static const float meshScale[] = + { + 0.5f, + 0.05f, + 0.5f, + 0.25f, + 0.05f, + 0.05f, + }; + + m_highlighted = UINT32_MAX; + m_reading = 0; + m_currFrame = UINT32_MAX; + m_fov = 3.0f; + m_cameraSpin = false; + + bx::RngMwc mwc; // Random number generator + for (uint32_t ii = 0; ii < 12; ++ii) + { + m_meshes[ii] = meshLoad(meshPaths[ii % BX_COUNTOF(meshPaths)]); + m_meshScale[ii] = meshScale[ii % BX_COUNTOF(meshPaths)]; + // For the sake of this example, we'll give each mesh a random color, so the debug output looks colorful. + // In an actual app, you'd probably just want to count starting from 1 + uint32_t rr = mwc.gen() % 256; + uint32_t gg = mwc.gen() % 256; + uint32_t bb = mwc.gen() % 256; + m_idsF[ii][0] = rr / 255.0f; + m_idsF[ii][1] = gg / 255.0f; + m_idsF[ii][2] = bb / 255.0f; + m_idsF[ii][3] = 1.0f; + m_idsU[ii] = rr + (gg << 8) + (bb << 16) + (255u << 24); + } + + m_timeOffset = bx::getHPCounter(); + + // Set up ID buffer, which has a color target and depth buffer + m_pickingRT = bgfx::createTexture2D(ID_DIM, ID_DIM, 1, bgfx::TextureFormat::RGBA8, 0 + | BGFX_TEXTURE_RT + | BGFX_TEXTURE_MIN_POINT + | BGFX_TEXTURE_MAG_POINT + | BGFX_TEXTURE_MIP_POINT + | BGFX_TEXTURE_U_CLAMP + | BGFX_TEXTURE_V_CLAMP + ); + m_pickingRTDepth = bgfx::createTexture2D(ID_DIM, ID_DIM, 1, bgfx::TextureFormat::D24S8, 0 + | BGFX_TEXTURE_RT + | BGFX_TEXTURE_MIN_POINT + | BGFX_TEXTURE_MAG_POINT + | BGFX_TEXTURE_MIP_POINT + | BGFX_TEXTURE_U_CLAMP + | BGFX_TEXTURE_V_CLAMP + ); + + // CPU texture for blitting to and reading ID buffer so we can see what was clicked on. + // Impossible to read directly from a render target, you *must* blit to a CPU texture + // first. Algorithm Overview: Render on GPU -> Blit to CPU texture -> Read from CPU + // texture. + m_blitTex = bgfx::createTexture2D(ID_DIM, ID_DIM, 1, bgfx::TextureFormat::RGBA8, 0 + | BGFX_TEXTURE_BLIT_DST + | BGFX_TEXTURE_READ_BACK + | BGFX_TEXTURE_MIN_POINT + | BGFX_TEXTURE_MAG_POINT + | BGFX_TEXTURE_MIP_POINT + | BGFX_TEXTURE_U_CLAMP + | BGFX_TEXTURE_V_CLAMP + ); + + bgfx::TextureHandle rt[2] = + { + m_pickingRT, + m_pickingRTDepth + }; + m_pickingFB = bgfx::createFrameBuffer(BX_COUNTOF(rt), rt, true); + + imguiCreate(); + } + + int shutdown() BX_OVERRIDE + { + for (uint32_t ii = 0; ii < 12; ++ii) + { + meshUnload(m_meshes[ii]); + } + + // Cleanup. + bgfx::destroyProgram(m_shadingProgram); + bgfx::destroyProgram(m_idProgram); + + bgfx::destroyUniform(u_tint); + bgfx::destroyUniform(u_id); + + bgfx::destroyFrameBuffer(m_pickingFB); + bgfx::destroyTexture(m_pickingRT); + bgfx::destroyTexture(m_pickingRTDepth); + bgfx::destroyTexture(m_blitTex); + + imguiDestroy(); + + // Shutdown bgfx. + bgfx::shutdown(); + + return 0; + } + + bool update() BX_OVERRIDE + { + if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) ) + { + bgfx::setViewFrameBuffer(RENDER_PASS_ID, m_pickingFB); + + int64_t now = bx::getHPCounter(); + static int64_t last = now; + const int64_t frameTime = now - last; + last = now; + const double freq = double(bx::getHPFrequency()); + const double toMs = 1000.0 / freq; + float time = (float)( (bx::getHPCounter() - m_timeOffset) / double(bx::getHPFrequency() ) ); + + // Use debug font to print information about this example. + bgfx::dbgTextClear(); + bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/30-picking"); + bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Mouse picking via GPU texture readback."); + bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); + + // Set up matrices for basic forward renderer + const float camSpeed = 0.25; + float cameraSpin = (float)m_cameraSpin; + float eyeDist = 2.5f; + float eye[3] = + { + -eyeDist * bx::fsin(time*cameraSpin*camSpeed), + 0.0f, + -eyeDist * bx::fcos(time*cameraSpin*camSpeed), + }; + float at[3] = { 0.0f, 0.0f, 0.0f }; + + float view[16]; + bx::mtxLookAt(view, eye, at); + + float proj[16]; + bx::mtxProj(proj, 60.0f, float(m_width) / float(m_height), 0.1f, 100.0f); + + // Set up view rect and transform for the shaded pass + bgfx::setViewRect(RENDER_PASS_SHADING, 0, 0, uint16_t(m_width), uint16_t(m_height) ); + bgfx::setViewTransform(RENDER_PASS_SHADING, view, proj); + + // Set up picking pass + float pickView[16]; + float pickAt[4]; // Need to inversly project the mouse pointer to determin what we're looking at + float pickEye[3] = { eye[0], eye[1], eye[2] }; // Eye is same location as before + float viewProj[16]; + bx::mtxMul(viewProj, view, proj); + float invViewProj[16]; + bx::mtxInverse(invViewProj, viewProj); + // Mouse coord in NDC + float mouseXNDC = (m_mouseState.m_mx / (float)m_width) * 2.0f - 1.0f; + float mouseYNDC = ((m_height - m_mouseState.m_my) / (float)m_height) * 2.0f - 1.0f; + float mousePosNDC[4] = { mouseXNDC, mouseYNDC, 0, 1.0f }; + // Unproject and perspective divide + bx::vec4MulMtx(pickAt, mousePosNDC, invViewProj); + pickAt[3] = 1.0f / pickAt[3]; + pickAt[0] *= pickAt[3]; + pickAt[1] *= pickAt[3]; + pickAt[2] *= pickAt[3]; + + // Look at our unprojected point + bx::mtxLookAt(pickView, pickEye, pickAt); + float pickProj[16]; + + // Tight FOV is best for picking + bx::mtxProj(pickProj, m_fov, 1, 0.1f, 100.0f); + // View rect and transforms for picking pass + bgfx::setViewRect(RENDER_PASS_ID, 0, 0, ID_DIM, ID_DIM); + bgfx::setViewTransform(RENDER_PASS_ID, pickView, pickProj); + + // Now that our passes are set up, we can finally draw each mesh + + // Picking highlights a mesh so we'll set up this tint color + const float tintBasic[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + const float tintHighlighted[4] = { 0.3f, 0.3f, 2.0f, 1.0f }; + + for (uint32_t mesh = 0; mesh < 12; ++mesh) + { + const float scale = m_meshScale[mesh]; + + // Set up transform matrix for each mesh + float mtx[16]; + bx::mtxSRT(mtx + , scale, scale, scale + , 0.0f + , time*0.37f*(mesh % 2 ? 1.0f : -1.0f) + , 0.0f + , (mesh % 4) - 1.5f + , (mesh / 4) - 1.25f + , 0.0f + ); + + // Submit mesh to both of our render passes + // Set uniform based on if this is the highlighted mesh + bgfx::setUniform(u_tint + , mesh == m_highlighted + ? tintHighlighted + : tintBasic + ); + meshSubmit(m_meshes[mesh], RENDER_PASS_SHADING, m_shadingProgram, mtx); + + // Submit ID pass based on mesh ID + bgfx::setUniform(u_id, m_idsF[mesh]); + meshSubmit(m_meshes[mesh], RENDER_PASS_ID, m_idProgram, mtx); + } + + // If the user previously clicked, and we're done reading data from GPU, look at ID buffer on CPU + // Whatever mesh has the most pixels in the ID buffer is the one the user clicked on. + if (m_reading == m_currFrame) + { + m_reading = 0; + std::map<uint32_t, uint32_t> ids; // This contains all the IDs found in the buffer + uint32_t maxAmount = 0; + for (uint8_t *x = m_blitData; x < m_blitData + ID_DIM * ID_DIM * 4;) + { + uint8_t rr = *x++; + uint8_t gg = *x++; + uint8_t bb = *x++; + uint8_t aa = *x++; + + const bgfx::Caps* caps = bgfx::getCaps(); + if (bgfx::RendererType::Direct3D9 == caps->rendererType) + { + // Comes back as BGRA + uint8_t temp = rr; + rr = bb; + bb = temp; + } + + if (0 == (rr|gg|bb) ) // Skip background + { + continue; + } + + uint32_t hashKey = rr + (gg << 8) + (bb << 16) + (aa << 24); + std::map<uint32_t, uint32_t>::iterator mapIter = ids.find(hashKey); + uint32_t amount = 1; + if (mapIter != ids.end() ) + { + amount = mapIter->second + 1; + } + + ids[hashKey] = amount; // Amount of times this ID (color) has been clicked on in buffer + maxAmount = maxAmount > amount + ? maxAmount + : amount + ; + } + + uint32_t idKey = 0; + m_highlighted = UINT32_MAX; + if (maxAmount) + { + for (std::map<uint32_t, uint32_t>::iterator mapIter = ids.begin(); mapIter != ids.end(); mapIter++) + { + if (mapIter->second == maxAmount) + { + idKey = mapIter->first; + break; + } + } + + for (uint32_t ii = 0; ii < 12; ++ii) + { + if (m_idsU[ii] == idKey) + { + m_highlighted = ii; + break; + } + } + } + } + + // Start a new readback? + if (!m_reading + && m_mouseState.m_buttons[entry::MouseButton::Left]) + { + // Blit and read + bgfx::blit(RENDER_PASS_BLIT, m_blitTex, 0, 0, m_pickingRT); + m_reading = bgfx::readTexture(m_blitTex, m_blitData); + } + + // Draw UI + imguiBeginFrame(m_mouseState.m_mx + , m_mouseState.m_my + , (m_mouseState.m_buttons[entry::MouseButton::Left] ? IMGUI_MBUT_LEFT : 0) + | (m_mouseState.m_buttons[entry::MouseButton::Right] ? IMGUI_MBUT_RIGHT : 0) + | (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0) + , m_mouseState.m_mz + , m_width + , m_height + ); + + imguiBeginArea("Picking Render Target:", 10, 100, 300, 400); + imguiImage(m_pickingRT, 1.0f, 1.0f, 1.0f); + imguiSlider("FOV", m_fov, 1.0f, 60.0f, 1.0f); + + if (imguiCheck("Spin Camera", m_cameraSpin)) + { + m_cameraSpin = !m_cameraSpin; + } + + imguiEndArea(); + imguiEndFrame(); + + // Advance to next frame. Rendering thread will be kicked to + // process submitted rendering primitives. + m_currFrame = bgfx::frame(); + + return true; + } + + return false; + } + + uint32_t m_width; + uint32_t m_height; + uint32_t m_debug; + uint32_t m_reset; + int64_t m_timeOffset; + + entry::MouseState m_mouseState; + + Mesh* m_meshes[12]; + float m_meshScale[12]; + float m_idsF[12][4]; + uint32_t m_idsU[12]; + uint32_t m_highlighted; + + // Resource handles + bgfx::ProgramHandle m_shadingProgram; + bgfx::ProgramHandle m_idProgram; + bgfx::UniformHandle u_tint; + bgfx::UniformHandle u_id; + bgfx::TextureHandle m_pickingRT; + bgfx::TextureHandle m_pickingRTDepth; + bgfx::TextureHandle m_blitTex; + bgfx::FrameBufferHandle m_pickingFB; + + uint8_t m_blitData[ID_DIM*ID_DIM * 4]; // Read blit into this + + uint32_t m_reading; + uint32_t m_currFrame; + + float m_fov; + bool m_cameraSpin; +}; + +ENTRY_IMPLEMENT_MAIN(ExamplePicking); diff --git a/3rdparty/bgfx/examples/30-picking/screenshot.png b/3rdparty/bgfx/examples/30-picking/screenshot.png Binary files differnew file mode 100644 index 00000000000..e51fcee2a43 --- /dev/null +++ b/3rdparty/bgfx/examples/30-picking/screenshot.png diff --git a/3rdparty/bgfx/examples/30-picking/varying.def.sc b/3rdparty/bgfx/examples/30-picking/varying.def.sc new file mode 100644 index 00000000000..a6670786528 --- /dev/null +++ b/3rdparty/bgfx/examples/30-picking/varying.def.sc @@ -0,0 +1,10 @@ +vec4 v_color0 : COLOR0 = vec4(1.0, 0.0, 0.0, 1.0); +vec3 v_normal : NORMAL = vec3(0.0, 0.0, 1.0); +vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0); +vec3 v_pos : TEXCOORD1 = vec3(0.0, 0.0, 0.0); +vec3 v_view : TEXCOORD2 = vec3(0.0, 0.0, 0.0); + +vec3 a_position : POSITION; +vec4 a_color0 : COLOR0; +vec2 a_texcoord0 : TEXCOORD0; +vec3 a_normal : NORMAL; diff --git a/3rdparty/bgfx/examples/30-picking/vs_picking_shaded.sc b/3rdparty/bgfx/examples/30-picking/vs_picking_shaded.sc new file mode 100644 index 00000000000..441419040bb --- /dev/null +++ b/3rdparty/bgfx/examples/30-picking/vs_picking_shaded.sc @@ -0,0 +1,25 @@ +$input a_position, a_normal +$output v_pos, v_view, v_normal, v_color0 + +/* + * Copyright 2011-2016 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "../common/common.sh" + +uniform vec4 u_tint; + +void main() +{ + vec3 pos = a_position; + vec3 normal = a_normal.xyz*2.0 - 1.0; + + gl_Position = mul(u_modelViewProj, vec4(pos, 1.0) ); + v_pos = gl_Position.xyz; + v_view = mul(u_modelView, vec4(pos, 1.0) ).xyz; + + v_normal = mul(u_modelView, vec4(normal, 0.0) ).xyz; + + v_color0 = u_tint*vec4(0.8, 0.8, 0.8, 1.0); +} diff --git a/3rdparty/bgfx/examples/31-rsm/fs_rsm_combine.sc b/3rdparty/bgfx/examples/31-rsm/fs_rsm_combine.sc new file mode 100644 index 00000000000..af4f5fc23f7 --- /dev/null +++ b/3rdparty/bgfx/examples/31-rsm/fs_rsm_combine.sc @@ -0,0 +1,131 @@ +$input v_texcoord0 + +/* + * Copyright 2016 Joseph Cherlin. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "../common/common.sh" + +SAMPLER2D(s_normal, 0); +SAMPLER2D(s_color, 1); +SAMPLER2D(s_light, 2); +SAMPLER2D(s_depth, 3); +SAMPLER2DSHADOW(s_shadowMap, 4); + +// Single directional light for entire scene +uniform vec4 u_lightDir; +uniform mat4 u_invMvp; +uniform mat4 u_lightMtx; +uniform vec4 u_shadowDimsInv; +uniform vec4 u_rsmAmount; + +float hardShadow(sampler2DShadow _sampler, vec4 _shadowCoord, float _bias) +{ + vec2 texCoord = _shadowCoord.xy; + return shadow2D(_sampler, vec3(texCoord.xy, _shadowCoord.z-_bias) ); +} + +float PCF(sampler2DShadow _sampler, vec4 _shadowCoord, float _bias, vec2 _texelSize) +{ + vec2 texCoord = _shadowCoord.xy; + + bool outside = any(greaterThan(texCoord, vec2_splat(1.0))) + || any(lessThan (texCoord, vec2_splat(0.0))) + ; + + if (outside) + { + return 1.0; + } + + float result = 0.0; + vec2 offset = _texelSize * _shadowCoord.w; + + result += hardShadow(_sampler, _shadowCoord + vec4(vec2(-1.5, -1.5) * offset, 0.0, 0.0), _bias); + result += hardShadow(_sampler, _shadowCoord + vec4(vec2(-1.5, -0.5) * offset, 0.0, 0.0), _bias); + result += hardShadow(_sampler, _shadowCoord + vec4(vec2(-1.5, 0.5) * offset, 0.0, 0.0), _bias); + result += hardShadow(_sampler, _shadowCoord + vec4(vec2(-1.5, 1.5) * offset, 0.0, 0.0), _bias); + + result += hardShadow(_sampler, _shadowCoord + vec4(vec2(-0.5, -1.5) * offset, 0.0, 0.0), _bias); + result += hardShadow(_sampler, _shadowCoord + vec4(vec2(-0.5, -0.5) * offset, 0.0, 0.0), _bias); + result += hardShadow(_sampler, _shadowCoord + vec4(vec2(-0.5, 0.5) * offset, 0.0, 0.0), _bias); + result += hardShadow(_sampler, _shadowCoord + vec4(vec2(-0.5, 1.5) * offset, 0.0, 0.0), _bias); + + result += hardShadow(_sampler, _shadowCoord + vec4(vec2(0.5, -1.5) * offset, 0.0, 0.0), _bias); + result += hardShadow(_sampler, _shadowCoord + vec4(vec2(0.5, -0.5) * offset, 0.0, 0.0), _bias); + result += hardShadow(_sampler, _shadowCoord + vec4(vec2(0.5, 0.5) * offset, 0.0, 0.0), _bias); + result += hardShadow(_sampler, _shadowCoord + vec4(vec2(0.5, 1.5) * offset, 0.0, 0.0), _bias); + + result += hardShadow(_sampler, _shadowCoord + vec4(vec2(1.5, -1.5) * offset, 0.0, 0.0), _bias); + result += hardShadow(_sampler, _shadowCoord + vec4(vec2(1.5, -0.5) * offset, 0.0, 0.0), _bias); + result += hardShadow(_sampler, _shadowCoord + vec4(vec2(1.5, 0.5) * offset, 0.0, 0.0), _bias); + result += hardShadow(_sampler, _shadowCoord + vec4(vec2(1.5, 1.5) * offset, 0.0, 0.0), _bias); + + return result / 16.0; +} + + +float toClipSpaceDepth(float _depthTextureZ) +{ +#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL + return _depthTextureZ; +#else + return _depthTextureZ * 2.0 - 1.0; +#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL +} + +vec3 clipToWorld(mat4 _invViewProj, vec3 _clipPos) +{ + vec4 wpos = mul(_invViewProj, vec4(_clipPos, 1.0) ); + return wpos.xyz / wpos.w; +} + + +void main() +{ + vec3 n = texture2D(s_normal, v_texcoord0).xyz; + // Expand out normal + n = n*2.0+-1.0; + vec3 l = u_lightDir.xyz;//normalize(vec3(-0.8,0.75,-1.0)); + float dirLightIntensity = 1.0; + float dirLight = max(0.0,dot(n,l)) * dirLightIntensity; + + // Apply shadow map + + // Get world position so we can transform it into light space, to look into shadow map + vec2 texCoord = v_texcoord0.xy; + float deviceDepth = texture2D(s_depth, texCoord).x; + float depth = toClipSpaceDepth(deviceDepth); + vec3 clip = vec3(texCoord * 2.0 - 1.0, depth); +#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL + clip.y = -clip.y; +#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL + vec3 wpos = clipToWorld(u_invMvp, clip); + + const float shadowMapOffset = 0.003; + vec3 posOffset = wpos + n.xyz * shadowMapOffset; + vec4 shadowCoord = mul(u_lightMtx, vec4(posOffset, 1.0) ); + +#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL + shadowCoord.y *= -1.0; +#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL + + float shadowMapBias = 0.001; + vec2 texelSize = vec2_splat(u_shadowDimsInv.x); + + shadowCoord.xy /= shadowCoord.w; + shadowCoord.xy = shadowCoord.xy*0.5+0.5; + + float visibility = PCF(s_shadowMap, shadowCoord, shadowMapBias, texelSize); + + dirLight *= visibility; + + // Light from light buffer + vec3 albedo = texture2D(s_color, v_texcoord0).xyz; + vec3 lightBuffer = texture2D(s_light, v_texcoord0).xyz; + + gl_FragColor.xyz = mix(dirLight * albedo, lightBuffer * albedo, u_rsmAmount.x); + + gl_FragColor.w = 1.0; +} diff --git a/3rdparty/bgfx/examples/31-rsm/fs_rsm_gbuffer.sc b/3rdparty/bgfx/examples/31-rsm/fs_rsm_gbuffer.sc new file mode 100644 index 00000000000..a220ecf9dc3 --- /dev/null +++ b/3rdparty/bgfx/examples/31-rsm/fs_rsm_gbuffer.sc @@ -0,0 +1,22 @@ +$input v_normal + +/* + * Copyright 2016 Joseph Cherlin. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "../common/common.sh" + +uniform vec4 u_tint; + +void main() +{ + vec3 normalWorldSpace = v_normal; + + // Write normal + gl_FragData[0].xyz = normalWorldSpace.xyz; // Normal is already compressed to [0,1] so can fit in gbuffer + gl_FragData[0].w = 0.0; + + // Write color + gl_FragData[1] = u_tint; +} diff --git a/3rdparty/bgfx/examples/31-rsm/fs_rsm_lbuffer.sc b/3rdparty/bgfx/examples/31-rsm/fs_rsm_lbuffer.sc new file mode 100644 index 00000000000..259c850a3e5 --- /dev/null +++ b/3rdparty/bgfx/examples/31-rsm/fs_rsm_lbuffer.sc @@ -0,0 +1,67 @@ +$input v_lightCenterScale, v_color0 + +/* + * Copyright 2016 Joseph Cherlin. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "../common/common.sh" + +SAMPLER2D(s_normal, 0); // Normal output from gbuffer +SAMPLER2D(s_depth, 1); // Depth output from gbuffer + +uniform mat4 u_invMvp; + +float toClipSpaceDepth(float _depthTextureZ) +{ +#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL + return _depthTextureZ; +#else + return _depthTextureZ * 2.0 - 1.0; +#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL +} + +vec3 clipToWorld(mat4 _invViewProj, vec3 _clipPos) +{ + vec4 wpos = mul(_invViewProj, vec4(_clipPos, 1.0) ); + return wpos.xyz / wpos.w; +} + +void main() +{ +#if BGFX_SHADER_LANGUAGE_HLSL && (BGFX_SHADER_LANGUAGE_HLSL < 4) + vec2 texCoord = gl_FragCoord.xy * u_viewTexel.xy + u_viewTexel.xy * vec2_splat(0.5); +#else + vec2 texCoord = gl_FragCoord.xy * u_viewTexel.xy; +#endif + + // Get world position + float deviceDepth = texture2D(s_depth, texCoord).x; + float depth = toClipSpaceDepth(deviceDepth); + + vec3 clip = vec3(texCoord * 2.0 - 1.0, depth); +#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL + clip.y = -clip.y; +#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL + vec3 wpos = clipToWorld(u_invMvp, clip); + + // Get normal from its map, and decompress + vec3 n = texture2D(s_normal, texCoord).xyz*2.0-1.0; + + // Do lighting + vec3 pointToLight = v_lightCenterScale.xyz-wpos; + float lightLen = sqrt(dot(pointToLight, pointToLight)); + + float lightFalloff; + + if (lightLen > v_lightCenterScale.w) + lightFalloff = 0.0; + else + lightFalloff = 1.0-(lightLen/v_lightCenterScale.w); // Linear falloff for light (could use dist sq if you want) + + vec3 l = normalize(pointToLight)*lightFalloff; + + gl_FragColor.xyz = v_color0.xyz * max(0.0, dot(n,l)); + + gl_FragColor.w = 1.0; +} diff --git a/3rdparty/bgfx/examples/31-rsm/fs_rsm_shadow.sc b/3rdparty/bgfx/examples/31-rsm/fs_rsm_shadow.sc new file mode 100644 index 00000000000..56026da168a --- /dev/null +++ b/3rdparty/bgfx/examples/31-rsm/fs_rsm_shadow.sc @@ -0,0 +1,22 @@ +$input v_normal + +/* + * Copyright 2016 Joseph Cherlin. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "../common/common.sh" + +uniform vec4 u_tint; + +void main() +{ +#if BGFX_SHADER_LANGUAGE_HLSL && (BGFX_SHADER_LANGUAGE_HLSL < 4) + vec2 texCoord = gl_FragCoord.xy * u_viewTexel.xy + u_viewTexel.xy * vec2_splat(0.5); +#else + vec2 texCoord = gl_FragCoord.xy * u_viewTexel.xy; +#endif + + gl_FragData[0].xyz = u_tint.xyz; // Color of light sphere + gl_FragData[0].w = -v_normal.z; // Radius of light sphere +} diff --git a/3rdparty/bgfx/examples/31-rsm/makefile b/3rdparty/bgfx/examples/31-rsm/makefile new file mode 100644 index 00000000000..e6278cb66dc --- /dev/null +++ b/3rdparty/bgfx/examples/31-rsm/makefile @@ -0,0 +1,18 @@ +# +# Copyright 2011-2016 Branimir Karadzic. All rights reserved. +# License: http://www.opensource.org/licenses/BSD-2-Clause +# + +BGFX_DIR=../.. +RUNTIME_DIR=$(BGFX_DIR)/examples/runtime +BUILD_DIR=../../.build + +include $(BGFX_DIR)/scripts/shader.mk + +rebuild: + @make -s --no-print-directory TARGET=0 clean all + @make -s --no-print-directory TARGET=1 clean all + @make -s --no-print-directory TARGET=2 clean all + @make -s --no-print-directory TARGET=3 clean all + @make -s --no-print-directory TARGET=4 clean all + @make -s --no-print-directory TARGET=5 clean all diff --git a/3rdparty/bgfx/examples/31-rsm/reflectiveshadowmap.cpp b/3rdparty/bgfx/examples/31-rsm/reflectiveshadowmap.cpp new file mode 100644 index 00000000000..a7bbb6078db --- /dev/null +++ b/3rdparty/bgfx/examples/31-rsm/reflectiveshadowmap.cpp @@ -0,0 +1,745 @@ +/* + * Copyright 2016 Joseph Cherlin. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "common.h" +#include "camera.h" +#include "bgfx_utils.h" +#include "imgui/imgui.h" +#include <bx/rng.h> + +/* + * Intro + * ===== + * + * RSM (reflective shadow map) is a technique for global illumination. + * It is similar to shadow map. It piggybacks on the shadow map, in fact. + * + * RSM is compatible with any type of lighting which can handle handle + * a lot of point lights. This sample happens to use a deferred renderer, + * but other types would work. + * + * Overview: + * + * - Draw into G-Buffer + * - Draw Shadow Map (with RSM piggybacked on) + * - Populate light buffer + * - Deferred "combine" pass. + * + * Details + * ======= + * + * ## G-Buffer + * + * Typical G-Buffer with normals, color, depth. + * + * ## RSM + * + * A typical shadow map, except it also outputs to a "RSM" buffer. + * The RSM contains the color of the item drawn, as well as a scalar value which represents + * how much light would bounce off of the surface if it were hit with light from the origin + * of the shadow map. + * + * ## Light Buffer + * + * We draw a lot of spheres into the light buffer. These spheres are called VPL (virtual + * point lights). VPLs represent bounced light, and let us eliminate the classic "ambient" + * term. Instead of us supplying their world space position in a transform matrix, + * VPLs gain their position from the shadow map from step 2, using an unprojection. They gain + * their color from the RSM. You could also store their position in a buffer while drawing shadows, + * I'm just using depth to keep the sample smaller. + * + * ## Deferred combine + * + * Typical combine used in almost any sort of deferred renderer. + * + * References + * ========== + * + * http: *www.bpeers.com/blog/?itemid=517 + * + */ + +// Render passes +#define RENDER_PASS_GBUFFER 0 // GBuffer for normals and albedo +#define RENDER_PASS_SHADOW_MAP 1 // Draw into the shadow map (RSM and regular shadow map at same time) +#define RENDER_PASS_LIGHT_BUFFER 2 // Light buffer for point lights +#define RENDER_PASS_COMBINE 3 // Directional light and final result + +// Gbuffer has multiple render targets +#define GBUFFER_RT_NORMAL 0 +#define GBUFFER_RT_COLOR 1 +#define GBUFFER_RT_DEPTH 2 + +// Shadow map has multiple render targets +#define SHADOW_RT_RSM 0 // In this algorithm, shadows write lighting info as well. +#define SHADOW_RT_DEPTH 1 // Shadow maps always write a depth + +// Random meshes we draw +#define MODEL_COUNT 222 // In this demo, a model is a mesh plus a transform and a color + +#define SHADOW_MAP_DIM 512 +#define LIGHT_DIST 10.0f + +static const char * s_meshPaths[] = +{ + "meshes/cube.bin", + "meshes/orb.bin", + "meshes/column.bin", + "meshes/bunny.bin", + "meshes/tree.bin", + "meshes/hollowcube.bin" +}; + +static const float s_meshScale[] = +{ + 0.25f, + 0.5f, + 0.05f, + 0.5f, + 0.05f, + 0.05f +}; + +// Vertex decl for our screen space quad (used in deferred rendering) +struct PosTexCoord0Vertex +{ + float m_x; + float m_y; + float m_z; + float m_u; + float m_v; + + static void init() + { + ms_decl + .begin() + .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) + .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float) + .end(); + } + + static bgfx::VertexDecl ms_decl; +}; +bgfx::VertexDecl PosTexCoord0Vertex::ms_decl; + +// Utility function to draw a screen space quad for deferred rendering +void screenSpaceQuad(float _textureWidth, float _textureHeight, float _texelHalf, bool _originBottomLeft, float _width = 1.0f, float _height = 1.0f) +{ + if (bgfx::checkAvailTransientVertexBuffer(3, PosTexCoord0Vertex::ms_decl) ) + { + bgfx::TransientVertexBuffer vb; + bgfx::allocTransientVertexBuffer(&vb, 3, PosTexCoord0Vertex::ms_decl); + PosTexCoord0Vertex* vertex = (PosTexCoord0Vertex*)vb.data; + + const float minx = -_width; + const float maxx = _width; + const float miny = 0.0f; + const float maxy = _height*2.0f; + + const float texelHalfW = _texelHalf/_textureWidth; + const float texelHalfH = _texelHalf/_textureHeight; + const float minu = -1.0f + texelHalfW; + const float maxu = 1.0f + texelHalfH; + + const float zz = 0.0f; + + float minv = texelHalfH; + float maxv = 2.0f + texelHalfH; + + if (_originBottomLeft) + { + float temp = minv; + minv = maxv; + maxv = temp; + + minv -= 1.0f; + maxv -= 1.0f; + } + + vertex[0].m_x = minx; + vertex[0].m_y = miny; + vertex[0].m_z = zz; + vertex[0].m_u = minu; + vertex[0].m_v = minv; + + vertex[1].m_x = maxx; + vertex[1].m_y = miny; + vertex[1].m_z = zz; + vertex[1].m_u = maxu; + vertex[1].m_v = minv; + + vertex[2].m_x = maxx; + vertex[2].m_y = maxy; + vertex[2].m_z = zz; + vertex[2].m_u = maxu; + vertex[2].m_v = maxv; + + bgfx::setVertexBuffer(&vb); + } +} + +class ExampleRSM : public entry::AppI +{ +public: + ExampleRSM() + : m_reading(0) + , m_currFrame(UINT32_MAX) + , m_cameraSpin(false) + , m_lightElevation(35.0f) + , m_lightAzimuth(215.0f) + , m_rsmAmount(0.25f) + , m_vplRadius(3.0f) + , m_texelHalf(0.0f) + { + } + + void init(int _argc, char** _argv) BX_OVERRIDE + { + Args args(_argc, _argv); + + m_width = 1280; + m_height = 720; + m_debug = BGFX_DEBUG_TEXT; + m_reset = BGFX_RESET_VSYNC; + + bgfx::init(args.m_type, args.m_pciId); + + bgfx::reset(m_width, m_height, m_reset); + + // Enable debug text. + bgfx::setDebug(m_debug); + + // Labeling for renderdoc captures, etc + bgfx::setViewName(RENDER_PASS_GBUFFER, "gbuffer" ); + bgfx::setViewName(RENDER_PASS_SHADOW_MAP, "shadow map" ); + bgfx::setViewName(RENDER_PASS_LIGHT_BUFFER, "light buffer"); + bgfx::setViewName(RENDER_PASS_COMBINE, "post combine"); + + // Set up screen clears + bgfx::setViewClear(RENDER_PASS_GBUFFER + , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH + , 0 + , 1.0f + , 0 + ); + + bgfx::setViewClear(RENDER_PASS_LIGHT_BUFFER + , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH + , 0 + , 1.0f + , 0 + ); + + bgfx::setViewClear(RENDER_PASS_SHADOW_MAP + , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH + , 0 + , 1.0f + , 0 + ); + + // Create uniforms + u_tint = bgfx::createUniform("u_tint", bgfx::UniformType::Vec4); // Tint for when you click on items + u_lightDir = bgfx::createUniform("u_lightDir", bgfx::UniformType::Vec4); // Single directional light for entire scene + u_sphereInfo = bgfx::createUniform("u_sphereInfo", bgfx::UniformType::Vec4); // Info for RSM + u_invMvp = bgfx::createUniform("u_invMvp", bgfx::UniformType::Mat4); // Matrix needed in light buffer + u_invMvpShadow = bgfx::createUniform("u_invMvpShadow", bgfx::UniformType::Mat4); // Matrix needed in light buffer + u_lightMtx = bgfx::createUniform("u_lightMtx", bgfx::UniformType::Mat4); // Matrix needed to use shadow map (world to shadow space) + u_shadowDimsInv = bgfx::createUniform("u_shadowDimsInv", bgfx::UniformType::Vec4); // Used in PCF + u_rsmAmount = bgfx::createUniform("u_rsmAmount", bgfx::UniformType::Vec4); // How much RSM to use vs directional light + + // Create texture sampler uniforms (used when we bind textures) + s_normal = bgfx::createUniform("s_normal", bgfx::UniformType::Int1); // Normal gbuffer + s_depth = bgfx::createUniform("s_depth", bgfx::UniformType::Int1); // Normal gbuffer + s_color = bgfx::createUniform("s_color", bgfx::UniformType::Int1); // Color (albedo) gbuffer + s_light = bgfx::createUniform("s_light", bgfx::UniformType::Int1); // Light buffer + s_shadowMap = bgfx::createUniform("s_shadowMap", bgfx::UniformType::Int1); // Shadow map + s_rsm = bgfx::createUniform("s_rsm", bgfx::UniformType::Int1); // Reflective shadow map + + // Create program from shaders. + m_gbufferProgram = loadProgram("vs_rsm_gbuffer", "fs_rsm_gbuffer"); // Gbuffer + m_shadowProgram = loadProgram("vs_rsm_shadow", "fs_rsm_shadow" ); // Drawing shadow map + m_lightProgram = loadProgram("vs_rsm_lbuffer", "fs_rsm_lbuffer"); // Light buffer + m_combineProgram = loadProgram("vs_rsm_combine", "fs_rsm_combine"); // Combiner + + // Load some meshes + for (uint32_t ii = 0; ii < BX_COUNTOF(s_meshPaths); ++ii) + { + m_meshes[ii] = meshLoad(s_meshPaths[ii]); + } + + // Randomly create some models + bx::RngMwc mwc; // Random number generator + for (uint32_t ii = 0; ii < BX_COUNTOF(m_models); ++ii) + { + Model& model = m_models[ii]; + + uint32_t rr = mwc.gen() % 256; + uint32_t gg = mwc.gen() % 256; + uint32_t bb = mwc.gen() % 256; + model.mesh = 1+mwc.gen()%(BX_COUNTOF(s_meshPaths)-1); + model.color[0] = rr/255.0f; + model.color[1] = gg/255.0f; + model.color[2] = bb/255.0f; + model.color[3] = 1.0f; + model.position[0] = (((mwc.gen() % 256)) - 128.0f)/20.0f; + model.position[1] = 0; + model.position[2] = (((mwc.gen() % 256)) - 128.0f)/20.0f; + } + + // Load ground. We'll just use the cube since I don't have a ground model right now + m_ground = meshLoad("meshes/cube.bin"); + + // Light sphere + m_lightSphere = meshLoad("meshes/unit_sphere.bin"); + + const uint32_t samplerFlags = 0 + | BGFX_TEXTURE_RT + | BGFX_TEXTURE_MIN_POINT + | BGFX_TEXTURE_MAG_POINT + | BGFX_TEXTURE_MIP_POINT + | BGFX_TEXTURE_U_CLAMP + | BGFX_TEXTURE_V_CLAMP + ; + + // Make gbuffer and related textures + m_gbufferTex[GBUFFER_RT_NORMAL] = bgfx::createTexture2D(bgfx::BackbufferRatio::Equal, 1, bgfx::TextureFormat::BGRA8, samplerFlags); + m_gbufferTex[GBUFFER_RT_COLOR] = bgfx::createTexture2D(bgfx::BackbufferRatio::Equal, 1, bgfx::TextureFormat::BGRA8, samplerFlags); + m_gbufferTex[GBUFFER_RT_DEPTH] = bgfx::createTexture2D(bgfx::BackbufferRatio::Equal, 1, bgfx::TextureFormat::D24, samplerFlags); + m_gbuffer = bgfx::createFrameBuffer(BX_COUNTOF(m_gbufferTex), m_gbufferTex, true); + + // Make light buffer + m_lightBufferTex = bgfx::createTexture2D(bgfx::BackbufferRatio::Equal, 1, bgfx::TextureFormat::BGRA8, samplerFlags); + bgfx::TextureHandle lightBufferRTs[] = { + m_lightBufferTex + }; + m_lightBuffer = bgfx::createFrameBuffer(BX_COUNTOF(lightBufferRTs), lightBufferRTs, true); + + // Make shadow buffer + const uint32_t rsmFlags = 0 + | BGFX_TEXTURE_RT + | BGFX_TEXTURE_MIN_POINT + | BGFX_TEXTURE_MAG_POINT + | BGFX_TEXTURE_MIP_POINT + | BGFX_TEXTURE_U_CLAMP + | BGFX_TEXTURE_V_CLAMP + ; + + // Reflective shadow map + m_shadowBufferTex[SHADOW_RT_RSM] = bgfx::createTexture2D( + SHADOW_MAP_DIM + , SHADOW_MAP_DIM + , 1 + , bgfx::TextureFormat::BGRA8, + rsmFlags + ); + + // Typical shadow map + m_shadowBufferTex[SHADOW_RT_DEPTH] = bgfx::createTexture2D( + SHADOW_MAP_DIM + , SHADOW_MAP_DIM + , 1 + , bgfx::TextureFormat::D16, + BGFX_TEXTURE_RT/* | BGFX_TEXTURE_COMPARE_LEQUAL*/ + ); // Note I'm not setting BGFX_TEXTURE_COMPARE_LEQUAL. Why? + // Normally a PCF shadow map such as this requires a compare. However, this sample also + // reads from this texture in the lighting pass, and only uses the PCF capabilites in the + // combine pass, so the flag is disabled by default. + + m_shadowBuffer = bgfx::createFrameBuffer(BX_COUNTOF(m_shadowBufferTex), m_shadowBufferTex, true); + + // Vertex decl + PosTexCoord0Vertex::init(); + + // Init camera + cameraCreate(); + float camPos[] = {0.0f, 1.5f, 0.0f}; + cameraSetPosition(camPos); + cameraSetVerticalAngle(-0.3f); + + // Init directional light + updateLightDir(); + + // Get renderer capabilities info. + m_caps = bgfx::getCaps(); + const bgfx::RendererType::Enum renderer = bgfx::getRendererType(); + m_texelHalf = bgfx::RendererType::Direct3D9 == renderer ? 0.5f : 0.0f; + + imguiCreate(); + } + + int shutdown() BX_OVERRIDE + { + for (uint32_t ii = 0; ii < BX_COUNTOF(s_meshPaths); ++ii) + { + meshUnload(m_meshes[ii]); + } + + meshUnload(m_ground); + meshUnload(m_lightSphere); + + // Cleanup. + bgfx::destroyProgram(m_gbufferProgram); + bgfx::destroyProgram(m_lightProgram); + bgfx::destroyProgram(m_combineProgram); + bgfx::destroyProgram(m_shadowProgram); + + bgfx::destroyUniform(u_tint); + bgfx::destroyUniform(u_lightDir); + bgfx::destroyUniform(u_sphereInfo); + bgfx::destroyUniform(u_invMvp); + bgfx::destroyUniform(u_invMvpShadow); + bgfx::destroyUniform(u_lightMtx); + bgfx::destroyUniform(u_shadowDimsInv); + bgfx::destroyUniform(u_rsmAmount); + bgfx::destroyUniform(s_normal); + bgfx::destroyUniform(s_depth); + bgfx::destroyUniform(s_light); + bgfx::destroyUniform(s_color); + bgfx::destroyUniform(s_shadowMap); + bgfx::destroyUniform(s_rsm); + + bgfx::destroyFrameBuffer(m_gbuffer); + bgfx::destroyFrameBuffer(m_lightBuffer); + bgfx::destroyFrameBuffer(m_shadowBuffer); + + for (uint32_t ii = 0; ii < BX_COUNTOF(m_gbufferTex); ++ii) + { + bgfx::destroyTexture(m_gbufferTex[ii]); + } + + bgfx::destroyTexture(m_lightBufferTex); + for (uint32_t ii = 0; ii < BX_COUNTOF(m_shadowBufferTex); ++ii) + { + bgfx::destroyTexture(m_shadowBufferTex[ii]); + } + + cameraDestroy(); + + imguiDestroy(); + + // Shutdown bgfx. + bgfx::shutdown(); + + return 0; + } + + bool update() BX_OVERRIDE + { + if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) ) + { + // Update frame timer + int64_t now = bx::getHPCounter(); + static int64_t last = now; + const int64_t frameTime = now - last; + last = now; + const double freq = double(bx::getHPFrequency()); + const double toMs = 1000.0 / freq; + const float deltaTime = float(frameTime/freq); + + // Use debug font to print information about this example. + bgfx::dbgTextClear(); + bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/31-rsm"); + bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Global Illumination with Reflective Shadow Map."); + bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); + + // Update camera + cameraUpdate(deltaTime*0.15f, m_mouseState); + + // Set up matrices for gbuffer + float view[16]; + cameraGetViewMtx(view); + + float proj[16]; + bx::mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f); + + bgfx::setViewRect(RENDER_PASS_GBUFFER, 0, 0, uint16_t(m_width), uint16_t(m_height)); + bgfx::setViewTransform(RENDER_PASS_GBUFFER, view, proj); + // Make sure when we draw it goes into gbuffer and not backbuffer + bgfx::setViewFrameBuffer(RENDER_PASS_GBUFFER, m_gbuffer); + // Draw everything into g-buffer + drawAllModels(RENDER_PASS_GBUFFER, m_gbufferProgram); + + // Draw shadow map + + // Set up transforms for shadow map + float smView[16], smProj[16], lightEye[3], lightAt[3]; + lightEye[0] = m_lightDir[0]*LIGHT_DIST; + lightEye[1] = m_lightDir[1]*LIGHT_DIST; + lightEye[2] = m_lightDir[2]*LIGHT_DIST; + + lightAt[0] = 0.0f; + lightAt[1] = 0.0f; + lightAt[2] = 0.0f; + + bx::mtxLookAt(smView, lightEye, lightAt); + const float area = 10.0f; + bgfx::RendererType::Enum renderer = bgfx::getRendererType(); + bool flipV = false + || renderer == bgfx::RendererType::OpenGL + || renderer == bgfx::RendererType::OpenGLES + ; + bx::mtxOrtho(smProj, -area, area, -area, area, -100.0f, 100.0f, 0.0f, flipV); + bgfx::setViewTransform(RENDER_PASS_SHADOW_MAP, smView, smProj); + bgfx::setViewFrameBuffer(RENDER_PASS_SHADOW_MAP, m_shadowBuffer); + bgfx::setViewRect(RENDER_PASS_SHADOW_MAP, 0, 0, SHADOW_MAP_DIM, SHADOW_MAP_DIM); + + drawAllModels(RENDER_PASS_SHADOW_MAP, m_shadowProgram); + + // Next draw light buffer + + // Set up matrices for light buffer + bgfx::setViewRect(RENDER_PASS_LIGHT_BUFFER, 0, 0, uint16_t(m_width), uint16_t(m_height)); + bgfx::setViewTransform(RENDER_PASS_LIGHT_BUFFER, view, proj); // Notice, same view and proj as gbuffer + // Set drawing into light buffer + bgfx::setViewFrameBuffer(RENDER_PASS_LIGHT_BUFFER, m_lightBuffer); + + // Inverse view projection is needed in shader so set that up + float vp[16], invMvp[16]; + bx::mtxMul(vp, view, proj); + bx::mtxInverse(invMvp, vp); + + // Light matrix used in combine pass and inverse used in light pass + float lightMtx[16]; // World space to light space (shadow map space) + bx::mtxMul(lightMtx, smView, smProj); + float invMvpShadow[16]; + bx::mtxInverse(invMvpShadow, lightMtx); + + // Draw some lights (these should really be instanced but for this example they aren't...) + const unsigned MAX_SPHERE = 32; + for (uint32_t i = 0; i < MAX_SPHERE; i++) + { + for (uint32_t j = 0; j < MAX_SPHERE; j++) + { + // These are used in the fragment shader + bgfx::setTexture(0, s_normal, m_gbuffer, GBUFFER_RT_NORMAL); // Normal for lighting calculations + bgfx::setTexture(1, s_depth, m_gbuffer, GBUFFER_RT_DEPTH); // Depth to reconstruct world position + + // Thse are used in the vert shader + bgfx::setTexture(2, s_shadowMap, m_shadowBuffer, SHADOW_RT_DEPTH); // Used to place sphere + bgfx::setTexture(3, s_rsm, m_shadowBuffer, SHADOW_RT_RSM); // Used to scale/color sphere + + bgfx::setUniform(u_invMvp, invMvp); + bgfx::setUniform(u_invMvpShadow, invMvpShadow); + float sphereInfo[4]; + sphereInfo[0] = ((float)i/(MAX_SPHERE-1)); + sphereInfo[1] = ((float)j/(MAX_SPHERE-1)); + sphereInfo[2] = m_vplRadius; + sphereInfo[3] = 0.0; // Unused + bgfx::setUniform(u_sphereInfo, sphereInfo); + + const uint64_t lightDrawState = 0 + | BGFX_STATE_RGB_WRITE + | BGFX_STATE_BLEND_ADD // <=== Overlapping lights contribute more + | BGFX_STATE_ALPHA_WRITE + | BGFX_STATE_CULL_CW // <=== If we go into the lights, there will be problems, so we draw the far back face. + ; + + meshSubmit( + m_lightSphere, + RENDER_PASS_LIGHT_BUFFER, + m_lightProgram, + NULL, + lightDrawState + ); + } + } + + // Draw combine pass + + // Texture inputs for combine pass + bgfx::setTexture(0, s_normal, m_gbuffer, GBUFFER_RT_NORMAL); + bgfx::setTexture(1, s_color, m_gbuffer, GBUFFER_RT_COLOR); + bgfx::setTexture(2, s_light, m_lightBuffer, 0); + bgfx::setTexture(3, s_depth, m_gbuffer, GBUFFER_RT_DEPTH); + bgfx::setTexture(4, s_shadowMap, m_shadowBuffer, SHADOW_RT_DEPTH, BGFX_TEXTURE_COMPARE_LEQUAL); + + // Uniforms for combine pass + + bgfx::setUniform(u_lightDir, m_lightDir); + bgfx::setUniform(u_invMvp, invMvp); + bgfx::setUniform(u_lightMtx, lightMtx); + const float invDim[4] = {1.0f/SHADOW_MAP_DIM, 0.0f, 0.0f, 0.0f}; + bgfx::setUniform(u_shadowDimsInv, invDim); + float rsmAmount[4] = {m_rsmAmount,m_rsmAmount,m_rsmAmount,m_rsmAmount}; + bgfx::setUniform(u_rsmAmount, rsmAmount); + + // Set up state for combine pass + // point of this is to avoid doing depth test, which is in the default state + bgfx::setState(0 + | BGFX_STATE_RGB_WRITE + | BGFX_STATE_ALPHA_WRITE + ); + + // Set up transform matrix for fullscreen quad + float orthoProj[16]; + bx::mtxOrtho(orthoProj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f); + bgfx::setViewTransform(RENDER_PASS_COMBINE, NULL, orthoProj); + bgfx::setViewRect(RENDER_PASS_COMBINE, 0, 0, m_width, m_height); + // Bind vertex buffer and draw quad + screenSpaceQuad( (float)m_width, (float)m_height, m_texelHalf, m_caps->originBottomLeft); + bgfx::submit(RENDER_PASS_COMBINE, m_combineProgram); + + // Draw UI + imguiBeginFrame(m_mouseState.m_mx + , m_mouseState.m_my + , (m_mouseState.m_buttons[entry::MouseButton::Left] ? IMGUI_MBUT_LEFT : 0) + | (m_mouseState.m_buttons[entry::MouseButton::Right] ? IMGUI_MBUT_RIGHT : 0) + | (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0) + , m_mouseState.m_mz + , m_width + , m_height + ); + + imguiBeginArea("RSM:", 10, 100, 300, 400); + + imguiSlider("rsm amount", m_rsmAmount, 0.0f, 0.7f, 0.01f); + imguiSlider("vpl radius", m_vplRadius, 0.25f, 20.0f, 0.1f); + imguiSlider("light azimuth", m_lightAzimuth, 0.0f, 360.0f, 0.01f); + imguiSlider("light elevation", m_lightElevation, 35.0f, 90.0f, 0.01f); + + imguiEndArea(); + imguiEndFrame(); + + updateLightDir(); + + // Advance to next frame. Rendering thread will be kicked to + // process submitted rendering primitives. + m_currFrame = bgfx::frame(); + + return true; + } + + return false; + } + + void drawAllModels(uint8_t _pass, bgfx::ProgramHandle _program) + { + for (uint32_t ii = 0; ii < BX_COUNTOF(m_models); ++ii) + { + const Model& model = m_models[ii]; + + // Set up transform matrix for each model + float scale = s_meshScale[model.mesh]; + float mtx[16]; + bx::mtxSRT(mtx + , scale + , scale + , scale + , 0.0f + , 0.0f + , 0.0f + , model.position[0] + , model.position[1] + , model.position[2] + ); + + // Submit mesh to gbuffer + bgfx::setUniform(u_tint, model.color); + meshSubmit(m_meshes[model.mesh], _pass, _program, mtx); + } + + // Draw ground + const float white[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + bgfx::setUniform(u_tint, white); + float mtxScale[16]; + float scale = 10.0; + bx::mtxScale(mtxScale + , scale + , scale + , scale + ); + float mtxTrans[16]; + bx::mtxTranslate(mtxTrans + , 0.0f + , -10.0f + , 0.0f + ); + float mtx[16]; + bx::mtxMul(mtx, mtxScale, mtxTrans); + meshSubmit(m_ground, _pass, _program, mtx); + } + + void updateLightDir() + { + float el = m_lightElevation * (bx::pi/180.0f); + float az = m_lightAzimuth * (bx::pi/180.0f); + m_lightDir[0] = cos(el)*cos(az); + m_lightDir[2] = cos(el)*sin(az); + m_lightDir[1] = sin(el); + m_lightDir[3] = 0.0f; + } + + uint32_t m_width; + uint32_t m_height; + uint32_t m_debug; + uint32_t m_reset; + + entry::MouseState m_mouseState; + + Mesh* m_ground; + Mesh* m_lightSphere; // Unit sphere + + // Resource handles + bgfx::ProgramHandle m_gbufferProgram; + bgfx::ProgramHandle m_shadowProgram; + bgfx::ProgramHandle m_lightProgram; + bgfx::ProgramHandle m_combineProgram; + bgfx::FrameBufferHandle m_gbuffer; + bgfx::FrameBufferHandle m_lightBuffer; + bgfx::FrameBufferHandle m_shadowBuffer; + + // Shader uniforms + bgfx::UniformHandle u_tint; + bgfx::UniformHandle u_invMvp; + bgfx::UniformHandle u_invMvpShadow; + bgfx::UniformHandle u_lightMtx; + bgfx::UniformHandle u_lightDir; + bgfx::UniformHandle u_sphereInfo; + bgfx::UniformHandle u_shadowDimsInv; + bgfx::UniformHandle u_rsmAmount; + + // Uniforms to identify texture samples + bgfx::UniformHandle s_normal; + bgfx::UniformHandle s_depth; + bgfx::UniformHandle s_color; + bgfx::UniformHandle s_light; + bgfx::UniformHandle s_shadowMap; + bgfx::UniformHandle s_rsm; + + // Various render targets + bgfx::TextureHandle m_gbufferTex[3]; + bgfx::TextureHandle m_lightBufferTex; + bgfx::TextureHandle m_shadowBufferTex[2]; + + const bgfx::Caps* m_caps; + + struct Model + { + uint32_t mesh; // Index of mesh in m_meshes + float color[4]; + float position[3]; + }; + + Model m_models[MODEL_COUNT]; + Mesh * m_meshes[BX_COUNTOF(s_meshPaths)]; + + uint32_t m_reading; + uint32_t m_currFrame; + + // UI + bool m_cameraSpin; + + // Light position; + float m_lightDir[4]; + float m_lightElevation; + float m_lightAzimuth; + + float m_rsmAmount; // Amount of rsm + float m_vplRadius; // Radius of virtual point light + + float m_texelHalf; +}; + +ENTRY_IMPLEMENT_MAIN(ExampleRSM); diff --git a/3rdparty/bgfx/examples/31-rsm/screenshot.png b/3rdparty/bgfx/examples/31-rsm/screenshot.png Binary files differnew file mode 100644 index 00000000000..f6cea027476 --- /dev/null +++ b/3rdparty/bgfx/examples/31-rsm/screenshot.png diff --git a/3rdparty/bgfx/examples/31-rsm/varying.def.sc b/3rdparty/bgfx/examples/31-rsm/varying.def.sc new file mode 100644 index 00000000000..50fbb16f454 --- /dev/null +++ b/3rdparty/bgfx/examples/31-rsm/varying.def.sc @@ -0,0 +1,10 @@ +vec4 v_color0 : COLOR0 = vec4(1.0, 0.0, 0.0, 1.0); +vec3 v_normal : NORMAL = vec3(0.0, 0.0, 1.0); +vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0); +vec3 v_view : TEXCOORD1 = vec3(0.0, 0.0, 0.0); +vec4 v_lightCenterScale : TEXCOORD2 = vec4(0.0, 0.0, 0.0, 0.0); // xyz is position z is scale + +vec3 a_position : POSITION; +vec4 a_color0 : COLOR0; +vec2 a_texcoord0 : TEXCOORD0; +vec3 a_normal : NORMAL; diff --git a/3rdparty/bgfx/examples/31-rsm/vs_rsm_combine.sc b/3rdparty/bgfx/examples/31-rsm/vs_rsm_combine.sc new file mode 100644 index 00000000000..be7032c2be5 --- /dev/null +++ b/3rdparty/bgfx/examples/31-rsm/vs_rsm_combine.sc @@ -0,0 +1,15 @@ +$input a_position, a_texcoord0 +$output v_texcoord0 + +/* + * Copyright 2016 Joseph Cherlin. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "../common/common.sh" + +void main() +{ + gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) ); + v_texcoord0 = a_texcoord0; +} diff --git a/3rdparty/bgfx/examples/31-rsm/vs_rsm_gbuffer.sc b/3rdparty/bgfx/examples/31-rsm/vs_rsm_gbuffer.sc new file mode 100644 index 00000000000..123e4fbf4af --- /dev/null +++ b/3rdparty/bgfx/examples/31-rsm/vs_rsm_gbuffer.sc @@ -0,0 +1,27 @@ +$input a_position, a_normal +$output v_normal + +/* + * Copyright 2016 Joseph Cherlin. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + + +#include "../common/common.sh" + +uniform vec4 u_tint; + +void main() +{ + // Calculate vertex position + vec3 pos = a_position; + gl_Position = mul(u_modelViewProj, vec4(pos, 1.0) ); + + // Calculate normal. Note that compressed normal is stored in the vertices + vec3 normalObjectSpace = a_normal.xyz*2.0+-1.0; // Normal is stored in [0,1], remap to [-1,1]. + + // Transform normal into world space. + vec3 normalWorldSpace = mul(u_model[0], vec4(normalObjectSpace, 0.0) ).xyz; + // Normalize to remove (uniform...) scaling, however, recompress + v_normal.xyz = normalize(normalWorldSpace)*0.5+0.5; +} diff --git a/3rdparty/bgfx/examples/31-rsm/vs_rsm_lbuffer.sc b/3rdparty/bgfx/examples/31-rsm/vs_rsm_lbuffer.sc new file mode 100644 index 00000000000..357b38ec387 --- /dev/null +++ b/3rdparty/bgfx/examples/31-rsm/vs_rsm_lbuffer.sc @@ -0,0 +1,60 @@ +$input a_position +$output v_lightCenterScale, v_color0 + +/* + * Copyright 2016 Joseph Cherlin. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "../common/common.sh" + +uniform vec4 u_sphereInfo; +uniform mat4 u_invMvpShadow; + + +// Note texture binding starts at slot 2. Problem is that vert textures and frag textures are different. +SAMPLER2D(s_shadowMap, 2); // Used to reconstruct 3d position for lights +SAMPLER2D(s_rsm, 3); // Reflective shadow map, used to scale/color light + +float toClipSpaceDepth(float _depthTextureZ) +{ +#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL + return _depthTextureZ; +#else + return _depthTextureZ * 2.0 - 1.0; +#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL +} + +vec3 clipToWorld(mat4 _invViewProj, vec3 _clipPos) +{ + vec4 wpos = mul(_invViewProj, vec4(_clipPos, 1.0) ); + return wpos.xyz / wpos.w; +} + +void main() +{ + // Calculate vertex position + vec3 objectSpacePos = a_position; + vec2 texCoord = u_sphereInfo.xy; + + // Get world position using the shadow map + float deviceDepth = texture2DLod(s_shadowMap, texCoord, 0).x; + float depth = toClipSpaceDepth(deviceDepth); + vec3 clip = vec3(texCoord * 2.0 - 1.0, depth); +#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL + clip.y = -clip.y; +#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL + vec3 wPos = clipToWorld(u_invMvpShadow, clip); + wPos.y -= 0.001; // Would be much better to perturb in normal direction, but I didn't do that. + + // Scale and color are already in the rsm + vec4 rsm = texture2DLod(s_rsm, texCoord, 0).xyzw; + float radScale = u_sphereInfo.z; + float rad = rsm.w * radScale; + + gl_Position = mul(u_viewProj, vec4(wPos+objectSpacePos*rad, 1.0) ); + + v_lightCenterScale.xyz = wPos.xyz; + v_lightCenterScale.w = rad; + v_color0.xyz = rsm.xyz; +} diff --git a/3rdparty/bgfx/examples/31-rsm/vs_rsm_shadow.sc b/3rdparty/bgfx/examples/31-rsm/vs_rsm_shadow.sc new file mode 100644 index 00000000000..41bf8ab118d --- /dev/null +++ b/3rdparty/bgfx/examples/31-rsm/vs_rsm_shadow.sc @@ -0,0 +1,24 @@ +$input a_position, a_normal +$output v_normal // RSM shadow + +/* + * Copyright 2016 Joseph Cherlin. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "../common/common.sh" + +uniform vec4 u_tint; + +void main() +{ + gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) ); + + // Calculate normal. Note that compressed normal is stored in the vertices + vec3 normalObjectSpace = a_normal.xyz*2.0+-1.0; // Normal is stored in [0,1], remap to [-1,1]. + + // Transform normal into view space. + v_normal = mul(u_modelView, vec4(normalObjectSpace, 0.0) ).xyz; + // Normalize to remove (uniform...) scaling + v_normal = normalize(v_normal); +} diff --git a/3rdparty/bgfx/examples/assets/meshes/build.ninja b/3rdparty/bgfx/examples/assets/meshes/build.ninja deleted file mode 100644 index 232ba6b6216..00000000000 --- a/3rdparty/bgfx/examples/assets/meshes/build.ninja +++ /dev/null @@ -1,18 +0,0 @@ -include ../../../scripts/common.ninja -meshes = ../../runtime/meshes - -build $meshes/bunny.bin: geometryc_pack_normal bunny.obj -build $meshes/bunny_decimated.bin: geometryc_pack_normal bunny_decimated.obj -build $meshes/bunny_patched.bin: geometryc_pack_normal bunny_patched.obj -build $meshes/column.bin: geometryc_pack_normal column.obj -build $meshes/cube.bin: geometryc_pack_normal cube.obj -build $meshes/hollowcube.bin: geometryc_pack_normal hollowcube.obj -build $meshes/orb.bin: geometryc_pack_normal orb.obj -build $meshes/platform.bin: geometryc_pack_normal platform.obj -build $meshes/tree.bin: geometryc_pack_normal tree.obj -build $meshes/tree1b_lod0_1.bin: geometryc_pack_normal tree1b_lod0_1.obj -build $meshes/tree1b_lod0_2.bin: geometryc_pack_normal tree1b_lod0_2.obj -build $meshes/tree1b_lod1_1.bin: geometryc_pack_normal tree1b_lod1_1.obj -build $meshes/tree1b_lod1_2.bin: geometryc_pack_normal tree1b_lod1_2.obj -build $meshes/tree1b_lod2_1.bin: geometryc_pack_normal tree1b_lod2_1.obj -build $meshes/tree1b_lod2_2.bin: geometryc_pack_normal tree1b_lod2_2.obj diff --git a/3rdparty/bgfx/examples/assets/meshes/meshes.ninja b/3rdparty/bgfx/examples/assets/meshes/meshes.ninja new file mode 100644 index 00000000000..f8a95dac498 --- /dev/null +++ b/3rdparty/bgfx/examples/assets/meshes/meshes.ninja @@ -0,0 +1,17 @@ +meshes = $pwd/../../runtime/meshes + +build $meshes/bunny.bin: geometryc_pack_normal_barycentric $pwd/bunny.obj +build $meshes/bunny_decimated.bin: geometryc_pack_normal $pwd/bunny_decimated.obj +build $meshes/bunny_patched.bin: geometryc_pack_normal $pwd/bunny_patched.obj +build $meshes/column.bin: geometryc_pack_normal $pwd/column.obj +build $meshes/cube.bin: geometryc_pack_normal $pwd/cube.obj +build $meshes/hollowcube.bin: geometryc_pack_normal_barycentric $pwd/hollowcube.obj +build $meshes/orb.bin: geometryc_pack_normal_barycentric $pwd/orb.obj +build $meshes/platform.bin: geometryc_pack_normal $pwd/platform.obj +build $meshes/tree.bin: geometryc_pack_normal $pwd/tree.obj +build $meshes/tree1b_lod0_1.bin: geometryc_pack_normal $pwd/tree1b_lod0_1.obj +build $meshes/tree1b_lod0_2.bin: geometryc_pack_normal $pwd/tree1b_lod0_2.obj +build $meshes/tree1b_lod1_1.bin: geometryc_pack_normal $pwd/tree1b_lod1_1.obj +build $meshes/tree1b_lod1_2.bin: geometryc_pack_normal $pwd/tree1b_lod1_2.obj +build $meshes/tree1b_lod2_1.bin: geometryc_pack_normal $pwd/tree1b_lod2_1.obj +build $meshes/tree1b_lod2_2.bin: geometryc_pack_normal $pwd/tree1b_lod2_2.obj diff --git a/3rdparty/bgfx/examples/assets/textures/build.ninja b/3rdparty/bgfx/examples/assets/textures/build.ninja deleted file mode 100644 index 019e5f868a8..00000000000 --- a/3rdparty/bgfx/examples/assets/textures/build.ninja +++ /dev/null @@ -1,8 +0,0 @@ -include ../../../scripts/common.ninja -textures = ../../runtime/textures - -build $textures/texture_compression_bc1.ktx: texturec_bc1 texture_compression.png -build $textures/texture_compression_bc2.ktx: texturec_bc2 texture_compression.png -build $textures/texture_compression_bc3.ktx: texturec_bc3 texture_compression.png -build $textures/texture_compression_etc1.ktx: texturec_etc1 texture_compression.png -build $textures/texture_compression_etc2.ktx: texturec_etc2 texture_compression.png diff --git a/3rdparty/bgfx/examples/assets/textures/textures.ninja b/3rdparty/bgfx/examples/assets/textures/textures.ninja new file mode 100644 index 00000000000..fffb9c51d34 --- /dev/null +++ b/3rdparty/bgfx/examples/assets/textures/textures.ninja @@ -0,0 +1,7 @@ +textures = $pwd/../../runtime/textures + +build $textures/texture_compression_bc1.ktx: texturec_bc1 $pwd/texture_compression.png +build $textures/texture_compression_bc2.ktx: texturec_bc2 $pwd/texture_compression.png +build $textures/texture_compression_bc3.ktx: texturec_bc3 $pwd/texture_compression.png +build $textures/texture_compression_etc1.ktx: texturec_etc1 $pwd/texture_compression.png +build $textures/texture_compression_etc2.ktx: texturec_etc2 $pwd/texture_compression.png diff --git a/3rdparty/bgfx/examples/common/cube_atlas.cpp b/3rdparty/bgfx/examples/common/cube_atlas.cpp index 7b83f6f7518..9407363a37f 100644 --- a/3rdparty/bgfx/examples/common/cube_atlas.cpp +++ b/3rdparty/bgfx/examples/common/cube_atlas.cpp @@ -149,6 +149,7 @@ bool RectanglePacker::addRectangle(uint16_t _width, uint16_t _height, uint16_t& { m_skyline.erase(m_skyline.begin() + ii); --ii; + --num; } else { diff --git a/3rdparty/bgfx/examples/common/debugdraw/debugdraw.cpp b/3rdparty/bgfx/examples/common/debugdraw/debugdraw.cpp index f02e4d6523d..ac242b01f44 100644 --- a/3rdparty/bgfx/examples/common/debugdraw/debugdraw.cpp +++ b/3rdparty/bgfx/examples/common/debugdraw/debugdraw.cpp @@ -39,13 +39,14 @@ struct DebugShapeVertex float m_x; float m_y; float m_z; - float m_mask; + uint8_t m_indices[4]; static void init() { ms_decl .begin() - .add(bgfx::Attrib::Position, 4, bgfx::AttribType::Float) + .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) + .add(bgfx::Attrib::Indices, 4, bgfx::AttribType::Uint8) .end(); } @@ -56,14 +57,14 @@ bgfx::VertexDecl DebugShapeVertex::ms_decl; static DebugShapeVertex s_cubeVertices[8] = { - {-1.0f, 1.0f, 1.0f, 0.0f }, - { 1.0f, 1.0f, 1.0f, 0.0f }, - {-1.0f, -1.0f, 1.0f, 0.0f }, - { 1.0f, -1.0f, 1.0f, 0.0f }, - {-1.0f, 1.0f, -1.0f, 0.0f }, - { 1.0f, 1.0f, -1.0f, 0.0f }, - {-1.0f, -1.0f, -1.0f, 0.0f }, - { 1.0f, -1.0f, -1.0f, 0.0f }, + {-1.0f, 1.0f, 1.0f, { 0, 0, 0, 0 } }, + { 1.0f, 1.0f, 1.0f, { 0, 0, 0, 0 } }, + {-1.0f, -1.0f, 1.0f, { 0, 0, 0, 0 } }, + { 1.0f, -1.0f, 1.0f, { 0, 0, 0, 0 } }, + {-1.0f, 1.0f, -1.0f, { 0, 0, 0, 0 } }, + { 1.0f, 1.0f, -1.0f, { 0, 0, 0, 0 } }, + {-1.0f, -1.0f, -1.0f, { 0, 0, 0, 0 } }, + { 1.0f, -1.0f, -1.0f, { 0, 0, 0, 0 } }, }; static const uint16_t s_cubeIndices[36] = @@ -389,6 +390,7 @@ struct DebugDraw const uint32_t numIndices = numVertices; vertices[id] = BX_ALLOC(m_allocator, numVertices*stride); + memset(vertices[id], 0, numVertices*stride); genSphere(tess, vertices[id], stride); uint16_t* trilist = (uint16_t*)BX_ALLOC(m_allocator, numIndices*sizeof(uint16_t) ); @@ -397,9 +399,6 @@ struct DebugDraw trilist[ii] = uint16_t(ii); } - - - uint32_t numLineListIndices = bgfx::topologyConvert(bgfx::TopologyConvert::TriListToLineList , NULL , 0 @@ -432,6 +431,207 @@ struct DebugDraw BX_FREE(m_allocator, trilist); } + for (uint32_t mesh = 0; mesh < 4; ++mesh) + { + Mesh::Enum id = Mesh::Enum(Mesh::Cone0+mesh); + + const uint32_t num = getCircleLod(uint8_t(mesh) ); + const float step = bx::pi * 2.0f / num; + + const uint32_t numVertices = num+1; + const uint32_t numIndices = num*6; + const uint32_t numLineListIndices = num*4; + + vertices[id] = BX_ALLOC(m_allocator, numVertices*stride); + indices[id] = (uint16_t*)BX_ALLOC(m_allocator, (numIndices + numLineListIndices)*sizeof(uint16_t) ); + memset(indices[id], 0, (numIndices + numLineListIndices)*sizeof(uint16_t) ); + + DebugShapeVertex* vertex = (DebugShapeVertex*)vertices[id]; + uint16_t* index = indices[id]; + + vertex[num].m_x = 0.0f; + vertex[num].m_y = 0.0f; + vertex[num].m_z = 0.0f; + vertex[num].m_indices[0] = 1; + + for (uint32_t ii = 0; ii < num; ++ii) + { + const float angle = step * ii; + + float xy[2]; + circle(xy, angle); + + vertex[ii].m_x = xy[1]; + vertex[ii].m_y = 0.0f; + vertex[ii].m_z = xy[0]; + vertex[ii].m_indices[0] = 0; + + index[ii*3+0] = uint16_t(num); + index[ii*3+1] = uint16_t( (ii+1)%num); + index[ii*3+2] = uint16_t(ii); + + index[num*3+ii*3+0] = 0; + index[num*3+ii*3+1] = uint16_t(ii); + index[num*3+ii*3+2] = uint16_t( (ii+1)%num); + + index[numIndices+ii*2+0] = uint16_t(ii); + index[numIndices+ii*2+1] = uint16_t(num); + + index[numIndices+num*2+ii*2+0] = uint16_t(ii); + index[numIndices+num*2+ii*2+1] = uint16_t( (ii+1)%num); + } + + m_mesh[id].m_startVertex = startVertex; + m_mesh[id].m_numVertices = numVertices; + m_mesh[id].m_startIndex[0] = startIndex; + m_mesh[id].m_numIndices[0] = numIndices; + m_mesh[id].m_startIndex[1] = startIndex+numIndices; + m_mesh[id].m_numIndices[1] = numLineListIndices; + + startVertex += numVertices; + startIndex += numIndices + numLineListIndices; + } + + for (uint32_t mesh = 0; mesh < 4; ++mesh) + { + Mesh::Enum id = Mesh::Enum(Mesh::Cylinder0+mesh); + + const uint32_t num = getCircleLod(uint8_t(mesh) ); + const float step = bx::pi * 2.0f / num; + + const uint32_t numVertices = num*2; + const uint32_t numIndices = num*12; + const uint32_t numLineListIndices = num*6; + + vertices[id] = BX_ALLOC(m_allocator, numVertices*stride); + indices[id] = (uint16_t*)BX_ALLOC(m_allocator, (numIndices + numLineListIndices)*sizeof(uint16_t) ); + memset(indices[id], 0, (numIndices + numLineListIndices)*sizeof(uint16_t) ); + + DebugShapeVertex* vertex = (DebugShapeVertex*)vertices[id]; + uint16_t* index = indices[id]; + + for (uint32_t ii = 0; ii < num; ++ii) + { + const float angle = step * ii; + + float xy[2]; + circle(xy, angle); + + vertex[ii].m_x = xy[1]; + vertex[ii].m_y = 0.0f; + vertex[ii].m_z = xy[0]; + vertex[ii].m_indices[0] = 0; + + vertex[ii+num].m_x = xy[1]; + vertex[ii+num].m_y = 0.0f; + vertex[ii+num].m_z = xy[0]; + vertex[ii+num].m_indices[0] = 1; + + index[ii*6+0] = uint16_t(ii+num); + index[ii*6+1] = uint16_t( (ii+1)%num); + index[ii*6+2] = uint16_t(ii); + index[ii*6+3] = uint16_t(ii+num); + index[ii*6+4] = uint16_t( (ii+1)%num+num); + index[ii*6+5] = uint16_t( (ii+1)%num); + + index[num*6+ii*6+0] = uint16_t(0); + index[num*6+ii*6+1] = uint16_t(ii); + index[num*6+ii*6+2] = uint16_t( (ii+1)%num); + index[num*6+ii*6+3] = uint16_t(num); + index[num*6+ii*6+4] = uint16_t( (ii+1)%num+num); + index[num*6+ii*6+5] = uint16_t(ii+num); + + index[numIndices+ii*2+0] = uint16_t(ii); + index[numIndices+ii*2+1] = uint16_t(ii+num); + + index[numIndices+num*2+ii*2+0] = uint16_t(ii); + index[numIndices+num*2+ii*2+1] = uint16_t( (ii+1)%num); + + index[numIndices+num*4+ii*2+0] = uint16_t(num + ii); + index[numIndices+num*4+ii*2+1] = uint16_t(num + (ii+1)%num); + } + + m_mesh[id].m_startVertex = startVertex; + m_mesh[id].m_numVertices = numVertices; + m_mesh[id].m_startIndex[0] = startIndex; + m_mesh[id].m_numIndices[0] = numIndices; + m_mesh[id].m_startIndex[1] = startIndex+numIndices; + m_mesh[id].m_numIndices[1] = numLineListIndices; + + startVertex += numVertices; + startIndex += numIndices + numLineListIndices; + } + + for (uint32_t mesh = 0; mesh < 4; ++mesh) + { + Mesh::Enum id = Mesh::Enum(Mesh::Capsule0+mesh); + + const uint32_t num = getCircleLod(uint8_t(mesh) ); + const float step = bx::pi * 2.0f / num; + + const uint32_t numVertices = num*2; + const uint32_t numIndices = num*6; + const uint32_t numLineListIndices = num*6; + + vertices[id] = BX_ALLOC(m_allocator, numVertices*stride); + indices[id] = (uint16_t*)BX_ALLOC(m_allocator, (numIndices + numLineListIndices)*sizeof(uint16_t) ); + memset(indices[id], 0, (numIndices + numLineListIndices)*sizeof(uint16_t) ); + + DebugShapeVertex* vertex = (DebugShapeVertex*)vertices[id]; + uint16_t* index = indices[id]; + + for (uint32_t ii = 0; ii < num; ++ii) + { + const float angle = step * ii; + + float xy[2]; + circle(xy, angle); + + vertex[ii].m_x = xy[1]; + vertex[ii].m_y = 0.0f; + vertex[ii].m_z = xy[0]; + vertex[ii].m_indices[0] = 0; + + vertex[ii+num].m_x = xy[1]; + vertex[ii+num].m_y = 0.0f; + vertex[ii+num].m_z = xy[0]; + vertex[ii+num].m_indices[0] = 1; + + index[ii*6+0] = uint16_t(ii+num); + index[ii*6+1] = uint16_t( (ii+1)%num); + index[ii*6+2] = uint16_t(ii); + index[ii*6+3] = uint16_t(ii+num); + index[ii*6+4] = uint16_t( (ii+1)%num+num); + index[ii*6+5] = uint16_t( (ii+1)%num); + +// index[num*6+ii*6+0] = uint16_t(0); +// index[num*6+ii*6+1] = uint16_t(ii); +// index[num*6+ii*6+2] = uint16_t( (ii+1)%num); +// index[num*6+ii*6+3] = uint16_t(num); +// index[num*6+ii*6+4] = uint16_t( (ii+1)%num+num); +// index[num*6+ii*6+5] = uint16_t(ii+num); + + index[numIndices+ii*2+0] = uint16_t(ii); + index[numIndices+ii*2+1] = uint16_t(ii+num); + + index[numIndices+num*2+ii*2+0] = uint16_t(ii); + index[numIndices+num*2+ii*2+1] = uint16_t( (ii+1)%num); + + index[numIndices+num*4+ii*2+0] = uint16_t(num + ii); + index[numIndices+num*4+ii*2+1] = uint16_t(num + (ii+1)%num); + } + + m_mesh[id].m_startVertex = startVertex; + m_mesh[id].m_numVertices = numVertices; + m_mesh[id].m_startIndex[0] = startIndex; + m_mesh[id].m_numIndices[0] = numIndices; + m_mesh[id].m_startIndex[1] = startIndex+numIndices; + m_mesh[id].m_numIndices[1] = numLineListIndices; + + startVertex += numVertices; + startIndex += numIndices + numLineListIndices; + } + m_mesh[Mesh::Cube].m_startVertex = startVertex; m_mesh[Mesh::Cube].m_numVertices = BX_COUNTOF(s_cubeVertices); m_mesh[Mesh::Cube].m_startIndex[0] = startIndex; @@ -444,9 +644,9 @@ struct DebugDraw const bgfx::Memory* vb = bgfx::alloc(startVertex*stride); const bgfx::Memory* ib = bgfx::alloc(startIndex*sizeof(uint16_t) ); - for (uint32_t mesh = 0; mesh < 4; ++mesh) + for (uint32_t mesh = Mesh::Sphere0; mesh < Mesh::Cube; ++mesh) { - Mesh::Enum id = Mesh::Enum(Mesh::Sphere0+mesh); + Mesh::Enum id = Mesh::Enum(mesh); memcpy(&vb->data[m_mesh[id].m_startVertex * stride] , vertices[id] , m_mesh[id].m_numVertices*stride @@ -780,7 +980,7 @@ struct DebugDraw void draw(const Cylinder& _cylinder, bool _capsule) { - BX_UNUSED(_cylinder, _capsule); + drawCylinder(_cylinder.m_pos, _cylinder.m_end, _cylinder.m_radius, _capsule); } void draw(const Disk& _disk) @@ -823,7 +1023,7 @@ struct DebugDraw } else { - draw(Mesh::Cube, _obb.m_mtx, false); + draw(Mesh::Cube, _obb.m_mtx, 1, false); } } @@ -846,7 +1046,7 @@ struct DebugDraw ? uint8_t(Mesh::SphereMaxLod) : attrib.m_lod ; - draw(Mesh::Enum(Mesh::Sphere0 + lod), mtx, attrib.m_wireframe); + draw(Mesh::Enum(Mesh::Sphere0 + lod), mtx, 1, attrib.m_wireframe); } void drawFrustum(const float* _viewProj) @@ -936,7 +1136,7 @@ struct DebugDraw lineTo(_x, _y, _z); } - void drawCircle(const float* _normal, const float* _center, float _radius, float _weight = 0.0f) + void drawCircle(const float* _normal, const float* _center, float _radius, float _weight) { const Attrib& attrib = m_attrib[m_stack]; const uint32_t num = getCircleLod(attrib.m_lod); @@ -979,12 +1179,12 @@ struct DebugDraw close(); } - void drawCircle(const void* _normal, const void* _center, float _radius, float _weight = 0.0f) + void drawCircle(const void* _normal, const void* _center, float _radius, float _weight) { drawCircle( (const float*)_normal, (const float*)_center, _radius, _weight); } - void drawCircle(Axis::Enum _axis, float _x, float _y, float _z, float _radius, float _weight = 0.0f) + void drawCircle(Axis::Enum _axis, float _x, float _y, float _z, float _radius, float _weight) { const Attrib& attrib = m_attrib[m_stack]; const uint32_t num = getCircleLod(attrib.m_lod); @@ -1018,147 +1218,139 @@ struct DebugDraw close(); } - void drawCone(const float* _from, const float* _to, float _radius, float _weight = 0.0f) + void drawCone(const float* _from, const float* _to, float _radius) { const Attrib& attrib = m_attrib[m_stack]; - const uint32_t num = getCircleLod(attrib.m_lod); - const float step = bx::pi * 2.0f / num; - _weight = bx::fclamp(_weight, 0.0f, 2.0f); - float pos[3]; float tmp0[3]; - float tmp1[3]; - bx::vec3Sub(tmp0, _from, _to); - Plane plane; - plane.m_dist = 0.0f; - bx::vec3Norm(plane.m_normal, tmp0); + float normal[3]; + bx::vec3Norm(normal, tmp0); - float udir[3]; - float vdir[3]; - calcPlaneUv(plane, udir, vdir); + float mtx[2][16]; + bx::mtxFromNormal(mtx[0], normal, _radius, _from); - float xy0[2]; - float xy1[2]; - circle(xy0, 0.0f); - squircle(xy1, 0.0f); + memcpy(mtx[1], mtx[0], 64); + mtx[1][12] = _to[0]; + mtx[1][13] = _to[1]; + mtx[1][14] = _to[2]; - bx::vec3Mul(pos, udir, bx::flerp(xy0[0], xy1[0], _weight)*_radius); - bx::vec3Mul(tmp0, vdir, bx::flerp(xy0[1], xy1[1], _weight)*_radius); - bx::vec3Add(tmp1, pos, tmp0); - bx::vec3Add(pos, tmp1, _from); - moveTo(pos); - - for (uint32_t ii = 1; ii < num; ++ii) - { - float angle = step * ii; - circle(xy0, angle); - squircle(xy1, angle); - - bx::vec3Mul(pos, udir, bx::flerp(xy0[0], xy1[0], _weight)*_radius); - bx::vec3Mul(tmp0, vdir, bx::flerp(xy0[1], xy1[1], _weight)*_radius); - bx::vec3Add(tmp1, pos, tmp0); - bx::vec3Add(pos, tmp1, _from); - lineTo(pos); - } - - close(); - - for (uint32_t ii = 0; ii < num; ++ii) - { - float angle = step * ii; - circle(xy0, angle); - squircle(xy1, angle); - - bx::vec3Mul(pos, udir, bx::flerp(xy0[0], xy1[0], _weight)*_radius); - bx::vec3Mul(tmp0, vdir, bx::flerp(xy0[1], xy1[1], _weight)*_radius); - bx::vec3Add(tmp1, pos, tmp0); - bx::vec3Add(pos, tmp1, _from); - moveTo(pos); - lineTo(_to); - } + uint8_t lod = attrib.m_lod > Mesh::ConeMaxLod + ? uint8_t(Mesh::ConeMaxLod) + : attrib.m_lod + ; + draw(Mesh::Enum(Mesh::Cone0 + lod), mtx[0], 2, attrib.m_wireframe); } - void drawCone(const void* _from, const void* _to, float _radius, float _weight = 0.0f) + void drawCone(const void* _from, const void* _to, float _radius) { - drawCone( (const float*)_from, (const float*)_to, _radius, _weight); + drawCone( (const float*)_from, (const float*)_to, _radius); } - void drawCylinder(const float* _from, const float* _to, float _radius, float _weight = 0.0f) + void drawCylinder(const float* _from, const float* _to, float _radius, bool _capsule) { const Attrib& attrib = m_attrib[m_stack]; - const uint32_t num = getCircleLod(attrib.m_lod); - const float step = bx::pi * 2.0f / num; - _weight = bx::fclamp(_weight, 0.0f, 2.0f); - float pos[3]; float tmp0[3]; - float tmp1[3]; - bx::vec3Sub(tmp0, _from, _to); - Plane plane; - plane.m_dist = 0.0f; - bx::vec3Norm(plane.m_normal, tmp0); + float normal[3]; + bx::vec3Norm(normal, tmp0); - float udir[3]; - float vdir[3]; - calcPlaneUv(plane, udir, vdir); + float mtx[2][16]; + bx::mtxFromNormal(mtx[0], normal, _radius, _from); - float xy0[2]; - float xy1[2]; - circle(xy0, 0.0f); - squircle(xy1, 0.0f); + memcpy(mtx[1], mtx[0], 64); + mtx[1][12] = _to[0]; + mtx[1][13] = _to[1]; + mtx[1][14] = _to[2]; - float pos1[3]; - bx::vec3Mul(pos, udir, bx::flerp(xy0[0], xy1[0], _weight)*_radius); - bx::vec3Mul(tmp0, vdir, bx::flerp(xy0[1], xy1[1], _weight)*_radius); - bx::vec3Add(tmp1, pos, tmp0); - bx::vec3Add(pos, tmp1, _from); - bx::vec3Add(pos1, tmp1, _to); - - for (uint32_t ii = 1; ii < num+1; ++ii) + if (_capsule) { - float angle = step * ii; - circle(xy0, angle); - squircle(xy1, angle); - - moveTo(pos); lineTo(pos1); - - moveTo(pos); - bx::vec3Mul(pos, udir, bx::flerp(xy0[0], xy1[0], _weight)*_radius); - bx::vec3Mul(tmp0, vdir, bx::flerp(xy0[1], xy1[1], _weight)*_radius); - bx::vec3Add(tmp1, pos, tmp0); - bx::vec3Add(pos, tmp1, _from); - lineTo(pos); - - moveTo(pos1); - bx::vec3Add(pos1, tmp1, _to); - lineTo(pos1); + uint8_t lod = attrib.m_lod > Mesh::CapsuleMaxLod + ? uint8_t(Mesh::CapsuleMaxLod) + : attrib.m_lod + ; + draw(Mesh::Enum(Mesh::Capsule0 + lod), mtx[0], 2, attrib.m_wireframe); + + Sphere sphere; + bx::vec3Move(sphere.m_center, _from); + sphere.m_radius = _radius; + draw(sphere); + + bx::vec3Move(sphere.m_center, _to); + draw(sphere); + } + else + { + uint8_t lod = attrib.m_lod > Mesh::CylinderMaxLod + ? uint8_t(Mesh::CylinderMaxLod) + : attrib.m_lod + ; + draw(Mesh::Enum(Mesh::Cylinder0 + lod), mtx[0], 2, attrib.m_wireframe); } } - void drawCylinder(const void* _from, const void* _to, float _radius, float _weight = 0.0f) + void drawCylinder(const void* _from, const void* _to, float _radius, bool _capsule) { - drawCylinder( (const float*)_from, (const float*)_to, _radius, _weight); + drawCylinder( (const float*)_from, (const float*)_to, _radius, _capsule); } - void drawAxis(float _x, float _y, float _z, float _len, Axis::Enum _highlight) + void drawAxis(float _x, float _y, float _z, float _len, Axis::Enum _highlight, float _thickness) { push(); - setColor(Axis::X == _highlight ? 0xff00ffff : 0xff0000ff); - moveTo(_x, _y, _z); - lineTo(_x + _len, _y, _z); + if (_thickness > 0.0f) + { + float from[3] = { _x, _y, _z }; + float mid[3]; + float to[3]; + + setColor(Axis::X == _highlight ? 0xff00ffff : 0xff0000ff); + mid[0] = _x + _len - _thickness; + mid[1] = _y; + mid[2] = _z; + to[0] = _x + _len; + to[1] = _y; + to[2] = _z; + drawCylinder(from, mid, _thickness, false); + drawCone(mid, to, _thickness); + + setColor(Axis::Y == _highlight ? 0xff00ffff : 0xff00ff00); + mid[0] = _x; + mid[1] = _y + _len - _thickness; + mid[2] = _z; + to[0] = _x; + to[1] = _y + _len; + to[2] = _z; + drawCylinder(from, mid, _thickness, false); + drawCone(mid, to, _thickness); + + setColor(Axis::Z == _highlight ? 0xff00ffff : 0xffff0000); + mid[0] = _x; + mid[1] = _y; + mid[2] = _z + _len - _thickness; + to[0] = _x; + to[1] = _y; + to[2] = _z + _len; + drawCylinder(from, mid, _thickness, false); + drawCone(mid, to, _thickness); + } + else + { + setColor(Axis::X == _highlight ? 0xff00ffff : 0xff0000ff); + moveTo(_x, _y, _z); + lineTo(_x + _len, _y, _z); - setColor(Axis::Y == _highlight ? 0xff00ffff : 0xff00ff00); - moveTo(_x, _y, _z); - lineTo(_x, _y + _len, _z); + setColor(Axis::Y == _highlight ? 0xff00ffff : 0xff00ff00); + moveTo(_x, _y, _z); + lineTo(_x, _y + _len, _z); - setColor(Axis::Z == _highlight ? 0xff00ffff : 0xffff0000); - moveTo(_x, _y, _z); - lineTo(_x, _y, _z + _len); + setColor(Axis::Z == _highlight ? 0xff00ffff : 0xffff0000); + moveTo(_x, _y, _z); + lineTo(_x, _y, _z + _len); + } pop(); } @@ -1274,13 +1466,13 @@ struct DebugDraw push(); setColor(Axis::X == _hightlight ? 0xff00ffff : 0xff0000ff); - drawCircle(Axis::X, _x, _y, _z, _radius); + drawCircle(Axis::X, _x, _y, _z, _radius, 0.0f); setColor(Axis::Y == _hightlight ? 0xff00ffff : 0xff00ff00); - drawCircle(Axis::Y, _x, _y, _z, _radius); + drawCircle(Axis::Y, _x, _y, _z, _radius, 0.0f); setColor(Axis::Z == _hightlight ? 0xff00ffff : 0xffff0000); - drawCircle(Axis::Z, _x, _y, _z, _radius); + drawCircle(Axis::Z, _x, _y, _z, _radius, 0.0f); pop(); } @@ -1294,11 +1486,30 @@ private: Sphere1, Sphere2, Sphere3, + + Cone0, + Cone1, + Cone2, + Cone3, + + Cylinder0, + Cylinder1, + Cylinder2, + Cylinder3, + + Capsule0, + Capsule1, + Capsule2, + Capsule3, + Cube, Count, - SphereMaxLod = Sphere3 - Sphere0, + SphereMaxLod = Sphere3 - Sphere0, + ConeMaxLod = Cone3 - Cone0, + CylinderMaxLod = Cylinder3 - Cylinder0, + CapsuleMaxLod = Capsule3 - Capsule0, }; uint32_t m_startVertex; @@ -1320,7 +1531,7 @@ private: }; }; - void draw(Mesh::Enum _mesh, const float* _mtx, bool _wireframe) const + void draw(Mesh::Enum _mesh, const float* _mtx, uint16_t _num, bool _wireframe) const { const Mesh& mesh = m_mesh[_mesh]; @@ -1334,31 +1545,34 @@ private: ); } + const float flip = 0 == (attrib.m_state & BGFX_STATE_CULL_CCW) ? 1.0f : -1.0f; + const uint8_t alpha = attrib.m_abgr>>24; + float params[4][4] = { - { - 0.0f, - -1.0f, - 0.0f, - 3.0f, + { // lightDir + 0.0f * flip, + -1.0f * flip, + 0.0f * flip, + 3.0f, // shininess }, - { + { // skyColor 1.0f, 0.9f, 0.8f, - 0.0f, + 0.0f, // unused }, - { + { // groundColor.xyz0 0.2f, 0.22f, 0.5f, - 0.0f, + 0.0f, // unused }, - { - ( (attrib.m_abgr>>24) )/255.0f, - ( (attrib.m_abgr>>16)&0xff)/255.0f, - ( (attrib.m_abgr>> 8)&0xff)/255.0f, + { // matColor ( (attrib.m_abgr )&0xff)/255.0f, + ( (attrib.m_abgr>> 8)&0xff)/255.0f, + ( (attrib.m_abgr>>16)&0xff)/255.0f, + ( alpha )/255.0f, }, }; @@ -1366,11 +1580,12 @@ private: bgfx::setUniform(u_params, params, 4); - bgfx::setTransform(_mtx); + bgfx::setTransform(_mtx, _num); bgfx::setVertexBuffer(m_vbh, mesh.m_startVertex, mesh.m_numVertices); bgfx::setState(0 | attrib.m_state - | (_wireframe ? BGFX_STATE_PT_LINES|BGFX_STATE_LINEAA|BGFX_STATE_BLEND_ALPHA : 0) + | (_wireframe ? BGFX_STATE_PT_LINES|BGFX_STATE_LINEAA|BGFX_STATE_BLEND_ALPHA + : (alpha < 0xff) ? BGFX_STATE_BLEND_ALPHA : 0) ); bgfx::submit(m_viewId, m_program[_wireframe ? Program::Fill : Program::FillLit]); } @@ -1608,19 +1823,34 @@ void ddDrawCircle(Axis::Enum _axis, float _x, float _y, float _z, float _radius, s_dd.drawCircle(_axis, _x, _y, _z, _radius, _weight); } -void ddDrawCone(const void* _from, const void* _to, float _radius, float _weight) +void ddDrawCone(const void* _from, const void* _to, float _radius) { - s_dd.drawCone(_from, _to, _radius, _weight); + s_dd.drawCone(_from, _to, _radius); +} + +void ddDrawCylinder(const void* _from, const void* _to, float _radius, bool _capsule) +{ + if (_capsule) + { + s_dd.push(); + s_dd.setLod(0); + s_dd.drawCylinder(_from, _to, _radius, true); + s_dd.pop(); + } + else + { + s_dd.drawCylinder(_from, _to, _radius, false); + } } -void ddDrawCylinder(const void* _from, const void* _to, float _radius, float _weight) +void ddDrawCapsule(const void* _from, const void* _to, float _radius) { - s_dd.drawCylinder(_from, _to, _radius, _weight); + s_dd.drawCylinder(_from, _to, _radius, true); } -void ddDrawAxis(float _x, float _y, float _z, float _len, Axis::Enum _hightlight) +void ddDrawAxis(float _x, float _y, float _z, float _len, Axis::Enum _hightlight, float _thickness) { - s_dd.drawAxis(_x, _y, _z, _len, _hightlight); + s_dd.drawAxis(_x, _y, _z, _len, _hightlight, _thickness); } void ddDrawGrid(const void* _normal, const void* _center, uint32_t _size, float _step) diff --git a/3rdparty/bgfx/examples/common/debugdraw/debugdraw.h b/3rdparty/bgfx/examples/common/debugdraw/debugdraw.h index 0888ffdae61..2535e5b7aff 100644 --- a/3rdparty/bgfx/examples/common/debugdraw/debugdraw.h +++ b/3rdparty/bgfx/examples/common/debugdraw/debugdraw.h @@ -103,13 +103,16 @@ void ddDrawCircle(const void* _normal, const void* _center, float _radius, float void ddDrawCircle(Axis::Enum _axis, float _x, float _y, float _z, float _radius, float _weight = 0.0f); /// -void ddDrawCone(const void* _from, const void* _to, float _radius, float _weight = 0.0f); +void ddDrawCone(const void* _from, const void* _to, float _radius); /// -void ddDrawCylinder(const void* _from, const void* _to, float _radius, float _weight = 0.0f); +void ddDrawCylinder(const void* _from, const void* _to, float _radius, bool _capsule = false); /// -void ddDrawAxis(float _x, float _y, float _z, float _len = 1.0f, Axis::Enum _highlight = Axis::Count); +void ddDrawCapsule(const void* _from, const void* _to, float _radius); + +/// +void ddDrawAxis(float _x, float _y, float _z, float _len = 1.0f, Axis::Enum _highlight = Axis::Count, float _thickness = 0.0f); /// void ddDrawGrid(const void* _normal, const void* _center, uint32_t _size = 20, float _step = 1.0f); diff --git a/3rdparty/bgfx/examples/common/debugdraw/varying.def.sc b/3rdparty/bgfx/examples/common/debugdraw/varying.def.sc index 79ed7aebf68..07d21a33f59 100644 --- a/3rdparty/bgfx/examples/common/debugdraw/varying.def.sc +++ b/3rdparty/bgfx/examples/common/debugdraw/varying.def.sc @@ -1,4 +1,5 @@ vec3 a_position : POSITION; +ivec4 a_indices : BLENDINDICES; vec4 a_color0 : COLOR0; float a_texcoord0 : TEXCOORD0; diff --git a/3rdparty/bgfx/examples/common/debugdraw/vs_debugdraw_fill.bin.h b/3rdparty/bgfx/examples/common/debugdraw/vs_debugdraw_fill.bin.h index 16fd98a58ef..50c1b1e580d 100644 --- a/3rdparty/bgfx/examples/common/debugdraw/vs_debugdraw_fill.bin.h +++ b/3rdparty/bgfx/examples/common/debugdraw/vs_debugdraw_fill.bin.h @@ -1,107 +1,148 @@ -static const uint8_t vs_debugdraw_fill_glsl[242] = +static const uint8_t vs_debugdraw_fill_glsl[329] = { - 0x56, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0f, 0x75, 0x5f, 0x6d, 0x6f, 0x64, // VSH........u_mod - 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, // elViewProj...... - 0xcd, 0x00, 0x00, 0x00, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x68, 0x69, // ....attribute hi - 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, // ghp vec3 a_posit - 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x68, 0x69, 0x67, // ion;.uniform hig - 0x68, 0x70, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, // hp mat4 u_modelV - 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, // iewProj;.void ma - 0x69, 0x6e, 0x20, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, // in ().{. highp - 0x76, 0x65, 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, // vec4 tmpvar_1;. - 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x31, 0x2e, // tmpvar_1.w = 1. - 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x78, 0x79, // 0;. tmpvar_1.xy - 0x7a, 0x20, 0x3d, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, // z = a_position;. - 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, // gl_Position = - 0x28, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, // (u_modelViewProj - 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, // * tmpvar_1);.}. - 0x0a, 0x00, // .. + 0x56, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0a, 0x75, 0x5f, 0x76, 0x69, 0x65, // VSH........u_vie + 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x07, 0x75, 0x5f, 0x6d, 0x6f, // wProj.......u_mo + 0x64, 0x65, 0x6c, 0x04, 0x20, 0x00, 0x00, 0x20, 0x00, 0x1b, 0x01, 0x00, 0x00, 0x61, 0x74, 0x74, // del. .. .....att + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, // ribute highp vec + 0x34, 0x20, 0x61, 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x3b, 0x0a, 0x61, 0x74, 0x74, // 4 a_indices;.att + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, // ribute highp vec + 0x33, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x75, 0x6e, // 3 a_position;.un + 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x6d, 0x61, 0x74, 0x34, // iform highp mat4 + 0x20, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x3b, 0x0a, 0x75, 0x6e, 0x69, // u_viewProj;.uni + 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, // form mat4 u_mode + 0x6c, 0x5b, 0x33, 0x32, 0x5d, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, // l[32];.void main + 0x20, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, // ().{. highp ve + 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, // c4 tmpvar_1;. t + 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, // mpvar_1.w = 1.0; + 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x20, // . tmpvar_1.xyz + 0x3d, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, // = a_position;. + 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x28, 0x75, // gl_Position = (u + 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x28, 0x75, 0x5f, 0x6d, // _viewProj * (u_m + 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x69, 0x6e, 0x74, 0x28, 0x61, 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x63, // odel[int(a_indic + 0x65, 0x73, 0x2e, 0x78, 0x29, 0x5d, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // es.x)] * tmpvar_ + 0x31, 0x29, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00, // 1));.}... }; -static const uint8_t vs_debugdraw_fill_dx9[287] = +static const uint8_t vs_debugdraw_fill_dx9[492] = { - 0x56, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0f, 0x75, 0x5f, 0x6d, 0x6f, 0x64, // VSH........u_mod - 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x04, 0x01, 0x00, 0x00, 0x04, 0x00, // elViewProj...... - 0xfc, 0x00, 0x00, 0x03, 0xfe, 0xff, 0xfe, 0xff, 0x24, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, // ........$.CTAB.. - 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, // ..W............. - 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, // ......P...0..... - 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, // ......@.......u_ - 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x00, 0x03, 0x00, // modelViewProj... - 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x73, // ..............vs - 0x5f, 0x33, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, // _3_0.Microsoft ( - 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, // R) HLSL Shader C - 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x31, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x30, // ompiler 10.0.100 - 0x31, 0x31, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, 0x00, 0xab, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, // 11.16384........ - 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, // ................ - 0x0f, 0xe0, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80, 0x01, 0x00, 0xe4, 0xa0, 0x00, 0x00, // ................ - 0x55, 0x90, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0xa0, 0x00, 0x00, // U............... - 0x00, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80, 0x02, 0x00, // ................ - 0xe4, 0xa0, 0x00, 0x00, 0xaa, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, // ................ - 0x0f, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xe4, 0xa0, 0xff, 0xff, 0x00, 0x00, 0x00, // ............... + 0x56, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, 0x75, 0x5f, 0x6d, 0x6f, 0x64, // VSH........u_mod + 0x65, 0x6c, 0x04, 0x20, 0x00, 0x00, 0x80, 0x00, 0x0a, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, // el. .....u_viewP + 0x72, 0x6f, 0x6a, 0x04, 0x01, 0x80, 0x00, 0x04, 0x00, 0xc0, 0x01, 0x00, 0x03, 0xfe, 0xff, 0xfe, // roj............. + 0xff, 0x2e, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, // ...CTAB......... + 0x03, 0xfe, 0xff, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x78, // ...............x + 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x4c, // ...D...........L + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x00, 0x04, // ................ + 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, // ...h.......u_mod + 0x65, 0x6c, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, // el......... .... + 0x00, 0x00, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x00, 0xab, 0x03, // ...u_viewProj... + 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, // ...............v + 0x73, 0x5f, 0x33, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, // s_3_0.Microsoft + 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, // (R) HLSL Shader + 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x31, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, // Compiler 10.0.10 + 0x30, 0x31, 0x31, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, 0x00, 0xab, 0x51, 0x00, 0x00, 0x05, 0x84, // 011.16384..Q.... + 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ......@......... + 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, // ................ + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x00, // ................ + 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0xe0, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x84, // ................ + 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x90, 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0xb0, 0x00, // ................ + 0x00, 0x00, 0x80, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80, 0x01, 0x00, 0x55, 0x90, 0x01, // .............U.. + 0x20, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0xb0, 0x04, 0x00, 0x00, 0x05, 0x00, 0x00, 0x0f, 0x80, 0x00, // ............... + 0x20, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x04, // ............... + 0x00, 0x00, 0x05, 0x00, 0x00, 0x0f, 0x80, 0x02, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0xb0, 0x01, // ........ ....... + 0x00, 0xaa, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80, 0x00, // ................ + 0x00, 0xe4, 0x80, 0x03, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0xb0, 0x05, 0x00, 0x00, 0x03, 0x01, // .... ........... + 0x00, 0x0f, 0x80, 0x00, 0x00, 0x55, 0x80, 0x81, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04, 0x01, // .....U.......... + 0x00, 0x0f, 0x80, 0x80, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x04, // ................ + 0x00, 0x00, 0x04, 0x01, 0x00, 0x0f, 0x80, 0x82, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xaa, 0x80, 0x01, // ................ + 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0xe0, 0x83, 0x00, 0xe4, 0xa0, 0x00, // ................ + 0x00, 0xff, 0x80, 0x01, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, // ............ }; -static const uint8_t vs_debugdraw_fill_dx11[404] = +static const uint8_t vs_debugdraw_fill_dx11[675] = { - 0x56, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0f, 0x75, 0x5f, 0x6d, 0x6f, 0x64, // VSH........u_mod - 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, // elViewProj...... - 0x6c, 0x01, 0x44, 0x58, 0x42, 0x43, 0x87, 0x3c, 0x16, 0xa4, 0x8d, 0x3d, 0x5b, 0xea, 0x61, 0x5c, // l.DXBC.<...=[.a. - 0x10, 0x3b, 0xa1, 0xf8, 0xf8, 0xa1, 0x01, 0x00, 0x00, 0x00, 0x6c, 0x01, 0x00, 0x00, 0x03, 0x00, // .;........l..... - 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x49, 0x53, // ..,...`.......IS - 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, // GN,........... . - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ - 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0xab, // ......POSITION.. - 0xab, 0xab, 0x4f, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, // ..OSGN,......... - 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, // .. ............. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, // ..........SV_POS - 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x53, 0x48, 0x44, 0x52, 0xd0, 0x00, 0x00, 0x00, 0x40, 0x00, // ITION.SHDR....@. - 0x01, 0x00, 0x34, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, // ..4...Y...F. ... - 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0x72, 0x10, 0x10, 0x00, 0x00, 0x00, // ......_...r..... - 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, // ..g.... ........ - 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0xf2, 0x00, // ..h.......8..... - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x15, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, // ......V.......F. - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0xf2, 0x00, // .........2..... - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ......F. ....... - 0x00, 0x00, 0x06, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, // ..........F..... - 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, // ..2...........F. - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa6, 0x1a, 0x10, 0x00, 0x00, 0x00, // ............... - 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf2, 0x20, // ..F............ - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, // ......F.......F. - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x01, // .........>..... - 0x01, 0x00, 0x40, 0x00, // ..@. + 0x56, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0a, 0x75, 0x5f, 0x76, 0x69, 0x65, // VSH........u_vie + 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x07, 0x75, 0x5f, 0x6d, 0x6f, // wProj.......u_mo + 0x64, 0x65, 0x6c, 0x04, 0x20, 0x40, 0x00, 0x80, 0x00, 0x70, 0x02, 0x44, 0x58, 0x42, 0x43, 0x21, // del. @...p.DXBC! + 0x99, 0xbc, 0x62, 0x67, 0xb7, 0x95, 0xd6, 0x90, 0x9d, 0x96, 0xc0, 0x0e, 0x98, 0x00, 0xf9, 0x01, // ..bg............ + 0x00, 0x00, 0x00, 0x70, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x84, // ...p.......,.... + 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x4e, 0x50, 0x00, 0x00, 0x00, 0x02, // .......ISGNP.... + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .......8........ + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x01, 0x00, 0x00, 0x45, // ...............E + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, // ................ + 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x42, 0x4c, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x44, 0x49, // .......BLENDINDI + 0x43, 0x45, 0x53, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0xab, 0xab, 0x4f, // CES.POSITION...O + 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, // SGN,........... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, // .......SV_POSITI + 0x4f, 0x4e, 0x00, 0x53, 0x48, 0x44, 0x52, 0xb0, 0x01, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, 0x6c, // ON.SHDR....@...l + 0x00, 0x00, 0x00, 0x59, 0x08, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, // ...Y...F. ...... + 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0x12, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, // ..._..........._ + 0x00, 0x00, 0x03, 0x72, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0xf2, // ...r.......g.... + 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x02, // ..........h.... + 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, // ...)............ + 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x38, // ........@......8 + 0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x56, 0x15, 0x10, 0x00, 0x01, // ...........V.... + 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0a, // ...F. .......... + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0c, 0xf2, 0x00, 0x10, 0x00, 0x01, // .......2........ + 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, // ...F. .......... + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, // ...............F + 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0c, 0xf2, 0x00, 0x10, 0x00, 0x01, // .......2........ + 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, // ...F. .......... + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x1a, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, // ...............F + 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x00, // ................ + 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x06, 0x00, // ...F.......F. .. + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, // ...............8 + 0x00, 0x00, 0x08, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, 0x00, // ...........V.... + 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, // ...F. .........2 + 0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, // ...........F. .. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, // ...............F + 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x01, // .......2........ + 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa6, // ...F. .......... + 0x0a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, // .......F.......2 + 0x00, 0x00, 0x0a, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, // .... ......F. .. + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, // ...............F + 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x02, 0x0e, 0x00, 0x01, // .......>........ + 0x00, 0x40, 0x08, // .@. }; -static const uint8_t vs_debugdraw_fill_mtl[555] = +static const uint8_t vs_debugdraw_fill_mtl[650] = { - 0x56, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x00, 0x75, 0x73, // VSH...........us + 0x56, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x02, 0x00, 0x00, 0x75, 0x73, // VSH.......{...us 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me 0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput { - 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, // . float3 a_posi - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, // tion [[attribute - 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, // (0)]];.};.struct - 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, // xlatMtlShaderOu - 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, // tput {. float4 - 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x70, 0x6f, // gl_Position [[po - 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, // sition]];.};.str - 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // uct xlatMtlShade - 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, // rUniform {. flo - 0x61, 0x74, 0x34, 0x78, 0x34, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, // at4x4 u_modelVie - 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, // wProj;.};.vertex - 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, // xlatMtlShaderOu - 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, // tput xlatMtlMain - 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, // (xlatMtlShaderI - 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, // nput _mtl_i [[st - 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, // age_in]], consta - 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, // nt xlatMtlShader - 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, // Uniform& _mtl_u - 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, // [[buffer(0)]]).{ - 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, // . xlatMtlShader - 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, // Output _mtl_o;. - 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // float4 tmpvar_1 - 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x77, 0x20, 0x3d, // ;. tmpvar_1.w = - 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // 1.0;. tmpvar_1 - 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, // .xyz = _mtl_i.a_ - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // position;. _mtl - 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, // _o.gl_Position = - 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, // (_mtl_u.u_model - 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // ViewProj * tmpva - 0x72, 0x5f, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, // r_1);. return _ - 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00, // mtl_o;.}... + 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x61, 0x5f, 0x69, 0x6e, 0x64, 0x69, // . float4 a_indi + 0x63, 0x65, 0x73, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, // ces [[attribute( + 0x30, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x61, // 0)]];. float3 a + 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, // _position [[attr + 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, // ibute(1)]];.};.s + 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, // truct xlatMtlSha + 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, // derOutput {. fl + 0x6f, 0x61, 0x74, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, // oat4 gl_Position + 0x20, 0x5b, 0x5b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, // [[position]];.} + 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, // ;.struct xlatMtl + 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, // ShaderUniform {. + 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x20, 0x75, 0x5f, 0x76, 0x69, 0x65, // float4x4 u_vie + 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, // wProj;. float4x + 0x34, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x33, 0x32, 0x5d, 0x3b, 0x0a, 0x7d, // 4 u_model[32];.} + 0x3b, 0x0a, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, // ;.vertex xlatMtl + 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, // ShaderOutput xla + 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, // tMtlMain (xlatMt + 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, // lShaderInput _mt + 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, // l_i [[stage_in]] + 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // , constant xlatM + 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, // tlShaderUniform& + 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, // _mtl_u [[buffer + 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // (0)]]).{. xlatM + 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, // tlShaderOutput _ + 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, // mtl_o;. float4 + 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, // tmpvar_1;. tmpv + 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, // ar_1.w = 1.0;. + 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x5f, // tmpvar_1.xyz = _ + 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, // mtl_i.a_position + 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x50, 0x6f, // ;. _mtl_o.gl_Po + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, // sition = (_mtl_u + 0x2e, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x28, 0x5f, // .u_viewProj * (_ + 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x69, 0x6e, // mtl_u.u_model[in + 0x74, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x63, // t(_mtl_i.a_indic + 0x65, 0x73, 0x2e, 0x78, 0x29, 0x5d, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // es.x)] * tmpvar_ + 0x31, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, // 1));. return _m + 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00, // tl_o;.}... }; diff --git a/3rdparty/bgfx/examples/common/debugdraw/vs_debugdraw_fill.sc b/3rdparty/bgfx/examples/common/debugdraw/vs_debugdraw_fill.sc index d007e9367cd..58f7be44248 100644 --- a/3rdparty/bgfx/examples/common/debugdraw/vs_debugdraw_fill.sc +++ b/3rdparty/bgfx/examples/common/debugdraw/vs_debugdraw_fill.sc @@ -1,4 +1,4 @@ -$input a_position +$input a_position, a_indices /* * Copyright 2011-2016 Branimir Karadzic. All rights reserved. @@ -9,5 +9,6 @@ $input a_position void main() { - gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) ); + vec4 model = mul(u_model[int(a_indices.x)], vec4(a_position, 1.0) ); + gl_Position = mul(u_viewProj, model); } diff --git a/3rdparty/bgfx/examples/common/debugdraw/vs_debugdraw_fill_lit.bin.h b/3rdparty/bgfx/examples/common/debugdraw/vs_debugdraw_fill_lit.bin.h index 2df5e3fbe89..c8201414fa4 100644 --- a/3rdparty/bgfx/examples/common/debugdraw/vs_debugdraw_fill_lit.bin.h +++ b/3rdparty/bgfx/examples/common/debugdraw/vs_debugdraw_fill_lit.bin.h @@ -1,195 +1,198 @@ -static const uint8_t vs_debugdraw_fill_lit_glsl[613] = +static const uint8_t vs_debugdraw_fill_lit_glsl[532] = { - 0x56, 0x53, 0x48, 0x04, 0x0f, 0xc8, 0x56, 0x5f, 0x03, 0x00, 0x07, 0x75, 0x5f, 0x6d, 0x6f, 0x64, // VSH...V_...u_mod - 0x65, 0x6c, 0x04, 0x20, 0x00, 0x00, 0x20, 0x00, 0x0b, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, // el. .. ..u_model - 0x56, 0x69, 0x65, 0x77, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x0f, 0x75, 0x5f, 0x6d, 0x6f, 0x64, // View.......u_mod - 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, // elViewProj...... - 0x20, 0x02, 0x00, 0x00, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x68, 0x69, // ...attribute hi - 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, // ghp vec3 a_posit - 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x69, 0x67, // ion;.varying hig - 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x76, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x3b, 0x0a, // hp vec3 v_view;. - 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, // varying highp ve - 0x63, 0x33, 0x20, 0x76, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, // c3 v_world;.unif + 0x56, 0x53, 0x48, 0x04, 0x0f, 0xc8, 0x56, 0x5f, 0x03, 0x00, 0x06, 0x75, 0x5f, 0x76, 0x69, 0x65, // VSH...V_...u_vie + 0x77, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, // w.......u_viewPr + 0x6f, 0x6a, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x07, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, // oj.......u_model + 0x04, 0x20, 0x00, 0x00, 0x20, 0x00, 0xd9, 0x01, 0x00, 0x00, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, // . .. .....attrib + 0x75, 0x74, 0x65, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x61, // ute highp vec4 a + 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x3b, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, // _indices;.attrib + 0x75, 0x74, 0x65, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x61, // ute highp vec3 a + 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, // _position;.varyi + 0x6e, 0x67, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x76, 0x5f, // ng highp vec3 v_ + 0x76, 0x69, 0x65, 0x77, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x69, // view;.varying hi + 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x76, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, // ghp vec3 v_world + 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, // ;.uniform highp + 0x6d, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x3b, 0x0a, 0x75, 0x6e, 0x69, // mat4 u_view;.uni + 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x20, // form highp mat4 + 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, // u_viewProj;.unif 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, // orm mat4 u_model - 0x5b, 0x33, 0x32, 0x5d, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x68, 0x69, // [32];.uniform hi - 0x67, 0x68, 0x70, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, // ghp mat4 u_model - 0x56, 0x69, 0x65, 0x77, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x68, 0x69, // View;.uniform hi - 0x67, 0x68, 0x70, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, // ghp mat4 u_model - 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, // ViewProj;.void m - 0x61, 0x69, 0x6e, 0x20, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, // ain ().{. highp - 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, // vec4 tmpvar_1;. - 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x31, // tmpvar_1.w = 1 - 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x78, // .0;. tmpvar_1.x - 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, // yz = a_position; - 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, // . gl_Position = - 0x20, 0x28, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, // (u_modelViewPro - 0x6a, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x29, 0x3b, 0x0a, 0x20, // j * tmpvar_1);. - 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, // highp vec4 tmpv - 0x61, 0x72, 0x5f, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, // ar_2;. tmpvar_2 - 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, // .w = 1.0;. tmpv - 0x61, 0x72, 0x5f, 0x32, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, // ar_2.xyz = a_pos - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x20, // ition;. v_view - 0x3d, 0x20, 0x28, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x20, 0x2a, // = (u_modelView * - 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, // tmpvar_2).xyz;. - 0x20, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, // highp vec4 tmp - 0x76, 0x61, 0x72, 0x5f, 0x33, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // var_3;. tmpvar_ - 0x33, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, // 3.w = 1.0;. tmp - 0x76, 0x61, 0x72, 0x5f, 0x33, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x61, 0x5f, 0x70, 0x6f, // var_3.xyz = a_po - 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x5f, 0x77, 0x6f, 0x72, 0x6c, // sition;. v_worl - 0x64, 0x20, 0x3d, 0x20, 0x28, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x30, 0x5d, 0x20, // d = (u_model[0] - 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x3b, // * tmpvar_3).xyz; - 0x0a, 0x7d, 0x0a, 0x0a, 0x00, // .}... + 0x5b, 0x33, 0x32, 0x5d, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x20, // [32];.void main + 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, // ().{. highp vec + 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, // 4 tmpvar_1;. tm + 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, // pvar_1.w = 1.0;. + 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, // tmpvar_1.xyz = + 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x68, // a_position;. h + 0x69, 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // ighp vec4 tmpvar + 0x5f, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x20, 0x3d, // _2;. tmpvar_2 = + 0x20, 0x28, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x69, 0x6e, 0x74, 0x28, 0x61, 0x5f, // (u_model[int(a_ + 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x78, 0x29, 0x5d, 0x20, 0x2a, 0x20, 0x74, 0x6d, // indices.x)] * tm + 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, // pvar_1);. gl_Po + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x28, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, // sition = (u_view + 0x50, 0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x29, // Proj * tmpvar_2) + 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x20, 0x3d, 0x20, 0x28, 0x75, 0x5f, // ;. v_view = (u_ + 0x76, 0x69, 0x65, 0x77, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x29, // view * tmpvar_2) + 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, // .xyz;. v_world + 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, // = tmpvar_2.xyz;. + 0x7d, 0x0a, 0x0a, 0x00, // }... }; -static const uint8_t vs_debugdraw_fill_lit_dx9[563] = +static const uint8_t vs_debugdraw_fill_lit_dx9[645] = { 0x56, 0x53, 0x48, 0x04, 0x0f, 0xc8, 0x56, 0x5f, 0x03, 0x00, 0x07, 0x75, 0x5f, 0x6d, 0x6f, 0x64, // VSH...V_...u_mod - 0x65, 0x6c, 0x04, 0x20, 0x00, 0x00, 0x04, 0x00, 0x0b, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, // el. .....u_model - 0x56, 0x69, 0x65, 0x77, 0x04, 0x01, 0x04, 0x00, 0x04, 0x00, 0x0f, 0x75, 0x5f, 0x6d, 0x6f, 0x64, // View.......u_mod - 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x04, 0x01, 0x08, 0x00, 0x04, 0x00, // elViewProj...... - 0xf0, 0x01, 0x00, 0x03, 0xfe, 0xff, 0xfe, 0xff, 0x37, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, // ........7.CTAB.. - 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, // ................ - 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, // ..........X..... - 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, // ......`.......p. - 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, // ..........|..... - 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7c, 0x00, // ..............|. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x00, 0x03, 0x00, // ......u_model... - 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, // ...... .......u_ - 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, // modelView....... - 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, // ..........u_mode - 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x00, 0x76, 0x73, 0x5f, 0x33, 0x5f, 0x30, // lViewProj.vs_3_0 - 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, // .Microsoft (R) H - 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, // LSL Shader Compi - 0x6c, 0x65, 0x72, 0x20, 0x31, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x30, 0x31, 0x31, 0x2e, 0x31, // ler 10.0.10011.1 - 0x36, 0x33, 0x38, 0x34, 0x00, 0xab, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, // 6384............ - 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0xe0, 0x1f, 0x00, // ................ - 0x00, 0x02, 0x05, 0x00, 0x00, 0x80, 0x01, 0x00, 0x07, 0xe0, 0x1f, 0x00, 0x00, 0x02, 0x05, 0x00, // ................ - 0x01, 0x80, 0x02, 0x00, 0x07, 0xe0, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80, 0x09, 0x00, // ................ - 0xe4, 0xa0, 0x00, 0x00, 0x55, 0x90, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80, 0x08, 0x00, // ....U........... - 0xe4, 0xa0, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, // ................ - 0x0f, 0x80, 0x0a, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xaa, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, // ................ - 0x00, 0x03, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x0b, 0x00, 0xe4, 0xa0, 0x05, 0x00, // ................ - 0x00, 0x03, 0x00, 0x00, 0x07, 0x80, 0x05, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0x55, 0x90, 0x04, 0x00, // ............U... - 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, 0x04, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, // ................ - 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, 0x06, 0x00, 0xe4, 0xa0, 0x00, 0x00, // ................ - 0xaa, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x03, 0x01, 0x00, 0x07, 0xe0, 0x00, 0x00, // ................ - 0xe4, 0x80, 0x07, 0x00, 0xe4, 0xa0, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, // ................ - 0xe4, 0xa0, 0x00, 0x00, 0x55, 0x90, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, // ....U........... - 0xe4, 0xa0, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, // ................ - 0x07, 0x80, 0x02, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xaa, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, // ................ - 0x00, 0x03, 0x02, 0x00, 0x07, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xe4, 0xa0, 0xff, 0xff, // ................ - 0x00, 0x00, 0x00, // ... + 0x65, 0x6c, 0x04, 0x20, 0x00, 0x00, 0x80, 0x00, 0x06, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x04, // el. .....u_view. + 0x01, 0x80, 0x00, 0x04, 0x00, 0x0a, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, // ......u_viewProj + 0x04, 0x01, 0x84, 0x00, 0x04, 0x00, 0x4c, 0x02, 0x00, 0x03, 0xfe, 0xff, 0xfe, 0xff, 0x35, 0x00, // ......L.......5. + 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0xff, // CTAB............ + 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, // ................ + 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, // X...........`... + 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x00, // ....p........... + 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x02, 0x00, 0x84, 0x00, // x............... + 0x04, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, 0x6d, 0x6f, // ....x.......u_mo + 0x64, 0x65, 0x6c, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, // del......... ... + 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x00, 0xab, 0x03, 0x00, 0x03, 0x00, // ....u_view...... + 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, 0x76, 0x69, // ............u_vi + 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x00, 0x76, 0x73, 0x5f, 0x33, 0x5f, 0x30, 0x00, 0x4d, 0x69, // ewProj.vs_3_0.Mi + 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, // crosoft (R) HLSL + 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, // Shader Compiler + 0x20, 0x31, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x30, 0x31, 0x31, 0x2e, 0x31, 0x36, 0x33, 0x38, // 10.0.10011.1638 + 0x34, 0x00, 0xab, 0xab, 0x51, 0x00, 0x00, 0x05, 0x88, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x40, // 4...Q..........@ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02, // ................ + 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, // ................ + 0x01, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0xe0, // ................ + 0x1f, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x80, 0x01, 0x00, 0x07, 0xe0, 0x1f, 0x00, 0x00, 0x02, // ................ + 0x05, 0x00, 0x01, 0x80, 0x02, 0x00, 0x07, 0xe0, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, // ................ + 0x88, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x90, 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0xb0, // ................ + 0x00, 0x00, 0x00, 0x80, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80, 0x01, 0x00, 0x55, 0x90, // ..............U. + 0x01, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0xb0, 0x04, 0x00, 0x00, 0x05, 0x00, 0x00, 0x0f, 0x80, // . .............. + 0x00, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0xe4, 0x80, // . .............. + 0x04, 0x00, 0x00, 0x05, 0x00, 0x00, 0x0f, 0x80, 0x02, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0xb0, // ......... ...... + 0x01, 0x00, 0xaa, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80, // ................ + 0x00, 0x00, 0xe4, 0x80, 0x03, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0xb0, 0x05, 0x00, 0x00, 0x03, // ..... .......... + 0x01, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x55, 0x80, 0x85, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04, // ......U......... + 0x01, 0x00, 0x0f, 0x80, 0x84, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0xe4, 0x80, // ................ + 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x0f, 0x80, 0x86, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xaa, 0x80, // ................ + 0x01, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0xe0, 0x87, 0x00, 0xe4, 0xa0, // ................ + 0x00, 0x00, 0xff, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x07, 0x80, // ................ + 0x00, 0x00, 0x55, 0x80, 0x81, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x07, 0x80, // ..U............. + 0x80, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04, // ................ + 0x01, 0x00, 0x07, 0x80, 0x82, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xaa, 0x80, 0x01, 0x00, 0xe4, 0x80, // ................ + 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x07, 0xe0, 0x83, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0x80, // ................ + 0x01, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x07, 0xe0, 0x00, 0x00, 0xe4, 0x80, // ................ + 0xff, 0xff, 0x00, 0x00, 0x00, // ..... }; -static const uint8_t vs_debugdraw_fill_lit_dx11[808] = +static const uint8_t vs_debugdraw_fill_lit_dx11[944] = { - 0x56, 0x53, 0x48, 0x04, 0x0f, 0xc8, 0x56, 0x5f, 0x03, 0x00, 0x07, 0x75, 0x5f, 0x6d, 0x6f, 0x64, // VSH...V_...u_mod - 0x65, 0x6c, 0x04, 0x20, 0x00, 0x00, 0x80, 0x00, 0x0b, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, // el. .....u_model - 0x56, 0x69, 0x65, 0x77, 0x04, 0x00, 0x00, 0x08, 0x04, 0x00, 0x0f, 0x75, 0x5f, 0x6d, 0x6f, 0x64, // View.......u_mod - 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x04, 0x00, 0x40, 0x08, 0x04, 0x00, // elViewProj..@... - 0xe0, 0x02, 0x44, 0x58, 0x42, 0x43, 0xda, 0xb8, 0xef, 0x0e, 0x34, 0xc8, 0x8c, 0x2c, 0x06, 0xbc, // ..DXBC....4..,.. - 0x07, 0x0b, 0x43, 0x58, 0xee, 0x33, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x02, 0x00, 0x00, 0x03, 0x00, // ..CX.3.......... - 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x49, 0x53, // ..,...`.......IS - 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, // GN,........... . - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ - 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0xab, // ......POSITION.. - 0xab, 0xab, 0x4f, 0x53, 0x47, 0x4e, 0x68, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, // ..OSGNh......... - 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, // ..P............. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x08, // ................ - 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, // ................ - 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, // ..........SV_POS - 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, // ITION.TEXCOORD.. - 0xab, 0xab, 0x53, 0x48, 0x44, 0x52, 0x08, 0x02, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, 0x82, 0x00, // ..SHDR....@..... - 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, // ..Y...F. ....... - 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0x72, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x00, // .._...r.......g. - 0x00, 0x04, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, // ... ..........e. - 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, // ..r ......e...r - 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, // ......h.......8. - 0x00, 0x08, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x15, 0x10, 0x00, 0x00, 0x00, // ..........V..... - 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x32, 0x00, // ..F. .........2. - 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, // ..........F. ... - 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x06, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, // ..............F. - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, // ......2......... - 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0xa6, 0x1a, // ..F. ........... - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ......F......... - 0x00, 0x08, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, // ... ......F..... - 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x38, 0x00, // ..F. .........8. - 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x15, 0x10, 0x00, 0x00, 0x00, // ..r.......V..... - 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x32, 0x00, // ..F. .........2. - 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, // ..r.......F. ... - 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x06, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, // ..............F. - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, 0x00, 0x00, // ......2...r..... - 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0xa6, 0x1a, // ..F. ........... - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ......F......... - 0x00, 0x08, 0x72, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, // ..r ......F..... - 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x38, 0x00, // ..F. .........8. - 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x15, 0x10, 0x00, 0x00, 0x00, // ..r.......V..... - 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, // ..F. .........2. - 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, // ..r.......F. ... - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, // ..............F. - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, 0x00, 0x00, // ......2...r..... - 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa6, 0x1a, // ..F. ........... - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ......F......... - 0x00, 0x08, 0x72, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, // ..r ......F..... - 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3e, 0x00, // ..F. .........>. - 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x80, 0x08, // ........ + 0x56, 0x53, 0x48, 0x04, 0x0f, 0xc8, 0x56, 0x5f, 0x03, 0x00, 0x06, 0x75, 0x5f, 0x76, 0x69, 0x65, // VSH...V_...u_vie + 0x77, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, // w.......u_viewPr + 0x6f, 0x6a, 0x04, 0x00, 0x40, 0x00, 0x04, 0x00, 0x07, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, // oj..@....u_model + 0x04, 0x20, 0x80, 0x00, 0x80, 0x00, 0x70, 0x03, 0x44, 0x58, 0x42, 0x43, 0x4a, 0x63, 0x00, 0x1f, // . ....p.DXBCJc.. + 0x8c, 0xf0, 0x42, 0x23, 0xf7, 0x2c, 0xd7, 0x55, 0x64, 0x23, 0x64, 0x92, 0x01, 0x00, 0x00, 0x00, // ..B#.,.Ud#d..... + 0x70, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, // p.......,....... + 0xf4, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x4e, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // ....ISGNP....... + 0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ....8........... + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x01, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, // ............E... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // ................ + 0x07, 0x07, 0x00, 0x00, 0x42, 0x4c, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x44, 0x49, 0x43, 0x45, 0x53, // ....BLENDINDICES + 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0xab, 0xab, 0x4f, 0x53, 0x47, 0x4e, // .POSITION...OSGN + 0x68, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, // h...........P... + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x0f, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, // ................ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // ................ + 0x07, 0x08, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, // ....SV_POSITION. + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, 0xab, 0xab, 0x53, 0x48, 0x44, 0x52, // TEXCOORD....SHDR + 0x74, 0x02, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x59, 0x08, 0x00, 0x04, // t...@.......Y... + 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, // F. ........._... + 0x12, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0x72, 0x10, 0x10, 0x00, // ........_...r... + 0x01, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ....g.... ...... + 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, // ....e...r ...... + 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, // e...r ......h... + 0x02, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ....)........... + 0x0a, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // .........@...... + 0x38, 0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x56, 0x15, 0x10, 0x00, // 8...........V... + 0x01, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, // ....F. ......... + 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0c, 0xf2, 0x00, 0x10, 0x00, // ........2....... + 0x01, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, // ....F. ......... + 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, // ................ + 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0c, 0xf2, 0x00, 0x10, 0x00, // F.......2....... + 0x01, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, // ....F. ......... + 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x1a, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, // ................ + 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, // F............... + 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x06, // ....F.......F. . + 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x38, 0x00, 0x00, 0x08, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, // 8...........V... + 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, // ....F. ......... + 0x32, 0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, // 2...........F. . + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, // F.......2....... + 0x01, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, // ....F. ......... + 0xa6, 0x0a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, // ........F....... + 0x32, 0x00, 0x00, 0x0a, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, // 2.... ......F. . + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, // F.......8...r... + 0x01, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, // ....V.......F. . + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, // ........2...r... + 0x01, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ....F. ......... + 0x06, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, // ........F....... + 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, // 2...r.......F. . + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x72, 0x20, 0x10, 0x00, // F.......2...r .. + 0x01, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, // ....F. ......... + 0xf6, 0x0f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, // ........F....... + 0x36, 0x00, 0x00, 0x05, 0x72, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, // 6...r ......F... + 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x02, 0x0e, 0x00, 0x01, 0x00, 0x80, 0x08, // ....>........... }; -static const uint8_t vs_debugdraw_fill_lit_mtl[898] = +static const uint8_t vs_debugdraw_fill_lit_mtl[829] = { - 0x56, 0x53, 0x48, 0x04, 0x0f, 0xc8, 0x56, 0x5f, 0x00, 0x00, 0x73, 0x03, 0x00, 0x00, 0x75, 0x73, // VSH...V_..s...us + 0x56, 0x53, 0x48, 0x04, 0x0f, 0xc8, 0x56, 0x5f, 0x00, 0x00, 0x2e, 0x03, 0x00, 0x00, 0x75, 0x73, // VSH...V_......us 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me 0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput { - 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, // . float3 a_posi - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, // tion [[attribute - 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, // (0)]];.};.struct + 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x61, 0x5f, 0x69, 0x6e, 0x64, 0x69, // . float4 a_indi + 0x63, 0x65, 0x73, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, // ces [[attribute( + 0x30, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x61, // 0)]];. float3 a + 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, // _position [[attr + 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, // ibute(1)]];.};.s + 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, // truct xlatMtlSha + 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, // derOutput {. fl + 0x6f, 0x61, 0x74, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, // oat4 gl_Position + 0x20, 0x5b, 0x5b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, // [[position]];. + 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x76, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x3b, 0x0a, // float3 v_view;. + 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x76, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, // float3 v_world + 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // ;.};.struct xlat + 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, // MtlShaderUniform + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x20, 0x75, 0x5f, // {. float4x4 u_ + 0x76, 0x69, 0x65, 0x77, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, // view;. float4x4 + 0x20, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x3b, 0x0a, 0x20, 0x20, 0x66, // u_viewProj;. f + 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, // loat4x4 u_model[ + 0x33, 0x32, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x20, 0x78, // 32];.};.vertex x + 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, // latMtlShaderOutp + 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, // ut xlatMtlMain ( + 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, // xlatMtlShaderInp + 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, // ut _mtl_i [[stag + 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, // e_in]], constant + 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, // xlatMtlShaderUn + 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, // iform& _mtl_u [[ + 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, // buffer(0)]]).{. 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, // xlatMtlShaderOu - 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, // tput {. float4 - 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x70, 0x6f, // gl_Position [[po - 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, // sition]];. floa - 0x74, 0x33, 0x20, 0x76, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, // t3 v_view;. flo - 0x61, 0x74, 0x33, 0x20, 0x76, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, // at3 v_world;.};. - 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // struct xlatMtlSh - 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, // aderUniform {. - 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, // float4x4 u_model - 0x5b, 0x33, 0x32, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, // [32];. float4x4 - 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x3b, 0x0a, 0x20, 0x20, // u_modelView;. - 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, // float4x4 u_model - 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x76, 0x65, 0x72, // ViewProj;.};.ver - 0x74, 0x65, 0x78, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // tex xlatMtlShade - 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, // rOutput xlatMtlM - 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, // ain (xlatMtlShad - 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, // erInput _mtl_i [ - 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, // [stage_in]], con - 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, // stant xlatMtlSha - 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // derUniform& _mtl - 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, // _u [[buffer(0)]] - 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, // ).{. xlatMtlSha - 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, // derOutput _mtl_o - 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // ;. float4 tmpva - 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, // r_1;. tmpvar_1. - 0x77, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // w = 1.0;. tmpva - 0x72, 0x5f, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, // r_1.xyz = _mtl_i - 0x2e, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x5f, // .a_position;. _ - 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, // mtl_o.gl_Positio - 0x6e, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x6d, 0x6f, // n = (_mtl_u.u_mo - 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x74, 0x6d, // delViewProj * tm - 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, // pvar_1);. float - 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, // 4 tmpvar_2;. tm - 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, // pvar_2.w = 1.0;. - 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, // tmpvar_2.xyz = - 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, // _mtl_i.a_positi - 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x76, 0x5f, 0x76, // on;. _mtl_o.v_v - 0x69, 0x65, 0x77, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, // iew = (_mtl_u.u_ - 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, // modelView * tmpv - 0x61, 0x72, 0x5f, 0x32, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, // ar_2).xyz;. flo - 0x61, 0x74, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x3b, 0x0a, 0x20, 0x20, // at4 tmpvar_3;. - 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, // tmpvar_3.w = 1.0 - 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x2e, 0x78, 0x79, 0x7a, // ;. tmpvar_3.xyz - 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, // = _mtl_i.a_posi - 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x76, // tion;. _mtl_o.v - 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, // _world = (_mtl_u - 0x2e, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x30, 0x5d, 0x20, 0x2a, 0x20, 0x74, 0x6d, // .u_model[0] * tm - 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x72, // pvar_3).xyz;. r - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, // eturn _mtl_o;.}. - 0x0a, 0x00, // .. + 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x66, // tput _mtl_o;. f + 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, // loat4 tmpvar_1;. + 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x31, // tmpvar_1.w = 1 + 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x78, // .0;. tmpvar_1.x + 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x70, 0x6f, // yz = _mtl_i.a_po + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, // sition;. float4 + 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, // tmpvar_2;. tmp + 0x76, 0x61, 0x72, 0x5f, 0x32, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, // var_2 = (_mtl_u. + 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x69, 0x6e, 0x74, 0x28, 0x5f, 0x6d, 0x74, 0x6c, // u_model[int(_mtl + 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x78, 0x29, 0x5d, // _i.a_indices.x)] + 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, // * tmpvar_1);. + 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, // _mtl_o.gl_Positi + 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x76, // on = (_mtl_u.u_v + 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // iewProj * tmpvar + 0x5f, 0x32, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x76, 0x5f, // _2);. _mtl_o.v_ + 0x76, 0x69, 0x65, 0x77, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, // view = (_mtl_u.u + 0x5f, 0x76, 0x69, 0x65, 0x77, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, // _view * tmpvar_2 + 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, // ).xyz;. _mtl_o. + 0x76, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // v_world = tmpvar + 0x5f, 0x32, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, // _2.xyz;. return + 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00, // _mtl_o;.}... }; diff --git a/3rdparty/bgfx/examples/common/debugdraw/vs_debugdraw_fill_lit.sc b/3rdparty/bgfx/examples/common/debugdraw/vs_debugdraw_fill_lit.sc index 02054e3ef28..ea4ce6bdcad 100644 --- a/3rdparty/bgfx/examples/common/debugdraw/vs_debugdraw_fill_lit.sc +++ b/3rdparty/bgfx/examples/common/debugdraw/vs_debugdraw_fill_lit.sc @@ -1,4 +1,4 @@ -$input a_position +$input a_position, a_indices $output v_view, v_world /* @@ -10,7 +10,8 @@ $output v_view, v_world void main() { - gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) ); - v_view = mul(u_modelView, vec4(a_position, 1.0) ).xyz; - v_world = mul(u_model[0], vec4(a_position, 1.0) ).xyz; + vec4 world = mul(u_model[int(a_indices.x)], vec4(a_position, 1.0) ); + gl_Position = mul(u_viewProj, world); + v_view = mul(u_view, world).xyz; + v_world = world.xyz; } diff --git a/3rdparty/bgfx/examples/common/entry/entry.cpp b/3rdparty/bgfx/examples/common/entry/entry.cpp index 0e03876a17e..a72b8027864 100644 --- a/3rdparty/bgfx/examples/common/entry/entry.cpp +++ b/3rdparty/bgfx/examples/common/entry/entry.cpp @@ -473,11 +473,8 @@ BX_PRAGMA_DIAGNOSTIC_POP(); const MouseEvent* mouse = static_cast<const MouseEvent*>(ev); handle = mouse->m_handle; - if (mouse->m_move) - { - inputSetMousePos(mouse->m_mx, mouse->m_my, mouse->m_mz); - } - else + inputSetMousePos(mouse->m_mx, mouse->m_my, mouse->m_mz); + if (!mouse->m_move) { inputSetMouseButtonState(mouse->m_button, mouse->m_down); } @@ -485,13 +482,10 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (NULL != _mouse && !mouseLock) { - if (mouse->m_move) - { - _mouse->m_mx = mouse->m_mx; - _mouse->m_my = mouse->m_my; - _mouse->m_mz = mouse->m_mz; - } - else + _mouse->m_mx = mouse->m_mx; + _mouse->m_my = mouse->m_my; + _mouse->m_mz = mouse->m_mz; + if (!mouse->m_move) { _mouse->m_buttons[mouse->m_button] = mouse->m_down; } diff --git a/3rdparty/bgfx/examples/common/entry/entry_android.cpp b/3rdparty/bgfx/examples/common/entry/entry_android.cpp index 78c9dccbefa..90bfd131368 100644 --- a/3rdparty/bgfx/examples/common/entry/entry_android.cpp +++ b/3rdparty/bgfx/examples/common/entry/entry_android.cpp @@ -82,7 +82,6 @@ namespace entry { Context() : m_window(NULL) - , m_count(0) { memset(m_value, 0, sizeof(m_value) ); @@ -297,43 +296,35 @@ namespace entry int32_t action = (actionBits & AMOTION_EVENT_ACTION_MASK); int32_t index = (actionBits & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; - count = m_count; - - switch (action) - { - case AMOTION_EVENT_ACTION_DOWN: - case AMOTION_EVENT_ACTION_POINTER_DOWN: - m_count++; - break; - - case AMOTION_EVENT_ACTION_UP: - case AMOTION_EVENT_ACTION_POINTER_UP: - m_count--; - break; - - default: - break; - } - - if (count != m_count) + // Simulate left mouse click with 1st touch and right mouse click with 2nd touch. ignore other touchs + if (count < 2) { - m_eventQueue.postMouseEvent(defaultWindow - , (int32_t)mx - , (int32_t)my - , 0 - , 1 == count ? MouseButton::Left : MouseButton::Right - , false - ); - - if (0 != m_count) + switch (action) { + case AMOTION_EVENT_ACTION_DOWN: + case AMOTION_EVENT_ACTION_POINTER_DOWN: m_eventQueue.postMouseEvent(defaultWindow , (int32_t)mx , (int32_t)my , 0 - , 1 == m_count ? MouseButton::Left : MouseButton::Right + , action == AMOTION_EVENT_ACTION_DOWN ? MouseButton::Left : MouseButton::Right , true ); + break; + + case AMOTION_EVENT_ACTION_UP: + case AMOTION_EVENT_ACTION_POINTER_UP: + m_eventQueue.postMouseEvent(defaultWindow + , (int32_t)mx + , (int32_t)my + , 0 + , action == AMOTION_EVENT_ACTION_UP ? MouseButton::Left : MouseButton::Right + , false + ); + break; + + default: + break; } } @@ -405,7 +396,6 @@ namespace entry ANativeWindow* m_window; android_app* m_app; - int32_t m_count; int32_t m_value[GamepadAxis::Count]; int32_t m_deadzone[GamepadAxis::Count]; }; diff --git a/3rdparty/bgfx/examples/common/entry/entry_ios.mm b/3rdparty/bgfx/examples/common/entry/entry_ios.mm index 052c161abd4..a5348212ef0 100644 --- a/3rdparty/bgfx/examples/common/entry/entry_ios.mm +++ b/3rdparty/bgfx/examples/common/entry/entry_ios.mm @@ -312,7 +312,7 @@ static void* m_device = NULL; [m_window makeKeyAndVisible]; - //float scaleFactor = [[UIScreen mainScreen] scale]; // should use this, but ui is too small on ipad retina + //float scaleFactor = [[UIScreen mainScreen] scale]; // should use this, but needs to further pass the value to the `nvgBeginFrame()` call's `devicePixelRatio` parameter in `ExampleNanoVG` class' `update()` method so it can actually work properly. float scaleFactor = 1.0f; [m_view setContentScaleFactor: scaleFactor ]; diff --git a/3rdparty/bgfx/examples/common/font/fs_font_distance_field.bin.h b/3rdparty/bgfx/examples/common/font/fs_font_distance_field.bin.h index 9bd34a78a05..c3d5b95de55 100644 --- a/3rdparty/bgfx/examples/common/font/fs_font_distance_field.bin.h +++ b/3rdparty/bgfx/examples/common/font/fs_font_distance_field.bin.h @@ -185,9 +185,9 @@ static const uint8_t fs_font_distance_field_dx11[1053] = 0x00, 0x36, 0x00, 0x00, 0x05, 0x72, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x12, 0x10, // .6...r ......F.. 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // .....>....... }; -static const uint8_t fs_font_distance_field_mtl[1492] = +static const uint8_t fs_font_distance_field_mtl[1493] = { - 0x46, 0x53, 0x48, 0x04, 0x01, 0x83, 0xf2, 0xe1, 0x00, 0x00, 0xc5, 0x05, 0x00, 0x00, 0x75, 0x73, // FSH...........us + 0x46, 0x53, 0x48, 0x04, 0x01, 0x83, 0xf2, 0xe1, 0x00, 0x00, 0xc6, 0x05, 0x00, 0x00, 0x75, 0x73, // FSH...........us 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me 0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput { @@ -240,45 +240,45 @@ static const uint8_t fs_font_distance_field_mtl[1492] = 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, // mtl_i.v_texcoord 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, // 0.xyz);. float3 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, // tmpvar_5;. tmp - 0x76, 0x61, 0x72, 0x5f, 0x35, 0x20, 0x3d, 0x20, 0x64, 0x66, 0x64, 0x79, 0x28, 0x5f, 0x6d, 0x74, // var_5 = dfdy(_mt - 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, // l_i.v_texcoord0. - 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, 0x6d, // xyz);. float tm - 0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // pvar_6;. tmpvar - 0x5f, 0x36, 0x20, 0x3d, 0x20, 0x28, 0x38, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x28, 0x73, 0x71, 0x72, // _6 = (8.0 * (sqr - 0x74, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x74, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, // t(. dot (tmpv - 0x61, 0x72, 0x5f, 0x34, 0x2c, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x29, 0x0a, // ar_4, tmpvar_4). - 0x20, 0x20, 0x29, 0x20, 0x2b, 0x20, 0x73, 0x71, 0x72, 0x74, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, // ) + sqrt(. - 0x64, 0x6f, 0x74, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x2c, 0x20, 0x74, // dot (tmpvar_5, t - 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x29, 0x0a, 0x20, 0x20, 0x29, 0x29, 0x29, 0x3b, 0x0a, // mpvar_5). )));. - 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, 0x5f, 0x37, 0x3b, // float edge0_7; - 0x0a, 0x20, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, 0x5f, 0x37, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2e, // . edge0_7 = (0. - 0x35, 0x20, 0x2d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x29, 0x3b, 0x0a, 0x20, // 5 - tmpvar_6);. - 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x65, 0x64, 0x67, 0x65, 0x31, 0x5f, 0x38, 0x3b, 0x0a, // float edge1_8;. - 0x20, 0x20, 0x65, 0x64, 0x67, 0x65, 0x31, 0x5f, 0x38, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2e, 0x35, // edge1_8 = (0.5 - 0x20, 0x2b, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x29, 0x3b, 0x0a, 0x20, 0x20, // + tmpvar_6);. - 0x68, 0x61, 0x6c, 0x66, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x3b, 0x0a, 0x20, // half tmpvar_9;. - 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x6d, // tmpvar_9 = clam - 0x70, 0x20, 0x28, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, // p (((half)((floa - 0x74, 0x29, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, // t)((half)((float - 0x29, 0x72, 0x67, 0x62, 0x61, 0x5f, 0x31, 0x5b, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, // )rgba_1[tmpvar_3 - 0x5d, 0x20, 0x2d, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, 0x5f, 0x37, 0x29, 0x29, 0x20, 0x2f, 0x20, // ] - edge0_7)) / - 0x28, 0x65, 0x64, 0x67, 0x65, 0x31, 0x5f, 0x38, 0x20, 0x2d, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, // (edge1_8 - edge0 - 0x5f, 0x37, 0x29, 0x29, 0x29, 0x2c, 0x20, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x30, 0x2e, 0x30, // _7))), (half)0.0 - 0x2c, 0x20, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, // , (half)1.0);. - 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x3b, // half4 tmpvar_10; - 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x2e, 0x78, 0x79, 0x7a, // . tmpvar_10.xyz - 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, // = half3(_mtl_i. - 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, // v_color0.xyz);. - 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x28, // tmpvar_10.w = ( - 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, // (half)(_mtl_i.v_ - 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x2e, 0x77, 0x20, 0x2a, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, // color0.w * (floa - 0x74, 0x29, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x20, 0x2a, 0x20, 0x28, 0x74, // t)(tmpvar_9 * (t - 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x20, 0x2a, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x28, // mpvar_9 * . ( - 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x33, 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x28, 0x28, 0x68, 0x61, // (half)3.0 - ((ha - 0x6c, 0x66, 0x29, 0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // lf)2.0 * tmpvar_ - 0x39, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x29, 0x29, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, // 9)). ))));. _m - 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, // tl_o.gl_FragColo - 0x72, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x3b, 0x0a, 0x20, // r = tmpvar_10;. - 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, // return _mtl_o;. - 0x7d, 0x0a, 0x0a, 0x00, // }... + 0x76, 0x61, 0x72, 0x5f, 0x35, 0x20, 0x3d, 0x20, 0x64, 0x66, 0x64, 0x79, 0x28, 0x2d, 0x5f, 0x6d, // var_5 = dfdy(-_m + 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, // tl_i.v_texcoord0 + 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, // .xyz);. float t + 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // mpvar_6;. tmpva + 0x72, 0x5f, 0x36, 0x20, 0x3d, 0x20, 0x28, 0x38, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x28, 0x73, 0x71, // r_6 = (8.0 * (sq + 0x72, 0x74, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x74, 0x20, 0x28, 0x74, 0x6d, 0x70, // rt(. dot (tmp + 0x76, 0x61, 0x72, 0x5f, 0x34, 0x2c, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x29, // var_4, tmpvar_4) + 0x0a, 0x20, 0x20, 0x29, 0x20, 0x2b, 0x20, 0x73, 0x71, 0x72, 0x74, 0x28, 0x0a, 0x20, 0x20, 0x20, // . ) + sqrt(. + 0x20, 0x64, 0x6f, 0x74, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x2c, 0x20, // dot (tmpvar_5, + 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x29, 0x0a, 0x20, 0x20, 0x29, 0x29, 0x29, 0x3b, // tmpvar_5). ))); + 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, 0x5f, 0x37, // . float edge0_7 + 0x3b, 0x0a, 0x20, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, 0x5f, 0x37, 0x20, 0x3d, 0x20, 0x28, 0x30, // ;. edge0_7 = (0 + 0x2e, 0x35, 0x20, 0x2d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x29, 0x3b, 0x0a, // .5 - tmpvar_6);. + 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x65, 0x64, 0x67, 0x65, 0x31, 0x5f, 0x38, 0x3b, // float edge1_8; + 0x0a, 0x20, 0x20, 0x65, 0x64, 0x67, 0x65, 0x31, 0x5f, 0x38, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2e, // . edge1_8 = (0. + 0x35, 0x20, 0x2b, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x29, 0x3b, 0x0a, 0x20, // 5 + tmpvar_6);. + 0x20, 0x68, 0x61, 0x6c, 0x66, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x3b, 0x0a, // half tmpvar_9;. + 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, // tmpvar_9 = cla + 0x6d, 0x70, 0x20, 0x28, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, // mp (((half)((flo + 0x61, 0x74, 0x29, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, // at)((half)((floa + 0x74, 0x29, 0x72, 0x67, 0x62, 0x61, 0x5f, 0x31, 0x5b, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // t)rgba_1[tmpvar_ + 0x33, 0x5d, 0x20, 0x2d, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, 0x5f, 0x37, 0x29, 0x29, 0x20, 0x2f, // 3] - edge0_7)) / + 0x20, 0x28, 0x65, 0x64, 0x67, 0x65, 0x31, 0x5f, 0x38, 0x20, 0x2d, 0x20, 0x65, 0x64, 0x67, 0x65, // (edge1_8 - edge + 0x30, 0x5f, 0x37, 0x29, 0x29, 0x29, 0x2c, 0x20, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x30, 0x2e, // 0_7))), (half)0. + 0x30, 0x2c, 0x20, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, // 0, (half)1.0);. + 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, // half4 tmpvar_10 + 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x2e, 0x78, 0x79, // ;. tmpvar_10.xy + 0x7a, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, // z = half3(_mtl_i + 0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, // .v_color0.xyz);. + 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x2e, 0x77, 0x20, 0x3d, 0x20, // tmpvar_10.w = + 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, // ((half)(_mtl_i.v + 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x2e, 0x77, 0x20, 0x2a, 0x20, 0x28, 0x66, 0x6c, 0x6f, // _color0.w * (flo + 0x61, 0x74, 0x29, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x20, 0x2a, 0x20, 0x28, // at)(tmpvar_9 * ( + 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x20, 0x2a, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, // tmpvar_9 * . + 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x33, 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x28, 0x28, 0x68, // ((half)3.0 - ((h + 0x61, 0x6c, 0x66, 0x29, 0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // alf)2.0 * tmpvar + 0x5f, 0x39, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x29, 0x29, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, // _9)). ))));. _ + 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, // mtl_o.gl_FragCol + 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x3b, 0x0a, // or = tmpvar_10;. + 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, // return _mtl_o; + 0x0a, 0x7d, 0x0a, 0x0a, 0x00, // .}... }; diff --git a/3rdparty/bgfx/examples/common/font/fs_font_distance_field_subpixel.bin.h b/3rdparty/bgfx/examples/common/font/fs_font_distance_field_subpixel.bin.h index 154481dc393..f338948d50c 100644 --- a/3rdparty/bgfx/examples/common/font/fs_font_distance_field_subpixel.bin.h +++ b/3rdparty/bgfx/examples/common/font/fs_font_distance_field_subpixel.bin.h @@ -226,9 +226,9 @@ static const uint8_t fs_font_distance_field_subpixel_dx11[1305] = 0x00, 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x1f, 0x10, 0x00, 0x01, 0x00, 0x00, // .F.............. 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // .>....... }; -static const uint8_t fs_font_distance_field_subpixel_mtl[1945] = +static const uint8_t fs_font_distance_field_subpixel_mtl[1946] = { - 0x46, 0x53, 0x48, 0x04, 0x01, 0x83, 0xf2, 0xe1, 0x00, 0x00, 0x8a, 0x07, 0x00, 0x00, 0x75, 0x73, // FSH...........us + 0x46, 0x53, 0x48, 0x04, 0x01, 0x83, 0xf2, 0xe1, 0x00, 0x00, 0x8b, 0x07, 0x00, 0x00, 0x75, 0x73, // FSH...........us 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me 0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput { @@ -267,87 +267,87 @@ static const uint8_t fs_font_distance_field_subpixel_mtl[1945] = 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, // excoord0.xyz);. 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, // float3 tmpvar_3 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x20, 0x3d, 0x20, 0x64, // ;. tmpvar_3 = d - 0x66, 0x64, 0x79, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, // fdy(_mtl_i.v_tex - 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, // coord0.xyz);. f - 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x3b, 0x0a, // loat3 tmpvar_4;. - 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2e, // tmpvar_4 = (0. - 0x31, 0x36, 0x36, 0x36, 0x36, 0x37, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // 166667 * tmpvar_ - 0x32, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x74, 0x6d, 0x70, // 2);. float3 tmp - 0x76, 0x61, 0x72, 0x5f, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // var_5;. tmpvar_ - 0x35, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, // 5 = (_mtl_i.v_te - 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x2d, 0x20, 0x74, 0x6d, // xcoord0.xyz - tm - 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, // pvar_4);. float - 0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, // 3 tmpvar_6;. tm - 0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, // pvar_6 = (_mtl_i - 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x78, 0x79, 0x7a, // .v_texcoord0.xyz - 0x20, 0x2b, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, // + tmpvar_4);. - 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x37, 0x3b, 0x0a, // half4 tmpvar_7;. - 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x37, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, // tmpvar_7 = hal - 0x66, 0x34, 0x28, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x73, 0x61, // f4(s_texColor.sa - 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x73, 0x5f, 0x74, // mple(_mtlsmp_s_t - 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, // exColor, (float3 - 0x29, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x29, 0x29, 0x29, 0x3b, 0x0a, 0x20, // )(tmpvar_5)));. - 0x20, 0x68, 0x61, 0x6c, 0x66, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x3b, 0x0a, // half tmpvar_8;. - 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x68, // tmpvar_8 = ((h - 0x61, 0x6c, 0x66, 0x29, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x37, 0x2e, 0x7a, 0x79, 0x78, // alf)tmpvar_7.zyx - 0x77, 0x5b, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, // w[tmpvar_1]);. - 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x3b, 0x0a, // half4 tmpvar_9;. - 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, // tmpvar_9 = hal - 0x66, 0x34, 0x28, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x73, 0x61, // f4(s_texColor.sa - 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x73, 0x5f, 0x74, // mple(_mtlsmp_s_t - 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, // exColor, (float3 - 0x29, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x29, 0x29, 0x29, 0x3b, 0x0a, 0x20, // )(tmpvar_6)));. - 0x20, 0x68, 0x61, 0x6c, 0x66, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x3b, // half tmpvar_10; - 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x20, 0x3d, 0x20, 0x28, // . tmpvar_10 = ( - 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x2e, 0x7a, // (half)tmpvar_9.z - 0x79, 0x78, 0x77, 0x5b, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x5d, 0x29, 0x3b, 0x0a, // yxw[tmpvar_1]);. - 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x31, // half tmpvar_11 - 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x31, 0x20, 0x3d, 0x20, // ;. tmpvar_11 = - 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x30, 0x2e, 0x35, 0x20, 0x2a, 0x20, 0x28, 0x74, 0x6d, // ((half)0.5 * (tm - 0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x20, 0x2b, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // pvar_8 + tmpvar_ - 0x31, 0x30, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, 0x6d, // 10));. float tm - 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // pvar_12;. tmpva - 0x72, 0x5f, 0x31, 0x32, 0x20, 0x3d, 0x20, 0x28, 0x38, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x28, 0x73, // r_12 = (8.0 * (s - 0x71, 0x72, 0x74, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x74, 0x20, 0x28, 0x74, 0x6d, // qrt(. dot (tm - 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x2c, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, // pvar_2, tmpvar_2 - 0x29, 0x0a, 0x20, 0x20, 0x29, 0x20, 0x2b, 0x20, 0x73, 0x71, 0x72, 0x74, 0x28, 0x0a, 0x20, 0x20, // ). ) + sqrt(. - 0x20, 0x20, 0x64, 0x6f, 0x74, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x2c, // dot (tmpvar_3, - 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x29, 0x0a, 0x20, 0x20, 0x29, 0x29, 0x29, // tmpvar_3). ))) - 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // ;. half3 tmpvar - 0x5f, 0x31, 0x33, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x33, // _13;. tmpvar_13 - 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x3b, 0x0a, 0x20, // .x = tmpvar_8;. - 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x33, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x74, // tmpvar_13.y = t - 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, // mpvar_11;. tmpv - 0x61, 0x72, 0x5f, 0x31, 0x33, 0x2e, 0x7a, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // ar_13.z = tmpvar - 0x5f, 0x31, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x65, 0x64, 0x67, // _10;. float edg - 0x65, 0x30, 0x5f, 0x31, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, 0x5f, 0x31, // e0_14;. edge0_1 - 0x34, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2e, 0x35, 0x20, 0x2d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // 4 = (0.5 - tmpva - 0x72, 0x5f, 0x31, 0x32, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x65, // r_12);. float e - 0x64, 0x67, 0x65, 0x31, 0x5f, 0x31, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x65, 0x64, 0x67, 0x65, 0x31, // dge1_15;. edge1 - 0x5f, 0x31, 0x35, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2e, 0x35, 0x20, 0x2b, 0x20, 0x74, 0x6d, 0x70, // _15 = (0.5 + tmp - 0x76, 0x61, 0x72, 0x5f, 0x31, 0x32, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, // var_12);. half3 - 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x36, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, // tmpvar_16;. tm - 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x36, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x20, // pvar_16 = clamp - 0x28, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, // (((half3)((float - 0x33, 0x29, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, // 3)((half3)((floa - 0x74, 0x33, 0x29, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x33, 0x20, 0x2d, 0x20, 0x65, // t3)tmpvar_13 - e - 0x64, 0x67, 0x65, 0x30, 0x5f, 0x31, 0x34, 0x29, 0x29, 0x20, 0x2f, 0x20, 0x28, 0x65, 0x64, 0x67, // dge0_14)) / (edg - 0x65, 0x31, 0x5f, 0x31, 0x35, 0x20, 0x2d, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, 0x5f, 0x31, 0x34, // e1_15 - edge0_14 - 0x29, 0x29, 0x29, 0x2c, 0x20, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x30, 0x2e, 0x30, 0x2c, 0x20, // ))), (half)0.0, - 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, // (half)1.0);. _m - 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, // tl_o.gl_FragColo - 0x72, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x29, // r.xyz = ((half3) - 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x29, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // ((float3)(tmpvar - 0x5f, 0x31, 0x36, 0x20, 0x2a, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x36, // _16 * (tmpvar_16 - 0x20, 0x2a, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x33, // * . ((half)3 - 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x32, 0x2e, 0x30, 0x20, // .0 - ((half)2.0 - 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x36, 0x29, 0x29, 0x0a, 0x20, 0x20, // * tmpvar_16)). - 0x29, 0x29, 0x20, 0x2a, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x63, 0x6f, // )) * _mtl_i.v_co - 0x6c, 0x6f, 0x72, 0x30, 0x2e, 0x77, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // lor0.w));. _mtl - 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, // _o.gl_FragColor. - 0x77, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, // w = ((half)((flo - 0x61, 0x74, 0x29, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x31, 0x20, 0x2a, 0x20, 0x5f, // at)tmpvar_11 * _ - 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x2e, 0x77, // mtl_i.v_color0.w - 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, // ));. return _mt - 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00, // l_o;.}... + 0x66, 0x64, 0x79, 0x28, 0x2d, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, // fdy(-_mtl_i.v_te + 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, // xcoord0.xyz);. + 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x3b, // float3 tmpvar_4; + 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x20, 0x3d, 0x20, 0x28, 0x30, // . tmpvar_4 = (0 + 0x2e, 0x31, 0x36, 0x36, 0x36, 0x36, 0x37, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // .166667 * tmpvar + 0x5f, 0x32, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x74, 0x6d, // _2);. float3 tm + 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // pvar_5;. tmpvar + 0x5f, 0x35, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, // _5 = (_mtl_i.v_t + 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x2d, 0x20, 0x74, // excoord0.xyz - t + 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, // mpvar_4);. floa + 0x74, 0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x3b, 0x0a, 0x20, 0x20, 0x74, // t3 tmpvar_6;. t + 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // mpvar_6 = (_mtl_ + 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x78, 0x79, // i.v_texcoord0.xy + 0x7a, 0x20, 0x2b, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x29, 0x3b, 0x0a, 0x20, // z + tmpvar_4);. + 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x37, 0x3b, // half4 tmpvar_7; + 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x37, 0x20, 0x3d, 0x20, 0x68, 0x61, // . tmpvar_7 = ha + 0x6c, 0x66, 0x34, 0x28, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x73, // lf4(s_texColor.s + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x73, 0x5f, // ample(_mtlsmp_s_ + 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, // texColor, (float + 0x33, 0x29, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x29, 0x29, 0x29, 0x3b, 0x0a, // 3)(tmpvar_5)));. + 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x3b, // half tmpvar_8; + 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x20, 0x3d, 0x20, 0x28, 0x28, // . tmpvar_8 = (( + 0x68, 0x61, 0x6c, 0x66, 0x29, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x37, 0x2e, 0x7a, 0x79, // half)tmpvar_7.zy + 0x78, 0x77, 0x5b, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x5d, 0x29, 0x3b, 0x0a, 0x20, // xw[tmpvar_1]);. + 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x3b, // half4 tmpvar_9; + 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x20, 0x3d, 0x20, 0x68, 0x61, // . tmpvar_9 = ha + 0x6c, 0x66, 0x34, 0x28, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x73, // lf4(s_texColor.s + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x73, 0x5f, // ample(_mtlsmp_s_ + 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, // texColor, (float + 0x33, 0x29, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x29, 0x29, 0x29, 0x3b, 0x0a, // 3)(tmpvar_6)));. + 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, // half tmpvar_10 + 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x20, 0x3d, 0x20, // ;. tmpvar_10 = + 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x2e, // ((half)tmpvar_9. + 0x7a, 0x79, 0x78, 0x77, 0x5b, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x5d, 0x29, 0x3b, // zyxw[tmpvar_1]); + 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // . half tmpvar_1 + 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x31, 0x20, 0x3d, // 1;. tmpvar_11 = + 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x30, 0x2e, 0x35, 0x20, 0x2a, 0x20, 0x28, 0x74, // ((half)0.5 * (t + 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x20, 0x2b, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // mpvar_8 + tmpvar + 0x5f, 0x31, 0x30, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, // _10));. float t + 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, // mpvar_12;. tmpv + 0x61, 0x72, 0x5f, 0x31, 0x32, 0x20, 0x3d, 0x20, 0x28, 0x38, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x28, // ar_12 = (8.0 * ( + 0x73, 0x71, 0x72, 0x74, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x74, 0x20, 0x28, 0x74, // sqrt(. dot (t + 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x2c, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // mpvar_2, tmpvar_ + 0x32, 0x29, 0x0a, 0x20, 0x20, 0x29, 0x20, 0x2b, 0x20, 0x73, 0x71, 0x72, 0x74, 0x28, 0x0a, 0x20, // 2). ) + sqrt(. + 0x20, 0x20, 0x20, 0x64, 0x6f, 0x74, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, // dot (tmpvar_3 + 0x2c, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x29, 0x0a, 0x20, 0x20, 0x29, 0x29, // , tmpvar_3). )) + 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // );. half3 tmpva + 0x72, 0x5f, 0x31, 0x33, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // r_13;. tmpvar_1 + 0x33, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x3b, 0x0a, // 3.x = tmpvar_8;. + 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x33, 0x2e, 0x79, 0x20, 0x3d, 0x20, // tmpvar_13.y = + 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, // tmpvar_11;. tmp + 0x76, 0x61, 0x72, 0x5f, 0x31, 0x33, 0x2e, 0x7a, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // var_13.z = tmpva + 0x72, 0x5f, 0x31, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x65, 0x64, // r_10;. float ed + 0x67, 0x65, 0x30, 0x5f, 0x31, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, 0x5f, // ge0_14;. edge0_ + 0x31, 0x34, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2e, 0x35, 0x20, 0x2d, 0x20, 0x74, 0x6d, 0x70, 0x76, // 14 = (0.5 - tmpv + 0x61, 0x72, 0x5f, 0x31, 0x32, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, // ar_12);. float + 0x65, 0x64, 0x67, 0x65, 0x31, 0x5f, 0x31, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x65, 0x64, 0x67, 0x65, // edge1_15;. edge + 0x31, 0x5f, 0x31, 0x35, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2e, 0x35, 0x20, 0x2b, 0x20, 0x74, 0x6d, // 1_15 = (0.5 + tm + 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x32, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, // pvar_12);. half + 0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x36, 0x3b, 0x0a, 0x20, 0x20, 0x74, // 3 tmpvar_16;. t + 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x36, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70, // mpvar_16 = clamp + 0x20, 0x28, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, // (((half3)((floa + 0x74, 0x33, 0x29, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, // t3)((half3)((flo + 0x61, 0x74, 0x33, 0x29, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x33, 0x20, 0x2d, 0x20, // at3)tmpvar_13 - + 0x65, 0x64, 0x67, 0x65, 0x30, 0x5f, 0x31, 0x34, 0x29, 0x29, 0x20, 0x2f, 0x20, 0x28, 0x65, 0x64, // edge0_14)) / (ed + 0x67, 0x65, 0x31, 0x5f, 0x31, 0x35, 0x20, 0x2d, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, 0x5f, 0x31, // ge1_15 - edge0_1 + 0x34, 0x29, 0x29, 0x29, 0x2c, 0x20, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x30, 0x2e, 0x30, 0x2c, // 4))), (half)0.0, + 0x20, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, // (half)1.0);. _ + 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, // mtl_o.gl_FragCol + 0x6f, 0x72, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x33, // or.xyz = ((half3 + 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x29, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, // )((float3)(tmpva + 0x72, 0x5f, 0x31, 0x36, 0x20, 0x2a, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // r_16 * (tmpvar_1 + 0x36, 0x20, 0x2a, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, // 6 * . ((half) + 0x33, 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x32, 0x2e, 0x30, // 3.0 - ((half)2.0 + 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x36, 0x29, 0x29, 0x0a, 0x20, // * tmpvar_16)). + 0x20, 0x29, 0x29, 0x20, 0x2a, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x63, // )) * _mtl_i.v_c + 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x2e, 0x77, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, // olor0.w));. _mt + 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, // l_o.gl_FragColor + 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x28, 0x28, 0x66, 0x6c, // .w = ((half)((fl + 0x6f, 0x61, 0x74, 0x29, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x31, 0x20, 0x2a, 0x20, // oat)tmpvar_11 * + 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x2e, // _mtl_i.v_color0. + 0x77, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, // w));. return _m + 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00, // tl_o;.}... }; diff --git a/3rdparty/bgfx/examples/common/nanovg/nanovg.cpp b/3rdparty/bgfx/examples/common/nanovg/nanovg.cpp index 8dbac8a294e..c7433cdc45d 100644 --- a/3rdparty/bgfx/examples/common/nanovg/nanovg.cpp +++ b/3rdparty/bgfx/examples/common/nanovg/nanovg.cpp @@ -339,7 +339,7 @@ void nvgBeginFrame(NVGcontext* ctx, int windowWidth, int windowHeight, float dev nvg__setDevicePixelRatio(ctx, devicePixelRatio); - ctx->params.renderViewport(ctx->params.userPtr, windowWidth, windowHeight); + ctx->params.renderViewport(ctx->params.userPtr, windowWidth, windowHeight, devicePixelRatio); ctx->drawCallCount = 0; ctx->fillTriCount = 0; diff --git a/3rdparty/bgfx/examples/common/nanovg/nanovg.h b/3rdparty/bgfx/examples/common/nanovg/nanovg.h index 692d1bd2be8..984c1935e3c 100644 --- a/3rdparty/bgfx/examples/common/nanovg/nanovg.h +++ b/3rdparty/bgfx/examples/common/nanovg/nanovg.h @@ -19,6 +19,8 @@ #ifndef NANOVG_H #define NANOVG_H +#include "nanovg_bgfx.h" + #ifdef __cplusplus extern "C" { #endif @@ -588,7 +590,7 @@ struct NVGparams { int (*renderDeleteTexture)(void* uptr, int image); int (*renderUpdateTexture)(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data); int (*renderGetTextureSize)(void* uptr, int image, int* w, int* h); - void (*renderViewport)(void* uptr, int width, int height); + void (*renderViewport)(void* uptr, int width, int height, float devicePixelRatio); void (*renderCancel)(void* uptr); void (*renderFlush)(void* uptr); void (*renderFill)(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe, const float* bounds, const NVGpath* paths, int npaths); @@ -598,12 +600,6 @@ struct NVGparams { }; typedef struct NVGparams NVGparams; -namespace bx { struct AllocatorI; } - -NVGcontext* nvgCreate(int edgeaa, unsigned char _viewId, bx::AllocatorI* _allocator = NULL); -void nvgViewId(struct NVGcontext* ctx, unsigned char _viewId); -void nvgDelete(struct NVGcontext* ctx); - // Constructor and destructor, called by the render back-end. NVGcontext* nvgCreateInternal(NVGparams* params); void nvgDeleteInternal(NVGcontext* ctx); diff --git a/3rdparty/bgfx/examples/common/nanovg/nanovg_bgfx.cpp b/3rdparty/bgfx/examples/common/nanovg/nanovg_bgfx.cpp index e5795ad2131..41095d853bb 100644 --- a/3rdparty/bgfx/examples/common/nanovg/nanovg_bgfx.cpp +++ b/3rdparty/bgfx/examples/common/nanovg/nanovg_bgfx.cpp @@ -545,12 +545,12 @@ namespace gl->th = handle; } - static void nvgRenderViewport(void* _userPtr, int width, int height) + static void nvgRenderViewport(void* _userPtr, int width, int height, float devicePixelRatio) { struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; gl->view[0] = (float)width; gl->view[1] = (float)height; - bgfx::setViewRect(gl->m_viewId, 0, 0, width, height); + bgfx::setViewRect(gl->m_viewId, 0, 0, width * devicePixelRatio, height * devicePixelRatio); } static void fan(uint32_t _start, uint32_t _count) @@ -1088,6 +1088,10 @@ error: return NULL; } +NVGcontext* nvgCreate(int edgeaa, unsigned char _viewId) { + return nvgCreate(edgeaa, _viewId, NULL); +} + void nvgViewId(struct NVGcontext* ctx, unsigned char _viewId) { struct NVGparams* params = nvgInternalParams(ctx); diff --git a/3rdparty/bgfx/examples/common/nanovg/nanovg_bgfx.h b/3rdparty/bgfx/examples/common/nanovg/nanovg_bgfx.h new file mode 100644 index 00000000000..d24ee4fa72f --- /dev/null +++ b/3rdparty/bgfx/examples/common/nanovg/nanovg_bgfx.h @@ -0,0 +1,18 @@ +/* + * Copyright 2011-2016 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#ifndef NANOVG_BGFX_H_HEADER_GUARD +#define NANOVG_BGFX_H_HEADER_GUARD + +namespace bx { struct AllocatorI; } + +struct NVGcontext; + +NVGcontext* nvgCreate(int edgeaa, unsigned char _viewId, bx::AllocatorI* _allocator); +NVGcontext* nvgCreate(int edgeaa, unsigned char _viewId); +void nvgViewId(struct NVGcontext* ctx, unsigned char _viewId); +void nvgDelete(struct NVGcontext* ctx); + +#endif // NANOVG_BGFX_H_HEADER_GUARD diff --git a/3rdparty/bgfx/examples/runtime/meshes/bunny.bin b/3rdparty/bgfx/examples/runtime/meshes/bunny.bin Binary files differindex adcca877ef8..794ec22c7fe 100644 --- a/3rdparty/bgfx/examples/runtime/meshes/bunny.bin +++ b/3rdparty/bgfx/examples/runtime/meshes/bunny.bin diff --git a/3rdparty/bgfx/examples/runtime/meshes/hollowcube.bin b/3rdparty/bgfx/examples/runtime/meshes/hollowcube.bin Binary files differindex 3234750e081..0ea300901e5 100644 --- a/3rdparty/bgfx/examples/runtime/meshes/hollowcube.bin +++ b/3rdparty/bgfx/examples/runtime/meshes/hollowcube.bin diff --git a/3rdparty/bgfx/examples/runtime/meshes/orb.bin b/3rdparty/bgfx/examples/runtime/meshes/orb.bin Binary files differindex 336f3680565..22b9a8af452 100644 --- a/3rdparty/bgfx/examples/runtime/meshes/orb.bin +++ b/3rdparty/bgfx/examples/runtime/meshes/orb.bin diff --git a/3rdparty/bgfx/examples/runtime/meshes/unit_sphere.bin b/3rdparty/bgfx/examples/runtime/meshes/unit_sphere.bin Binary files differnew file mode 100644 index 00000000000..1ffc27f623f --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/meshes/unit_sphere.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_ibl_mesh.bin b/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_ibl_mesh.bin Binary files differindex 155058f3846..68159a75736 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_ibl_mesh.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_ibl_mesh.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_picking_id.bin b/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_picking_id.bin Binary files differnew file mode 100644 index 00000000000..88fffd64461 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_picking_id.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_picking_shaded.bin b/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_picking_shaded.bin Binary files differnew file mode 100644 index 00000000000..efa26898d42 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_picking_shaded.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_rsm_combine.bin b/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_rsm_combine.bin Binary files differnew file mode 100644 index 00000000000..5c633734433 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_rsm_combine.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_rsm_gbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_rsm_gbuffer.bin Binary files differnew file mode 100644 index 00000000000..71c20d5bfc5 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_rsm_gbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_rsm_lbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_rsm_lbuffer.bin Binary files differnew file mode 100644 index 00000000000..ae81827f81b --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_rsm_lbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_rsm_shadow.bin b/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_rsm_shadow.bin Binary files differnew file mode 100644 index 00000000000..faf21f024b8 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_rsm_shadow.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_sms_shadow.bin b/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_sms_shadow.bin Binary files differindex 2477d864d9a..2ffc6baeefc 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_sms_shadow.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/dx11/fs_sms_shadow.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_ibl_skybox.bin b/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_ibl_skybox.bin Binary files differindex 8c29510aa1b..1b32e1c6552 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_ibl_skybox.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_ibl_skybox.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_picking_shaded.bin b/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_picking_shaded.bin Binary files differnew file mode 100644 index 00000000000..27e8c4d29b9 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_picking_shaded.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_rsm_combine.bin b/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_rsm_combine.bin Binary files differnew file mode 100644 index 00000000000..2278290e567 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_rsm_combine.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_rsm_gbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_rsm_gbuffer.bin Binary files differnew file mode 100644 index 00000000000..40a542facc4 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_rsm_gbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_rsm_lbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_rsm_lbuffer.bin Binary files differnew file mode 100644 index 00000000000..be1624f7796 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_rsm_lbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_rsm_shadow.bin b/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_rsm_shadow.bin Binary files differnew file mode 100644 index 00000000000..1a351d8cd61 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx11/vs_rsm_shadow.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_ibl_mesh.bin b/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_ibl_mesh.bin Binary files differindex 74ad610bbf1..337a86b34cd 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_ibl_mesh.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_ibl_mesh.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_picking_id.bin b/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_picking_id.bin Binary files differnew file mode 100644 index 00000000000..6e0208149a0 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_picking_id.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_picking_shaded.bin b/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_picking_shaded.bin Binary files differnew file mode 100644 index 00000000000..8c5005ca008 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_picking_shaded.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_rsm_combine.bin b/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_rsm_combine.bin Binary files differnew file mode 100644 index 00000000000..28d904d8986 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_rsm_combine.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_rsm_gbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_rsm_gbuffer.bin Binary files differnew file mode 100644 index 00000000000..7facc87fc72 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_rsm_gbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_rsm_lbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_rsm_lbuffer.bin Binary files differnew file mode 100644 index 00000000000..5f9e5c0236e --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_rsm_lbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_rsm_shadow.bin b/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_rsm_shadow.bin Binary files differnew file mode 100644 index 00000000000..d93441c2f28 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx9/fs_rsm_shadow.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_ibl_skybox.bin b/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_ibl_skybox.bin Binary files differindex 0c8d2ffaf25..f408ee78684 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_ibl_skybox.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_ibl_skybox.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_picking_shaded.bin b/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_picking_shaded.bin Binary files differnew file mode 100644 index 00000000000..9df3ff89fd7 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_picking_shaded.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_rsm_combine.bin b/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_rsm_combine.bin Binary files differnew file mode 100644 index 00000000000..fe8592c138d --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_rsm_combine.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_rsm_gbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_rsm_gbuffer.bin Binary files differnew file mode 100644 index 00000000000..3cc1c15e95a --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_rsm_gbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_rsm_lbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_rsm_lbuffer.bin Binary files differnew file mode 100644 index 00000000000..12579db146c --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_rsm_lbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_rsm_shadow.bin b/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_rsm_shadow.bin Binary files differnew file mode 100644 index 00000000000..2d9ef91e8bb --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/dx9/vs_rsm_shadow.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/gles/fs_ibl_mesh.bin b/3rdparty/bgfx/examples/runtime/shaders/gles/fs_ibl_mesh.bin Binary files differindex 75c93b113e3..a4cd92a1904 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/gles/fs_ibl_mesh.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/gles/fs_ibl_mesh.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/gles/fs_picking_id.bin b/3rdparty/bgfx/examples/runtime/shaders/gles/fs_picking_id.bin Binary files differnew file mode 100644 index 00000000000..91acdf18ecd --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/gles/fs_picking_id.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/gles/fs_picking_shaded.bin b/3rdparty/bgfx/examples/runtime/shaders/gles/fs_picking_shaded.bin Binary files differnew file mode 100644 index 00000000000..62c604c3d4a --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/gles/fs_picking_shaded.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/gles/fs_rsm_combine.bin b/3rdparty/bgfx/examples/runtime/shaders/gles/fs_rsm_combine.bin Binary files differnew file mode 100644 index 00000000000..23364eb50e3 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/gles/fs_rsm_combine.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/gles/fs_rsm_gbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/gles/fs_rsm_gbuffer.bin Binary files differnew file mode 100644 index 00000000000..911c8ff6f09 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/gles/fs_rsm_gbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/gles/fs_rsm_lbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/gles/fs_rsm_lbuffer.bin Binary files differnew file mode 100644 index 00000000000..207c88361b2 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/gles/fs_rsm_lbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/gles/fs_rsm_shadow.bin b/3rdparty/bgfx/examples/runtime/shaders/gles/fs_rsm_shadow.bin Binary files differnew file mode 100644 index 00000000000..6c9adff2df9 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/gles/fs_rsm_shadow.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/gles/fs_sms_shadow.bin b/3rdparty/bgfx/examples/runtime/shaders/gles/fs_sms_shadow.bin Binary files differindex 3262874eaf3..81ccc6436e4 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/gles/fs_sms_shadow.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/gles/fs_sms_shadow.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/gles/vs_ibl_skybox.bin b/3rdparty/bgfx/examples/runtime/shaders/gles/vs_ibl_skybox.bin Binary files differindex d0c60ada93c..d518d061f73 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/gles/vs_ibl_skybox.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/gles/vs_ibl_skybox.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/gles/vs_picking_shaded.bin b/3rdparty/bgfx/examples/runtime/shaders/gles/vs_picking_shaded.bin Binary files differnew file mode 100644 index 00000000000..d066f631d54 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/gles/vs_picking_shaded.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/gles/vs_rsm_combine.bin b/3rdparty/bgfx/examples/runtime/shaders/gles/vs_rsm_combine.bin Binary files differnew file mode 100644 index 00000000000..3368689b86a --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/gles/vs_rsm_combine.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/gles/vs_rsm_gbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/gles/vs_rsm_gbuffer.bin Binary files differnew file mode 100644 index 00000000000..e86a13cbb9b --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/gles/vs_rsm_gbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/gles/vs_rsm_lbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/gles/vs_rsm_lbuffer.bin Binary files differnew file mode 100644 index 00000000000..68d4a767431 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/gles/vs_rsm_lbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/gles/vs_rsm_shadow.bin b/3rdparty/bgfx/examples/runtime/shaders/gles/vs_rsm_shadow.bin Binary files differnew file mode 100644 index 00000000000..cd0a5da2676 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/gles/vs_rsm_shadow.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_ibl_mesh.bin b/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_ibl_mesh.bin Binary files differindex 3260e151099..ea3aad7be31 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_ibl_mesh.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_ibl_mesh.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_picking_id.bin b/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_picking_id.bin Binary files differnew file mode 100644 index 00000000000..be0e43459bf --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_picking_id.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_picking_shaded.bin b/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_picking_shaded.bin Binary files differnew file mode 100644 index 00000000000..d53e31c1b60 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_picking_shaded.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_rsm_combine.bin b/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_rsm_combine.bin Binary files differnew file mode 100644 index 00000000000..fd9c2e5cf0c --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_rsm_combine.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_rsm_gbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_rsm_gbuffer.bin Binary files differnew file mode 100644 index 00000000000..1dcf49ce0da --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_rsm_gbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_rsm_lbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_rsm_lbuffer.bin Binary files differnew file mode 100644 index 00000000000..b1277284441 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_rsm_lbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_rsm_shadow.bin b/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_rsm_shadow.bin Binary files differnew file mode 100644 index 00000000000..c8b88b15b41 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_rsm_shadow.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_sms_shadow.bin b/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_sms_shadow.bin Binary files differindex 946d0e83e3b..81ccc6436e4 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_sms_shadow.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/glsl/fs_sms_shadow.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_ibl_skybox.bin b/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_ibl_skybox.bin Binary files differindex be3bea2edbd..e079c0a9c25 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_ibl_skybox.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_ibl_skybox.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_picking_shaded.bin b/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_picking_shaded.bin Binary files differnew file mode 100644 index 00000000000..786b5e30d1d --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_picking_shaded.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_rsm_combine.bin b/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_rsm_combine.bin Binary files differnew file mode 100644 index 00000000000..c75e2e66ea5 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_rsm_combine.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_rsm_gbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_rsm_gbuffer.bin Binary files differnew file mode 100644 index 00000000000..3bf03fd859f --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_rsm_gbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_rsm_lbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_rsm_lbuffer.bin Binary files differnew file mode 100644 index 00000000000..8553e1738a0 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_rsm_lbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_rsm_shadow.bin b/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_rsm_shadow.bin Binary files differnew file mode 100644 index 00000000000..a5d351de0f8 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/glsl/vs_rsm_shadow.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_callback.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_callback.bin Binary files differindex 9ac95509870..b08e28f567d 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_callback.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_callback.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_deferred_light.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_deferred_light.bin Binary files differindex 89bc35bc2a3..e5a03968999 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_deferred_light.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_deferred_light.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_ibl_mesh.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_ibl_mesh.bin Binary files differindex 917de5500a2..fef2951fc64 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_ibl_mesh.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_ibl_mesh.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_picking_id.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_picking_id.bin Binary files differnew file mode 100644 index 00000000000..fd86c31031a --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_picking_id.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_picking_shaded.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_picking_shaded.bin Binary files differnew file mode 100644 index 00000000000..4e5208aff4a --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_picking_shaded.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_rsm_combine.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_rsm_combine.bin Binary files differnew file mode 100644 index 00000000000..ef8a8cf216c --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_rsm_combine.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_rsm_gbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_rsm_gbuffer.bin Binary files differnew file mode 100644 index 00000000000..fdd2b86573a --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_rsm_gbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_rsm_lbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_rsm_lbuffer.bin Binary files differnew file mode 100644 index 00000000000..6eb32d9395e --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_rsm_lbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_rsm_shadow.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_rsm_shadow.bin Binary files differnew file mode 100644 index 00000000000..c88531c9d78 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_rsm_shadow.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_sms_shadow.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_sms_shadow.bin Binary files differindex b5140b48e9a..42cd46cf0c3 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_sms_shadow.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_sms_shadow.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_wf_mesh.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_wf_mesh.bin Binary files differindex 3628dd93e5d..995ba28b892 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_wf_mesh.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_wf_mesh.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_wf_wireframe.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_wf_wireframe.bin Binary files differindex e00b6fa3f91..5b3d28b2c06 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/metal/fs_wf_wireframe.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/fs_wf_wireframe.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/vs_ibl_skybox.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/vs_ibl_skybox.bin Binary files differindex 0052efc7049..78302fa339b 100644 --- a/3rdparty/bgfx/examples/runtime/shaders/metal/vs_ibl_skybox.bin +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/vs_ibl_skybox.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/vs_picking_shaded.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/vs_picking_shaded.bin Binary files differnew file mode 100644 index 00000000000..c5326d93db6 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/vs_picking_shaded.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/vs_rsm_combine.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/vs_rsm_combine.bin Binary files differnew file mode 100644 index 00000000000..10fb2d926e2 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/vs_rsm_combine.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/vs_rsm_gbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/vs_rsm_gbuffer.bin Binary files differnew file mode 100644 index 00000000000..83a9b434292 --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/vs_rsm_gbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/vs_rsm_lbuffer.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/vs_rsm_lbuffer.bin Binary files differnew file mode 100644 index 00000000000..1050eb976bf --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/vs_rsm_lbuffer.bin diff --git a/3rdparty/bgfx/examples/runtime/shaders/metal/vs_rsm_shadow.bin b/3rdparty/bgfx/examples/runtime/shaders/metal/vs_rsm_shadow.bin Binary files differnew file mode 100644 index 00000000000..c0b666b772a --- /dev/null +++ b/3rdparty/bgfx/examples/runtime/shaders/metal/vs_rsm_shadow.bin diff --git a/3rdparty/bgfx/include/bgfx/bgfx.h b/3rdparty/bgfx/include/bgfx/bgfx.h index 323a2ebe19e..03f360528a1 100644 --- a/3rdparty/bgfx/include/bgfx/bgfx.h +++ b/3rdparty/bgfx/include/bgfx/bgfx.h @@ -285,6 +285,7 @@ namespace bgfx /// struct OcclusionQueryResult { + /// Occlusion query results: enum Enum { Invisible, //!< Query failed test. @@ -301,6 +302,7 @@ namespace bgfx /// struct TopologyConvert { + /// Topology conversion functions: enum Enum { TriListFlipWinding, //!< Flip winding order of triangle list. @@ -312,6 +314,32 @@ namespace bgfx }; }; + /// Topology sort order. + /// + /// @attention C99 equivalent is `bgfx_topology_sort_t`. + /// + struct TopologySort + { + /// Topology sort order: + enum Enum + { + DirectionFrontToBackMin, //!< + DirectionFrontToBackAvg, //!< + DirectionFrontToBackMax, //!< + DirectionBackToFrontMin, //!< + DirectionBackToFrontAvg, //!< + DirectionBackToFrontMax, //!< + DistanceFrontToBackMin, //!< + DistanceFrontToBackAvg, //!< + DistanceFrontToBackMax, //!< + DistanceBackToFrontMin, //!< + DistanceBackToFrontAvg, //!< + DistanceBackToFrontMax, //!< + + Count + }; + }; + static const uint16_t invalidHandle = UINT16_MAX; BGFX_HANDLE(DynamicIndexBufferHandle); @@ -515,10 +543,24 @@ namespace bgfx GPU gpu[4]; //!< Enumerated GPUs. /// Supported texture formats. - /// - `BGFX_CAPS_FORMAT_TEXTURE_NONE` - not supported - /// - `BGFX_CAPS_FORMAT_TEXTURE_2D` - supported - /// - `BGFX_CAPS_FORMAT_TEXTURE_2D_EMULATED` - emulated - /// - `BGFX_CAPS_FORMAT_TEXTURE_VERTEX` - supported vertex texture + /// - `BGFX_CAPS_FORMAT_TEXTURE_NONE` - Texture format is not supported. + /// - `BGFX_CAPS_FORMAT_TEXTURE_2D` - Texture format is supported. + /// - `BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB` - Texture as sRGB format is supported. + /// - `BGFX_CAPS_FORMAT_TEXTURE_2D_EMULATED` - Texture format is emulated. + /// - `BGFX_CAPS_FORMAT_TEXTURE_3D` - Texture format is supported. + /// - `BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB` - Texture as sRGB format is supported. + /// - `BGFX_CAPS_FORMAT_TEXTURE_3D_EMULATED` - Texture format is emulated. + /// - `BGFX_CAPS_FORMAT_TEXTURE_CUBE` - Texture format is supported. + /// - `BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB` - Texture as sRGB format is supported. + /// - `BGFX_CAPS_FORMAT_TEXTURE_CUBE_EMULATED` - Texture format is emulated. + /// - `BGFX_CAPS_FORMAT_TEXTURE_VERTEX` - Texture format can be used from vertex shader. + /// - `BGFX_CAPS_FORMAT_TEXTURE_IMAGE` - Texture format can be used as image from compute + /// shader. + /// - `BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER` - Texture format can be used as frame + /// buffer. + /// - `BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA` - Texture format can be used as MSAA + /// frame buffer. + /// - `BGFX_CAPS_FORMAT_TEXTURE_MSAA` - Texture can be sampled as MSAA. uint16_t formats[TextureFormat::Count]; }; @@ -641,8 +683,9 @@ namespace bgfx uint64_t gpuTimeEnd; //!< GPU frame end time. uint64_t gpuTimerFreq; //!< GPU timer frequency. - int64_t waitRender; //!< Render wait time. - int64_t waitSubmit; //!< Submit wait time. + int64_t waitRender; //!< Time spent waiting for render backend thread to finish issuing + //! draw commands to underlying graphics API. + int64_t waitSubmit; //!< Time spent waiting for submit thread to advance to next frame. }; /// Vertex declaration. @@ -798,7 +841,7 @@ namespace bgfx /// @param[in] _dstSize Destination index buffer in bytes. It must be /// large enough to contain output indices. If destination size is /// insufficient index buffer will be truncated. - /// @param[in] _indices Source indices. + /// @param[in]_indices Source indices. /// @param[in] _numIndices Number of input indices. /// @param[in] _index32 Set to `true` if input indices are 32-bit. /// @@ -815,6 +858,38 @@ namespace bgfx , bool _index32 ); + /// Sort indices. + /// + /// @param[in] _sort Sort order, see `TopologySort::Enum`. + /// @param[in] _dst Destination index buffer. + /// @param[in] _dstSize Destination index buffer in bytes. It must be + /// large enough to contain output indices. If destination size is + /// insufficient index buffer will be truncated. + /// @param[in] _dir Direction (vector must be normalized). + /// @param[in] _pos Position. + /// @param[in] _vertices Pointer to first vertex represented as + /// float x, y, z. Must contain at least number of vertices + /// referencende by index buffer. + /// @param[in] _stride Vertex stride. + /// @param[in] _indices Source indices. + /// @param[in] _numIndices Number of input indices. + /// @param[in] _index32 Set to `true` if input indices are 32-bit. + /// + /// @attention C99 equivalent is `bgfx_topology_sort_tri_list`. + /// + void topologySortTriList( + TopologySort::Enum _sort + , void* _dst + , uint32_t _dstSize + , const float _dir[3] + , const float _pos[3] + , const void* _vertices + , uint32_t _stride + , const void* _indices + , uint32_t _numIndices + , bool _index32 + ); + /// Swizzle RGBA8 image to BGRA8. /// /// @param[in] _width Width of input image (pixels). diff --git a/3rdparty/bgfx/include/bgfx/bgfxdefines.h b/3rdparty/bgfx/include/bgfx/bgfxdefines.h index f8923517184..36e308507bf 100644 --- a/3rdparty/bgfx/include/bgfx/bgfxdefines.h +++ b/3rdparty/bgfx/include/bgfx/bgfxdefines.h @@ -6,7 +6,7 @@ #ifndef BGFX_DEFINES_H_HEADER_GUARD #define BGFX_DEFINES_H_HEADER_GUARD -#define BGFX_API_VERSION UINT32_C(16) +#define BGFX_API_VERSION UINT32_C(17) /// #define BGFX_STATE_RGB_WRITE UINT64_C(0x0000000000000001) //!< Enable RGB write. @@ -403,6 +403,7 @@ #define BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER UINT16_C(0x0800) //!< Texture format can be used as frame buffer. #define BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA UINT16_C(0x1000) //!< Texture format can be used as MSAA frame buffer. #define BGFX_CAPS_FORMAT_TEXTURE_MSAA UINT16_C(0x2000) //!< Texture can be sampled as MSAA. +#define BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN UINT16_C(0x4000) //!< Texture format supports auto-generated mips. /// #define BGFX_VIEW_NONE UINT8_C(0x00) //!< diff --git a/3rdparty/bgfx/include/bgfx/bgfxplatform.h b/3rdparty/bgfx/include/bgfx/bgfxplatform.h index 1912c05b9d8..4984d68e8f9 100644 --- a/3rdparty/bgfx/include/bgfx/bgfxplatform.h +++ b/3rdparty/bgfx/include/bgfx/bgfxplatform.h @@ -316,7 +316,7 @@ namespace bgfx PlatformData pd; # if BX_PLATFORM_LINUX || BX_PLATFORM_BSD pd.ndt = glfwGetX11Display(); - pd.nwh = (void*)(uintptr_t)glfwGetX11Window(_window); + pd.nwh = (void*)(uintptr_t)glfwGetGLXWindow(_window); pd.context = glfwGetGLXContext(_window); # elif BX_PLATFORM_OSX pd.ndt = NULL; diff --git a/3rdparty/bgfx/include/bgfx/c99/bgfx.h b/3rdparty/bgfx/include/bgfx/c99/bgfx.h index 222f202f29d..c91c5e7ee67 100644 --- a/3rdparty/bgfx/include/bgfx/c99/bgfx.h +++ b/3rdparty/bgfx/include/bgfx/c99/bgfx.h @@ -235,6 +235,25 @@ typedef enum bgfx_topology_convert } bgfx_topology_convert_t; +typedef enum bgfx_topology_sort +{ + BGFX_TOPOLOGY_SORT_DIRECTION_FRONT_TO_BACK_MIN, + BGFX_TOPOLOGY_SORT_DIRECTION_FRONT_TO_BACK_AVG, + BGFX_TOPOLOGY_SORT_DIRECTION_FRONT_TO_BACK_MAX, + BGFX_TOPOLOGY_SORT_DIRECTION_BACK_TO_FRONT_MIN, + BGFX_TOPOLOGY_SORT_DIRECTION_BACK_TO_FRONT_AVG, + BGFX_TOPOLOGY_SORT_DIRECTION_BACK_TO_FRONT_MAX, + BGFX_TOPOLOGY_SORT_DISTANCE_FRONT_TO_BACK_MIN, + BGFX_TOPOLOGY_SORT_DISTANCE_FRONT_TO_BACK_AVG, + BGFX_TOPOLOGY_SORT_DISTANCE_FRONT_TO_BACK_MAX, + BGFX_TOPOLOGY_SORT_DISTANCE_BACK_TO_FRONT_MIN, + BGFX_TOPOLOGY_SORT_DISTANCE_BACK_TO_FRONT_AVG, + BGFX_TOPOLOGY_SORT_DISTANCE_BACK_TO_FRONT_MAX, + + BGFX_TOPOLOGY_SORT_COUNT + +} bgfx_topology_sort_t; + #define BGFX_HANDLE_T(_name) \ typedef struct _name { uint16_t idx; } _name##_t @@ -484,6 +503,12 @@ BGFX_C_API void bgfx_vertex_convert(const bgfx_vertex_decl_t* _destDecl, void* _ BGFX_C_API uint16_t bgfx_weld_vertices(uint16_t* _output, const bgfx_vertex_decl_t* _decl, const void* _data, uint16_t _num, float _epsilon); /**/ +BGFX_C_API uint32_t bgfx_topology_convert(bgfx_topology_convert_t _conversion, void* _dst, uint32_t _dstSize, const void* _indices, uint32_t _numIndices, bool _index32); + +/**/ +BGFX_C_API void bgfx_topology_sort_tri_list(bgfx_topology_sort_t _sort, void* _dst, uint32_t _dstSize, const float _dir[3], const float _pos[3], const void* _vertices, uint32_t _stride, const void* _indices, uint32_t _numIndices, bool _index32); + +/**/ BGFX_C_API void bgfx_image_swizzle_bgra8(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst); /**/ diff --git a/3rdparty/bgfx/include/bgfx/c99/bgfxplatform.h b/3rdparty/bgfx/include/bgfx/c99/bgfxplatform.h index f7d5b76b532..cfde4834214 100644 --- a/3rdparty/bgfx/include/bgfx/c99/bgfxplatform.h +++ b/3rdparty/bgfx/include/bgfx/c99/bgfxplatform.h @@ -78,6 +78,7 @@ typedef struct bgfx_interface_vtbl void (*vertex_convert)(const bgfx_vertex_decl_t* _destDecl, void* _destData, const bgfx_vertex_decl_t* _srcDecl, const void* _srcData, uint32_t _num); uint16_t (*weld_vertices)(uint16_t* _output, const bgfx_vertex_decl_t* _decl, const void* _data, uint16_t _num, float _epsilon); uint32_t (*topology_convert)(bgfx_topology_convert_t _conversion, void* _dst, uint32_t _dstSize, const void* _indices, uint32_t _numIndices, bool _index32); + void (*topology_sort_tri_list)(bgfx_topology_sort_t _sort, void* _dst, uint32_t _dstSize, const float _dir[3], const float _pos[3], const void* _vertices, uint32_t _stride, const void* _indices, uint32_t _numIndices, bool _index32); void (*image_swizzle_bgra8)(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst); void (*image_rgba8_downsample_2x2)(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst); uint8_t (*get_supported_renderers)(bgfx_renderer_type_t _enum[BGFX_RENDERER_TYPE_COUNT]); diff --git a/3rdparty/bgfx/makefile b/3rdparty/bgfx/makefile index 965de58a245..82a054ffa56 100644 --- a/3rdparty/bgfx/makefile +++ b/3rdparty/bgfx/makefile @@ -25,6 +25,7 @@ endif BX_DIR?=../bx GENIE?=$(BX_DIR)/tools/bin/$(OS)/genie +NINJA?=$(BX_DIR)/tools/bin/$(OS)/ninja .PHONY: help @@ -276,6 +277,9 @@ build: build-$(OS) rebuild-shaders: $(MAKE) -R -C examples rebuild +assets: # Build assets. + $(NINJA) -C scripts + analyze: cppcheck src/ cppcheck examples/ diff --git a/3rdparty/bgfx/scripts/common.ninja b/3rdparty/bgfx/scripts/build.ninja index 0cde35fa310..54b099e0b6f 100644 --- a/3rdparty/bgfx/scripts/common.ninja +++ b/3rdparty/bgfx/scripts/build.ninja @@ -4,6 +4,10 @@ rule geometryc_pack_normal command = geometryc -f $in -o $out --packnormal 1 description = Converting geometry $in... +rule geometryc_pack_normal_barycentric + command = geometryc -f $in -o $out --packnormal 1 --barycentric + description = Converting geometry $in... + rule texturec_bc1 command = texturec -f $in -o $out -t bc1 -m @@ -24,3 +28,9 @@ rule texturec_etc1 rule texturec_etc2 command = texturec -f $in -o $out -t etc2 -m + +pwd = ../examples/assets/meshes +subninja ../examples/assets/meshes/meshes.ninja + +pwd = ../examples/assets/textures +subninja ../examples/assets/textures/textures.ninja diff --git a/3rdparty/bgfx/scripts/genie.lua b/3rdparty/bgfx/scripts/genie.lua index ce34df5d990..fe21f0eaa14 100644 --- a/3rdparty/bgfx/scripts/genie.lua +++ b/3rdparty/bgfx/scripts/genie.lua @@ -391,6 +391,8 @@ exampleProject("26-occlusion") exampleProject("27-terrain") exampleProject("28-wireframe") exampleProject("29-debugdraw") +exampleProject("30-picking") +exampleProject("31-rsm") -- C99 source doesn't compile under WinRT settings if not premake.vstudio.iswinrt() then diff --git a/3rdparty/bgfx/scripts/shader-embeded.mk b/3rdparty/bgfx/scripts/shader-embeded.mk index aea94c7c930..14cc9c23c1e 100644 --- a/3rdparty/bgfx/scripts/shader-embeded.mk +++ b/3rdparty/bgfx/scripts/shader-embeded.mk @@ -24,7 +24,7 @@ SHADER_TMP = $(TEMP)/tmp vs_%.bin.h : vs_%.sc @echo [$(<)] - $(SILENT) $(SHADERC) $(VS_FLAGS) --platform linux -f $(<) -o $(SHADER_TMP) --bin2c $(basename $(<))_glsl + $(SILENT) $(SHADERC) $(VS_FLAGS) --platform linux -f $(<) -o $(SHADER_TMP) --bin2c $(basename $(<))_glsl @cat $(SHADER_TMP) > $(@) -$(SILENT) $(SHADERC) $(VS_FLAGS) --platform windows -p vs_3_0 -O 3 -f $(<) -o $(SHADER_TMP) --bin2c $(basename $(<))_dx9 -@cat $(SHADER_TMP) >> $(@) @@ -35,7 +35,7 @@ vs_%.bin.h : vs_%.sc fs_%.bin.h : fs_%.sc @echo [$(<)] - $(SILENT) $(SHADERC) $(FS_FLAGS) --platform linux -f $(<) -o $(SHADER_TMP) --bin2c $(basename $(<))_glsl + $(SILENT) $(SHADERC) $(FS_FLAGS) --platform linux -f $(<) -o $(SHADER_TMP) --bin2c $(basename $(<))_glsl @cat $(SHADER_TMP) > $(@) -$(SILENT) $(SHADERC) $(FS_FLAGS) --platform windows -p ps_3_0 -O 3 -f $(<) -o $(SHADER_TMP) --bin2c $(basename $(<))_dx9 -@cat $(SHADER_TMP) >> $(@) @@ -46,7 +46,7 @@ fs_%.bin.h : fs_%.sc cs_%.bin.h : cs_%.sc @echo [$(<)] - $(SILENT) $(SHADERC) $(CS_FLAGS) --platform linux -p 430 -f $(<) -o $(SHADER_TMP) --bin2c $(basename $(<))_glsl + $(SILENT) $(SHADERC) $(CS_FLAGS) --platform linux -p 430 -f $(<) -o $(SHADER_TMP) --bin2c $(basename $(<))_glsl @cat $(SHADER_TMP) > $(@) -$(SILENT) $(SHADERC) $(CS_FLAGS) --platform windows -p cs_5_0 -O 1 -f $(<) -o $(SHADER_TMP) --bin2c $(basename $(<))_dx11 -@cat $(SHADER_TMP) >> $(@) diff --git a/3rdparty/bgfx/src/bgfx.cpp b/3rdparty/bgfx/src/bgfx.cpp index a1d37e82c41..90c6cee6113 100644 --- a/3rdparty/bgfx/src/bgfx.cpp +++ b/3rdparty/bgfx/src/bgfx.cpp @@ -383,28 +383,38 @@ namespace bgfx void fatal(Fatal::Enum _code, const char* _format, ...) { - char temp[8192]; - va_list argList; va_start(argList, _format); - char* out = temp; - int32_t len = bx::vsnprintf(out, sizeof(temp), _format, argList); - if ( (int32_t)sizeof(temp) < len) + + if (BX_UNLIKELY(NULL == g_callback) ) { - out = (char*)alloca(len+1); - len = bx::vsnprintf(out, len, _format, argList); + dbgPrintfVargs(_format, argList); + abort(); + } + else + { + char temp[8192]; + char* out = temp; + int32_t len = bx::vsnprintf(out, sizeof(temp), _format, argList); + if ( (int32_t)sizeof(temp) < len) + { + out = (char*)alloca(len+1); + len = bx::vsnprintf(out, len, _format, argList); + } + out[len] = '\0'; + + g_callback->fatal(_code, out); } - out[len] = '\0'; - va_end(argList); - g_callback->fatal(_code, out); + va_end(argList); } void trace(const char* _filePath, uint16_t _line, const char* _format, ...) { va_list argList; va_start(argList, _format); - if (NULL == g_callback) + + if (BX_UNLIKELY(NULL == g_callback) ) { dbgPrintfVargs(_format, argList); } @@ -412,6 +422,7 @@ namespace bgfx { g_callback->traceVargs(_filePath, _line, _format, argList); } + va_end(argList); } @@ -1118,25 +1129,26 @@ namespace bgfx } BX_TRACE("Supported texture formats:"); - BX_TRACE("\t +--------------- 2D: x = supported / * = emulated"); - BX_TRACE("\t |+-------------- 2D: sRGB format"); - BX_TRACE("\t ||+------------- 3D: x = supported / * = emulated"); - BX_TRACE("\t |||+------------ 3D: sRGB format"); - BX_TRACE("\t ||||+----------- Cube: x = supported / * = emulated"); - BX_TRACE("\t |||||+---------- Cube: sRGB format"); - BX_TRACE("\t ||||||+--------- vertex format"); - BX_TRACE("\t |||||||+-------- image"); - BX_TRACE("\t ||||||||+------- framebuffer"); - BX_TRACE("\t |||||||||+------ MSAA framebuffer"); - BX_TRACE("\t ||||||||||+----- MSAA texture"); - BX_TRACE("\t ||||||||||| +-- name"); + BX_TRACE("\t +---------------- 2D: x = supported / * = emulated"); + BX_TRACE("\t |+--------------- 2D: sRGB format"); + BX_TRACE("\t ||+-------------- 3D: x = supported / * = emulated"); + BX_TRACE("\t |||+------------- 3D: sRGB format"); + BX_TRACE("\t ||||+------------ Cube: x = supported / * = emulated"); + BX_TRACE("\t |||||+----------- Cube: sRGB format"); + BX_TRACE("\t ||||||+---------- vertex format"); + BX_TRACE("\t |||||||+--------- image"); + BX_TRACE("\t ||||||||+-------- framebuffer"); + BX_TRACE("\t |||||||||+------- MSAA framebuffer"); + BX_TRACE("\t ||||||||||+------ MSAA texture"); + BX_TRACE("\t |||||||||||+----- Auto-generated mips"); + BX_TRACE("\t |||||||||||| +-- name"); for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii) { if (TextureFormat::Unknown != ii && TextureFormat::UnknownDepth != ii) { uint16_t flags = g_caps.formats[ii]; - BX_TRACE("\t[%c%c%c%c%c%c%c%c%c%c%c] %s" + BX_TRACE("\t[%c%c%c%c%c%c%c%c%c%c%c%c] %s" , flags&BGFX_CAPS_FORMAT_TEXTURE_2D ? 'x' : flags&BGFX_CAPS_FORMAT_TEXTURE_2D_EMULATED ? '*' : ' ' , flags&BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB ? 'l' : ' ' , flags&BGFX_CAPS_FORMAT_TEXTURE_3D ? 'x' : flags&BGFX_CAPS_FORMAT_TEXTURE_3D_EMULATED ? '*' : ' ' @@ -1148,6 +1160,7 @@ namespace bgfx , flags&BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER ? 'f' : ' ' , flags&BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA ? '+' : ' ' , flags&BGFX_CAPS_FORMAT_TEXTURE_MSAA ? 'm' : ' ' + , flags&BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN ? 'M' : ' ' , getName(TextureFormat::Enum(ii) ) ); BX_UNUSED(flags); @@ -2236,7 +2249,10 @@ namespace bgfx uint16_t height; _cmdbuf.read(height); - m_renderCtx->resizeTexture(handle, width, height); + uint8_t numMips; + _cmdbuf.read(numMips); + + m_renderCtx->resizeTexture(handle, width, height, numMips); } break; @@ -2363,6 +2379,11 @@ namespace bgfx return topologyConvert(_conversion, _dst, _dstSize, _indices, _numIndices, _index32, g_allocator); } + void topologySortTriList(TopologySort::Enum _sort, void* _dst, uint32_t _dstSize, const float _dir[3], const float _pos[3], const void* _vertices, uint32_t _stride, const void* _indices, uint32_t _numIndices, bool _index32) + { + topologySortTriList(_sort, _dst, _dstSize, _dir, _pos, _vertices, _stride, _indices, _numIndices, _index32, g_allocator); + } + uint8_t getSupportedRenderers(RendererType::Enum _enum[RendererType::Count]) { uint8_t num = 0; @@ -2393,27 +2414,20 @@ namespace bgfx { if (NULL != s_ctx) { - BX_CHECK(false, "bgfx is already initialized."); + BX_TRACE("bgfx is already initialized."); return false; } - if (!BX_ENABLED(BX_PLATFORM_EMSCRIPTEN || BX_PLATFORM_NACL) - && NULL == g_platformData.ndt - && NULL == g_platformData.nwh - && NULL == g_platformData.context - && NULL == g_platformData.backBuffer - && NULL == g_platformData.backBufferDS) + struct ErrorState { - BX_CHECK(false, "bgfx platform data like window handle or backbuffer must be set."); - return false; - } + enum Enum + { + Default, + ContextAllocated, + }; + }; - memset(&g_caps, 0, sizeof(g_caps) ); - g_caps.maxViews = BGFX_CONFIG_MAX_VIEWS; - g_caps.maxDrawCalls = BGFX_CONFIG_MAX_DRAW_CALLS; - g_caps.maxFBAttachments = 1; - g_caps.vendorId = _vendorId; - g_caps.deviceId = _deviceId; + ErrorState::Enum errorState = ErrorState::Default; if (NULL != _allocator) { @@ -2436,16 +2450,45 @@ namespace bgfx s_callbackStub = BX_NEW(g_allocator, CallbackStub); } + if (!BX_ENABLED(BX_PLATFORM_EMSCRIPTEN || BX_PLATFORM_NACL) + && NULL == g_platformData.ndt + && NULL == g_platformData.nwh + && NULL == g_platformData.context + && NULL == g_platformData.backBuffer + && NULL == g_platformData.backBufferDS) + { + BX_TRACE("bgfx platform data like window handle or backbuffer must be set."); + goto error; + } + + memset(&g_caps, 0, sizeof(g_caps) ); + g_caps.maxViews = BGFX_CONFIG_MAX_VIEWS; + g_caps.maxDrawCalls = BGFX_CONFIG_MAX_DRAW_CALLS; + g_caps.maxFBAttachments = 1; + g_caps.vendorId = _vendorId; + g_caps.deviceId = _deviceId; + BX_TRACE("Init..."); + errorState = ErrorState::ContextAllocated; + s_ctx = BX_ALIGNED_NEW(g_allocator, Context, 16); - if (!s_ctx->init(_type) ) + if (s_ctx->init(_type) ) { - BX_TRACE("Init failed."); + BX_TRACE("Init complete."); + return true; + } +error: + BX_TRACE("Init failed."); + + switch (errorState) + { + case ErrorState::ContextAllocated: BX_ALIGNED_DELETE(g_allocator, s_ctx, 16); s_ctx = NULL; + case ErrorState::Default: if (NULL != s_callbackStub) { BX_DELETE(g_allocator, s_callbackStub); @@ -2462,11 +2505,10 @@ namespace bgfx s_threadIndex = 0; g_callback = NULL; g_allocator = NULL; - return false; + break; } - BX_TRACE("Init complete."); - return true; + return false; } void shutdown() @@ -2920,7 +2962,14 @@ namespace bgfx , getName(_format) ); - _numMips = uint8_t(bx::uint32_max(1, _numMips) ); + if (BackbufferRatio::Count != _ratio) + { + _width = uint16_t(s_ctx->m_resolution.m_width); + _height = uint16_t(s_ctx->m_resolution.m_height); + getTextureSizeFromRatio(_ratio, _width, _height); + } + + _numMips = calcNumMips(_numMips, _width, _height); if (BX_ENABLED(BGFX_CONFIG_DEBUG) && NULL != _mem) @@ -2934,13 +2983,6 @@ namespace bgfx ); } - if (BackbufferRatio::Count != _ratio) - { - _width = uint16_t(s_ctx->m_resolution.m_width); - _height = uint16_t(s_ctx->m_resolution.m_height); - getTextureSizeFromRatio(_ratio, _width, _height); - } - uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate); const Memory* mem = alloc(size); @@ -2983,7 +3025,7 @@ namespace bgfx , getName(_format) ); - _numMips = uint8_t(bx::uint32_max(1, _numMips) ); + _numMips = calcNumMips(_numMips, _width, _height, _depth); if (BX_ENABLED(BGFX_CONFIG_DEBUG) && NULL != _mem) @@ -3026,7 +3068,7 @@ namespace bgfx , getName(_format) ); - _numMips = uint8_t(bx::uint32_max(1, _numMips) ); + _numMips = calcNumMips(_numMips, _size, _size); if (BX_ENABLED(BGFX_CONFIG_DEBUG) && NULL != _mem) @@ -3815,6 +3857,11 @@ uint32_t bgfx_topology_convert(bgfx_topology_convert_t _conversion, void* _dst, return bgfx::topologyConvert(bgfx::TopologyConvert::Enum(_conversion), _dst, _dstSize, _indices, _numIndices, _index32); } +void bgfx_topology_sort_tri_list(bgfx_topology_sort_t _sort, void* _dst, uint32_t _dstSize, const float _dir[3], const float _pos[3], const void* _vertices, uint32_t _stride, const void* _indices, uint32_t _numIndices, bool _index32) +{ + bgfx::topologySortTriList(bgfx::TopologySort::Enum(_sort), _dst, _dstSize, _dir, _pos, _vertices, _stride, _indices, _numIndices, _index32); +} + BGFX_C_API void bgfx_image_swizzle_bgra8(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst) { bgfx::imageSwizzleBgra8(_width, _height, _pitch, _src, _dst); @@ -4588,6 +4635,7 @@ BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version) BGFX_IMPORT_FUNC(vertex_convert) \ BGFX_IMPORT_FUNC(weld_vertices) \ BGFX_IMPORT_FUNC(topology_convert) \ + BGFX_IMPORT_FUNC(topology_sort_tri_list) \ BGFX_IMPORT_FUNC(image_swizzle_bgra8) \ BGFX_IMPORT_FUNC(image_rgba8_downsample_2x2) \ BGFX_IMPORT_FUNC(get_supported_renderers) \ diff --git a/3rdparty/bgfx/src/bgfx_p.h b/3rdparty/bgfx/src/bgfx_p.h index 02955987eff..e624dba372d 100644 --- a/3rdparty/bgfx/src/bgfx_p.h +++ b/3rdparty/bgfx/src/bgfx_p.h @@ -62,9 +62,9 @@ # define RMT_USE_D3D11 BGFX_CONFIG_RENDERER_DIRECT3D11 # define RMT_USE_OPENGL BGFX_CONFIG_RENDERER_OPENGL # include <remotery/lib/Remotery.h> -# define BGFX_PROFILER_SCOPE(_group, _name, _color) rmt_ScopedCPUSample(_group##_##_name) -# define BGFX_PROFILER_BEGIN(_group, _name, _color) rmt_BeginCPUSample(_group##_##_name) -# define BGFX_PROFILER_BEGIN_DYNAMIC(_namestr) rmt_BeginCPUSampleDynamic(_namestr) +# define BGFX_PROFILER_SCOPE(_group, _name, _color) rmt_ScopedCPUSample(_group##_##_name, RMTSF_None) +# define BGFX_PROFILER_BEGIN(_group, _name, _color) rmt_BeginCPUSample(_group##_##_name, RMTSF_None) +# define BGFX_PROFILER_BEGIN_DYNAMIC(_namestr) rmt_BeginCPUSampleDynamic(_namestr, RMTSF_None) # define BGFX_PROFILER_END() rmt_EndCPUSample() # define BGFX_PROFILER_SET_CURRENT_THREAD_NAME(_name) rmt_SetCurrentThreadName(_name) # else @@ -364,6 +364,19 @@ namespace bgfx ; } + inline uint8_t calcNumMips(uint8_t _numMips, uint16_t _width, uint16_t _height, uint16_t _depth = 1) + { + if (1 < _numMips) + { + const uint32_t max = bx::uint32_max(bx::uint32_max(_width, _height), _depth); + const uint32_t num = 1 + uint32_t(bx::flog2(float(max) ) ); + + return uint8_t(num); + } + + return 1; + } + void dump(const VertexDecl& _decl); struct TextVideoMem @@ -1460,8 +1473,9 @@ namespace bgfx void setState(uint64_t _state, uint32_t _rgba) { uint8_t blend = ( (_state&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT)&0xff; + uint8_t alphaRef = ( (_state&BGFX_STATE_ALPHA_REF_MASK)>>BGFX_STATE_ALPHA_REF_SHIFT)&0xff; // transparency sort order table - m_key.m_trans = "\x0\x1\x1\x2\x2\x1\x2\x1\x2\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1"[( (blend)&0xf) + (!!blend)]; + m_key.m_trans = "\x0\x2\x2\x3\x3\x2\x3\x2\x3\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2"[( (blend)&0xf) + (!!blend)] + !!alphaRef; m_draw.m_stateFlags = _state; m_draw.m_rgba = _rgba; } @@ -2060,7 +2074,7 @@ namespace bgfx virtual void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) = 0; virtual void updateTextureEnd() = 0; virtual void readTexture(TextureHandle _handle, void* _data) = 0; - virtual void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) = 0; + virtual void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips) = 0; virtual void overrideInternal(TextureHandle _handle, uintptr_t _ptr) = 0; virtual uintptr_t getInternal(TextureHandle _handle) = 0; virtual void destroyTexture(TextureHandle _handle) = 0; @@ -2159,6 +2173,7 @@ namespace bgfx resizeTexture(handle , uint16_t(m_resolution.m_width) , uint16_t(m_resolution.m_height) + , textureRef.m_numMips ); m_resolution.m_flags |= BGFX_RESET_INTERNAL_FORCE; } @@ -2626,8 +2641,9 @@ namespace bgfx uint16_t flags = BGFX_BUFFER_NONE; cmdbuf.write(flags); - tib = (TransientIndexBuffer*)BX_ALLOC(g_allocator, sizeof(TransientIndexBuffer)+_size); - tib->data = (uint8_t*)&tib[1]; + const uint32_t size = BX_ALIGN_16(sizeof(TransientIndexBuffer) ) + BX_ALIGN_16(_size); + tib = (TransientIndexBuffer*)BX_ALIGNED_ALLOC(g_allocator, size, 16); + tib->data = (uint8_t *)tib + BX_ALIGN_16(sizeof(TransientIndexBuffer) ); tib->size = _size; tib->handle = handle; } @@ -2641,7 +2657,7 @@ namespace bgfx cmdbuf.write(_tib->handle); m_submit->free(_tib->handle); - BX_FREE(g_allocator, _tib); + BX_ALIGNED_FREE(g_allocator, _tib, 16); } BGFX_API_FUNC(void allocTransientIndexBuffer(TransientIndexBuffer* _tib, uint32_t _num) ) @@ -2682,8 +2698,9 @@ namespace bgfx uint16_t flags = BGFX_BUFFER_NONE; cmdbuf.write(flags); - tvb = (TransientVertexBuffer*)BX_ALLOC(g_allocator, sizeof(TransientVertexBuffer)+_size); - tvb->data = (uint8_t*)&tvb[1]; + const uint32_t size = BX_ALIGN_16(sizeof(TransientVertexBuffer) ) + BX_ALIGN_16(_size); + tvb = (TransientVertexBuffer*)BX_ALIGNED_ALLOC(g_allocator, size, 16); + tvb->data = (uint8_t *)tvb + BX_ALIGN_16(sizeof(TransientVertexBuffer) ); tvb->size = _size; tvb->startVertex = 0; tvb->stride = stride; @@ -2700,7 +2717,7 @@ namespace bgfx cmdbuf.write(_tvb->handle); m_submit->free(_tvb->handle); - BX_FREE(g_allocator, _tvb); + BX_ALIGNED_FREE(g_allocator, _tvb, 16); } BGFX_API_FUNC(void allocTransientVertexBuffer(TransientVertexBuffer* _tvb, uint32_t _num, const VertexDecl& _decl) ) @@ -3104,6 +3121,7 @@ namespace bgfx ref.m_refCount = 1; ref.m_bbRatio = uint8_t(_ratio); ref.m_format = uint8_t(_info->format); + ref.m_numMips = imageContainer.m_numMips; ref.m_owned = false; CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateTexture); @@ -3146,12 +3164,13 @@ namespace bgfx return readTexture(textureHandle, _data); } - void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) + void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips) { const TextureRef& textureRef = m_textureRef[_handle.idx]; BX_CHECK(BackbufferRatio::Count != textureRef.m_bbRatio, ""); getTextureSizeFromRatio(BackbufferRatio::Enum(textureRef.m_bbRatio), _width, _height); + _numMips = calcNumMips(_numMips, _width, _height); BX_TRACE("Resize %3d: %4dx%d %s" , _handle.idx @@ -3164,6 +3183,7 @@ namespace bgfx cmdbuf.write(_handle); cmdbuf.write(_width); cmdbuf.write(_height); + cmdbuf.write(_numMips); } void textureTakeOwnership(TextureHandle _handle) @@ -4009,6 +4029,7 @@ namespace bgfx int16_t m_refCount; uint8_t m_bbRatio; uint8_t m_format; + uint8_t m_numMips; bool m_owned; }; diff --git a/3rdparty/bgfx/src/debug_renderdoc.cpp b/3rdparty/bgfx/src/debug_renderdoc.cpp index b3e3e61f468..0aca626468b 100644 --- a/3rdparty/bgfx/src/debug_renderdoc.cpp +++ b/3rdparty/bgfx/src/debug_renderdoc.cpp @@ -56,7 +56,7 @@ namespace bgfx } pRENDERDOC_GetAPI RENDERDOC_GetAPI; - static RENDERDOC_API_1_0_1* s_renderDoc; + static RENDERDOC_API_1_1_0* s_renderDoc; void* loadRenderDoc() { @@ -72,7 +72,7 @@ namespace bgfx { RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)bx::dlsym(renderdocdll, "RENDERDOC_GetAPI"); if (NULL != RENDERDOC_GetAPI - && 1 == RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_0_0, (void**)&s_renderDoc) ) + && 1 == RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_0, (void**)&s_renderDoc) ) { s_renderDoc->SetLogFilePathTemplate("temp/bgfx"); diff --git a/3rdparty/bgfx/src/glcontext_eagl.mm b/3rdparty/bgfx/src/glcontext_eagl.mm index 1092b6259a8..24c6ec04ab0 100644 --- a/3rdparty/bgfx/src/glcontext_eagl.mm +++ b/3rdparty/bgfx/src/glcontext_eagl.mm @@ -27,7 +27,7 @@ namespace bgfx { namespace gl { _layer.contentsScale = [UIScreen mainScreen].scale; - _layer.opaque = true; + _layer.opaque = [_layer.style valueForKey:@"opaque"] == nil ? true : [[_layer.style valueForKey:@"opaque"] boolValue]; _layer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys : [NSNumber numberWithBool:false] @@ -158,7 +158,7 @@ namespace bgfx { namespace gl BX_UNUSED(_width, _height); CAEAGLLayer* layer = (CAEAGLLayer*)g_platformData.nwh; - layer.opaque = true; + layer.opaque = [layer.style valueForKey:@"opaque"] == nil ? true : [[layer.style valueForKey:@"opaque"] boolValue]; layer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys : [NSNumber numberWithBool:false] diff --git a/3rdparty/bgfx/src/glimports.h b/3rdparty/bgfx/src/glimports.h index a12acb19d50..40781f43da0 100644 --- a/3rdparty/bgfx/src/glimports.h +++ b/3rdparty/bgfx/src/glimports.h @@ -113,6 +113,7 @@ typedef void (GL_APIENTRYP PFNGLFLUSHPROC) (); typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (GL_APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); +typedef void (GL_APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); typedef void (GL_APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); typedef void (GL_APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); typedef void (GL_APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); @@ -301,6 +302,7 @@ GL_IMPORT______(false, PFNGLFLUSHPROC, glFlush); GL_IMPORT______(true, PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer); GL_IMPORT______(true, PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D); GL_IMPORT______(false, PFNGLGENBUFFERSPROC, glGenBuffers); +GL_IMPORT______(true, PFNGLGENERATEMIPMAPPROC, glGenerateMipmap); GL_IMPORT______(true, PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers); GL_IMPORT______(true, PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers); GL_IMPORT______(true, PFNGLGENQUERIESPROC, glGenQueries); @@ -372,9 +374,7 @@ GL_IMPORT______(true, PFNGLSTENCILMASKSEPARATEPROC, glStencilMask GL_IMPORT______(false, PFNGLSTENCILOPPROC, glStencilOp); GL_IMPORT______(true, PFNGLSTENCILOPSEPARATEPROC, glStencilOpSeparate); GL_IMPORT______(false, PFNGLTEXIMAGE2DPROC, glTexImage2D); -GL_IMPORT______(true, PFNGLTEXIMAGE2DMULTISAMPLEPROC, glTexImage2DMultisample); GL_IMPORT______(true, PFNGLTEXIMAGE3DPROC, glTexImage3D); -GL_IMPORT______(true, PFNGLTEXIMAGE3DMULTISAMPLEPROC, glTexImage3DMultisample); GL_IMPORT______(false, PFNGLTEXPARAMETERIPROC, glTexParameteri); GL_IMPORT______(false, PFNGLTEXPARAMETERIVPROC, glTexParameteriv); GL_IMPORT______(false, PFNGLTEXPARAMETERFPROC, glTexParameterf); @@ -446,6 +446,9 @@ GL_IMPORT_EXT__(true, PFNGLDELETERENDERBUFFERSPROC, glDeleteRende GL_IMPORT_EXT__(true, PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage); GL_IMPORT_EXT__(true, PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC, glRenderbufferStorageMultisample); +GL_IMPORT______(true, PFNGLTEXIMAGE2DMULTISAMPLEPROC, glTexImage2DMultisample); +GL_IMPORT______(true, PFNGLTEXIMAGE3DMULTISAMPLEPROC, glTexImage3DMultisample); + # else // GLES GL_IMPORT______(false, PFNGLCLEARDEPTHFPROC, glClearDepthf); # endif // BGFX_CONFIG_RENDERER_OPENGL @@ -488,6 +491,7 @@ GL_IMPORT_OES__(true, PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC, glCompressedT GL_IMPORT_EXT__(true, PFNGLTEXSTORAGE2DPROC, glTexStorage2D); GL_IMPORT_EXT__(true, PFNGLTEXSTORAGE3DPROC, glTexStorage3D); GL_IMPORT______(true, PFNGLTEXIMAGE2DMULTISAMPLEPROC, glTexImage2DMultisample); +GL_IMPORT______(true, PFNGLTEXIMAGE3DMULTISAMPLEPROC, glTexImage3DMultisample); GL_IMPORT_EXT__(true, PFNGLINSERTEVENTMARKEREXTPROC, glInsertEventMarker); GL_IMPORT_EXT__(true, PFNGLPUSHGROUPMARKEREXTPROC, glPushGroupMarker); diff --git a/3rdparty/bgfx/src/image.cpp b/3rdparty/bgfx/src/image.cpp index 1d91f1e7627..4b31a7ba08a 100644 --- a/3rdparty/bgfx/src/image.cpp +++ b/3rdparty/bgfx/src/image.cpp @@ -387,68 +387,68 @@ namespace bgfx const uint8_t* src = (const uint8_t*)_src; using namespace bx; - const float4_t unpack = float4_ld(1.0f, 1.0f/256.0f, 1.0f/65536.0f, 1.0f/16777216.0f); - const float4_t pack = float4_ld(1.0f, 256.0f*0.5f, 65536.0f, 16777216.0f*0.5f); - const float4_t umask = float4_ild(0xff, 0xff00, 0xff0000, 0xff000000); - const float4_t pmask = float4_ild(0xff, 0x7f80, 0xff0000, 0x7f800000); - const float4_t wflip = float4_ild(0, 0, 0, 0x80000000); - const float4_t wadd = float4_ld(0.0f, 0.0f, 0.0f, 32768.0f*65536.0f); - const float4_t gamma = float4_ld(1.0f/2.2f, 1.0f/2.2f, 1.0f/2.2f, 1.0f); - const float4_t linear = float4_ld(2.2f, 2.2f, 2.2f, 1.0f); - const float4_t quater = float4_splat(0.25f); + const simd128_t unpack = simd_ld(1.0f, 1.0f/256.0f, 1.0f/65536.0f, 1.0f/16777216.0f); + const simd128_t pack = simd_ld(1.0f, 256.0f*0.5f, 65536.0f, 16777216.0f*0.5f); + const simd128_t umask = simd_ild(0xff, 0xff00, 0xff0000, 0xff000000); + const simd128_t pmask = simd_ild(0xff, 0x7f80, 0xff0000, 0x7f800000); + const simd128_t wflip = simd_ild(0, 0, 0, 0x80000000); + const simd128_t wadd = simd_ld(0.0f, 0.0f, 0.0f, 32768.0f*65536.0f); + const simd128_t gamma = simd_ld(1.0f/2.2f, 1.0f/2.2f, 1.0f/2.2f, 1.0f); + const simd128_t linear = simd_ld(2.2f, 2.2f, 2.2f, 1.0f); + const simd128_t quater = simd_splat(0.25f); for (uint32_t yy = 0, ystep = _pitch*2; yy < dstheight; ++yy, src += ystep) { const uint8_t* rgba = src; for (uint32_t xx = 0; xx < dstwidth; ++xx, rgba += 8, dst += 4) { - const float4_t abgr0 = float4_splat(rgba); - const float4_t abgr1 = float4_splat(rgba+4); - const float4_t abgr2 = float4_splat(rgba+_pitch); - const float4_t abgr3 = float4_splat(rgba+_pitch+4); - - const float4_t abgr0m = float4_and(abgr0, umask); - const float4_t abgr1m = float4_and(abgr1, umask); - const float4_t abgr2m = float4_and(abgr2, umask); - const float4_t abgr3m = float4_and(abgr3, umask); - const float4_t abgr0x = float4_xor(abgr0m, wflip); - const float4_t abgr1x = float4_xor(abgr1m, wflip); - const float4_t abgr2x = float4_xor(abgr2m, wflip); - const float4_t abgr3x = float4_xor(abgr3m, wflip); - const float4_t abgr0f = float4_itof(abgr0x); - const float4_t abgr1f = float4_itof(abgr1x); - const float4_t abgr2f = float4_itof(abgr2x); - const float4_t abgr3f = float4_itof(abgr3x); - const float4_t abgr0c = float4_add(abgr0f, wadd); - const float4_t abgr1c = float4_add(abgr1f, wadd); - const float4_t abgr2c = float4_add(abgr2f, wadd); - const float4_t abgr3c = float4_add(abgr3f, wadd); - const float4_t abgr0n = float4_mul(abgr0c, unpack); - const float4_t abgr1n = float4_mul(abgr1c, unpack); - const float4_t abgr2n = float4_mul(abgr2c, unpack); - const float4_t abgr3n = float4_mul(abgr3c, unpack); - - const float4_t abgr0l = float4_pow(abgr0n, linear); - const float4_t abgr1l = float4_pow(abgr1n, linear); - const float4_t abgr2l = float4_pow(abgr2n, linear); - const float4_t abgr3l = float4_pow(abgr3n, linear); - - const float4_t sum0 = float4_add(abgr0l, abgr1l); - const float4_t sum1 = float4_add(abgr2l, abgr3l); - const float4_t sum2 = float4_add(sum0, sum1); - const float4_t avg0 = float4_mul(sum2, quater); - const float4_t avg1 = float4_pow(avg0, gamma); - - const float4_t avg2 = float4_mul(avg1, pack); - const float4_t ftoi0 = float4_ftoi(avg2); - const float4_t ftoi1 = float4_and(ftoi0, pmask); - const float4_t zwxy = float4_swiz_zwxy(ftoi1); - const float4_t tmp0 = float4_or(ftoi1, zwxy); - const float4_t yyyy = float4_swiz_yyyy(tmp0); - const float4_t tmp1 = float4_iadd(yyyy, yyyy); - const float4_t result = float4_or(tmp0, tmp1); - - float4_stx(dst, result); + const simd128_t abgr0 = simd_splat(rgba); + const simd128_t abgr1 = simd_splat(rgba+4); + const simd128_t abgr2 = simd_splat(rgba+_pitch); + const simd128_t abgr3 = simd_splat(rgba+_pitch+4); + + const simd128_t abgr0m = simd_and(abgr0, umask); + const simd128_t abgr1m = simd_and(abgr1, umask); + const simd128_t abgr2m = simd_and(abgr2, umask); + const simd128_t abgr3m = simd_and(abgr3, umask); + const simd128_t abgr0x = simd_xor(abgr0m, wflip); + const simd128_t abgr1x = simd_xor(abgr1m, wflip); + const simd128_t abgr2x = simd_xor(abgr2m, wflip); + const simd128_t abgr3x = simd_xor(abgr3m, wflip); + const simd128_t abgr0f = simd_itof(abgr0x); + const simd128_t abgr1f = simd_itof(abgr1x); + const simd128_t abgr2f = simd_itof(abgr2x); + const simd128_t abgr3f = simd_itof(abgr3x); + const simd128_t abgr0c = simd_add(abgr0f, wadd); + const simd128_t abgr1c = simd_add(abgr1f, wadd); + const simd128_t abgr2c = simd_add(abgr2f, wadd); + const simd128_t abgr3c = simd_add(abgr3f, wadd); + const simd128_t abgr0n = simd_mul(abgr0c, unpack); + const simd128_t abgr1n = simd_mul(abgr1c, unpack); + const simd128_t abgr2n = simd_mul(abgr2c, unpack); + const simd128_t abgr3n = simd_mul(abgr3c, unpack); + + const simd128_t abgr0l = simd_pow(abgr0n, linear); + const simd128_t abgr1l = simd_pow(abgr1n, linear); + const simd128_t abgr2l = simd_pow(abgr2n, linear); + const simd128_t abgr3l = simd_pow(abgr3n, linear); + + const simd128_t sum0 = simd_add(abgr0l, abgr1l); + const simd128_t sum1 = simd_add(abgr2l, abgr3l); + const simd128_t sum2 = simd_add(sum0, sum1); + const simd128_t avg0 = simd_mul(sum2, quater); + const simd128_t avg1 = simd_pow(avg0, gamma); + + const simd128_t avg2 = simd_mul(avg1, pack); + const simd128_t ftoi0 = simd_ftoi(avg2); + const simd128_t ftoi1 = simd_and(ftoi0, pmask); + const simd128_t zwxy = simd_swiz_zwxy(ftoi1); + const simd128_t tmp0 = simd_or(ftoi1, zwxy); + const simd128_t yyyy = simd_swiz_yyyy(tmp0); + const simd128_t tmp1 = simd_iadd(yyyy, yyyy); + const simd128_t result = simd_or(tmp0, tmp1); + + simd_stx(dst, result); } } } @@ -630,8 +630,8 @@ namespace bgfx using namespace bx; - const float4_t mf0f0 = float4_isplat(0xff00ff00); - const float4_t m0f0f = float4_isplat(0x00ff00ff); + const simd128_t mf0f0 = simd_isplat(0xff00ff00); + const simd128_t m0f0f = simd_isplat(0x00ff00ff); const uint8_t* src = (uint8_t*) _src; const uint8_t* next = src + _pitch; uint8_t* dst = (uint8_t*)_dst; @@ -642,14 +642,14 @@ namespace bgfx { for (uint32_t xx = 0; xx < width; ++xx, src += 16, dst += 16) { - const float4_t tabgr = float4_ld(src); - const float4_t t00ab = float4_srl(tabgr, 16); - const float4_t tgr00 = float4_sll(tabgr, 16); - const float4_t tgrab = float4_or(t00ab, tgr00); - const float4_t ta0g0 = float4_and(tabgr, mf0f0); - const float4_t t0r0b = float4_and(tgrab, m0f0f); - const float4_t targb = float4_or(ta0g0, t0r0b); - float4_st(dst, targb); + const simd128_t tabgr = simd_ld(src); + const simd128_t t00ab = simd_srl(tabgr, 16); + const simd128_t tgr00 = simd_sll(tabgr, 16); + const simd128_t tgrab = simd_or(t00ab, tgr00); + const simd128_t ta0g0 = simd_and(tabgr, mf0f0); + const simd128_t t0r0b = simd_and(tgrab, m0f0f); + const simd128_t targb = simd_or(ta0g0, t0r0b); + simd_st(dst, targb); } } } @@ -707,6 +707,9 @@ namespace bgfx { const uint8_t* src = (const uint8_t*)_src; _dst[0] = fromUnorm(src[0], 255.0f); + _dst[1] = 0.0f; + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // R8S @@ -720,6 +723,9 @@ namespace bgfx { const int8_t* src = (const int8_t*)_src; _dst[0] = fromSnorm(src[0], 127.0f); + _dst[1] = 0.0f; + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // R8I @@ -733,6 +739,9 @@ namespace bgfx { const int8_t* src = (const int8_t*)_src; _dst[0] = float(src[0]); + _dst[1] = 0.0f; + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // R8U @@ -746,6 +755,9 @@ namespace bgfx { const uint8_t* src = (const uint8_t*)_src; _dst[0] = float(src[0]); + _dst[1] = 0.0f; + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // RG8 @@ -761,6 +773,8 @@ namespace bgfx const uint8_t* src = (const uint8_t*)_src; _dst[0] = fromUnorm(src[0], 255.0f); _dst[1] = fromUnorm(src[1], 255.0f); + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // RG8S @@ -776,6 +790,8 @@ namespace bgfx const int8_t* src = (const int8_t*)_src; _dst[0] = fromSnorm(src[0], 127.0f); _dst[1] = fromSnorm(src[1], 127.0f); + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // RG8I @@ -791,6 +807,8 @@ namespace bgfx const int8_t* src = (const int8_t*)_src; _dst[0] = float(src[0]); _dst[1] = float(src[1]); + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // RG8U @@ -806,6 +824,8 @@ namespace bgfx const uint8_t* src = (const uint8_t*)_src; _dst[0] = float(src[0]); _dst[1] = float(src[1]); + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // RGB8 @@ -823,6 +843,7 @@ namespace bgfx _dst[0] = fromUnorm(src[0], 255.0f); _dst[1] = fromUnorm(src[1], 255.0f); _dst[2] = fromUnorm(src[2], 255.0f); + _dst[3] = 1.0f; } // RGB8S @@ -840,6 +861,7 @@ namespace bgfx _dst[0] = fromSnorm(src[0], 127.0f); _dst[1] = fromSnorm(src[1], 127.0f); _dst[2] = fromSnorm(src[2], 127.0f); + _dst[3] = 1.0f; } // RGB8I @@ -857,6 +879,7 @@ namespace bgfx _dst[0] = float(src[0]); _dst[1] = float(src[1]); _dst[2] = float(src[2]); + _dst[3] = 1.0f; } // RGB8U @@ -874,6 +897,7 @@ namespace bgfx _dst[0] = float(src[0]); _dst[1] = float(src[1]); _dst[2] = float(src[2]); + _dst[3] = 1.0f; } // BGRA8 @@ -982,6 +1006,9 @@ namespace bgfx { const uint16_t* src = (const uint16_t*)_src; _dst[0] = fromUnorm(src[0], 65535.0f); + _dst[1] = 0.0f; + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // R16S @@ -995,6 +1022,9 @@ namespace bgfx { const int16_t* src = (const int16_t*)_src; _dst[0] = fromSnorm(src[0], 32767.0f); + _dst[1] = 0.0f; + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // R16I @@ -1008,6 +1038,9 @@ namespace bgfx { const int16_t* src = (const int16_t*)_src; _dst[0] = float(src[0]); + _dst[1] = 0.0f; + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // R16U @@ -1034,6 +1067,9 @@ namespace bgfx { const uint16_t* src = (const uint16_t*)_src; _dst[0] = bx::halfToFloat(src[0]); + _dst[1] = 0.0f; + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // RG16 @@ -1049,6 +1085,8 @@ namespace bgfx const uint16_t* src = (const uint16_t*)_src; _dst[0] = fromUnorm(src[0], 65535.0f); _dst[1] = fromUnorm(src[1], 65535.0f); + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // RG16S @@ -1064,6 +1102,8 @@ namespace bgfx const int16_t* src = (const int16_t*)_src; _dst[0] = fromSnorm(src[0], 32767.0f); _dst[1] = fromSnorm(src[1], 32767.0f); + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // RG16I @@ -1079,6 +1119,8 @@ namespace bgfx const int16_t* src = (const int16_t*)_src; _dst[0] = float(src[0]); _dst[1] = float(src[1]); + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // RG16U @@ -1094,6 +1136,8 @@ namespace bgfx const uint16_t* src = (const uint16_t*)_src; _dst[0] = float(src[0]); _dst[1] = float(src[1]); + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // RG16F @@ -1109,6 +1153,8 @@ namespace bgfx const uint16_t* src = (const uint16_t*)_src; _dst[0] = bx::halfToFloat(src[0]); _dst[1] = bx::halfToFloat(src[1]); + _dst[2] = 0.0f; + _dst[3] = 1.0f; } // RGBA16 @@ -1389,6 +1435,7 @@ namespace bgfx _dst[0] = float( ( (packed>>11) & 0x1f) ) / 31.0f; _dst[1] = float( ( (packed>> 5) & 0x3f) ) / 63.0f; _dst[2] = float( ( (packed ) & 0x1f) ) / 31.0f; + _dst[3] = 1.0f; } // RGBA4 @@ -1507,6 +1554,7 @@ namespace bgfx _dst[0] = bx::halfToFloat( (packed<< 4) & 0x7ff0); _dst[1] = bx::halfToFloat( (packed>> 7) & 0x7ff0); _dst[2] = bx::halfToFloat( (packed>>17) & 0x7fe0); + _dst[3] = 1.0f; } struct PackUnpack @@ -3581,7 +3629,7 @@ namespace bgfx default: imageDecodeToBgra8(_dst, _src, _width, _height, _pitch, _format); - imageSwizzleBgra8(_width, _height, _pitch, _dst, _dst); + imageSwizzleBgra8(_width, _height, _width*4, _dst, _dst); break; } } @@ -3628,24 +3676,24 @@ namespace bgfx const uint8_t* src = (const uint8_t*)_src; using namespace bx; - const float4_t unpack = float4_ld(1.0f, 1.0f/256.0f, 1.0f/65536.0f, 1.0f/16777216.0f); - const float4_t umask = float4_ild(0xff, 0xff00, 0xff0000, 0xff000000); - const float4_t wflip = float4_ild(0, 0, 0, 0x80000000); - const float4_t wadd = float4_ld(0.0f, 0.0f, 0.0f, 32768.0f*65536.0f); + const simd128_t unpack = simd_ld(1.0f, 1.0f/256.0f, 1.0f/65536.0f, 1.0f/16777216.0f); + const simd128_t umask = simd_ild(0xff, 0xff00, 0xff0000, 0xff000000); + const simd128_t wflip = simd_ild(0, 0, 0, 0x80000000); + const simd128_t wadd = simd_ld(0.0f, 0.0f, 0.0f, 32768.0f*65536.0f); for (uint32_t yy = 0, ystep = _pitch; yy < dstheight; ++yy, src += ystep) { const uint8_t* rgba = src; for (uint32_t xx = 0; xx < dstwidth; ++xx, rgba += 4, dst += 4) { - const float4_t abgr0 = float4_splat(rgba); - const float4_t abgr0m = float4_and(abgr0, umask); - const float4_t abgr0x = float4_xor(abgr0m, wflip); - const float4_t abgr0f = float4_itof(abgr0x); - const float4_t abgr0c = float4_add(abgr0f, wadd); - const float4_t abgr0n = float4_mul(abgr0c, unpack); - - float4_st(dst, abgr0n); + const simd128_t abgr0 = simd_splat(rgba); + const simd128_t abgr0m = simd_and(abgr0, umask); + const simd128_t abgr0x = simd_xor(abgr0m, wflip); + const simd128_t abgr0f = simd_itof(abgr0x); + const simd128_t abgr0c = simd_add(abgr0f, wadd); + const simd128_t abgr0n = simd_mul(abgr0c, unpack); + + simd_st(dst, abgr0n); } } } diff --git a/3rdparty/bgfx/src/renderer_d3d11.cpp b/3rdparty/bgfx/src/renderer_d3d11.cpp index f8185ed0900..5e6fb036dde 100644 --- a/3rdparty/bgfx/src/renderer_d3d11.cpp +++ b/3rdparty/bgfx/src/renderer_d3d11.cpp @@ -800,7 +800,11 @@ namespace bgfx { namespace d3d11 errorState = ErrorState::LoadedDXGI; - CreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY)bx::dlsym(m_dxgidll, "CreateDXGIFactory"); + CreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY)bx::dlsym(m_dxgidll, "CreateDXGIFactory1"); + if (NULL == CreateDXGIFactory) + { + CreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY)bx::dlsym(m_dxgidll, "CreateDXGIFactory"); + } if (NULL == CreateDXGIFactory) { BX_TRACE("Function CreateDXGIFactory not found."); @@ -1342,7 +1346,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii) { - uint8_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE; + uint16_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE; const DXGI_FORMAT fmt = isDepth(TextureFormat::Enum(ii) ) ? s_textureFormat[ii].m_fmtDsv @@ -1425,6 +1429,13 @@ BX_PRAGMA_DIAGNOSTIC_POP(); ? BGFX_CAPS_FORMAT_TEXTURE_MSAA : BGFX_CAPS_FORMAT_TEXTURE_NONE ; + + support |= 0 != (data.OutFormatSupport & (0 + | D3D11_FORMAT_SUPPORT_MIP_AUTOGEN + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; } else { @@ -1827,7 +1838,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); m_deviceCtx->Unmap(texture.m_ptr, 0); } - void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) BX_OVERRIDE + void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips) BX_OVERRIDE { TextureD3D11& texture = m_textures[_handle.idx]; @@ -1843,7 +1854,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); tc.m_height = _height; tc.m_sides = 0; tc.m_depth = 0; - tc.m_numMips = 1; + tc.m_numMips = _numMips; tc.m_format = TextureFormat::Enum(texture.m_requestedFormat); tc.m_cubeMap = false; tc.m_mem = NULL; @@ -2662,18 +2673,26 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { _state &= BGFX_D3D11_BLEND_STATE_MASK; - const uint64_t hash = _state; + bx::HashMurmur2A murmur; + murmur.begin(); + murmur.add(_state); + murmur.add(!!(BGFX_STATE_BLEND_INDEPENDENT & _state) + ? _rgba + : -1 + ); + const uint32_t hash = murmur.end(); + ID3D11BlendState* bs = m_blendStateCache.find(hash); if (NULL == bs) { D3D11_BLEND_DESC desc; desc.AlphaToCoverageEnable = !!(BGFX_STATE_BLEND_ALPHA_TO_COVERAGE & _state); - desc.IndependentBlendEnable = !!(BGFX_STATE_BLEND_INDEPENDENT & _state); + desc.IndependentBlendEnable = !!(BGFX_STATE_BLEND_INDEPENDENT & _state); D3D11_RENDER_TARGET_BLEND_DESC* drt = &desc.RenderTarget[0]; drt->BlendEnable = !!(BGFX_STATE_BLEND_MASK & _state); - const uint32_t blend = uint32_t( (_state&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT); + const uint32_t blend = uint32_t( (_state&BGFX_STATE_BLEND_MASK )>>BGFX_STATE_BLEND_SHIFT); const uint32_t equation = uint32_t( (_state&BGFX_STATE_BLEND_EQUATION_MASK)>>BGFX_STATE_BLEND_EQUATION_SHIFT); const uint32_t srcRGB = (blend ) & 0xf; @@ -2889,6 +2908,12 @@ BX_PRAGMA_DIAGNOSTIC_POP(); const uint32_t index = (_flags & BGFX_TEXTURE_BORDER_COLOR_MASK) >> BGFX_TEXTURE_BORDER_COLOR_SHIFT; _flags &= BGFX_TEXTURE_SAMPLER_BITS_MASK; + // Force both min+max anisotropic, can't be set individually. + _flags |= 0 != (_flags & (BGFX_TEXTURE_MIN_ANISOTROPIC|BGFX_TEXTURE_MAG_ANISOTROPIC) ) + ? BGFX_TEXTURE_MIN_ANISOTROPIC|BGFX_TEXTURE_MAG_ANISOTROPIC + : 0 + ; + uint32_t hash; ID3D11SamplerState* sampler; if (!needBorderColor(_flags) ) @@ -3079,16 +3104,16 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (NULL == ptr) { const TextureD3D11& texture = m_textures[_handle.idx]; - const bool msaaSample = 0 != (texture.m_flags&BGFX_TEXTURE_MSAA_SAMPLE); const uint32_t msaaQuality = bx::uint32_satsub( (texture.m_flags&BGFX_TEXTURE_RT_MSAA_MASK)>>BGFX_TEXTURE_RT_MSAA_SHIFT, 1); const DXGI_SAMPLE_DESC& msaa = s_msaa[msaaQuality]; + const bool msaaSample = 1 < msaa.Count && 0 != (texture.m_flags&BGFX_TEXTURE_MSAA_SAMPLE); D3D11_SHADER_RESOURCE_VIEW_DESC desc; desc.Format = s_textureFormat[texture.m_textureFormat].m_fmtSrv; switch (texture.m_type) { case TextureD3D11::Texture2D: - desc.ViewDimension = 1 < msaa.Count && msaaSample + desc.ViewDimension = msaaSample ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D ; @@ -4333,9 +4358,18 @@ BX_PRAGMA_DIAGNOSTIC_POP(); const bool srgb = 0 != (m_flags&BGFX_TEXTURE_SRGB) || imageContainer.m_srgb; const bool blit = 0 != (m_flags&BGFX_TEXTURE_BLIT_DST); const bool readBack = 0 != (m_flags&BGFX_TEXTURE_READ_BACK); - const bool msaaSample = 0 != (m_flags&BGFX_TEXTURE_MSAA_SAMPLE); const uint32_t msaaQuality = bx::uint32_satsub( (m_flags&BGFX_TEXTURE_RT_MSAA_MASK)>>BGFX_TEXTURE_RT_MSAA_SHIFT, 1); const DXGI_SAMPLE_DESC& msaa = s_msaa[msaaQuality]; + const bool msaaSample = true + && 1 < msaa.Count + && 0 != (m_flags&BGFX_TEXTURE_MSAA_SAMPLE) + && !writeOnly + ; + const bool needResolve = true + && 1 < msaa.Count + && 0 == (m_flags&BGFX_TEXTURE_MSAA_SAMPLE) + && !writeOnly + ; D3D11_SHADER_RESOURCE_VIEW_DESC srvd; memset(&srvd, 0, sizeof(srvd) ); @@ -4374,6 +4408,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); desc.Usage = kk == 0 || blit ? D3D11_USAGE_DEFAULT : D3D11_USAGE_IMMUTABLE; desc.BindFlags = writeOnly ? 0 : D3D11_BIND_SHADER_RESOURCE; desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; if (isDepth( (TextureFormat::Enum)m_textureFormat) ) { @@ -4384,6 +4419,9 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { desc.BindFlags |= D3D11_BIND_RENDER_TARGET; desc.Usage = D3D11_USAGE_DEFAULT; + desc.MiscFlags |= 0 + | (1 < numMips ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0) + ; } if (computeWrite) @@ -4402,16 +4440,14 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (imageContainer.m_cubeMap) { desc.ArraySize = 6; - desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; + desc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE; srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; srvd.TextureCube.MipLevels = numMips; } else { desc.ArraySize = 1; - desc.MiscFlags = 0; - if (1 < msaa.Count - && msaaSample) + if (msaaSample) { srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; } @@ -4422,6 +4458,13 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } } + if (needResolve) + { + DX_CHECK(s_renderD3D11->m_device->CreateTexture2D(&desc, NULL, &m_rt2d) ); + desc.BindFlags &= ~(D3D11_BIND_RENDER_TARGET|D3D11_BIND_DEPTH_STENCIL); + desc.SampleDesc = s_msaa[0]; + } + DX_CHECK(s_renderD3D11->m_device->CreateTexture2D(&desc, kk == 0 ? NULL : srd, &m_texture2d) ); } break; @@ -4482,6 +4525,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); void TextureD3D11::destroy() { s_renderD3D11->m_srvUavLru.invalidateWithParent(getHandle().idx); + DX_RELEASE(m_rt, 0); DX_RELEASE(m_srv, 0); DX_RELEASE(m_uav, 0); if (0 == (m_flags & BGFX_TEXTURE_INTERNAL_SHARED) ) @@ -4550,8 +4594,22 @@ BX_PRAGMA_DIAGNOSTIC_POP(); ; } - void TextureD3D11::resolve() + void TextureD3D11::resolve() const { + ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx; + + const bool needResolve = NULL != m_rt; + if (needResolve) + { + deviceCtx->ResolveSubresource(m_texture2d, 0, m_rt, 0, s_textureFormat[m_textureFormat].m_fmt); + } + + const bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK); + if (renderTarget + && 1 < m_numMips) + { + deviceCtx->GenerateMips(m_srv); + } } TextureHandle TextureD3D11::getHandle() const @@ -4713,7 +4771,11 @@ BX_PRAGMA_DIAGNOSTIC_POP(); ; dsvDesc.Flags = 0; dsvDesc.Texture2D.MipSlice = m_attachment[ii].mip; - DX_CHECK(s_renderD3D11->m_device->CreateDepthStencilView(texture.m_ptr, &dsvDesc, &m_dsv) ); + DX_CHECK(s_renderD3D11->m_device->CreateDepthStencilView( + NULL == texture.m_rt ? texture.m_ptr : texture.m_rt + , &dsvDesc + , &m_dsv + ) ); } break; @@ -4758,7 +4820,12 @@ BX_PRAGMA_DIAGNOSTIC_POP(); desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; desc.Texture2D.MipSlice = m_attachment[ii].mip; } - DX_CHECK(s_renderD3D11->m_device->CreateRenderTargetView(texture.m_ptr, &desc, &m_rtv[m_num]) ); + + DX_CHECK(s_renderD3D11->m_device->CreateRenderTargetView( + NULL == texture.m_rt ? texture.m_ptr : texture.m_rt + , &desc + , &m_rtv[m_num] + ) ); } break; @@ -4806,6 +4873,18 @@ BX_PRAGMA_DIAGNOSTIC_POP(); void FrameBufferD3D11::resolve() { + if (0 < m_numTh) + { + for (uint32_t ii = 0; ii < m_numTh; ++ii) + { + TextureHandle handle = m_attachment[ii].handle; + if (isValid(handle) ) + { + const TextureD3D11& texture = s_renderD3D11->m_textures[handle.idx]; + texture.resolve(); + } + } + } } void FrameBufferD3D11::clear(const Clear& _clear, const float _palette[][4]) @@ -5958,12 +6037,14 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { m_gpuTimer.end(); - while (m_gpuTimer.get() ) + do { double toGpuMs = 1000.0 / double(m_gpuTimer.m_frequency); elapsedGpuMs = m_gpuTimer.m_elapsed * toGpuMs; maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed; } + while (m_gpuTimer.get() ); + maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.available()-1); } diff --git a/3rdparty/bgfx/src/renderer_d3d11.h b/3rdparty/bgfx/src/renderer_d3d11.h index 84dd0c61981..5d8614a7301 100644 --- a/3rdparty/bgfx/src/renderer_d3d11.h +++ b/3rdparty/bgfx/src/renderer_d3d11.h @@ -242,6 +242,7 @@ namespace bgfx { namespace d3d11 TextureD3D11() : m_ptr(NULL) + , m_rt(NULL) , m_srv(NULL) , m_uav(NULL) , m_numMips(0) @@ -253,7 +254,7 @@ namespace bgfx { namespace d3d11 void overrideInternal(uintptr_t _ptr); void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem); void commit(uint8_t _stage, uint32_t _flags, const float _palette[][4]); - void resolve(); + void resolve() const; TextureHandle getHandle() const; union @@ -263,6 +264,12 @@ namespace bgfx { namespace d3d11 ID3D11Texture3D* m_texture3d; }; + union + { + ID3D11Resource* m_rt; + ID3D11Texture2D* m_rt2d; + }; + ID3D11ShaderResourceView* m_srv; ID3D11UnorderedAccessView* m_uav; uint32_t m_flags; diff --git a/3rdparty/bgfx/src/renderer_d3d12.cpp b/3rdparty/bgfx/src/renderer_d3d12.cpp index 3a35feacd04..5624dc5dc58 100644 --- a/3rdparty/bgfx/src/renderer_d3d12.cpp +++ b/3rdparty/bgfx/src/renderer_d3d12.cpp @@ -1014,7 +1014,7 @@ namespace bgfx { namespace d3d12 for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii) { - uint8_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE; + uint16_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE; const DXGI_FORMAT fmt = isDepth(TextureFormat::Enum(ii) ) ? s_textureFormat[ii].m_fmtDsv @@ -1464,7 +1464,7 @@ namespace bgfx { namespace d3d12 DX_RELEASE(readback, 0); } - void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) BX_OVERRIDE + void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips) BX_OVERRIDE { TextureD3D12& texture = m_textures[_handle.idx]; @@ -1480,7 +1480,7 @@ namespace bgfx { namespace d3d12 tc.m_height = _height; tc.m_sides = 0; tc.m_depth = 0; - tc.m_numMips = 1; + tc.m_numMips = _numMips; tc.m_format = TextureFormat::Enum(texture.m_requestedFormat); tc.m_cubeMap = false; tc.m_mem = NULL; @@ -5413,12 +5413,14 @@ data.NumQualityLevels = 0; m_gpuTimer.end(m_commandList); - while (m_gpuTimer.get() ) + do { double toGpuMs = 1000.0 / double(m_gpuTimer.m_frequency); elapsedGpuMs = m_gpuTimer.m_elapsed * toGpuMs; maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed; } + while (m_gpuTimer.get() ); + maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.available()-1); const int64_t timerFreq = bx::getHPFrequency(); diff --git a/3rdparty/bgfx/src/renderer_d3d9.cpp b/3rdparty/bgfx/src/renderer_d3d9.cpp index 84230d317df..81e53cecba1 100644 --- a/3rdparty/bgfx/src/renderer_d3d9.cpp +++ b/3rdparty/bgfx/src/renderer_d3d9.cpp @@ -628,7 +628,7 @@ namespace bgfx { namespace d3d9 for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii) { - uint8_t support = 0; + uint16_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE; support |= SUCCEEDED(m_d3d9->CheckDeviceFormat(m_adapter , m_deviceType @@ -702,6 +702,14 @@ namespace bgfx { namespace d3d9 , NULL ) ) ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA : BGFX_CAPS_FORMAT_TEXTURE_NONE; + support |= SUCCEEDED(m_d3d9->CheckDeviceFormat(m_adapter + , m_deviceType + , adapterFormat + , isDepth(TextureFormat::Enum(ii) ) ? D3DUSAGE_DEPTHSTENCIL : D3DUSAGE_RENDERTARGET + , D3DRTYPE_TEXTURE + , s_textureFormat[ii].m_fmt + ) ) ? BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN : BGFX_CAPS_FORMAT_TEXTURE_NONE; + g_caps.formats[ii] = support; } @@ -1011,7 +1019,7 @@ namespace bgfx { namespace d3d9 DX_CHECK(texture.m_texture2d->UnlockRect(0) ); } - void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) BX_OVERRIDE + void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips) BX_OVERRIDE { TextureD3D9& texture = m_textures[_handle.idx]; @@ -1027,13 +1035,13 @@ namespace bgfx { namespace d3d9 tc.m_height = _height; tc.m_sides = 0; tc.m_depth = 0; - tc.m_numMips = 1; + tc.m_numMips = _numMips; tc.m_format = TextureFormat::Enum(texture.m_requestedFormat); tc.m_cubeMap = false; tc.m_mem = NULL; bx::write(&writer, tc); - texture.destroy(); + texture.destroy(true); texture.create(mem, texture.m_flags, 0); release(mem); @@ -1340,8 +1348,7 @@ namespace bgfx { namespace d3d9 void setFrameBuffer(FrameBufferHandle _fbh, bool _msaa = true) { if (isValid(m_fbh) - && m_fbh.idx != _fbh.idx - && m_rtMsaa) + && m_fbh.idx != _fbh.idx) { FrameBufferD3D9& frameBuffer = m_frameBuffers[m_fbh.idx]; frameBuffer.resolve(); @@ -2495,7 +2502,10 @@ namespace bgfx { namespace d3d9 } else if (renderTarget || blit) { - usage = D3DUSAGE_RENDERTARGET; + usage = 0 + | D3DUSAGE_RENDERTARGET + | (1 < _numMips ? D3DUSAGE_AUTOGENMIPMAP : 0) + ; } IDirect3DDevice9* device = s_renderD3D9->m_device; @@ -3092,7 +3102,7 @@ namespace bgfx { namespace d3d9 void TextureD3D9::resolve() const { if (NULL != m_surface - && NULL != m_texture2d) + && NULL != m_ptr) { IDirect3DSurface9* surface = getSurface(); DX_CHECK(s_renderD3D9->m_device->StretchRect(m_surface @@ -3102,6 +3112,11 @@ namespace bgfx { namespace d3d9 , D3DTEXF_LINEAR ) ); DX_RELEASE(surface, 1); + + if (1 < m_numMips) + { + m_ptr->GenerateMipSubLevels(); + } } } @@ -4188,12 +4203,14 @@ namespace bgfx { namespace d3d9 { m_gpuTimer.end(); - while (m_gpuTimer.get() ) + do { double toGpuMs = 1000.0 / double(m_gpuTimer.m_frequency); elapsedGpuMs = m_gpuTimer.m_elapsed * toGpuMs; maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed; } + while (m_gpuTimer.get() ); + maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.available()-1); } diff --git a/3rdparty/bgfx/src/renderer_d3d9.h b/3rdparty/bgfx/src/renderer_d3d9.h index 84bb83f1399..dc5f234b7c3 100644 --- a/3rdparty/bgfx/src/renderer_d3d9.h +++ b/3rdparty/bgfx/src/renderer_d3d9.h @@ -323,11 +323,21 @@ namespace bgfx { namespace d3d9 void create(const Memory* _mem, uint32_t _flags, uint8_t _skip); - void destroy() + void destroy(bool _resize = false) { if (0 == (m_flags & BGFX_TEXTURE_INTERNAL_SHARED) ) { - DX_RELEASE(m_ptr, 0); + if (_resize) + { + // BK - at the time of resize there might be one reference held by frame buffer + // surface. This frame buffer will be recreated later, and release reference + // to existing surface. That's why here we don't care about ref count. + m_ptr->Release(); + } + else + { + DX_RELEASE(m_ptr, 0); + } } DX_RELEASE(m_surface, 0); DX_RELEASE(m_staging, 0); diff --git a/3rdparty/bgfx/src/renderer_gl.cpp b/3rdparty/bgfx/src/renderer_gl.cpp index 1ed6333c217..0fea6a7c9d8 100644 --- a/3rdparty/bgfx/src/renderer_gl.cpp +++ b/3rdparty/bgfx/src/renderer_gl.cpp @@ -223,8 +223,8 @@ namespace bgfx { namespace gl { GL_ZERO, GL_ZERO, GL_ZERO, GL_ZERO, false }, // R1 { GL_ALPHA, GL_ZERO, GL_ALPHA, GL_UNSIGNED_BYTE, false }, // A8 { GL_R8, GL_ZERO, GL_RED, GL_UNSIGNED_BYTE, false }, // R8 - { GL_R8I, GL_ZERO, GL_RED, GL_BYTE, false }, // R8S - { GL_R8UI, GL_ZERO, GL_RED, GL_UNSIGNED_BYTE, false }, // R8S + { GL_R8I, GL_ZERO, GL_RED, GL_BYTE, false }, // R8I + { GL_R8UI, GL_ZERO, GL_RED, GL_UNSIGNED_BYTE, false }, // R8U { GL_R8_SNORM, GL_ZERO, GL_RED, GL_BYTE, false }, // R8S { GL_R16, GL_ZERO, GL_RED, GL_UNSIGNED_SHORT, false }, // R16 { GL_R16I, GL_ZERO, GL_RED, GL_SHORT, false }, // R16I @@ -239,8 +239,8 @@ namespace bgfx { namespace gl { GL_RG8UI, GL_ZERO, GL_RG, GL_UNSIGNED_BYTE, false }, // RG8U { GL_RG8_SNORM, GL_ZERO, GL_RG, GL_BYTE, false }, // RG8S { GL_RG16, GL_ZERO, GL_RG, GL_UNSIGNED_SHORT, false }, // RG16 - { GL_RG16I, GL_ZERO, GL_RG, GL_SHORT, false }, // RG16 - { GL_RG16UI, GL_ZERO, GL_RG, GL_UNSIGNED_SHORT, false }, // RG16 + { GL_RG16I, GL_ZERO, GL_RG, GL_SHORT, false }, // RG16I + { GL_RG16UI, GL_ZERO, GL_RG, GL_UNSIGNED_SHORT, false }, // RG16U { GL_RG16F, GL_ZERO, GL_RG, GL_FLOAT, false }, // RG16F { GL_RG16_SNORM, GL_ZERO, GL_RG, GL_SHORT, false }, // RG16S { GL_RG32I, GL_ZERO, GL_RG, GL_INT, false }, // RG32I @@ -1110,10 +1110,10 @@ namespace bgfx { namespace gl tfi.m_type = _type; } - void initTestTexture(TextureFormat::Enum _format, bool srgb = false) + GLenum initTestTexture(TextureFormat::Enum _format, bool _srgb, bool _mipmaps) { const TextureFormatInfo& tfi = s_textureFormat[_format]; - GLenum internalFmt = srgb + GLenum internalFmt = _srgb ? tfi.m_internalFmtSrgb : tfi.m_internalFmt ; @@ -1121,20 +1121,48 @@ namespace bgfx { namespace gl GLsizei size = (16*16*getBitsPerPixel(_format) )/8; void* data = bx::alignPtr(alloca(size+16), 0, 16); + GLenum err = 0; + if (isCompressed(_format) ) { glCompressedTexImage2D(GL_TEXTURE_2D, 0, internalFmt, 16, 16, 0, size, data); + err |= glGetError(); + if (_mipmaps) + { + glCompressedTexImage2D(GL_TEXTURE_2D, 1, internalFmt, 8, 8, 0, size, data); + err |= glGetError(); + glCompressedTexImage2D(GL_TEXTURE_2D, 2, internalFmt, 4, 4, 0, size, data); + err |= glGetError(); + glCompressedTexImage2D(GL_TEXTURE_2D, 3, internalFmt, 2, 2, 0, size, data); + err |= glGetError(); + glCompressedTexImage2D(GL_TEXTURE_2D, 4, internalFmt, 1, 1, 0, size, data); + err |= glGetError(); + } } else { glTexImage2D(GL_TEXTURE_2D, 0, internalFmt, 16, 16, 0, tfi.m_fmt, tfi.m_type, data); + err |= glGetError(); + if (_mipmaps) + { + glTexImage2D(GL_TEXTURE_2D, 1, internalFmt, 8, 8, 0, tfi.m_fmt, tfi.m_type, data); + err |= glGetError(); + glTexImage2D(GL_TEXTURE_2D, 2, internalFmt, 4, 4, 0, tfi.m_fmt, tfi.m_type, data); + err |= glGetError(); + glTexImage2D(GL_TEXTURE_2D, 3, internalFmt, 2, 2, 0, tfi.m_fmt, tfi.m_type, data); + err |= glGetError(); + glTexImage2D(GL_TEXTURE_2D, 4, internalFmt, 1, 1, 0, tfi.m_fmt, tfi.m_type, data); + err |= glGetError(); + } } + + return err; } - static bool isTextureFormatValid(TextureFormat::Enum _format, bool srgb = false) + static bool isTextureFormatValid(TextureFormat::Enum _format, bool _srgb = false, bool _mipAutogen = false) { const TextureFormatInfo& tfi = s_textureFormat[_format]; - GLenum internalFmt = srgb + GLenum internalFmt = _srgb ? tfi.m_internalFmtSrgb : tfi.m_internalFmt ; @@ -1146,11 +1174,17 @@ namespace bgfx { namespace gl GLuint id; GL_CHECK(glGenTextures(1, &id) ); GL_CHECK(glBindTexture(GL_TEXTURE_2D, id) ); - initTestTexture(_format); - GLenum err = glGetError(); + GLenum err = initTestTexture(_format, _srgb, _mipAutogen); BX_WARN(0 == err, "TextureFormat::%s is not supported (%x: %s).", getName(_format), err, glEnumName(err) ); + if (0 == err + && _mipAutogen) + { + glGenerateMipmap(GL_TEXTURE_2D); + err = glGetError(); + } + GL_CHECK(glDeleteTextures(1, &id) ); return 0 == err; @@ -1186,10 +1220,10 @@ namespace bgfx { namespace gl return 0 == err; } - static bool isFramebufferFormatValid(TextureFormat::Enum _format, bool srgb = false) + static bool isFramebufferFormatValid(TextureFormat::Enum _format, bool _srgb = false) { const TextureFormatInfo& tfi = s_textureFormat[_format]; - GLenum internalFmt = srgb + GLenum internalFmt = _srgb ? tfi.m_internalFmtSrgb : tfi.m_internalFmt ; @@ -1207,9 +1241,7 @@ namespace bgfx { namespace gl GL_CHECK(glGenTextures(1, &id) ); GL_CHECK(glBindTexture(GL_TEXTURE_2D, id) ); - initTestTexture(_format); - - GLenum err = glGetError(); + GLenum err = initTestTexture(_format, _srgb, false); GLenum attachment; if (isDepth(_format) ) @@ -1686,7 +1718,7 @@ namespace bgfx { namespace gl for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii) { - uint8_t supported = 0; + uint16_t supported = BGFX_CAPS_FORMAT_TEXTURE_NONE; supported |= s_textureFormat[ii].m_supported ? BGFX_CAPS_FORMAT_TEXTURE_2D | BGFX_CAPS_FORMAT_TEXTURE_3D @@ -1701,6 +1733,11 @@ namespace bgfx { namespace gl : BGFX_CAPS_FORMAT_TEXTURE_NONE ; + supported |= isTextureFormatValid(TextureFormat::Enum(ii), false, true) + ? BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; + supported |= computeSupport && isImageFormatValid(TextureFormat::Enum(ii) ) ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE @@ -2269,7 +2306,7 @@ namespace bgfx { namespace gl } } - void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) BX_OVERRIDE + void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips) BX_OVERRIDE { TextureGL& texture = m_textures[_handle.idx]; @@ -2285,7 +2322,7 @@ namespace bgfx { namespace gl tc.m_height = _height; tc.m_sides = 0; tc.m_depth = 0; - tc.m_numMips = 1; + tc.m_numMips = _numMips; tc.m_format = TextureFormat::Enum(texture.m_requestedFormat); tc.m_cubeMap = false; tc.m_mem = NULL; @@ -2573,21 +2610,16 @@ namespace bgfx { namespace gl uint32_t setFrameBuffer(FrameBufferHandle _fbh, uint32_t _height, uint16_t _discard = BGFX_CLEAR_NONE, bool _msaa = true) { if (isValid(m_fbh) - && m_fbh.idx != _fbh.idx - && (BGFX_CLEAR_NONE != m_fbDiscard || m_rtMsaa) ) + && m_fbh.idx != _fbh.idx) { FrameBufferGL& frameBuffer = m_frameBuffers[m_fbh.idx]; - if (m_rtMsaa) - { - frameBuffer.resolve(); - } + frameBuffer.resolve(); if (BGFX_CLEAR_NONE != m_fbDiscard) { frameBuffer.discard(m_fbDiscard); + m_fbDiscard = BGFX_CLEAR_NONE; } - - m_fbDiscard = BGFX_CLEAR_NONE; } m_glctx.makeCurrent(NULL); @@ -4315,9 +4347,10 @@ namespace bgfx { namespace gl uint32_t msaaQuality = ( (m_flags&BGFX_TEXTURE_RT_MSAA_MASK)>>BGFX_TEXTURE_RT_MSAA_SHIFT); msaaQuality = bx::uint32_satsub(msaaQuality, 1); msaaQuality = bx::uint32_min(s_renderGL->m_maxMsaa, msaaQuality == 0 ? 0 : 1<<msaaQuality); + const bool msaaSample = 0 != (m_flags&BGFX_TEXTURE_MSAA_SAMPLE); - if (0 != msaaQuality - || writeOnly) + if (!msaaSample + && (0 != msaaQuality || writeOnly) ) { GL_CHECK(glGenRenderbuffers(1, &m_rbo) ); BX_CHECK(0 != m_rbo, "Failed to generate renderbuffer id."); @@ -4822,6 +4855,18 @@ namespace bgfx { namespace gl } } + void TextureGL::resolve() const + { + const bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK); + if (renderTarget + && 1 < m_numMips) + { + GL_CHECK(glBindTexture(m_target, m_id) ); + GL_CHECK(glGenerateMipmap(m_target) ); + GL_CHECK(glBindTexture(m_target, 0) ); + } + } + void writeString(bx::WriterI* _writer, const char* _str) { bx::write(_writer, _str, (int32_t)strlen(_str) ); @@ -4920,10 +4965,11 @@ namespace bgfx { namespace gl if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES) && BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES < 30) ) { - writeString(&writer - , "#define flat\n" - "#define smooth\n" - "#define noperspective\n" + writeString(&writer, + "#define centroid\n" + "#define flat\n" + "#define noperspective\n" + "#define smooth\n" ); bool usesDerivatives = s_extension[Extension::OES_standard_derivatives].m_supported @@ -5082,9 +5128,10 @@ namespace bgfx { namespace gl && s_extension[Extension::ARB_shader_texture_lod].m_supported && bx::findIdentifierMatch(code, s_ARB_shader_texture_lod) ; + const bool usesGpuShader5 = !!bx::findIdentifierMatch(code, s_ARB_gpu_shader5); const bool usesIUsamplers = !!bx::findIdentifierMatch(code, s_uisamplers); const bool usesTexelFetch = !!bx::findIdentifierMatch(code, s_texelFetch); - const bool usesGpuShader5 = !!bx::findIdentifierMatch(code, s_ARB_gpu_shader5); + const bool usesTextureMS = !!bx::findIdentifierMatch(code, s_ARB_texture_multisample); const bool usesPacking = !!bx::findIdentifierMatch(code, s_ARB_shading_language_packing); uint32_t version = @@ -5116,6 +5163,11 @@ namespace bgfx { namespace gl writeString(&writer, "#extension GL_ARB_shading_language_packing : enable\n"); } + if (usesTextureMS) + { + writeString(&writer, "#extension GL_ARB_texture_multisample : enable\n"); + } + if (130 <= version) { if (m_type == GL_FRAGMENT_SHADER) @@ -5166,13 +5218,14 @@ namespace bgfx { namespace gl } } - writeString(&writer - , "#define lowp\n" - "#define mediump\n" - "#define highp\n" - "#define flat\n" - "#define smooth\n" - "#define noperspective\n" + writeString(&writer, + "#define lowp\n" + "#define mediump\n" + "#define highp\n" + "#define centroid\n" + "#define flat\n" + "#define noperspective\n" + "#define smooth\n" ); bx::write(&writer, code, codeLen); @@ -5539,6 +5592,19 @@ namespace bgfx { namespace gl GL_CHECK(glReadBuffer(GL_NONE) ); GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, s_renderGL->m_msaaBackBufferFbo) ); } + + if (0 < m_numTh) + { + for (uint32_t ii = 0; ii < m_numTh; ++ii) + { + TextureHandle handle = m_attachment[ii].handle; + if (isValid(handle) ) + { + const TextureGL& texture = s_renderGL->m_textures[handle.idx]; + texture.resolve(); + } + } + } } void FrameBufferGL::discard(uint16_t _flags) @@ -6785,12 +6851,14 @@ namespace bgfx { namespace gl if (m_timerQuerySupport) { m_gpuTimer.end(); - while (m_gpuTimer.get() ) + do { elapsedGl = m_gpuTimer.m_elapsed; elapsedGpuMs = double(elapsedGl)/1e6; maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed; } + while (m_gpuTimer.get() ); + maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.available()-1); } diff --git a/3rdparty/bgfx/src/renderer_gl.h b/3rdparty/bgfx/src/renderer_gl.h index 4e205fe3095..189c17b29e5 100644 --- a/3rdparty/bgfx/src/renderer_gl.h +++ b/3rdparty/bgfx/src/renderer_gl.h @@ -1234,6 +1234,7 @@ namespace bgfx { namespace gl void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem); void setSamplerState(uint32_t _flags, const float _rgba[4]); void commit(uint32_t _stage, uint32_t _flags, const float _palette[][4]); + void resolve() const; GLuint m_id; GLuint m_rbo; diff --git a/3rdparty/bgfx/src/renderer_mtl.h b/3rdparty/bgfx/src/renderer_mtl.h index f471ee5d457..42145e0c036 100644 --- a/3rdparty/bgfx/src/renderer_mtl.h +++ b/3rdparty/bgfx/src/renderer_mtl.h @@ -19,10 +19,38 @@ namespace bgfx { namespace mtl { + //runtime os check + inline bool iOSVersionEqualOrGreater(const char* _version) + { +#if BX_PLATFORM_IOS + return ([[[UIDevice currentDevice] systemVersion] compare:@(_version) options:NSNumericSearch] != NSOrderedAscending); +#else + BX_UNUSED(_version); + return false; +#endif + } + + inline bool macOSVersionEqualOrGreater(NSInteger _majorVersion, + NSInteger _minorVersion, + NSInteger _patchVersion) + { +#if BX_PLATFORM_OSX + NSOperatingSystemVersion v = [[NSProcessInfo processInfo] operatingSystemVersion]; + return (v.majorVersion<<16) + (v.minorVersion<<8) + v.patchVersion >= + (_majorVersion<<16) + (_minorVersion<<8) + _patchVersion; +#else + BX_UNUSED(_majorVersion, _minorVersion, _patchVersion); + return false; +#endif + } + + // c++ wrapper // objects with creation functions starting with 'new' has a refcount 1 after creation, object must be destroyed with release. // commandBuffer, commandEncoders are autoreleased objects. Needs AutoreleasePool! +#define MTL_MAX_FRAMES_IN_FLIGHT (3) + #define MTL_CLASS(name) \ class name \ { \ @@ -35,6 +63,36 @@ namespace bgfx { namespace mtl typedef void (*mtlCallback)(void* userData); + MTL_CLASS(BlitCommandEncoder) + void copyFromTexture(id<MTLTexture> _sourceTexture, NSUInteger _sourceSlice, NSUInteger _sourceLevel, MTLOrigin _sourceOrigin, MTLSize _sourceSize, + id<MTLTexture> _destinationTexture, NSUInteger _destinationSlice, NSUInteger _destinationLevel, MTLOrigin _destinationOrigin) + { + [m_obj copyFromTexture:_sourceTexture sourceSlice:_sourceSlice sourceLevel:_sourceLevel sourceOrigin:_sourceOrigin sourceSize:_sourceSize + toTexture:_destinationTexture destinationSlice:_destinationSlice destinationLevel:_destinationLevel destinationOrigin:_destinationOrigin]; + } + + void copyFromBuffer(id<MTLBuffer> _sourceBuffer, NSUInteger _sourceOffset, id<MTLBuffer> _destinationBuffer, + NSUInteger _destinationOffset, NSUInteger _size) + { + [m_obj copyFromBuffer:_sourceBuffer sourceOffset:_sourceOffset toBuffer:_destinationBuffer + destinationOffset:_destinationOffset size:_size]; + } + + void copyFromBuffer(id<MTLBuffer> _sourceBuffer, NSUInteger _sourceOffset, NSUInteger _sourceBytesPerRow, + NSUInteger _sourceBytesPerImage, MTLSize _sourceSize, id<MTLTexture> _destinationTexture, + NSUInteger _destinationSlice, NSUInteger _destinationLevel, MTLOrigin _destinationOrigin) + { + [m_obj copyFromBuffer:_sourceBuffer sourceOffset:_sourceOffset sourceBytesPerRow:_sourceBytesPerRow + sourceBytesPerImage:_sourceBytesPerImage sourceSize:_sourceSize toTexture:_destinationTexture + destinationSlice:_destinationSlice destinationLevel:_destinationLevel destinationOrigin:_destinationOrigin]; + } + + void endEncoding() + { + [m_obj endEncoding]; + } + MTL_CLASS_END + MTL_CLASS(Buffer) void* contents() { @@ -74,6 +132,11 @@ namespace bgfx { namespace mtl [m_obj commit]; } + void addScheduledHandler(mtlCallback _cb, void* _data) + { + [m_obj addScheduledHandler:^(id <MTLCommandBuffer>){ _cb(_data); }]; + } + void addCompletedHandler(mtlCallback _cb, void* _data) { [m_obj addCompletedHandler:^(id <MTLCommandBuffer>){ _cb(_data); }]; @@ -148,8 +211,14 @@ namespace bgfx { namespace mtl id<MTLLibrary> newLibraryWithSource(const char* _source) { + MTLCompileOptions* options = [MTLCompileOptions new]; + //NOTE: turned of as 'When using the fast variants, math functions execute more quickly, + // but operate over a **LIMITED RANGE** and their behavior when handling NaN values is not defined.' + if (BX_ENABLED(BX_PLATFORM_IOS)) + options.fastMathEnabled = NO; + NSError* error; - id<MTLLibrary> lib = [m_obj newLibraryWithSource:@(_source) options:nil error:&error]; + id<MTLLibrary> lib = [m_obj newLibraryWithSource:@(_source) options:options error:&error]; BX_WARN(NULL == error , "Shader compilation failed: %s" , [error.localizedDescription cStringUsingEncoding:NSASCIIStringEncoding] @@ -229,6 +298,23 @@ namespace bgfx { namespace mtl ); return state; } + + bool supportsTextureSampleCount(int sampleCount) + { + if (BX_ENABLED(BX_PLATFORM_IOS) && !iOSVersionEqualOrGreater("9.0.0") ) + return sampleCount == 1 || sampleCount == 2 || sampleCount == 4; + else + return [m_obj supportsTextureSampleCount:sampleCount]; + } + + bool depth24Stencil8PixelFormatSupported() + { +#if BX_PLATFORM_IOS + return false; +#else + return m_obj.depth24Stencil8PixelFormatSupported; +#endif // BX_PLATFORM_IOS + } MTL_CLASS_END MTL_CLASS(Function) @@ -369,7 +455,7 @@ namespace bgfx { namespace mtl } // Copying Data from a Texture Image - void getBytes(void* _pixelBytes, NSUInteger _bytesPerRow, NSUInteger _bytesPerImage, MTLRegion _region, NSUInteger _mipmapLevel, NSUInteger _slice) + void getBytes(void* _pixelBytes, NSUInteger _bytesPerRow, NSUInteger _bytesPerImage, MTLRegion _region, NSUInteger _mipmapLevel, NSUInteger _slice) const { [m_obj getBytes:_pixelBytes bytesPerRow:_bytesPerRow bytesPerImage:_bytesPerImage fromRegion:_region mipmapLevel:_mipmapLevel slice:_slice]; } @@ -381,12 +467,12 @@ namespace bgfx { namespace mtl } //properties - uint32_t width() + uint32_t width() const { return (uint32_t)m_obj.width; } - uint32_t height() + uint32_t height() const { return (uint32_t)m_obj.height; } @@ -395,6 +481,16 @@ namespace bgfx { namespace mtl { return m_obj.pixelFormat; } + + uint32_t sampleCount() const + { + return (uint32_t)m_obj.sampleCount; + } + + MTLTextureType textureType() const + { + return m_obj.textureType; + } MTL_CLASS_END typedef id<MTLComputePipelineState> ComputePipelineState; @@ -493,14 +589,6 @@ namespace bgfx { namespace mtl _obj = nil; \ BX_MACRO_BLOCK_END -#if BX_PLATFORM_IOS - inline bool OsVersionEqualOrGreater(const char* _version) - { - return ([[[UIDevice currentDevice] systemVersion] compare:@(_version) options:NSNumericSearch] != NSOrderedAscending); - } - //TODO: this could be in bx ? -#endif // - // end of c++ wrapper template <typename Ty> @@ -557,10 +645,12 @@ namespace bgfx { namespace mtl struct BufferMtl { BufferMtl() - : m_buffer(NULL) - , m_flags(BGFX_BUFFER_NONE) + : m_flags(BGFX_BUFFER_NONE) , m_dynamic(false) + , m_bufferIndex(0) { + for (uint32_t ii = 0; ii < MTL_MAX_FRAMES_IN_FLIGHT; ++ii) + m_buffers[ii] = NULL; } void create(uint32_t _size, void* _data, uint16_t _flags, uint16_t _stride = 0, bool _vertex = false); @@ -568,18 +658,22 @@ namespace bgfx { namespace mtl void destroy() { - if (NULL != m_buffer) + for (uint32_t ii = 0; ii < MTL_MAX_FRAMES_IN_FLIGHT; ++ii) { - [m_buffer release]; - m_buffer = NULL; - m_dynamic = false; + MTL_RELEASE(m_buffers[ii]); } + m_dynamic = false; } - Buffer m_buffer; + Buffer getBuffer() const { return m_buffers[m_bufferIndex]; } + uint32_t m_size; uint16_t m_flags; + bool m_dynamic; + private: + uint8_t m_bufferIndex; + Buffer m_buffers[MTL_MAX_FRAMES_IN_FLIGHT]; }; typedef BufferMtl IndexBufferMtl; @@ -625,6 +719,8 @@ namespace bgfx { namespace mtl , m_vshConstantBufferAlignmentMask(0) , m_fshConstantBufferSize(0) , m_fshConstantBufferAlignmentMask(0) + , m_usedVertexSamplerStages(0) + , m_usedFragmentSamplerStages(0) , m_numPredefined(0) , m_processedUniforms(false) { @@ -650,6 +746,8 @@ namespace bgfx { namespace mtl uint32_t m_vshConstantBufferAlignmentMask; uint32_t m_fshConstantBufferSize; uint32_t m_fshConstantBufferAlignmentMask; + uint32_t m_usedVertexSamplerStages; + uint32_t m_usedFragmentSamplerStages; PredefinedUniform m_predefined[PredefinedUniform::Count*2]; uint8_t m_numPredefined; bool m_processedUniforms; @@ -659,9 +757,13 @@ namespace bgfx { namespace mtl { TextureMtl() : m_ptr(NULL) + , m_ptrMSAA(NULL) , m_ptrStencil(NULL) , m_sampler(NULL) , m_flags(0) + , m_width(0) + , m_height(0) + , m_depth(0) , m_numMips(0) { } @@ -673,14 +775,18 @@ namespace bgfx { namespace mtl MTL_RELEASE(m_ptrStencil); } void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem); - void commit(uint8_t _stage, uint32_t _flags = BGFX_TEXTURE_INTERNAL_DEFAULT_SAMPLER); + void commit(uint8_t _stage, bool _vertex, bool _fragment, uint32_t _flags = BGFX_TEXTURE_INTERNAL_DEFAULT_SAMPLER); Texture m_ptr; + Texture m_ptrMSAA; Texture m_ptrStencil; // for emulating packed depth/stencil formats - only for iOS8... SamplerState m_sampler; uint32_t m_flags; uint8_t m_requestedFormat; uint8_t m_textureFormat; + uint32_t m_width; + uint32_t m_height; + uint32_t m_depth; uint8_t m_numMips; }; @@ -711,6 +817,27 @@ namespace bgfx { namespace mtl uint8_t m_num; // number of color handles }; + struct TimerQueryMtl + { + TimerQueryMtl() + : m_control(4) + { + } + + void init(); + void shutdown(); + void addHandlers(CommandBuffer& _commandBuffer); + bool get(); + + uint64_t m_begin; + uint64_t m_end; + uint64_t m_elapsed; + uint64_t m_frequency; + + uint64_t m_result[4*2]; + bx::RingBufferControl m_control; + }; + struct OcclusionQueryMTL { OcclusionQueryMTL() diff --git a/3rdparty/bgfx/src/renderer_mtl.mm b/3rdparty/bgfx/src/renderer_mtl.mm index 5de80bd577d..b2dcdd36900 100644 --- a/3rdparty/bgfx/src/renderer_mtl.mm +++ b/3rdparty/bgfx/src/renderer_mtl.mm @@ -1,5 +1,5 @@ /* - * Copyright 2011-2015 Attila Kocsis. All rights reserved. + * Copyright 2011-2016 Attila Kocsis. All rights reserved. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause */ @@ -17,36 +17,57 @@ #import <Foundation/Foundation.h> -#define UNIFORM_BUFFER_SIZE (1024*1024) -#define UNIFORM_BUFFER_COUNT (3) +#define UNIFORM_BUFFER_SIZE (8*1024*1024) /* -Known issues / TODOs: -- 15-shadowmaps-simple (modified shaderc and example needs modification too, mtxCrop znew = z * 0.5 + 0.5 is not needed ) could be hacked in shader too -- 19-oit ( hacked shaderc to support MRT output) -- 21-deferred ( hacked shaderc to support MRT output and fs_deferred_light needed modification for metal (similar to BGFX_SHADER_LANGUAGE_HLSL ) - -07-callback, saveScreenshot should be implemented with one frame latency (using saveScreenshotBegin and End) - -16-shadowmaps, //problem with essl -> metal: SAMPLER2D(u_shadowMap0, 4); sampler index is lost. Shadowmap is set to slot 4, but - metal shader uses sampler/texture slot 0. this could require changes outside of renderer_mtl? - Otherwise it works with hacking the slot. - -24-nbody - cannot generate compute shaders for metal - -20-nanonvg - TODO: remove sampler/texture hack - -- caps - -- optimization... - -create binary shader representation - - 13-stencil and 16-shadowmaps are very inefficient. every view stores/loads backbuffer data - - BGFX_RESET_FLIP_AFTER_RENDER on low level renderers should be true? (crashes even with BGFX_RESET_FLIP_AFTER_RENDER because there is - one rendering frame before reset). Do I have absolutely need to send result to View at flip or can I do it in submit? - + // known metal shader generation issues: + 03-raymarch: OSX10.11.3 nothing is visible ( depth/color swap in fragment output struct fixed this ) + 14-shadowvolumes: in texture as stencil mode - columns/bunny are dark. in fs_shadowvolume_color_lighting SAMPLER2D(s_texStencil, 1) is + converted to "texture2d<float> s_texStencil [[texture(0)]], sampler _mtlsmp_s_texStencil [[sampler(0)]]". Slot is 1 -> 0. + 15-shadowmaps-simple: shader compilation error + 16-shadowmaps: //problem with essl -> metal: SAMPLER2D(u_shadowMap0, 4); sampler index is lost. Shadowmap is set to slot 4, but + metal shader uses sampler/texture slot 0. this could require changes outside of renderer_mtl? + packFloatToRGBA needs highp. currently it uses half. + 24-nbody: no generated compute shaders for metal + 27-terrain: shaderc generates invalid metal shader for vs_terrain_height_texture. vertex output: half4 gl_Position [[position]], should be float4 + 31-rsm: + <program source>:6:23: error: type 'half4' (aka 'vector_half4') is not valid for attribute 'position' + half4 gl_Position [[position]]; + + +Known issues(driver problems??): + OSX mac mini(late 2014), OSX10.11.3 : nanovg-rendering: color writemask off causes problem... + 03-raymarch: OSX nothing is visible ( depth/color order should be swapped in fragment output struct) + works fine with newer OSX + iPad mini 2, iOS 8.1.1: 21-deferred: scissor not working properly + 26-occlusion: query doesn't work with two rendercommandencoders + Only on this device ( no problem on iPad Air 2 with iOS9.3.1) + + TODOs: + - remove sync points at mesh update. clearquad: 13-stencil, 26-occlusion, 30-picking + - framebufferMtl and TextureMtl resolve + + - FrameBufferMtl::postReset recreate framebuffer??? + + renderpass load/resolve + - capture with msaa: 07-callback + - implement fb discard. problematic with multiple views that has same fb... + - msaa color/depth/stencil is not saved. could have problem when we switch back to msaa framebuffer + - refactor store/load actions to support msaa/discard/capture/readback etc... + + - finish savescreenshot with screenshotbegin/end + + - support multiple windows: 22-windows + - multithreading with multiple commandbuffer + + - compute and drawindirect: 24-nbody (needs compute shaders) + + INFO: + - 15-shadowmaps-simple (example needs modification mtxCrop znew = z * 0.5 + 0.5 is not needed ) could be hacked in shader too + + ASK: + BGFX_RESET_FLIP_AFTER_RENDER on low level renderers should be true? + Do I have absolutely need to send result to screen at flip or can I do it in submit? */ namespace bgfx { namespace mtl @@ -122,12 +143,12 @@ namespace bgfx { namespace mtl }, //Uint10 - //TODO: normalized only + //Note: unnormalized is handled as normalized now { - { MTLVertexFormatInvalid, MTLVertexFormatUInt1010102Normalized }, - { MTLVertexFormatInvalid, MTLVertexFormatUInt1010102Normalized }, - { MTLVertexFormatInvalid, MTLVertexFormatUInt1010102Normalized }, - { MTLVertexFormatInvalid, MTLVertexFormatUInt1010102Normalized } + { MTLVertexFormatUInt1010102Normalized, MTLVertexFormatUInt1010102Normalized }, + { MTLVertexFormatUInt1010102Normalized, MTLVertexFormatUInt1010102Normalized }, + { MTLVertexFormatUInt1010102Normalized, MTLVertexFormatUInt1010102Normalized }, + { MTLVertexFormatUInt1010102Normalized, MTLVertexFormatUInt1010102Normalized } }, //Int16 @@ -142,8 +163,8 @@ namespace bgfx { namespace mtl { { MTLVertexFormatHalf2, MTLVertexFormatHalf2 }, { MTLVertexFormatHalf2, MTLVertexFormatHalf2 }, - { MTLVertexFormatHalf3, MTLVertexFormatHalf2 }, - { MTLVertexFormatHalf4, MTLVertexFormatHalf2 } + { MTLVertexFormatHalf3, MTLVertexFormatHalf3 }, + { MTLVertexFormatHalf4, MTLVertexFormatHalf4 } }, //Float @@ -193,7 +214,7 @@ namespace bgfx { namespace mtl static const MTLCompareFunction s_cmpFunc[] = { - MTLCompareFunctionAlways, //TODO: depth disable? + MTLCompareFunctionAlways, MTLCompareFunctionLess, MTLCompareFunctionLessEqual, MTLCompareFunctionEqual, @@ -245,81 +266,87 @@ namespace bgfx { namespace mtl static TextureFormatInfo s_textureFormat[] = { - { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // BC1 - { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // BC2 - { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // BC3 - { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // BC4 - { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // BC5 - { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // BC6H - { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // BC7 - { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // ETC1 - { MTLPixelFormat(180) /*ETC2_RGB8*/, MTLPixelFormat(181) /*ETC2_RGB8_sRGB*/ }, // ETC2 - { MTLPixelFormat(178) /*EAC_RGBA8*/, MTLPixelFormat(179) /*EAC_RGBA8_sRGB*/ }, // ETC2A - { MTLPixelFormat(182) /*ETC2_RGB8A1*/, MTLPixelFormat(183) /*ETC2_RGB8A1_sRGB*/ }, // ETC2A1 - { MTLPixelFormat(160) /*PVRTC_RGB_2BPP*/, MTLPixelFormat(161) /*PVRTC_RGB_2BPP_sRGB*/ }, // PTC12 - { MTLPixelFormat(162) /*PVRTC_RGB_4BPP*/, MTLPixelFormat(163) /*PVRTC_RGB_4BPP_sRGB*/ }, // PTC14 - { MTLPixelFormat(164) /*PVRTC_RGBA_2BPP*/, MTLPixelFormat(165) /*PVRTC_RGBA_2BPP_sRGB*/ }, // PTC12A - { MTLPixelFormat(166) /*PVRTC_RGBA_4BPP*/, MTLPixelFormat(167) /*PVRTC_RGBA_4BPP_sRGB*/ }, // PTC14A - { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // PTC22 - { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // PTC24 - { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // Unknown - { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // R1 - { MTLPixelFormatA8Unorm, MTLPixelFormatInvalid }, // A8 - { MTLPixelFormatR8Unorm, MTLPixelFormat(11) /*R8Unorm_sRGB*/ }, // R8 - { MTLPixelFormatR8Sint, MTLPixelFormatInvalid }, // R8I - { MTLPixelFormatR8Uint, MTLPixelFormatInvalid }, // R8U - { MTLPixelFormatR8Snorm, MTLPixelFormatInvalid }, // R8S - { MTLPixelFormatR16Unorm, MTLPixelFormatInvalid }, // R16 - { MTLPixelFormatR16Sint, MTLPixelFormatInvalid }, // R16I - { MTLPixelFormatR16Uint, MTLPixelFormatInvalid }, // R16U - { MTLPixelFormatR16Float, MTLPixelFormatInvalid }, // R16F - { MTLPixelFormatR16Snorm, MTLPixelFormatInvalid }, // R16S - { MTLPixelFormatR32Sint, MTLPixelFormatInvalid }, // R32I - { MTLPixelFormatR32Uint, MTLPixelFormatInvalid }, // R32U - { MTLPixelFormatR32Float, MTLPixelFormatInvalid }, // R32F - { MTLPixelFormatRG8Unorm, MTLPixelFormat(31) /*RG8Unorm_sRGB*/ }, // RG8 - { MTLPixelFormatRG8Sint, MTLPixelFormatInvalid }, // RG8I - { MTLPixelFormatRG8Uint, MTLPixelFormatInvalid }, // RG8U - { MTLPixelFormatRG8Snorm, MTLPixelFormatInvalid }, // RG8S - { MTLPixelFormatRG16Unorm, MTLPixelFormatInvalid }, // RG16 - { MTLPixelFormatRG16Sint, MTLPixelFormatInvalid }, // RG16I - { MTLPixelFormatRG16Uint, MTLPixelFormatInvalid }, // RG16U - { MTLPixelFormatRG16Float, MTLPixelFormatInvalid }, // RG16F - { MTLPixelFormatRG16Snorm, MTLPixelFormatInvalid }, // RG16S - { MTLPixelFormatRG32Sint, MTLPixelFormatInvalid }, // RG32I - { MTLPixelFormatRG32Uint, MTLPixelFormatInvalid }, // RG32U - { MTLPixelFormatRG32Float, MTLPixelFormatInvalid }, // RG32F - { MTLPixelFormatRGB9E5Float, MTLPixelFormatInvalid }, // RGB9E5F - { MTLPixelFormatBGRA8Unorm, MTLPixelFormatBGRA8Unorm_sRGB }, // BGRA8 - { MTLPixelFormatRGBA8Unorm, MTLPixelFormatRGBA8Unorm_sRGB }, // RGBA8 - { MTLPixelFormatRGBA8Sint, MTLPixelFormatInvalid }, // RGBA8I - { MTLPixelFormatRGBA8Uint, MTLPixelFormatInvalid }, // RGBA8U - { MTLPixelFormatRGBA8Snorm, MTLPixelFormatInvalid }, // RGBA8S - { MTLPixelFormatRGBA16Unorm, MTLPixelFormatInvalid }, // RGBA16 - { MTLPixelFormatRGBA16Sint, MTLPixelFormatInvalid }, // RGBA16I - { MTLPixelFormatRGBA16Uint, MTLPixelFormatInvalid }, // RGBA16I - { MTLPixelFormatRGBA16Float, MTLPixelFormatInvalid }, // RGBA16F - { MTLPixelFormatRGBA16Snorm, MTLPixelFormatInvalid }, // RGBA16S - { MTLPixelFormatRGBA32Sint, MTLPixelFormatInvalid }, // RGBA32I - { MTLPixelFormatRGBA32Uint, MTLPixelFormatInvalid }, // RGBA32U - { MTLPixelFormatRGBA32Float, MTLPixelFormatInvalid }, // RGBA32F - { MTLPixelFormat(40) /*B5G6R5Unorm*/, MTLPixelFormatInvalid }, // R5G6B5 - { MTLPixelFormat(42) /*ABGR4Unorm*/, MTLPixelFormatInvalid }, // RGBA4 - { MTLPixelFormat(41) /*A1BGR5Unorm*/, MTLPixelFormatInvalid }, // RGB5A1 - { MTLPixelFormatRGB10A2Unorm, MTLPixelFormatInvalid }, // RGB10A2 - { MTLPixelFormatRG11B10Float, MTLPixelFormatInvalid }, // R11G11B10F - { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // UnknownDepth - { MTLPixelFormatDepth32Float, MTLPixelFormatInvalid }, // D16 - { MTLPixelFormatDepth32Float, MTLPixelFormatInvalid }, // D24 - { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // D24S8 - { MTLPixelFormatDepth32Float, MTLPixelFormatInvalid }, // D32 - { MTLPixelFormatDepth32Float, MTLPixelFormatInvalid }, // D16F - { MTLPixelFormatDepth32Float, MTLPixelFormatInvalid }, // D24F - { MTLPixelFormatDepth32Float, MTLPixelFormatInvalid }, // D32F - { MTLPixelFormatStencil8, MTLPixelFormatInvalid }, // D0S8 + { MTLPixelFormat(130) /*BC1_RGBA*/, MTLPixelFormat(131) /*BC1_RGBA_sRGB*/ }, // BC1 + { MTLPixelFormat(132) /*BC2_RGBA*/, MTLPixelFormat(133) /*BC2_RGBA_sRGB*/ }, // BC2 + { MTLPixelFormat(134) /*BC3_RGBA*/, MTLPixelFormat(135) /*BC3_RGBA_sRGB*/ }, // BC3 + { MTLPixelFormat(140) /*BC4_RUnorm*/, MTLPixelFormatInvalid }, // BC4 + { MTLPixelFormat(142) /*BC5_RGUnorm*/, MTLPixelFormatInvalid }, // BC5 + { MTLPixelFormat(150) /*BC6H_RGBFloat*/, MTLPixelFormatInvalid }, // BC6H + { MTLPixelFormat(152) /*BC7_RGBAUnorm*/, MTLPixelFormat(153) /*BC7_RGBAUnorm_sRGB*/ }, // BC7 + { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // ETC1 + { MTLPixelFormat(180) /*ETC2_RGB8*/, MTLPixelFormat(181) /*ETC2_RGB8_sRGB*/ }, // ETC2 + { MTLPixelFormat(178) /*EAC_RGBA8*/, MTLPixelFormat(179) /*EAC_RGBA8_sRGB*/ }, // ETC2A + { MTLPixelFormat(182) /*ETC2_RGB8A1*/, MTLPixelFormat(183) /*ETC2_RGB8A1_sRGB*/ }, // ETC2A1 + { MTLPixelFormat(160) /*PVRTC_RGB_2BPP*/, MTLPixelFormat(161) /*PVRTC_RGB_2BPP_sRGB*/ }, // PTC12 + { MTLPixelFormat(162) /*PVRTC_RGB_4BPP*/, MTLPixelFormat(163) /*PVRTC_RGB_4BPP_sRGB*/ }, // PTC14 + { MTLPixelFormat(164) /*PVRTC_RGBA_2BPP*/, MTLPixelFormat(165) /*PVRTC_RGBA_2BPP_sRGB*/ }, // PTC12A + { MTLPixelFormat(166) /*PVRTC_RGBA_4BPP*/, MTLPixelFormat(167) /*PVRTC_RGBA_4BPP_sRGB*/ }, // PTC14A + { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // PTC22 + { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // PTC24 + { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // Unknown + { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // R1 + { MTLPixelFormatA8Unorm, MTLPixelFormatInvalid }, // A8 + { MTLPixelFormatR8Unorm, MTLPixelFormat(11) /*R8Unorm_sRGB*/ }, // R8 + { MTLPixelFormatR8Sint, MTLPixelFormatInvalid }, // R8I + { MTLPixelFormatR8Uint, MTLPixelFormatInvalid }, // R8U + { MTLPixelFormatR8Snorm, MTLPixelFormatInvalid }, // R8S + { MTLPixelFormatR16Unorm, MTLPixelFormatInvalid }, // R16 + { MTLPixelFormatR16Sint, MTLPixelFormatInvalid }, // R16I + { MTLPixelFormatR16Uint, MTLPixelFormatInvalid }, // R16U + { MTLPixelFormatR16Float, MTLPixelFormatInvalid }, // R16F + { MTLPixelFormatR16Snorm, MTLPixelFormatInvalid }, // R16S + { MTLPixelFormatR32Sint, MTLPixelFormatInvalid }, // R32I + { MTLPixelFormatR32Uint, MTLPixelFormatInvalid }, // R32U + { MTLPixelFormatR32Float, MTLPixelFormatInvalid }, // R32F + { MTLPixelFormatRG8Unorm, MTLPixelFormat(31) /*RG8Unorm_sRGB*/ }, // RG8 + { MTLPixelFormatRG8Sint, MTLPixelFormatInvalid }, // RG8I + { MTLPixelFormatRG8Uint, MTLPixelFormatInvalid }, // RG8U + { MTLPixelFormatRG8Snorm, MTLPixelFormatInvalid }, // RG8S + { MTLPixelFormatRG16Unorm, MTLPixelFormatInvalid }, // RG16 + { MTLPixelFormatRG16Sint, MTLPixelFormatInvalid }, // RG16I + { MTLPixelFormatRG16Uint, MTLPixelFormatInvalid }, // RG16U + { MTLPixelFormatRG16Float, MTLPixelFormatInvalid }, // RG16F + { MTLPixelFormatRG16Snorm, MTLPixelFormatInvalid }, // RG16S + { MTLPixelFormatRG32Sint, MTLPixelFormatInvalid }, // RG32I + { MTLPixelFormatRG32Uint, MTLPixelFormatInvalid }, // RG32U + { MTLPixelFormatRG32Float, MTLPixelFormatInvalid }, // RG32F + { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // RGB8 + { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // RGB8I + { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // RGB8U + { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // RGB8S + { MTLPixelFormatRGB9E5Float, MTLPixelFormatInvalid }, // RGB9E5F + { MTLPixelFormatBGRA8Unorm, MTLPixelFormatBGRA8Unorm_sRGB }, // BGRA8 + { MTLPixelFormatRGBA8Unorm, MTLPixelFormatRGBA8Unorm_sRGB }, // RGBA8 + { MTLPixelFormatRGBA8Sint, MTLPixelFormatInvalid }, // RGBA8I + { MTLPixelFormatRGBA8Uint, MTLPixelFormatInvalid }, // RGBA8U + { MTLPixelFormatRGBA8Snorm, MTLPixelFormatInvalid }, // RGBA8S + { MTLPixelFormatRGBA16Unorm, MTLPixelFormatInvalid }, // RGBA16 + { MTLPixelFormatRGBA16Sint, MTLPixelFormatInvalid }, // RGBA16I + { MTLPixelFormatRGBA16Uint, MTLPixelFormatInvalid }, // RGBA16U + { MTLPixelFormatRGBA16Float, MTLPixelFormatInvalid }, // RGBA16F + { MTLPixelFormatRGBA16Snorm, MTLPixelFormatInvalid }, // RGBA16S + { MTLPixelFormatRGBA32Sint, MTLPixelFormatInvalid }, // RGBA32I + { MTLPixelFormatRGBA32Uint, MTLPixelFormatInvalid }, // RGBA32U + { MTLPixelFormatRGBA32Float, MTLPixelFormatInvalid }, // RGBA32F + { MTLPixelFormat(40) /*B5G6R5Unorm*/, MTLPixelFormatInvalid }, // R5G6B5 + { MTLPixelFormat(42) /*ABGR4Unorm*/, MTLPixelFormatInvalid }, // RGBA4 + { MTLPixelFormat(41) /*A1BGR5Unorm*/, MTLPixelFormatInvalid }, // RGB5A1 + { MTLPixelFormatRGB10A2Unorm, MTLPixelFormatInvalid }, // RGB10A2 + { MTLPixelFormatRG11B10Float, MTLPixelFormatInvalid }, // R11G11B10F + { MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // UnknownDepth + { MTLPixelFormatDepth32Float, MTLPixelFormatInvalid }, // D16 + { MTLPixelFormatDepth32Float, MTLPixelFormatInvalid }, // D24 + { MTLPixelFormat(255) /*Depth24Unorm_Stencil8*/,MTLPixelFormatInvalid }, // D24S8 + { MTLPixelFormatDepth32Float, MTLPixelFormatInvalid }, // D32 + { MTLPixelFormatDepth32Float, MTLPixelFormatInvalid }, // D16F + { MTLPixelFormatDepth32Float, MTLPixelFormatInvalid }, // D24F + { MTLPixelFormatDepth32Float, MTLPixelFormatInvalid }, // D32F + { MTLPixelFormatStencil8, MTLPixelFormatInvalid }, // D0S8 }; BX_STATIC_ASSERT(TextureFormat::Count == BX_COUNTOF(s_textureFormat) ); + int s_msaa[5] = { 1,2,4,8,16 }; + #define SHADER_FUNCTION_NAME ("xlatMtlMain") #define SHADER_UNIFORM_NAME ("_mtl_u") @@ -329,10 +356,13 @@ namespace bgfx { namespace mtl : m_metalLayer(NULL) , m_backBufferPixelFormatHash(0) , m_maxAnisotropy(1) - , m_uniformBufferIndex(0) + , m_bufferIndex(0) , m_numWindows(1) , m_rtMsaa(false) + , m_capture(NULL) + , m_captureSize(0) , m_drawable(NULL) + , m_saveScreenshot(false) { } @@ -400,52 +430,107 @@ namespace bgfx { namespace mtl m_textureDescriptor = newTextureDescriptor(); m_samplerDescriptor = newSamplerDescriptor(); - for (uint8_t i=0; i < UNIFORM_BUFFER_COUNT; ++i) + m_framesSemaphore.post(MTL_MAX_FRAMES_IN_FLIGHT); + for (uint8_t i=0; i < MTL_MAX_FRAMES_IN_FLIGHT; ++i) { m_uniformBuffers[i] = m_device.newBufferWithLength(UNIFORM_BUFFER_SIZE, 0); } m_uniformBufferVertexOffset = 0; m_uniformBufferFragmentOffset = 0; + const char* vshSource = + "using namespace metal;\n" + "struct xlatMtlShaderOutput { float4 gl_Position [[position]]; float2 v_texcoord0; }; \n" + "vertex xlatMtlShaderOutput xlatMtlMain (uint v_id [[ vertex_id ]]) \n" + "{\n" + " xlatMtlShaderOutput _mtl_o;\n" + " if (v_id==0) { _mtl_o.gl_Position = float4(-1.0,-1.0,0.0,1.0); _mtl_o.v_texcoord0 = float2(0.0,1.0); } \n" + " else if (v_id==1) { _mtl_o.gl_Position = float4(3.0,-1.0,0.0,1.0); _mtl_o.v_texcoord0 = float2(2.0,1.0); } \n" + " else { _mtl_o.gl_Position = float4(-1.0,3.0,0.0,1.0); _mtl_o.v_texcoord0 = float2(0.0,-1.0); }\n" + " return _mtl_o;\n" + "}\n"; + + const char* fshSource = "using namespace metal; \n" + " struct xlatMtlShaderInput { float2 v_texcoord0; }; \n" + " fragment half4 xlatMtlMain (xlatMtlShaderInput _mtl_i[[stage_in]], texture2d<float> s_texColor [[texture(0)]], sampler _mtlsmp_s_texColor [[sampler(0)]] ) \n" + " { return half4(s_texColor.sample(_mtlsmp_s_texColor, _mtl_i.v_texcoord0)); } \n"; + + Library lib = m_device.newLibraryWithSource(vshSource); + if (NULL != lib) + { + m_screenshotBlitProgramVsh.m_function = lib.newFunctionWithName(SHADER_FUNCTION_NAME); + } + lib = m_device.newLibraryWithSource(fshSource); + if (NULL != lib) + { + m_screenshotBlitProgramFsh.m_function = lib.newFunctionWithName(SHADER_FUNCTION_NAME); + } + m_screenshotBlitProgram.create(&m_screenshotBlitProgramVsh, &m_screenshotBlitProgramFsh); + + reset(m_renderPipelineDescriptor); + m_renderPipelineDescriptor.colorAttachments[0].pixelFormat = m_metalLayer.pixelFormat; + m_renderPipelineDescriptor.vertexFunction = m_screenshotBlitProgram.m_vsh->m_function; + m_renderPipelineDescriptor.fragmentFunction = m_screenshotBlitProgram.m_fsh->m_function; + m_screenshotBlitRenderPipelineState = m_device.newRenderPipelineStateWithDescriptor(m_renderPipelineDescriptor); + g_caps.supported |= (0 + | BGFX_CAPS_TEXTURE_COMPARE_LEQUAL //NOTE: on IOS Gpu Family 1/2 have to set compare in shader + | BGFX_CAPS_TEXTURE_COMPARE_ALL | BGFX_CAPS_TEXTURE_3D - | BGFX_CAPS_TEXTURE_COMPARE_LEQUAL - | BGFX_CAPS_INSTANCING | BGFX_CAPS_VERTEX_ATTRIB_HALF -// | BGFX_CAPS_FRAGMENT_DEPTH + | BGFX_CAPS_VERTEX_ATTRIB_UINT10 + | BGFX_CAPS_INSTANCING + | BGFX_CAPS_FRAGMENT_DEPTH | BGFX_CAPS_BLEND_INDEPENDENT - | BGFX_CAPS_COMPUTE + //| BGFX_CAPS_COMPUTE // TODO: api/hw supports it but metal compute shaders are not yet supported | BGFX_CAPS_INDEX32 - | BGFX_CAPS_DRAW_INDIRECT -// | BGFX_CAPS_TEXTURE_BLIT -// | BGFX_CAPS_TEXTURE_READ_BACK - | BGFX_CAPS_OCCLUSION_QUERY + //| BGFX_CAPS_DRAW_INDIRECT // TODO: support on iOS9+gpu family3+ and on macOS + | BGFX_CAPS_TEXTURE_BLIT + | BGFX_CAPS_TEXTURE_READ_BACK + | BGFX_CAPS_OCCLUSION_QUERY + | BGFX_CAPS_ALPHA_TO_COVERAGE ); - g_caps.maxTextureSize = 2048; //ASK: real caps width/height: 4096, but max depth(3D) size is only: 2048 - g_caps.maxFBAttachments = 4; // uint8_t(bx::uint32_min(m_device.supportsFeatureSet(MTLFeatureSet_iOS_GPUFamily2_v1) ? 8 : 4, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS)); + if (BX_ENABLED(BX_PLATFORM_IOS) ) + { + if ( iOSVersionEqualOrGreater("9.0.0") ) + { + g_caps.maxTextureSize = m_device.supportsFeatureSet((MTLFeatureSet)4 /* iOS_GPUFamily3_v1 */) ? 16384 : 8192; + } + else + { + g_caps.maxTextureSize = 4096; + } + g_caps.maxFBAttachments = uint8_t(bx::uint32_min(m_device.supportsFeatureSet((MTLFeatureSet)1 /* MTLFeatureSet_iOS_GPUFamily2_v1 */) ? 8 : 4, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS)); + + } else if (BX_ENABLED(BX_PLATFORM_OSX) ) + { + g_caps.maxTextureSize = 16384; + g_caps.maxFBAttachments = 8; + } //todo: vendor id, device id, gpu enum - //todo: texture format caps - //add texture formats/caps/etc that are available only on new sdk/devices -#if BX_PLATFORM_IOS -# ifdef __IPHONE_8_0 - if (OsVersionEqualOrGreater("8.0.0")) + m_hasPixelFormatDepth32Float_Stencil8 = (BX_ENABLED(BX_PLATFORM_OSX) || + ( BX_ENABLED(BX_PLATFORM_IOS) && iOSVersionEqualOrGreater("9.0.0") ) ); + m_macOS11Runtime = (BX_ENABLED(BX_PLATFORM_OSX) && macOSVersionEqualOrGreater(10,11,0) ); + m_iOS9Runtime = (BX_ENABLED(BX_PLATFORM_IOS) && iOSVersionEqualOrGreater("9.0.0") ); + + if (BX_ENABLED(BX_PLATFORM_OSX) ) { - s_textureFormat[TextureFormat::D24S8].m_fmt = MTLPixelFormatDepth32Float; + s_textureFormat[TextureFormat::R8].m_fmtSrgb = MTLPixelFormatInvalid; + s_textureFormat[TextureFormat::RG8].m_fmtSrgb = MTLPixelFormatInvalid; } -# endif // __IPHONE_8_0 -#endif // BX_PLATFORM_* for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii) { - uint8_t support = 0; + uint16_t support = 0; support |= MTLPixelFormatInvalid != s_textureFormat[ii].m_fmt ? BGFX_CAPS_FORMAT_TEXTURE_2D | BGFX_CAPS_FORMAT_TEXTURE_3D | BGFX_CAPS_FORMAT_TEXTURE_CUBE + | BGFX_CAPS_FORMAT_TEXTURE_VERTEX : BGFX_CAPS_FORMAT_TEXTURE_NONE ; @@ -453,20 +538,51 @@ namespace bgfx { namespace mtl ? BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB | BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB | BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB + | BGFX_CAPS_FORMAT_TEXTURE_VERTEX : BGFX_CAPS_FORMAT_TEXTURE_NONE ; + if (!isCompressed((TextureFormat::Enum)(ii))) + { + support |= BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER + | BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA; + } + //TODO: additional caps flags -// support |= BGFX_CAPS_FORMAT_TEXTURE_VERTEX : BGFX_CAPS_FORMAT_TEXTURE_NONE; // support |= BGFX_CAPS_FORMAT_TEXTURE_IMAGE : BGFX_CAPS_FORMAT_TEXTURE_NONE; -// support |= BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER : BGFX_CAPS_FORMAT_TEXTURE_NONE; g_caps.formats[ii] = support; } + g_caps.formats[TextureFormat::A8] &= ~(BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER | BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA); + g_caps.formats[TextureFormat::RG32I] &= ~(BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA); + g_caps.formats[TextureFormat::RG32U] &= ~(BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA); + g_caps.formats[TextureFormat::RGBA32I] &= ~(BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA); + g_caps.formats[TextureFormat::RGBA32U] &= ~(BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA); + + + if (BX_ENABLED(BX_PLATFORM_IOS) ) + { + s_textureFormat[TextureFormat::D24S8].m_fmt = MTLPixelFormatDepth32Float; + + g_caps.formats[TextureFormat::BC1] = + g_caps.formats[TextureFormat::BC2] = + g_caps.formats[TextureFormat::BC3] = + g_caps.formats[TextureFormat::BC4] = + g_caps.formats[TextureFormat::BC5] = + g_caps.formats[TextureFormat::BC6H] = + g_caps.formats[TextureFormat::BC7] = BGFX_CAPS_FORMAT_TEXTURE_NONE; + + g_caps.formats[TextureFormat::RG32F] &= ~(BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA); + g_caps.formats[TextureFormat::RGBA32F] &= ~(BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA); + } + if (BX_ENABLED(BX_PLATFORM_OSX) ) { - g_caps.formats[TextureFormat::ETC1 ] = + s_textureFormat[TextureFormat::D24S8].m_fmt = (MTLPixelFormat)(m_device.depth24Stencil8PixelFormatSupported() ? + 255 /* Depth24Unorm_Stencil8 */ : + MTLPixelFormatDepth32Float_Stencil8); + g_caps.formats[TextureFormat::ETC2 ] = g_caps.formats[TextureFormat::ETC2A ] = g_caps.formats[TextureFormat::ETC2A1] = @@ -474,8 +590,11 @@ namespace bgfx { namespace mtl g_caps.formats[TextureFormat::PTC14 ] = g_caps.formats[TextureFormat::PTC12A] = g_caps.formats[TextureFormat::PTC14A] = - g_caps.formats[TextureFormat::PTC22 ] = - g_caps.formats[TextureFormat::PTC24 ] = BGFX_CAPS_FORMAT_TEXTURE_NONE; + g_caps.formats[TextureFormat::R5G6B5] = + g_caps.formats[TextureFormat::RGBA4 ] = + g_caps.formats[TextureFormat::RGB5A1] = BGFX_CAPS_FORMAT_TEXTURE_NONE; + + g_caps.formats[TextureFormat::RGB9E5F] &= ~(BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER | BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA); } for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii) @@ -487,6 +606,15 @@ namespace bgfx { namespace mtl } } + for(uint32_t ii=1; ii<5; ++ii) + { + if (!m_device.supportsTextureSampleCount(s_msaa[ii])) + { + s_msaa[ii] = s_msaa[ii-1]; + } + } + + // Init reserved part of view name. for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii) { @@ -494,6 +622,7 @@ namespace bgfx { namespace mtl } m_occlusionQuery.preReset(); + m_gpuTimer.init(); g_internalData.context = m_device; return true; @@ -502,6 +631,7 @@ namespace bgfx { namespace mtl void shutdown() { m_occlusionQuery.postReset(); + m_gpuTimer.shutdown(); for (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii) { @@ -513,6 +643,8 @@ namespace bgfx { namespace mtl m_textures[ii].destroy(); } + captureFinish(); + MTL_RELEASE(m_depthStencilDescriptor); MTL_RELEASE(m_frontFaceStencilDescriptor); MTL_RELEASE(m_backFaceStencilDescriptor); @@ -527,7 +659,7 @@ namespace bgfx { namespace mtl MTL_RELEASE(m_backBufferStencil); } - for (uint8_t i=0; i < UNIFORM_BUFFER_COUNT; ++i) + for (uint8_t i=0; i < MTL_MAX_FRAMES_IN_FLIGHT; ++i) { MTL_RELEASE(m_uniformBuffers[i]); } @@ -645,11 +777,27 @@ namespace bgfx { namespace mtl { } - void readTexture(TextureHandle /*_handle*/, void* /*_data*/) BX_OVERRIDE + void readTexture(TextureHandle _handle, void* _data) BX_OVERRIDE { + m_commandBuffer.commit(); + m_commandBuffer.waitUntilCompleted(); + MTL_RELEASE(m_commandBuffer) + + const TextureMtl& texture = m_textures[_handle.idx]; + + uint32_t width = texture.m_ptr.width(); + uint32_t height = texture.m_ptr.height(); + const uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(texture.m_textureFormat) ); + + MTLRegion region = { { 0, 0, 0 }, { width, height, 1 } }; + + texture.m_ptr.getBytes(_data, width*bpp/8, 0, region, 0, 0); + + m_commandBuffer = m_commandQueue.commandBuffer(); + retain(m_commandBuffer); //NOTE: keep alive to be useable at 'flip' } - void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) BX_OVERRIDE + void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips) BX_OVERRIDE { TextureMtl& texture = m_textures[_handle.idx]; @@ -665,7 +813,7 @@ namespace bgfx { namespace mtl tc.m_height = _height; tc.m_sides = 0; tc.m_depth = 0; - tc.m_numMips = 1; + tc.m_numMips = _numMips; tc.m_format = TextureFormat::Enum(texture.m_requestedFormat); tc.m_cubeMap = false; tc.m_mem = NULL; @@ -740,30 +888,35 @@ namespace bgfx { namespace mtl m_uniforms[_handle.idx] = NULL; } + //cmdPre + void saveScreenShotPre(const char* _filePath) BX_OVERRIDE + { + BX_UNUSED(_filePath); + m_saveScreenshot = true; + } + + //cmdPost void saveScreenShot(const char* _filePath) BX_OVERRIDE { - if (NULL == m_drawable - || NULL == m_drawable.texture) - { + if (NULL == m_screenshotTarget) return; - } - //TODO: we should wait for completion of pending commandBuffers - //TODO: implement this with saveScreenshotBegin/End + m_commandBuffer.commit(); + m_commandBuffer.waitUntilCompleted(); + MTL_RELEASE(m_commandBuffer) - Texture backBuffer = m_drawable.texture; - uint32_t width = backBuffer.width(); - uint32_t height = backBuffer.height(); + uint32_t width = m_screenshotTarget.width(); + uint32_t height = m_screenshotTarget.height(); uint32_t length = width*height*4; uint8_t* data = (uint8_t*)BX_ALLOC(g_allocator, length); MTLRegion region = { { 0, 0, 0 }, { width, height, 1 } }; - backBuffer.getBytes(data, 4*width, 0, region, 0, 0); + m_screenshotTarget.getBytes(data, 4*width, 0, region, 0, 0); g_callback->screenShot(_filePath - , backBuffer.width() - , backBuffer.height() + , m_screenshotTarget.width() + , m_screenshotTarget.height() , width*4 , data , length @@ -771,6 +924,9 @@ namespace bgfx { namespace mtl ); BX_FREE(g_allocator, data); + + m_commandBuffer = m_commandQueue.commandBuffer(); + retain(m_commandBuffer); //NOTE: keep alive to be useable at 'flip' } void updateViewName(uint8_t _id, const char* _name) BX_OVERRIDE @@ -812,8 +968,25 @@ namespace bgfx { namespace mtl //} FrameBufferHandle fbh = BGFX_INVALID_HANDLE; - //TODO: change to default framebuffer - we need a new encoder for this! - //setFrameBuffer(fbh, false); + + if ( NULL == rce || m_renderCommandEncoderFrameBufferHandle.idx != invalidHandle ) + { + if ( m_renderCommandEncoder ) + m_renderCommandEncoder.endEncoding(); + + RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor(); + + setFrameBuffer(renderPassDescriptor, fbh); + + renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionLoad; + renderPassDescriptor.colorAttachments[0].storeAction = NULL != renderPassDescriptor.colorAttachments[0].resolveTexture ? + MTLStoreActionMultisampleResolve : MTLStoreActionStore; + + rce = m_commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor); + m_renderCommandEncoder = rce; + m_renderCommandEncoderFrameBufferHandle = fbh; + MTL_RELEASE(renderPassDescriptor); + } MTLViewport viewport = { 0.0f, 0.0f, (float)width, (float)height, 0.0f, 1.0f}; rce.setViewport(viewport); @@ -849,9 +1022,6 @@ namespace bgfx { namespace mtl rce.setFragmentBuffer(m_uniformBuffer, m_uniformBufferFragmentOffset, 0); } - VertexBufferMtl& vb = m_vertexBuffers[_blitter.m_vb->handle.idx]; - rce.setVertexBuffer(vb.m_buffer, 0, 1); - float proj[16]; bx::mtxOrtho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f); @@ -859,7 +1029,7 @@ namespace bgfx { namespace mtl uint8_t flags = predefined.m_type; setShaderUniform(flags, predefined.m_loc, proj, 4); - m_textures[_blitter.m_texture.idx].commit(0); + m_textures[_blitter.m_texture.idx].commit(0, false, true); } void blitRender(TextVideoMemBlitter& _blitter, uint32_t _numIndices) BX_OVERRIDE @@ -867,30 +1037,44 @@ namespace bgfx { namespace mtl const uint32_t numVertices = _numIndices*4/6; if (0 < numVertices) { - m_indexBuffers [_blitter.m_ib->handle.idx].update(0, _numIndices*2, _blitter.m_ib->data); + m_indexBuffers [_blitter.m_ib->handle.idx].update(0, _numIndices*2, _blitter.m_ib->data, true); m_vertexBuffers[_blitter.m_vb->handle.idx].update(0, numVertices*_blitter.m_decl.m_stride, _blitter.m_vb->data, true); - m_renderCommandEncoder.drawIndexedPrimitives(MTLPrimitiveTypeTriangle, _numIndices, MTLIndexTypeUInt16, m_indexBuffers[_blitter.m_ib->handle.idx].m_buffer, 0, 1); + VertexBufferMtl& vb = m_vertexBuffers[_blitter.m_vb->handle.idx]; + m_renderCommandEncoder.setVertexBuffer(vb.getBuffer(), 0, 1); + + m_renderCommandEncoder.drawIndexedPrimitives(MTLPrimitiveTypeTriangle, _numIndices, MTLIndexTypeUInt16, m_indexBuffers[_blitter.m_ib->handle.idx].getBuffer(), 0, 1); } } + static void commandBufferFinishedCallback(void* _data) + { + RendererContextMtl* renderer = (RendererContextMtl*)_data; + if ( renderer ) + renderer->m_framesSemaphore.post(); + } + void flip(HMD& /*_hmd*/) BX_OVERRIDE { - if (NULL == m_drawable - || NULL == m_commandBuffer) + if (NULL == m_commandBuffer) { return; } // Present and commit the command buffer - m_commandBuffer.presentDrawable(m_drawable); - MTL_RELEASE(m_drawable); + if ( NULL != m_drawable) + { + m_commandBuffer.presentDrawable(m_drawable); + MTL_RELEASE(m_drawable); + } + + m_commandBuffer.addCompletedHandler(commandBufferFinishedCallback, this); m_commandBuffer.commit(); - // using heavy syncing now - // TODO: refactor it with double/triple buffering frame data - m_commandBuffer.waitUntilCompleted(); + MTL_RELEASE(m_prevCommandBuffer); + m_prevCommandBuffer = m_commandBuffer; + retain(m_prevCommandBuffer); MTL_RELEASE(m_commandBuffer); @@ -918,55 +1102,83 @@ namespace bgfx { namespace mtl : 1 ; - //TODO: _resolution has wrong dimensions, using m_drawable.texture size now - if (NULL == m_drawable.texture) + //TODO: there should be a way to specify if backbuffer needs stencil/depth. + const uint32_t maskFlags = ~(0 + | BGFX_RESET_HMD_RECENTER + | BGFX_RESET_MAXANISOTROPY + | BGFX_RESET_DEPTH_CLAMP + | BGFX_RESET_SUSPEND + ); + + if (m_resolution.m_width != _resolution.m_width + || m_resolution.m_height != _resolution.m_height + || (m_resolution.m_flags&maskFlags) != (_resolution.m_flags&maskFlags) ) { - return; - } + int sampleCount = s_msaa[(_resolution.m_flags&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT]; - uint32_t width = (uint32_t)m_drawable.texture.width; - uint32_t height = (uint32_t)m_drawable.texture.height; + MTLPixelFormat prevMetalLayerPixelFormat = m_metalLayer.pixelFormat; + + m_metalLayer.drawableSize = CGSizeMake(_resolution.m_width, _resolution.m_height); + m_metalLayer.pixelFormat = (m_resolution.m_flags & BGFX_RESET_SRGB_BACKBUFFER) + ? MTLPixelFormatBGRA8Unorm_sRGB + : MTLPixelFormatBGRA8Unorm + ; - //TODO: there should be a way to specify if backbuffer needs stencil/depth. - //TODO: support msaa - if (NULL == m_backBufferDepth - || width != m_backBufferDepth.width() - || height != m_backBufferDepth.height() - || m_resolution.m_width != _resolution.m_width - || m_resolution.m_height != _resolution.m_height - || m_resolution.m_flags != _resolution.m_flags) - { m_resolution = _resolution; m_resolution.m_flags &= ~BGFX_RESET_INTERNAL_FORCE; - m_textureDescriptor.textureType = MTLTextureType2D; + m_textureDescriptor.textureType = sampleCount > 1 ? MTLTextureType2DMultisample : MTLTextureType2D; - m_textureDescriptor.pixelFormat = MTLPixelFormatDepth32Float_Stencil8; + if (m_hasPixelFormatDepth32Float_Stencil8) + m_textureDescriptor.pixelFormat = MTLPixelFormatDepth32Float_Stencil8; + else + m_textureDescriptor.pixelFormat = MTLPixelFormatDepth32Float; - m_textureDescriptor.width = width; - m_textureDescriptor.height = height; + m_textureDescriptor.width = _resolution.m_width; + m_textureDescriptor.height = _resolution.m_height; m_textureDescriptor.depth = 1; m_textureDescriptor.mipmapLevelCount = 1; - m_textureDescriptor.sampleCount = 1; + m_textureDescriptor.sampleCount = sampleCount; m_textureDescriptor.arrayLength = 1; - m_textureDescriptor.resourceOptions = MTLResourceStorageModePrivate; - m_textureDescriptor.cpuCacheMode = MTLCPUCacheModeDefaultCache; - m_textureDescriptor.storageMode = MTLStorageModePrivate; - m_textureDescriptor.usage = MTLTextureUsageRenderTarget; + if ( m_iOS9Runtime || m_macOS11Runtime ) + { + m_textureDescriptor.cpuCacheMode = MTLCPUCacheModeDefaultCache; + m_textureDescriptor.storageMode = MTLStorageModePrivate; + m_textureDescriptor.usage = MTLTextureUsageRenderTarget; + } if (NULL != m_backBufferDepth) { release(m_backBufferDepth); } m_backBufferDepth = m_device.newTextureWithDescriptor(m_textureDescriptor); - m_backBufferStencil = m_backBufferDepth; + + + if (m_hasPixelFormatDepth32Float_Stencil8) + m_backBufferStencil = m_backBufferDepth; + else + { + m_textureDescriptor.pixelFormat = MTLPixelFormatStencil8; + m_backBufferStencil = m_device.newTextureWithDescriptor(m_textureDescriptor); + } + + if ( sampleCount > 1 ) + { + if (NULL != m_backBufferColorMSAA) + { + release(m_backBufferColorMSAA); + } + m_textureDescriptor.pixelFormat = m_metalLayer.pixelFormat; + m_backBufferColorMSAA = m_device.newTextureWithDescriptor(m_textureDescriptor); + } bx::HashMurmur2A murmur; murmur.begin(); murmur.add(1); - murmur.add((uint32_t)m_drawable.texture.pixelFormat); + murmur.add((uint32_t)m_metalLayer.pixelFormat); murmur.add((uint32_t)m_backBufferDepth.pixelFormat()); murmur.add((uint32_t)m_backBufferStencil.pixelFormat()); + murmur.add((uint32_t)sampleCount); m_backBufferPixelFormatHash = murmur.end(); for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) @@ -974,11 +1186,107 @@ namespace bgfx { namespace mtl m_frameBuffers[ii].postReset(); } - m_textVideoMem.resize(false, width, height); + updateCapture(); + + m_textVideoMem.resize(false, _resolution.m_width, _resolution.m_height); m_textVideoMem.clear(); + + if ( prevMetalLayerPixelFormat != m_metalLayer.pixelFormat) + { + MTL_RELEASE(m_screenshotBlitRenderPipelineState) + reset(m_renderPipelineDescriptor); + m_renderPipelineDescriptor.colorAttachments[0].pixelFormat = m_metalLayer.pixelFormat; + m_renderPipelineDescriptor.vertexFunction = m_screenshotBlitProgram.m_vsh->m_function; + m_renderPipelineDescriptor.fragmentFunction = m_screenshotBlitProgram.m_fsh->m_function; + m_screenshotBlitRenderPipelineState = m_device.newRenderPipelineStateWithDescriptor(m_renderPipelineDescriptor); + } } } + + void updateCapture() + { + if (m_resolution.m_flags&BGFX_RESET_CAPTURE) + { + m_captureSize = m_resolution.m_width*m_resolution.m_height*4; + m_capture = BX_REALLOC(g_allocator, m_capture, m_captureSize); + g_callback->captureBegin(m_resolution.m_width, m_resolution.m_height, m_resolution.m_width*4, TextureFormat::BGRA8, false); + } + else + { + captureFinish(); + } + } + + void capture() + { + if (NULL != m_capture) + { + if (NULL == m_screenshotTarget) + return; + + m_renderCommandEncoder.endEncoding(); + + m_commandBuffer.commit(); + m_commandBuffer.waitUntilCompleted(); + MTL_RELEASE(m_commandBuffer) + + MTLRegion region = { { 0, 0, 0 }, { m_resolution.m_width, m_resolution.m_height, 1 } }; + + //TODO: enable screenshot target when capturing + m_screenshotTarget.getBytes(m_capture, 4*m_resolution.m_width, 0, region, 0, 0); + + m_commandBuffer = m_commandQueue.commandBuffer(); + retain(m_commandBuffer); //NOTE: keep alive to be useable at 'flip' + + if (m_screenshotTarget.pixelFormat() == MTLPixelFormatRGBA8Uint) + { + imageSwizzleBgra8(m_resolution.m_width, m_resolution.m_height, m_resolution.m_width*4, m_capture, m_capture); + } + + g_callback->captureFrame(m_capture, m_captureSize); + + RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor(); + setFrameBuffer(renderPassDescriptor, m_renderCommandEncoderFrameBufferHandle); + + for(uint32_t ii = 0; ii < g_caps.maxFBAttachments; ++ii) + { + MTLRenderPassColorAttachmentDescriptor* desc = renderPassDescriptor.colorAttachments[ii]; + if ( desc.texture != NULL) + desc.loadAction = MTLLoadActionLoad; + } + + RenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.depthAttachment; + if (NULL != depthAttachment.texture) + { + depthAttachment.loadAction = MTLLoadActionLoad; + depthAttachment.storeAction = MTLStoreActionStore; + } + + RenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.stencilAttachment; + if (NULL != stencilAttachment.texture) + { + stencilAttachment.loadAction = MTLLoadActionLoad; + stencilAttachment.storeAction = MTLStoreActionStore; + } + + m_renderCommandEncoder = m_commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor); + MTL_RELEASE(renderPassDescriptor); + } + } + + void captureFinish() + { + if (NULL != m_capture) + { + g_callback->captureEnd(); + BX_FREE(g_allocator, m_capture); + m_capture = NULL; + m_captureSize = 0; + } + } + + void setShaderUniform(uint8_t _flags, uint32_t _loc, const void* _val, uint32_t _numRegs) { uint32_t offset = 0 != (_flags&BGFX_UNIFORM_FRAGMENTBIT) @@ -1081,16 +1389,155 @@ namespace bgfx { namespace mtl } } - void clearQuad(ClearQuad& _clearQuad, const Rect& _rect, const Clear& _clear, const float _palette[][4]) + void clearQuad(ClearQuad& _clearQuad, const Rect& /*_rect*/, const Clear& _clear, const float _palette[][4]) { - BX_UNUSED(_clearQuad, _rect, _clear, _palette); + uint32_t width; + uint32_t height; + + if (isValid(m_fbh) ) + { + const FrameBufferMtl& fb = m_frameBuffers[m_fbh.idx]; + width = fb.m_width; + height = fb.m_height; + } + else + { + width = getBufferWidth(); + height = getBufferHeight(); + } + + + uint64_t state = 0; + state |= _clear.m_flags & BGFX_CLEAR_COLOR ? BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE : 0; + state |= _clear.m_flags & BGFX_CLEAR_DEPTH ? BGFX_STATE_DEPTH_TEST_ALWAYS|BGFX_STATE_DEPTH_WRITE : 0; + + uint64_t stencil = 0; + stencil |= _clear.m_flags & BGFX_CLEAR_STENCIL ? 0 + | BGFX_STENCIL_TEST_ALWAYS + | BGFX_STENCIL_FUNC_REF(_clear.m_stencil) + | BGFX_STENCIL_FUNC_RMASK(0xff) + | BGFX_STENCIL_OP_FAIL_S_REPLACE + | BGFX_STENCIL_OP_FAIL_Z_REPLACE + | BGFX_STENCIL_OP_PASS_Z_REPLACE + : 0 + ; + + setDepthStencilState(state, stencil); + + uint32_t numMrt = 1; + FrameBufferHandle fbh = m_fbh; + if (isValid(fbh) ) + { + const FrameBufferMtl& fb = m_frameBuffers[fbh.idx]; + numMrt = bx::uint32_max(1, fb.m_num); + } + + ProgramMtl& program = m_program[_clearQuad.m_program[numMrt-1].idx]; + m_renderCommandEncoder.setRenderPipelineState(program.getRenderPipelineState(state, 0, fbh, _clearQuad.m_vb->decl, 0)); + + uint32_t fragmentUniformBufferSize = program.m_fshConstantBufferSize; + + m_uniformBufferFragmentOffset = m_uniformBufferVertexOffset; + if (fragmentUniformBufferSize) + { + m_uniformBufferFragmentOffset = BX_ALIGN_MASK(m_uniformBufferFragmentOffset, program.m_fshConstantBufferAlignmentMask); + m_renderCommandEncoder.setFragmentBuffer(m_uniformBuffer, m_uniformBufferFragmentOffset, 0); + } + + if (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags) + { + float mrtClear[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS][4]; + for (uint32_t ii = 0; ii < numMrt; ++ii) + { + uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_COLOR_PALETTE-1, _clear.m_index[ii]); + memcpy(mrtClear[ii], _palette[index], 16); + } + + memcpy((uint8_t*)m_uniformBuffer.contents() + m_uniformBufferFragmentOffset, + mrtClear, + bx::uint32_min(fragmentUniformBufferSize, sizeof(mrtClear))); + } + else + { + float rgba[4] = + { + _clear.m_index[0]*1.0f/255.0f, + _clear.m_index[1]*1.0f/255.0f, + _clear.m_index[2]*1.0f/255.0f, + _clear.m_index[3]*1.0f/255.0f, + }; + + memcpy((uint8_t*)m_uniformBuffer.contents() + m_uniformBufferFragmentOffset, + rgba, + bx::uint32_min(fragmentUniformBufferSize, sizeof(rgba))); + } + + m_uniformBufferFragmentOffset += fragmentUniformBufferSize; + m_uniformBufferVertexOffset = m_uniformBufferFragmentOffset; + + const VertexBufferMtl& vb = m_vertexBuffers[_clearQuad.m_vb->handle.idx]; + const VertexDecl& vertexDecl = m_vertexDecls[_clearQuad.m_vb->decl.idx]; + const uint32_t stride = vertexDecl.m_stride; + const uint32_t offset = 0; + + { + struct Vertex + { + float m_x; + float m_y; + float m_z; + }; + + Vertex* vertex = (Vertex*)_clearQuad.m_vb->data; + BX_CHECK(stride == sizeof(Vertex) + , "Stride/Vertex mismatch (stride %d, sizeof(Vertex) %d)" + , stride + , sizeof(Vertex) + ); + BX_UNUSED(stride); + + const float depth = _clear.m_depth; + + vertex->m_x = -1.0f; + vertex->m_y = -1.0f; + vertex->m_z = depth; + vertex++; + vertex->m_x = 1.0f; + vertex->m_y = -1.0f; + vertex->m_z = depth; + vertex++; + vertex->m_x = -1.0f; + vertex->m_y = 1.0f; + vertex->m_z = depth; + vertex++; + vertex->m_x = 1.0f; + vertex->m_y = 1.0f; + vertex->m_z = depth; + } + + m_vertexBuffers[_clearQuad.m_vb->handle.idx].update(0, 4*_clearQuad.m_decl.m_stride, _clearQuad.m_vb->data); + m_renderCommandEncoder.setCullMode(MTLCullModeNone); + m_renderCommandEncoder.setVertexBuffer(vb.getBuffer(), offset, 1); + m_renderCommandEncoder.drawPrimitives(MTLPrimitiveTypeTriangleStrip, 0, 4, 1); } void setFrameBuffer(RenderPassDescriptor renderPassDescriptor, FrameBufferHandle _fbh, bool _msaa = true) { if (!isValid(_fbh) ) { - renderPassDescriptor.colorAttachments[0].texture = m_drawable.texture; + if ( NULL != m_backBufferColorMSAA ) + { + renderPassDescriptor.colorAttachments[0].texture = m_backBufferColorMSAA; + renderPassDescriptor.colorAttachments[0].resolveTexture = ((NULL != m_screenshotTarget) ? + m_screenshotTarget.m_obj : + currentDrawable().texture); + } + else + { + renderPassDescriptor.colorAttachments[0].texture = ((NULL != m_screenshotTarget) ? + m_screenshotTarget.m_obj : + currentDrawable().texture); + } renderPassDescriptor.depthAttachment.texture = m_backBufferDepth; renderPassDescriptor.stencilAttachment.texture = m_backBufferStencil; } @@ -1101,15 +1548,26 @@ namespace bgfx { namespace mtl for (uint32_t ii = 0; ii < frameBuffer.m_num; ++ii) { const TextureMtl& texture = m_textures[frameBuffer.m_colorHandle[ii].idx]; - renderPassDescriptor.colorAttachments[ii].texture = texture.m_ptr; + renderPassDescriptor.colorAttachments[ii].texture = texture.m_ptrMSAA ? texture.m_ptrMSAA : texture.m_ptr; + renderPassDescriptor.colorAttachments[ii].resolveTexture = texture.m_ptrMSAA ? texture.m_ptr.m_obj : NULL; } if (isValid(frameBuffer.m_depthHandle) ) { const TextureMtl& texture = m_textures[frameBuffer.m_depthHandle.idx]; - renderPassDescriptor.depthAttachment.texture = texture.m_ptr; + renderPassDescriptor.depthAttachment.texture = texture.m_ptrMSAA ? texture.m_ptrMSAA : texture.m_ptr; renderPassDescriptor.stencilAttachment.texture = texture.m_ptrStencil; - //TODO: stencilAttachment should be the same if packed/depth stencil format is used + + if ( texture.m_textureFormat == TextureFormat::D24S8)//TODO: msaa and stencil iOS8 hack + { + if ( texture.m_ptr.pixelFormat() == 255 /* Depth24Unorm_Stencil8 */|| + texture.m_ptr.pixelFormat() == 260 /* Depth32Float_Stencil8 */ ) + { + renderPassDescriptor.stencilAttachment.texture = renderPassDescriptor.depthAttachment.texture; + } + else + renderPassDescriptor.stencilAttachment.texture = texture.m_ptrMSAA ? texture.m_ptrMSAA : texture.m_ptrStencil; + } } } @@ -1203,11 +1661,12 @@ namespace bgfx { namespace mtl m_samplerDescriptor.normalizedCoordinates = TRUE; m_samplerDescriptor.maxAnisotropy = m_maxAnisotropy; - //TODO: I haven't found how to specify this. Comparison function can be specified in shader. - // On OSX this can be specified. There is no support for this on iOS right now. - //const uint32_t cmpFunc = (_flags&BGFX_TEXTURE_COMPARE_MASK)>>BGFX_TEXTURE_COMPARE_SHIFT; - //const uint8_t filter = 0 == cmpFunc ? 0 : D3D11_COMPARISON_FILTERING_BIT; - //m_samplerDescriptor.comparisonFunc = 0 == cmpFunc ? D3D11_COMPARISON_NEVER : s_cmpFunc[cmpFunc]; + //NOTE: Comparison function can be specified in shader on all metal hw. + if ( m_macOS11Runtime || [m_device supportsFeatureSet:(MTLFeatureSet)4/*MTLFeatureSet_iOS_GPUFamily3_v1*/]) + { + const uint32_t cmpFunc = (_flags&BGFX_TEXTURE_COMPARE_MASK)>>BGFX_TEXTURE_COMPARE_SHIFT; + m_samplerDescriptor.compareFunction = 0 == cmpFunc ? MTLCompareFunctionNever : s_cmpFunc[cmpFunc]; + } sampler = m_device.newSamplerStateWithDescriptor(m_samplerDescriptor); m_samplerStateCache.add(_flags, sampler); @@ -1232,21 +1691,68 @@ namespace bgfx { namespace mtl return m_backBufferDepth.height(); } - Device m_device; + void sync() + { + if ( m_prevCommandBuffer ) + m_prevCommandBuffer.waitUntilCompleted(); + } + + BlitCommandEncoder getBlitCommandEncoder() + { + if ( m_blitCommandEncoder == NULL) + { + if ( m_commandBuffer == NULL ) + { + m_commandBuffer = m_commandQueue.commandBuffer(); + retain(m_commandBuffer); + } + + m_blitCommandEncoder = m_commandBuffer.blitCommandEncoder(); + } + + return m_blitCommandEncoder; + } + + id<CAMetalDrawable> currentDrawable() + { + if (m_drawable == nil) + { + m_drawable = m_metalLayer.nextDrawable; +#if BX_PLATFORM_IOS + retain(m_drawable); // keep alive to be useable at 'flip' +#endif + } + + return m_drawable; + } + + + Device m_device; + OcclusionQueryMTL m_occlusionQuery; + TimerQueryMtl m_gpuTimer; + CommandQueue m_commandQueue; CAMetalLayer* m_metalLayer; + Texture m_backBufferColorMSAA; Texture m_backBufferDepth; Texture m_backBufferStencil; uint32_t m_backBufferPixelFormatHash; uint32_t m_maxAnisotropy; - OcclusionQueryMTL m_occlusionQuery; + bool m_iOS9Runtime; + bool m_macOS11Runtime; + bool m_hasPixelFormatDepth32Float_Stencil8; + + + + bx::Semaphore m_framesSemaphore; Buffer m_uniformBuffer; - Buffer m_uniformBuffers[UNIFORM_BUFFER_COUNT]; + Buffer m_uniformBuffers[MTL_MAX_FRAMES_IN_FLIGHT]; uint32_t m_uniformBufferVertexOffset; uint32_t m_uniformBufferFragmentOffset; - uint8_t m_uniformBufferIndex; + + uint8_t m_bufferIndex; uint16_t m_numWindows; FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS]; @@ -1270,6 +1776,8 @@ namespace bgfx { namespace mtl bool m_rtMsaa; Resolution m_resolution; + void* m_capture; + uint32_t m_captureSize; // descriptors RenderPipelineDescriptor m_renderPipelineDescriptor; @@ -1281,9 +1789,19 @@ namespace bgfx { namespace mtl SamplerDescriptor m_samplerDescriptor; // currently active objects data - id <CAMetalDrawable> m_drawable; - CommandBuffer m_commandBuffer; - RenderCommandEncoder m_renderCommandEncoder; + id <CAMetalDrawable> m_drawable; + bool m_saveScreenshot; + Texture m_screenshotTarget; + ShaderMtl m_screenshotBlitProgramVsh; + ShaderMtl m_screenshotBlitProgramFsh; + ProgramMtl m_screenshotBlitProgram; + RenderPipelineState m_screenshotBlitRenderPipelineState; + + CommandBuffer m_commandBuffer; + CommandBuffer m_prevCommandBuffer; + BlitCommandEncoder m_blitCommandEncoder; + RenderCommandEncoder m_renderCommandEncoder; + FrameBufferHandle m_renderCommandEncoderFrameBufferHandle; }; static RendererContextMtl* s_renderMtl; @@ -1330,8 +1848,6 @@ namespace bgfx { namespace mtl break; } - //bool fragment = BGFX_CHUNK_MAGIC_FSH == magic; - uint32_t iohash; bx::read(&reader, iohash); @@ -1371,23 +1887,6 @@ namespace bgfx { namespace mtl const char* code = (const char*)reader.getDataPtr(); bx::skip(&reader, shaderSize+1); - int32_t codeLen = (int32_t)strlen(code); - int32_t tempLen = codeLen + (4<<10); - char* temp = (char*)alloca(tempLen); - bx::StaticMemoryBlockWriter writer(temp, tempLen); - - //TODO: remove this hack. some shaders have problem with half<->float conversion - writeString(&writer - , "#define half float\n" - "#define half2 float2\n" - "#define half3 float3\n" - "#define half4 float4\n" - ); - - bx::write(&writer, code, codeLen); - bx::write(&writer, '\0'); - code = temp; - //TODO: use binary format Library lib = s_renderMtl->m_device.newLibraryWithSource(code); @@ -1506,7 +2005,7 @@ namespace bgfx { namespace mtl RenderPipelineState ProgramMtl::getRenderPipelineState(uint64_t _state, uint32_t _rgba, FrameBufferHandle _fbHandle, VertexDeclHandle _declHandle, uint16_t _numInstanceData) { - _state &= (BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE|BGFX_STATE_BLEND_INDEPENDENT|BGFX_STATE_MSAA); + _state &= (BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE|BGFX_STATE_BLEND_INDEPENDENT|BGFX_STATE_MSAA|BGFX_STATE_BLEND_ALPHA_TO_COVERAGE); bool independentBlendEnable = !!(BGFX_STATE_BLEND_INDEPENDENT & _state); @@ -1532,11 +2031,15 @@ namespace bgfx { namespace mtl { RenderPipelineDescriptor& pd = s_renderMtl->m_renderPipelineDescriptor; reset(pd); + + pd.alphaToCoverageEnabled = !!(BGFX_STATE_BLEND_ALPHA_TO_COVERAGE & _state); + uint32_t frameBufferAttachment = 1; if (!isValid(_fbHandle) ) { - pd.colorAttachments[0].pixelFormat = s_renderMtl->m_drawable.texture.pixelFormat; + pd.sampleCount = NULL != s_renderMtl->m_backBufferColorMSAA ? s_renderMtl->m_backBufferColorMSAA.sampleCount() : 1; + pd.colorAttachments[0].pixelFormat = s_renderMtl->currentDrawable().texture.pixelFormat; pd.depthAttachmentPixelFormat = s_renderMtl->m_backBufferDepth.m_obj.pixelFormat; pd.stencilAttachmentPixelFormat = s_renderMtl->m_backBufferStencil.m_obj.pixelFormat; } @@ -1548,6 +2051,7 @@ namespace bgfx { namespace mtl for (uint32_t ii = 0; ii < frameBuffer.m_num; ++ii) { const TextureMtl& texture = s_renderMtl->m_textures[frameBuffer.m_colorHandle[ii].idx]; + pd.sampleCount = NULL != texture.m_ptrMSAA ? texture.m_ptrMSAA.sampleCount() : 1; pd.colorAttachments[ii].pixelFormat = texture.m_ptr.m_obj.pixelFormat; } @@ -1557,13 +2061,16 @@ namespace bgfx { namespace mtl pd.depthAttachmentPixelFormat = texture.m_ptr.m_obj.pixelFormat; if (NULL != texture.m_ptrStencil) { - pd.stencilAttachmentPixelFormat = MTLPixelFormatInvalid; //texture.m_ptrStencil.m_obj.pixelFormat; + pd.stencilAttachmentPixelFormat = texture.m_ptrStencil.m_obj.pixelFormat; + } + else + { + if ( texture.m_textureFormat == TextureFormat::D24S8) + pd.stencilAttachmentPixelFormat = texture.m_ptr.m_obj.pixelFormat; } - //todo: stencil attachment should be the same as depth for packed depth/stencil } } - // TODO: BGFX_STATE_MSAA using _fbHandle texture msaa values const uint32_t blend = uint32_t( (_state&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT); const uint32_t equation = uint32_t( (_state&BGFX_STATE_BLEND_EQUATION_MASK)>>BGFX_STATE_BLEND_EQUATION_SHIFT); @@ -1649,7 +2156,7 @@ namespace bgfx { namespace mtl BX_TRACE("attrib:%s format: %d offset:%d", s_attribName[attr], (int)vertexDesc.attributes[loc].format, (int)vertexDesc.attributes[loc].offset); } else - { // missing attribute: using dummy attribute with smallest possible size + { // NOTE: missing attribute: using dummy attribute with smallest possible size vertexDesc.attributes[loc].format = MTLVertexFormatUChar2; vertexDesc.attributes[loc].bufferIndex = 1; vertexDesc.attributes[loc].offset = 0; @@ -1778,6 +2285,9 @@ namespace bgfx { namespace mtl } else if (arg.type == MTLArgumentTypeTexture) { + if ( shaderType == 0 ) m_usedVertexSamplerStages |= 1<<arg.index; + else m_usedFragmentSamplerStages |= 1<<arg.index; + BX_TRACE("texture: %s index:%d", utf8String(arg.name), arg.index); } else if (arg.type == MTLArgumentTypeSampler) @@ -1803,20 +2313,23 @@ namespace bgfx { namespace mtl return rps; } + void BufferMtl::create(uint32_t _size, void* _data, uint16_t _flags, uint16_t _stride, bool _vertex) { BX_UNUSED(_stride, _vertex); m_size = _size; m_flags = _flags; + m_dynamic = (NULL == _data); if (NULL == _data) { - m_buffer = s_renderMtl->m_device.newBufferWithLength(_size, 0); + for (uint32_t ii = 0; ii < MTL_MAX_FRAMES_IN_FLIGHT; ++ii) + m_buffers[ii] = s_renderMtl->m_device.newBufferWithLength(_size, 0); } else { - m_buffer = s_renderMtl->m_device.newBufferWithBytes(_data, _size, 0); + m_buffers[0] = s_renderMtl->m_device.newBufferWithBytes(_data, _size, 0); } } @@ -1824,7 +2337,26 @@ namespace bgfx { namespace mtl { BX_UNUSED(_discard); - memcpy( (uint8_t*)m_buffer.contents() + _offset, _data, _size); + //TODO: cannot call this more than once per frame + if ( m_dynamic && _discard ) + { + m_bufferIndex = (m_bufferIndex + 1) % MTL_MAX_FRAMES_IN_FLIGHT; + memcpy( (uint8_t*)getBuffer().contents() + _offset, _data, _size); + } + else if ( NULL != s_renderMtl->m_renderCommandEncoder ) + { // NOTE: cannot blit while rendercommander is active. have to sync. slow. remove these. + // ClearQuad triggers this now + s_renderMtl->sync(); + memcpy( (uint8_t*)getBuffer().contents() + _offset, _data, _size); + } + else + { + BlitCommandEncoder bce = s_renderMtl->getBlitCommandEncoder(); + + Buffer temp = s_renderMtl->m_device.newBufferWithBytes(_data, _size, 0); + bce.copyFromBuffer(temp, 0, getBuffer(), _offset, _size); + release(temp); + } } void VertexBufferMtl::create(uint32_t _size, void* _data, VertexDeclHandle _declHandle, uint16_t _flags) @@ -1854,6 +2386,9 @@ namespace bgfx { namespace mtl const uint32_t textureHeight = bx::uint32_max(blockInfo.blockHeight, imageContainer.m_height>>startLod); m_flags = _flags; + m_width = textureWidth; + m_height = textureHeight; + m_depth = imageContainer.m_depth; m_requestedFormat = uint8_t(imageContainer.m_format); m_textureFormat = uint8_t(getViableTextureFormat(imageContainer) ); const bool convert = m_textureFormat != m_requestedFormat; @@ -1889,11 +2424,11 @@ namespace bgfx { namespace mtl ); const bool writeOnly = 0 != (_flags&BGFX_TEXTURE_RT_WRITE_ONLY); -// const bool computeWrite = 0 != (_flags&BGFX_TEXTURE_COMPUTE_WRITE); -// const bool renderTarget = 0 != (_flags&BGFX_TEXTURE_RT_MASK); + const bool computeWrite = 0 != (_flags&BGFX_TEXTURE_COMPUTE_WRITE); + const bool renderTarget = 0 != (_flags&BGFX_TEXTURE_RT_MASK); const bool srgb = 0 != (_flags&BGFX_TEXTURE_SRGB) || imageContainer.m_srgb; -// const uint32_t msaaQuality = bx::uint32_satsub( (_flags&BGFX_TEXTURE_RT_MSAA_MASK)>>BGFX_TEXTURE_RT_MSAA_SHIFT, 1); -// const DXGI_SAMPLE_DESC& msaa = s_msaa[msaaQuality]; + const uint32_t msaaQuality = bx::uint32_satsub( (_flags&BGFX_TEXTURE_RT_MSAA_MASK)>>BGFX_TEXTURE_RT_MSAA_SHIFT, 1); + int sampleCount = s_msaa[msaaQuality]; MTLPixelFormat format = MTLPixelFormatInvalid; if (srgb) @@ -1916,22 +2451,35 @@ namespace bgfx { namespace mtl desc.height = textureHeight; desc.depth = bx::uint32_max(1,imageContainer.m_depth); desc.mipmapLevelCount = imageContainer.m_numMips; - desc.sampleCount = 1; //TODO: set samplecount - If textureType is not MTLTextureType2DMultisample, the value must be 1. - desc.resourceOptions = MTLResourceStorageModePrivate; - desc.cpuCacheMode = MTLCPUCacheModeDefaultCache; - - desc.storageMode = (MTLStorageMode)(writeOnly - ? 2 /*MTLStorageModePrivate*/ - : 1 /*MTLStorageModeManaged*/ - ); - desc.usage = writeOnly - ? MTLTextureUsageShaderWrite - : MTLTextureUsageShaderRead - ; + desc.sampleCount = 1; - //TODO: set resource flags depending on usage(renderTarget/computeWrite/etc) on iOS9/OSX + if (s_renderMtl->m_iOS9Runtime || s_renderMtl->m_macOS11Runtime) + { + desc.cpuCacheMode = MTLCPUCacheModeDefaultCache; + + desc.storageMode = (MTLStorageMode)(writeOnly||isDepth(TextureFormat::Enum(m_textureFormat)) + ? 2 /*MTLStorageModePrivate*/ + : ((BX_ENABLED(BX_PLATFORM_IOS)) ? 0 /* MTLStorageModeShared */ : 1 /*MTLStorageModeManaged*/) + ); + + desc.usage = MTLTextureUsageShaderRead; + if (computeWrite) + desc.usage |= MTLTextureUsageShaderWrite; + if (renderTarget) + desc.usage |= MTLTextureUsageRenderTarget; + } m_ptr = s_renderMtl->m_device.newTextureWithDescriptor(desc); + + if ( sampleCount > 1) + { + desc.textureType = MTLTextureType2DMultisample; + desc.sampleCount = sampleCount; + if (s_renderMtl->m_iOS9Runtime || s_renderMtl->m_macOS11Runtime) + desc.storageMode = (MTLStorageMode)( 2 /*MTLStorageModePrivate*/); + m_ptrMSAA = s_renderMtl->m_device.newTextureWithDescriptor(desc); + } + if (m_requestedFormat == TextureFormat::D24S8 && desc.pixelFormat == MTLPixelFormatDepth32Float) { @@ -1964,7 +2512,7 @@ namespace bgfx { namespace mtl if (convert) { - imageDecodeToRgba8(temp + imageDecodeToBgra8(temp , mip.m_data , mip.m_width , mip.m_height @@ -2023,12 +2571,6 @@ namespace bgfx { namespace mtl void TextureMtl::update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) { - MTLRegion region = - { - { _rect.m_x, _rect.m_y, _z }, - { _rect.m_width, _rect.m_height, _depth }, - }; - const uint32_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) ); const uint32_t rectpitch = _rect.m_width*bpp/8; const uint32_t srcpitch = UINT16_MAX == _pitch ? rectpitch : _pitch; @@ -2051,7 +2593,38 @@ namespace bgfx { namespace mtl data = temp; } - m_ptr.replaceRegion(region, _mip, _side, data, srcpitch, srcpitch * _rect.m_height); + if ( NULL != s_renderMtl->m_renderCommandEncoder ) + { + s_renderMtl->sync(); + + MTLRegion region = + { + { _rect.m_x, _rect.m_y, _z }, + { _rect.m_width, _rect.m_height, _depth }, + }; + + m_ptr.replaceRegion(region, _mip, _side, data, srcpitch, srcpitch * _rect.m_height); + } + else + { + BlitCommandEncoder bce = s_renderMtl->getBlitCommandEncoder(); + + const uint32_t dstpitch = bx::strideAlign(rectpitch, 64); + + Buffer tempBuffer = s_renderMtl->m_device.newBufferWithLength(dstpitch*_rect.m_height, 0); + + const uint8_t* src = (uint8_t*)data; + uint8_t* dst = (uint8_t*)tempBuffer.contents(); + + for (uint32_t yy = 0; yy < _rect.m_height; ++yy, src += srcpitch, dst += dstpitch) + { + memcpy(dst, src, rectpitch); + } + + bce.copyFromBuffer(tempBuffer, 0, dstpitch, dstpitch * _rect.m_height, MTLSizeMake(_rect.m_width, _rect.m_height, _depth), + m_ptr, _side, _mip, MTLOriginMake(_rect.m_x, _rect.m_y, _z)); + release(tempBuffer); + } if (NULL != temp) { @@ -2059,13 +2632,23 @@ namespace bgfx { namespace mtl } } - void TextureMtl::commit(uint8_t _stage, uint32_t _flags) + void TextureMtl::commit(uint8_t _stage, bool _vertex, bool _fragment, uint32_t _flags) { - //TODO: vertex or fragment stage? - s_renderMtl->m_renderCommandEncoder.setFragmentTexture(m_ptr, _stage); - s_renderMtl->m_renderCommandEncoder.setFragmentSamplerState(0 == (BGFX_TEXTURE_INTERNAL_DEFAULT_SAMPLER & _flags) - ? s_renderMtl->getSamplerState(_flags) - : m_sampler, _stage); + if (_vertex) + { + s_renderMtl->m_renderCommandEncoder.setVertexTexture(m_ptr, _stage); + s_renderMtl->m_renderCommandEncoder.setVertexSamplerState(0 == (BGFX_TEXTURE_INTERNAL_DEFAULT_SAMPLER & _flags) + ? s_renderMtl->getSamplerState(_flags) + : m_sampler, _stage); + } + + if (_fragment) + { + s_renderMtl->m_renderCommandEncoder.setFragmentTexture(m_ptr, _stage); + s_renderMtl->m_renderCommandEncoder.setFragmentSamplerState(0 == (BGFX_TEXTURE_INTERNAL_DEFAULT_SAMPLER & _flags) + ? s_renderMtl->getSamplerState(_flags) + : m_sampler, _stage); + } } void FrameBufferMtl::create(uint8_t _num, const Attachment* _attachment) @@ -2078,7 +2661,6 @@ namespace bgfx { namespace mtl { const TextureMtl& texture = s_renderMtl->m_textures[handle.idx]; - //TODO: separate stencil buffer? or just use packed depth/stencil (which is not available on iOS8) if (isDepth( (TextureFormat::Enum)texture.m_textureFormat) ) { m_depthHandle = handle; @@ -2100,9 +2682,18 @@ namespace bgfx { namespace mtl const TextureMtl& texture = s_renderMtl->m_textures[m_colorHandle[ii].idx]; murmur.add((uint32_t)texture.m_ptr.pixelFormat()); } - const TextureMtl& depthTexture = s_renderMtl->m_textures[m_depthHandle.idx]; - murmur.add((uint32_t)depthTexture.m_ptr.pixelFormat()); - murmur.add((uint32_t)MTLPixelFormatInvalid); //stencil + if (!isValid(m_depthHandle)) + { + murmur.add((uint32_t)MTLPixelFormatInvalid); + murmur.add((uint32_t)MTLPixelFormatInvalid); + } + else + { + const TextureMtl& depthTexture = s_renderMtl->m_textures[m_depthHandle.idx]; + murmur.add((uint32_t)depthTexture.m_ptr.pixelFormat()); + murmur.add((uint32_t)(NULL != depthTexture.m_ptrStencil ? depthTexture.m_ptrStencil.pixelFormat() : MTLPixelFormatInvalid)); + } + murmur.add(1); //SampleCount m_pixelFormatHash = murmur.end(); } @@ -2131,6 +2722,51 @@ namespace bgfx { namespace mtl return denseIdx; } + void TimerQueryMtl::init() + { + m_frequency = bx::getHPFrequency(); + } + + void TimerQueryMtl::shutdown() + { + } + + static void setTimestamp(void* _data) + { + *((int64_t*)_data) = bx::getHPCounter(); + } + + void TimerQueryMtl::addHandlers(CommandBuffer& _commandBuffer) + { + while (0 == m_control.reserve(1) ) + { + m_control.consume(1); + } + + uint32_t offset = m_control.m_current * 2 + 0; + + _commandBuffer.addScheduledHandler(setTimestamp, &m_result[offset]); + _commandBuffer.addCompletedHandler(setTimestamp, &m_result[offset+1]); + m_control.commit(1); + } + + bool TimerQueryMtl::get() + { + if (0 != m_control.available() ) + { + uint32_t offset = m_control.m_read * 2; + m_begin = m_result[offset+0]; + m_end = m_result[offset+1]; + m_elapsed = m_end - m_begin; + + m_control.consume(1); + + return true; + } + + return false; + } + void OcclusionQueryMTL::postReset() { MTL_RELEASE(m_buffer); @@ -2177,42 +2813,82 @@ namespace bgfx { namespace mtl void RendererContextMtl::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) BX_OVERRIDE { - m_commandBuffer = m_commandQueue.commandBuffer(); - retain(m_commandBuffer); // keep alive to be useable at 'flip' + m_framesSemaphore.wait(); + + if ( m_commandBuffer == NULL ) + { + m_commandBuffer = m_commandQueue.commandBuffer(); + retain(m_commandBuffer); // keep alive to be useable at 'flip' + } - //TODO: multithreading with multiple commandbuffer - // is there a FAST way to tell which view is active? + int64_t elapsed = -bx::getHPCounter(); + int64_t captureElapsed = 0; - //TODO: acquire CAMetalDrawable just before we really need it. When we are using an encoder with target metalLayer's texture - m_drawable = m_metalLayer.nextDrawable; -// retain(m_drawable); // keep alive to be useable at 'flip' + m_gpuTimer.addHandlers(m_commandBuffer); - m_uniformBuffer = m_uniformBuffers[m_uniformBufferIndex]; - m_uniformBufferIndex = (m_uniformBufferIndex + 1) % UNIFORM_BUFFER_COUNT; - m_uniformBufferVertexOffset = 0; - m_uniformBufferFragmentOffset = 0; + if ( m_blitCommandEncoder ) + { + m_blitCommandEncoder.endEncoding(); + m_blitCommandEncoder = 0; + } updateResolution(_render->m_resolution); - int64_t elapsed = -bx::getHPCounter(); - int64_t captureElapsed = 0; + if ( m_saveScreenshot || NULL != m_capture ) + { + if ( m_screenshotTarget ) + { + if ( m_screenshotTarget.width() != m_resolution.m_width || + m_screenshotTarget.height() != m_resolution.m_height ) + { + MTL_RELEASE(m_screenshotTarget); + } + } - if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) + if ( NULL == m_screenshotTarget) + { + m_textureDescriptor.textureType = MTLTextureType2D; + m_textureDescriptor.pixelFormat = m_metalLayer.pixelFormat; + m_textureDescriptor.width = m_resolution.m_width; + m_textureDescriptor.height = m_resolution.m_height; + m_textureDescriptor.depth = 1; + m_textureDescriptor.mipmapLevelCount = 1; + m_textureDescriptor.sampleCount = 1; + m_textureDescriptor.arrayLength = 1; + if ( m_iOS9Runtime || m_macOS11Runtime ) + { + m_textureDescriptor.cpuCacheMode = MTLCPUCacheModeDefaultCache; + m_textureDescriptor.storageMode = (MTLStorageMode)(((BX_ENABLED(BX_PLATFORM_IOS)) ? 0 /* MTLStorageModeShared */ : 1 /*MTLStorageModeManaged*/) + ); + m_textureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead; + } + + m_screenshotTarget = m_device.newTextureWithDescriptor(m_textureDescriptor); + } + m_saveScreenshot = false; + } + else { - //TODO - //m_gpuTimer.begin(); + MTL_RELEASE(m_screenshotTarget); } + m_uniformBuffer = m_uniformBuffers[m_bufferIndex]; + m_bufferIndex = (m_bufferIndex + 1) % MTL_MAX_FRAMES_IN_FLIGHT; + m_uniformBufferVertexOffset = 0; + m_uniformBufferFragmentOffset = 0; + + + if (0 < _render->m_iboffset) { TransientIndexBuffer* ib = _render->m_transientIb; - m_indexBuffers[ib->handle.idx].update(0, _render->m_iboffset, ib->data); + m_indexBuffers[ib->handle.idx].update(0, _render->m_iboffset, ib->data, true); } if (0 < _render->m_vboffset) { TransientVertexBuffer* vb = _render->m_transientVb; - m_vertexBuffers[vb->handle.idx].update(0, _render->m_vboffset, vb->data); + m_vertexBuffers[vb->handle.idx].update(0, _render->m_vboffset, vb->data, true); } _render->sort(); @@ -2230,23 +2906,16 @@ namespace bgfx { namespace mtl bool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME); - //TODO: REMOVE THIS - TEMPORARY HACK - m_textureDescriptor.textureType = MTLTextureType2D; - m_textureDescriptor.pixelFormat = MTLPixelFormatRGBA8Unorm; - m_textureDescriptor.width = 4; - m_textureDescriptor.height = 4; - m_textureDescriptor.depth = 1; - m_textureDescriptor.mipmapLevelCount = 1; - m_textureDescriptor.sampleCount = 1; //TODO: set samplecount - If textureType is not MTLTextureType2DMultisample, the value must be 1. - Texture zeroTexture = m_device.newTextureWithDescriptor(m_textureDescriptor); - uint16_t programIdx = invalidHandle; SortKey key; uint16_t view = UINT16_MAX; FrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS }; - //ASK: why should we use this? It changes topology, so possible renders a big mess, doesn't it? - //const uint64_t primType = _render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0; + BlitKey blitKey; + blitKey.decode(_render->m_blitKeys[0]); + uint16_t numBlitItems = _render->m_numBlitItems; + uint16_t blitItem = 0; + const uint64_t primType = 0; uint8_t primIndex = uint8_t(primType>>BGFX_STATE_PT_SHIFT); PrimInfo prim = s_primInfo[primIndex]; @@ -2329,94 +2998,175 @@ namespace bgfx { namespace mtl viewState.m_rect.m_width /= 2; } + + for (; blitItem < numBlitItems && blitKey.m_view <= view; blitItem++) + { + if (0 != m_renderCommandEncoder) + { + m_renderCommandEncoder.endEncoding(); + m_renderCommandEncoder = 0; + } + m_blitCommandEncoder = getBlitCommandEncoder(); + + const BlitItem& blit = _render->m_blitItem[blitItem]; + blitKey.decode(_render->m_blitKeys[blitItem+1]); + + const TextureMtl& src = m_textures[blit.m_src.idx]; + const TextureMtl& dst = m_textures[blit.m_dst.idx]; + + uint32_t srcWidth = bx::uint32_min(src.m_width, blit.m_srcX + blit.m_width) - blit.m_srcX; + uint32_t srcHeight = bx::uint32_min(src.m_height, blit.m_srcY + blit.m_height) - blit.m_srcY; + uint32_t srcDepth = bx::uint32_min(src.m_depth, blit.m_srcZ + blit.m_depth) - blit.m_srcZ; + uint32_t dstWidth = bx::uint32_min(dst.m_width, blit.m_dstX + blit.m_width) - blit.m_dstX; + uint32_t dstHeight = bx::uint32_min(dst.m_height, blit.m_dstY + blit.m_height) - blit.m_dstY; + uint32_t dstDepth = bx::uint32_min(dst.m_depth, blit.m_dstZ + blit.m_depth) - blit.m_dstZ; + uint32_t width = bx::uint32_min(srcWidth, dstWidth); + uint32_t height = bx::uint32_min(srcHeight, dstHeight); + uint32_t depth = bx::uint32_min(srcDepth, dstDepth); + + if ( MTLTextureType3D == src.m_ptr.textureType()) + { + m_blitCommandEncoder.copyFromTexture(src.m_ptr, 0, 0, MTLOriginMake(blit.m_srcX, blit.m_srcY, blit.m_srcZ), MTLSizeMake(width, height, bx::uint32_imax(depth, 1)), + dst.m_ptr, 0, 0, MTLOriginMake(blit.m_dstX, blit.m_dstY, blit.m_dstZ)); + } + else + { + m_blitCommandEncoder.copyFromTexture(src.m_ptr, blit.m_srcZ, blit.m_srcMip, MTLOriginMake(blit.m_srcX, blit.m_srcY, 0), MTLSizeMake(width, height, 1), + dst.m_ptr, blit.m_dstZ, blit.m_dstMip, MTLOriginMake(blit.m_dstX, blit.m_dstY, 0)); + } + } + + if (0 != m_blitCommandEncoder) + { + m_blitCommandEncoder.endEncoding(); + m_blitCommandEncoder = 0; + } + const Rect& scissorRect = _render->m_scissor[view]; viewHasScissor = !scissorRect.isZero(); viewScissorRect = viewHasScissor ? scissorRect : viewState.m_rect; Clear& clr = _render->m_clear[view]; - RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor(); - renderPassDescriptor.visibilityResultBuffer = m_occlusionQuery.m_buffer; - uint32_t width = getBufferWidth(); uint32_t height = getBufferHeight(); Rect viewRect = viewState.m_rect; - bool fullscreenRect = true + bool clearWithRenderPass = true && 0 == viewRect.m_x && 0 == viewRect.m_y && width == viewRect.m_width && height == viewRect.m_height ; - fbh = _render->m_fb[view]; - setFrameBuffer(renderPassDescriptor, fbh); + if ( NULL == m_renderCommandEncoder || fbh.idx != _render->m_fb[view].idx ) + { + if (0 != m_renderCommandEncoder) + { + m_renderCommandEncoder.endEncoding(); + } - RenderPassColorAttachmentDescriptor colorAttachment0 = renderPassDescriptor.colorAttachments[0]; + RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor(); + renderPassDescriptor.visibilityResultBuffer = m_occlusionQuery.m_buffer; - if (0 != (BGFX_CLEAR_COLOR & clr.m_flags) ) - { - if (0 != (BGFX_CLEAR_COLOR_USE_PALETTE & clr.m_flags) ) + fbh = _render->m_fb[view]; + setFrameBuffer(renderPassDescriptor, fbh); + + if ( clearWithRenderPass ) { - uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_COLOR_PALETTE-1, clr.m_index[0]); - const float* rgba = _render->m_colorPalette[index]; - const float rr = rgba[0]; - const float gg = rgba[1]; - const float bb = rgba[2]; - const float aa = rgba[3]; - colorAttachment0.clearColor = MTLClearColorMake(rr, gg, bb, aa); + for(uint32_t ii = 0; ii < g_caps.maxFBAttachments; ++ii) + { + MTLRenderPassColorAttachmentDescriptor* desc = renderPassDescriptor.colorAttachments[ii]; + + if ( desc.texture != NULL) + { + if (0 != (BGFX_CLEAR_COLOR & clr.m_flags) ) + { + if (0 != (BGFX_CLEAR_COLOR_USE_PALETTE & clr.m_flags) ) + { + uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_COLOR_PALETTE-1, clr.m_index[ii]); + const float* rgba = _render->m_colorPalette[index]; + const float rr = rgba[0]; + const float gg = rgba[1]; + const float bb = rgba[2]; + const float aa = rgba[3]; + desc.clearColor = MTLClearColorMake(rr, gg, bb, aa); + } + else + { + float rr = clr.m_index[0]*1.0f/255.0f; + float gg = clr.m_index[1]*1.0f/255.0f; + float bb = clr.m_index[2]*1.0f/255.0f; + float aa = clr.m_index[3]*1.0f/255.0f; + desc.clearColor = MTLClearColorMake(rr, gg, bb, aa); + } + + desc.loadAction = MTLLoadActionClear; + } + else + { + desc.loadAction = MTLLoadActionLoad; + } + desc.storeAction = desc.texture.sampleCount > 1 ? MTLStoreActionMultisampleResolve : MTLStoreActionStore; + } + } + + //TODO: optimize store actions use discard flag + RenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.depthAttachment; + if (NULL != depthAttachment.texture) + { + depthAttachment.clearDepth = clr.m_depth; + depthAttachment.loadAction = 0 != (BGFX_CLEAR_DEPTH & clr.m_flags) + ? MTLLoadActionClear + : MTLLoadActionLoad + ; + depthAttachment.storeAction = NULL != m_backBufferColorMSAA ? MTLStoreActionDontCare : MTLStoreActionStore; + } + + RenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.stencilAttachment; + if (NULL != stencilAttachment.texture) + { + stencilAttachment.clearStencil = clr.m_stencil; + stencilAttachment.loadAction = 0 != (BGFX_CLEAR_STENCIL & clr.m_flags) + ? MTLLoadActionClear + : MTLLoadActionLoad + ; + stencilAttachment.storeAction = NULL != m_backBufferColorMSAA ? MTLStoreActionDontCare : MTLStoreActionStore; + } } else { - float rr = clr.m_index[0]*1.0f/255.0f; - float gg = clr.m_index[1]*1.0f/255.0f; - float bb = clr.m_index[2]*1.0f/255.0f; - float aa = clr.m_index[3]*1.0f/255.0f; - colorAttachment0.clearColor = MTLClearColorMake(rr, gg, bb, aa); - } + for(uint32_t ii = 0; ii < g_caps.maxFBAttachments; ++ii) + { + MTLRenderPassColorAttachmentDescriptor* desc = renderPassDescriptor.colorAttachments[ii]; + if ( desc.texture != NULL) + desc.loadAction = MTLLoadActionLoad; + } - colorAttachment0.loadAction = MTLLoadActionClear; - } - else - { - colorAttachment0.loadAction = MTLLoadActionLoad; - } + //TODO: optimize store actions use discard flag + RenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.depthAttachment; + if (NULL != depthAttachment.texture) + { + depthAttachment.loadAction = MTLLoadActionLoad; + depthAttachment.storeAction = MTLStoreActionStore; + } - //TODO: optimize store actions use discard flag - RenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.depthAttachment; - if (NULL != depthAttachment.texture) - { - depthAttachment.clearDepth = clr.m_depth; - depthAttachment.loadAction = 0 != (BGFX_CLEAR_DEPTH & clr.m_flags) - ? MTLLoadActionClear - : MTLLoadActionLoad - ; - depthAttachment.storeAction = MTLStoreActionStore; - } + RenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.stencilAttachment; + if (NULL != stencilAttachment.texture) + { + stencilAttachment.loadAction = MTLLoadActionLoad; + stencilAttachment.storeAction = MTLStoreActionStore; + } + } - RenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.stencilAttachment; - if (NULL != stencilAttachment.texture) - { - stencilAttachment.clearStencil = clr.m_stencil; - stencilAttachment.loadAction = 0 != (BGFX_CLEAR_STENCIL & clr.m_flags) - ? MTLLoadActionClear - : MTLLoadActionLoad - ; - stencilAttachment.storeAction = MTLStoreActionStore; + rce = m_commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor); + m_renderCommandEncoder = rce; + m_renderCommandEncoderFrameBufferHandle = fbh; + MTL_RELEASE(renderPassDescriptor); } - - if (0 != m_renderCommandEncoder) + else { - m_renderCommandEncoder.endEncoding(); + clearWithRenderPass = false; } - rce = m_commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor); - m_renderCommandEncoder = rce; - MTL_RELEASE(renderPassDescriptor); - - //TODO: REMOVE THIS!!!! - // TERRIBLE HACK TO SUPPRESS DEBUG LAYER WARNING ABOUT MISSING TEXTURE/SAMPLER AT 0 in 20-nanovg - m_renderCommandEncoder.setFragmentTexture(zeroTexture, 0); - m_renderCommandEncoder.setFragmentSamplerState(getSamplerState(0), 0); - rce.setTriangleFillMode(wireframe? MTLTriangleFillModeLines : MTLTriangleFillModeFill); if (BX_ENABLED(BGFX_CONFIG_DEBUG_MTL) ) @@ -2439,7 +3189,7 @@ namespace bgfx { namespace mtl rce.setViewport(vp); if (BGFX_CLEAR_NONE != (clr.m_flags & BGFX_CLEAR_MASK) - && !fullscreenRect) + && !clearWithRenderPass) { clearQuad(_clearQuad, viewState.m_rect, clr, _render->m_colorPalette); } @@ -2527,6 +3277,9 @@ namespace bgfx { namespace mtl rc.y = scissorRect.m_y; rc.width = scissorRect.m_width; rc.height = scissorRect.m_height; + + if ( rc.width == 0 || rc.height == 0 ) + continue; } rce.setScissorRect(rc); } @@ -2541,7 +3294,6 @@ namespace bgfx { namespace mtl | BGFX_STATE_CULL_MASK | BGFX_STATE_ALPHA_REF_MASK | BGFX_STATE_PT_MASK -// | BGFX_STATE_POINT_SIZE_MASK ) & changedFlags) { if (BGFX_STATE_CULL_MASK & changedFlags) @@ -2583,7 +3335,7 @@ namespace bgfx { namespace mtl rendererUpdateUniforms(this, _render->m_uniformBuffer, draw.m_constBegin, draw.m_constEnd); if (key.m_program != programIdx - || (BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE|BGFX_STATE_BLEND_INDEPENDENT|BGFX_STATE_MSAA) & changedFlags + || (BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE|BGFX_STATE_BLEND_INDEPENDENT|BGFX_STATE_MSAA|BGFX_STATE_BLEND_ALPHA_TO_COVERAGE) & changedFlags || currentState.m_vertexBuffer.idx != draw.m_vertexBuffer.idx || currentState.m_vertexDecl.idx != draw.m_vertexDecl.idx || currentState.m_instanceDataStride != draw.m_instanceDataStride @@ -2603,12 +3355,18 @@ namespace bgfx { namespace mtl ProgramMtl& program = m_program[programIdx]; currentProgram = &program; - uint16_t handle = draw.m_vertexBuffer.idx; - const VertexBufferMtl& vb = m_vertexBuffers[handle]; - VertexDeclHandle decl; - decl.idx = !isValid(vb.m_decl) ? draw.m_vertexDecl.idx : vb.m_decl.idx; + RenderPipelineState pipelineState = NULL; + + if ( isValid(draw.m_vertexBuffer) ) + { + uint16_t handle = draw.m_vertexBuffer.idx; + const VertexBufferMtl& vb = m_vertexBuffers[handle]; + VertexDeclHandle decl; + decl.idx = !isValid(vb.m_decl) ? draw.m_vertexDecl.idx : vb.m_decl.idx; + + pipelineState = program.getRenderPipelineState(newFlags, draw.m_rgba, fbh, decl, draw.m_instanceDataStride/16); + } - RenderPipelineState pipelineState = program.getRenderPipelineState(newFlags, draw.m_rgba, fbh, decl, draw.m_instanceDataStride/16); if (NULL == pipelineState ) { //call with invalid program currentProgram = NULL; @@ -2665,6 +3423,16 @@ namespace bgfx { namespace mtl } { + uint32_t usedVertexSamplerStages = 0; + uint32_t usedFragmentSamplerStages = 0; + + if (invalidHandle != programIdx) + { + ProgramMtl& program = m_program[programIdx]; + usedVertexSamplerStages = program.m_usedVertexSamplerStages; + usedFragmentSamplerStages = program.m_usedFragmentSamplerStages; + } + for (uint8_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage) { const Binding& sampler = draw.m_bind[stage]; @@ -2676,7 +3444,9 @@ namespace bgfx { namespace mtl if (invalidHandle != sampler.m_idx) { TextureMtl& texture = m_textures[sampler.m_idx]; - texture.commit(stage, sampler.m_un.m_draw.m_textureFlags); + texture.commit(stage, (usedVertexSamplerStages&(1<<stage))!=0, + (usedFragmentSamplerStages&(1<<stage))!=0, + sampler.m_un.m_draw.m_textureFlags); } } @@ -2703,12 +3473,12 @@ namespace bgfx { namespace mtl const VertexDecl& vertexDecl = m_vertexDecls[decl]; uint32_t offset = draw.m_startVertex * vertexDecl.getStride(); - rce.setVertexBuffer(vb.m_buffer, offset, 1); + rce.setVertexBuffer(vb.getBuffer(), offset, 1); if (isValid(draw.m_instanceDataBuffer) ) { const VertexBufferMtl& inst = m_vertexBuffers[draw.m_instanceDataBuffer.idx]; - rce.setVertexBuffer(inst.m_buffer, draw.m_instanceDataOffset, 2); + rce.setVertexBuffer(inst.getBuffer(), draw.m_instanceDataOffset, 2); } } } @@ -2753,7 +3523,7 @@ namespace bgfx { namespace mtl numInstances = draw.m_numInstances; numPrimsRendered = numPrimsSubmitted*draw.m_numInstances; - rce.drawIndexedPrimitives(prim.m_type, numIndices, indexType, ib.m_buffer, 0, draw.m_numInstances); + rce.drawIndexedPrimitives(prim.m_type, numIndices, indexType, ib.getBuffer(), 0, draw.m_numInstances); } else if (prim.m_min <= draw.m_numIndices) { @@ -2763,7 +3533,7 @@ namespace bgfx { namespace mtl numInstances = draw.m_numInstances; numPrimsRendered = numPrimsSubmitted*draw.m_numInstances; - rce.drawIndexedPrimitives(prim.m_type, numIndices, indexType, ib.m_buffer, draw.m_startIndex * indexSize,numInstances); + rce.drawIndexedPrimitives(prim.m_type, numIndices, indexType, ib.getBuffer(), draw.m_startIndex * indexSize,numInstances); } } else @@ -2797,7 +3567,8 @@ namespace bgfx { namespace mtl if (0 < _render->m_num) { captureElapsed = -bx::getHPCounter(); - //capture(); + capture(); + rce = m_renderCommandEncoder; //TODO: ugly, can create new encoder captureElapsed += bx::getHPCounter(); } } @@ -2814,31 +3585,44 @@ namespace bgfx { namespace mtl elapsed += now; static int64_t last = now; + + Stats& perfStats = _render->m_perfStats; + perfStats.cpuTimeBegin = last; + int64_t frameTime = now - last; last = now; static int64_t min = frameTime; static int64_t max = frameTime; - min = min > frameTime ? frameTime : min; - max = max < frameTime ? frameTime : max; + min = bx::int64_min(min, frameTime); + max = bx::int64_max(max, frameTime); - if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) + static uint32_t maxGpuLatency = 0; + static double maxGpuElapsed = 0.0f; + double elapsedGpuMs = 0.0; + + do { - rce.pushDebugGroup("debugstats"); + double toGpuMs = 1000.0 / double(m_gpuTimer.m_frequency); + elapsedGpuMs = m_gpuTimer.m_elapsed * toGpuMs; + maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed; + } + while (m_gpuTimer.get() ); + + maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.available()-1); + + const int64_t timerFreq = bx::getHPFrequency(); - static uint32_t maxGpuLatency = 0; - static double maxGpuElapsed = 0.0f; -// double elapsedGpuMs = 0.0; + perfStats.cpuTimeEnd = now; + perfStats.cpuTimerFreq = timerFreq; + perfStats.gpuTimeBegin = m_gpuTimer.m_begin; + perfStats.gpuTimeEnd = m_gpuTimer.m_end; + perfStats.gpuTimerFreq = m_gpuTimer.m_frequency; -// m_gpuTimer.end(); -// -// while (m_gpuTimer.get() ) -// { -// double toGpuMs = 1000.0 / double(m_gpuTimer.m_frequency); -// elapsedGpuMs = m_gpuTimer.m_elapsed * toGpuMs; -// maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed; -// } -// maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.available()-1); + rce.setTriangleFillMode(MTLTriangleFillModeFill); + if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) + { + rce.pushDebugGroup("debugstats"); TextVideoMem& tvm = m_textVideoMem; @@ -2916,6 +3700,7 @@ namespace bgfx { namespace mtl } blit(this, _textVideoMemBlitter, tvm); + rce = m_renderCommandEncoder; //TODO: ugly, blit can create encoder rce.popDebugGroup(); } @@ -2924,15 +3709,35 @@ namespace bgfx { namespace mtl rce.pushDebugGroup("debugtext"); blit(this, _textVideoMemBlitter, _render->m_textVideoMem); + rce = m_renderCommandEncoder; //TODO: ugly, blit can create encoder rce.popDebugGroup(); } - //TODO: REMOVE THIS - TEMPORARY HACK - release(zeroTexture); - rce.endEncoding(); m_renderCommandEncoder = 0; + m_renderCommandEncoderFrameBufferHandle.idx = invalidHandle; + + + if ( m_screenshotTarget ) + { + RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor(); + renderPassDescriptor.colorAttachments[0].texture = currentDrawable().texture; + renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; + + rce = m_commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor); + + rce.setCullMode(MTLCullModeNone); + + rce.setRenderPipelineState(m_screenshotBlitRenderPipelineState); + + rce.setFragmentSamplerState(getSamplerState(BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_MIN_POINT|BGFX_TEXTURE_MAG_POINT|BGFX_TEXTURE_MIP_POINT), 0); + rce.setFragmentTexture(m_screenshotTarget, 0); + + rce.drawPrimitives(MTLPrimitiveTypeTriangle, 0, 3, 1); + + rce.endEncoding(); + } } } /* namespace mtl */ } // namespace bgfx diff --git a/3rdparty/bgfx/src/renderer_null.cpp b/3rdparty/bgfx/src/renderer_null.cpp index 9b3de91416b..1dcd621759a 100644 --- a/3rdparty/bgfx/src/renderer_null.cpp +++ b/3rdparty/bgfx/src/renderer_null.cpp @@ -117,7 +117,7 @@ namespace bgfx { namespace noop { } - void resizeTexture(TextureHandle /*_handle*/, uint16_t /*_width*/, uint16_t /*_height*/) BX_OVERRIDE + void resizeTexture(TextureHandle /*_handle*/, uint16_t /*_width*/, uint16_t /*_height*/, uint8_t /*_numMips*/) BX_OVERRIDE { } diff --git a/3rdparty/bgfx/src/topology.cpp b/3rdparty/bgfx/src/topology.cpp index 767e4995772..da4609711f6 100644 --- a/3rdparty/bgfx/src/topology.cpp +++ b/3rdparty/bgfx/src/topology.cpp @@ -3,9 +3,11 @@ * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause */ -#include <bx/debug.h> #include <bx/allocator.h> +#include <bx/debug.h> +#include <bx/fpumath.h> #include <bx/radixsort.h> +#include <bx/uint32_t.h> #include "config.h" #include "topology.h" @@ -165,7 +167,15 @@ namespace bgfx return uint32_t(dst - (IndexT*)_dst); } - uint32_t topologyConvert(TopologyConvert::Enum _conversion, void* _dst, uint32_t _dstSize, const void* _indices, uint32_t _numIndices, bool _index32, bx::AllocatorI* _allocator) + uint32_t topologyConvert( + TopologyConvert::Enum _conversion + , void* _dst + , uint32_t _dstSize + , const void* _indices + , uint32_t _numIndices + , bool _index32 + , bx::AllocatorI* _allocator + ) { switch (_conversion) { @@ -213,4 +223,187 @@ namespace bgfx return 0; } + inline uint32_t floatFlip(uint32_t _value) + { + using namespace bx; + const uint32_t tmp0 = uint32_sra(_value, 31); + const uint32_t tmp1 = uint32_neg(tmp0); + const uint32_t mask = uint32_or(tmp1, 0x80000000); + const uint32_t result = uint32_xor(_value, mask); + return result; + } + + inline float favg3(float _a, float _b, float _c) + { + return (_a + _b + _c) * 1.0f/3.0f; + } + + const float* vertexPos(const void* _vertices, uint32_t _stride, uint32_t _index) + { + const uint8_t* vertices = (const uint8_t*)_vertices; + return (const float*)&vertices[_index*_stride]; + } + + inline float distanceDir(const float* __restrict _dir, const void* __restrict _vertices, uint32_t _stride, uint32_t _index) + { + return bx::vec3Dot(vertexPos(_vertices, _stride, _index), _dir); + } + + inline float distancePos(const float* __restrict _pos, const void* __restrict _vertices, uint32_t _stride, uint32_t _index) + { + float tmp[3]; + bx::vec3Sub(tmp, _pos, vertexPos(_vertices, _stride, _index) ); + return bx::fsqrt(bx::vec3Dot(tmp, tmp) ); + } + + typedef float (*KeyFn)(float, float, float); + typedef float (*DistanceFn)(const float*, const void*, uint32_t, uint32_t); + + template<typename IndexT, DistanceFn dfn, KeyFn kfn, uint32_t xorBits> + inline void calcSortKeys( + uint32_t* __restrict _keys + , uint32_t* __restrict _values + , const float _dirOrPos[3] + , const void* __restrict _vertices + , uint32_t _stride + , const IndexT* _indices + , uint32_t _num + ) + { + for (uint32_t ii = 0; ii < _num; ++ii) + { + const uint32_t idx0 = _indices[0]; + const uint32_t idx1 = _indices[1]; + const uint32_t idx2 = _indices[2]; + _indices += 3; + + float distance0 = dfn(_dirOrPos, _vertices, _stride, idx0); + float distance1 = dfn(_dirOrPos, _vertices, _stride, idx1); + float distance2 = dfn(_dirOrPos, _vertices, _stride, idx2); + + union { float fl; uint32_t ui; } un; + un.fl = kfn(distance0, distance1, distance2); + + _keys[ii] = floatFlip(un.ui) ^ xorBits; + _values[ii] = ii; + } + } + + template<typename IndexT> + void topologySortTriList( + TopologySort::Enum _sort + , IndexT* _dst + , uint32_t* _keys + , uint32_t* _values + , uint32_t* _tempKeys + , uint32_t* _tempValues + , uint32_t _num + , const float _dir[3] + , const float _pos[3] + , const void* _vertices + , uint32_t _stride + , const IndexT* _indices + ) + { + using namespace bx; + + switch (_sort) + { + default: + case TopologySort::DirectionFrontToBackMin: calcSortKeys<IndexT, distanceDir, fmin3, 0 >(_keys, _values, _dir, _vertices, _stride, _indices, _num); break; + case TopologySort::DirectionFrontToBackAvg: calcSortKeys<IndexT, distanceDir, favg3, 0 >(_keys, _values, _dir, _vertices, _stride, _indices, _num); break; + case TopologySort::DirectionFrontToBackMax: calcSortKeys<IndexT, distanceDir, fmax3, 0 >(_keys, _values, _dir, _vertices, _stride, _indices, _num); break; + case TopologySort::DirectionBackToFrontMin: calcSortKeys<IndexT, distanceDir, fmin3, UINT32_MAX>(_keys, _values, _dir, _vertices, _stride, _indices, _num); break; + case TopologySort::DirectionBackToFrontAvg: calcSortKeys<IndexT, distanceDir, favg3, UINT32_MAX>(_keys, _values, _dir, _vertices, _stride, _indices, _num); break; + case TopologySort::DirectionBackToFrontMax: calcSortKeys<IndexT, distanceDir, fmax3, UINT32_MAX>(_keys, _values, _dir, _vertices, _stride, _indices, _num); break; + case TopologySort::DistanceFrontToBackMin: calcSortKeys<IndexT, distancePos, fmin3, 0 >(_keys, _values, _pos, _vertices, _stride, _indices, _num); break; + case TopologySort::DistanceFrontToBackAvg: calcSortKeys<IndexT, distancePos, favg3, 0 >(_keys, _values, _pos, _vertices, _stride, _indices, _num); break; + case TopologySort::DistanceFrontToBackMax: calcSortKeys<IndexT, distancePos, fmax3, 0 >(_keys, _values, _pos, _vertices, _stride, _indices, _num); break; + case TopologySort::DistanceBackToFrontMin: calcSortKeys<IndexT, distancePos, fmin3, UINT32_MAX>(_keys, _values, _pos, _vertices, _stride, _indices, _num); break; + case TopologySort::DistanceBackToFrontAvg: calcSortKeys<IndexT, distancePos, favg3, UINT32_MAX>(_keys, _values, _pos, _vertices, _stride, _indices, _num); break; + case TopologySort::DistanceBackToFrontMax: calcSortKeys<IndexT, distancePos, fmax3, UINT32_MAX>(_keys, _values, _pos, _vertices, _stride, _indices, _num); break; + } + + radixSort(_keys, _tempKeys, _values, _tempValues, _num); + + IndexT* sorted = _dst; + + for (uint32_t ii = 0; ii < _num; ++ii) + { + uint32_t face = _values[ii]*3; + const IndexT idx0 = _indices[face+0]; + const IndexT idx1 = _indices[face+1]; + const IndexT idx2 = _indices[face+2]; + + sorted[0] = idx0; + sorted[1] = idx1; + sorted[2] = idx2; + sorted += 3; + } + } + + void topologySortTriList( + TopologySort::Enum _sort + , void* _dst + , uint32_t _dstSize + , const float _dir[3] + , const float _pos[3] + , const void* _vertices + , uint32_t _stride + , const void* _indices + , uint32_t _numIndices + , bool _index32 + , bx::AllocatorI* _allocator + ) + { + uint32_t indexSize = _index32 + ? sizeof(uint32_t) + : sizeof(uint16_t) + ; + uint32_t num = bx::uint32_min(_numIndices*indexSize, _dstSize)/(indexSize*3); + uint32_t* temp = (uint32_t*)BX_ALLOC(_allocator, sizeof(uint32_t)*num*4); + + uint32_t* keys = &temp[num*0]; + uint32_t* values = &temp[num*1]; + uint32_t* tempKeys = &temp[num*2]; + uint32_t* tempValues = &temp[num*3]; + + if (_index32) + { + topologySortTriList( + _sort + , (uint32_t*)_dst + , keys + , values + , tempKeys + , tempValues + , num + , _dir + , _pos + , _vertices + , _stride + , (const uint32_t*)_indices + ); + } + else + { + topologySortTriList( + _sort + , (uint16_t*)_dst + , keys + , values + , tempKeys + , tempValues + , num + , _dir + , _pos + , _vertices + , _stride + , (const uint16_t*)_indices + ); + } + + BX_FREE(_allocator, temp); + } + } //namespace bgfx diff --git a/3rdparty/bgfx/src/topology.h b/3rdparty/bgfx/src/topology.h index 014d67559df..a0a1be588ce 100644 --- a/3rdparty/bgfx/src/topology.h +++ b/3rdparty/bgfx/src/topology.h @@ -26,7 +26,30 @@ namespace bgfx /// /// @attention C99 equivalent is `bgfx_topology_convert`. /// - uint32_t topologyConvert(TopologyConvert::Enum _conversion, void* _dst, uint32_t _dstSize, const void* _indices, uint32_t _numIndices, bool _index32, bx::AllocatorI* _allocator); + uint32_t topologyConvert( + TopologyConvert::Enum _conversion + , void* _dst + , uint32_t _dstSize + , const void* _indices + , uint32_t _numIndices + , bool _index32 + , bx::AllocatorI* _allocator + ); + + /// + void topologySortTriList( + TopologySort::Enum _sort + , void* _dst + , uint32_t _dstSize + , const float _dir[3] + , const float _pos[3] + , const void* _vertices + , uint32_t _stride + , const void* _indices + , uint32_t _numIndices + , bool _index32 + , bx::AllocatorI* _allocator + ); } // namespace bgfx diff --git a/3rdparty/bgfx/tools/shaderc/shaderc.cpp b/3rdparty/bgfx/tools/shaderc/shaderc.cpp index 2376e492a1d..1b3e03900c0 100644 --- a/3rdparty/bgfx/tools/shaderc/shaderc.cpp +++ b/3rdparty/bgfx/tools/shaderc/shaderc.cpp @@ -20,15 +20,6 @@ namespace bgfx #define BGFX_CHUNK_MAGIC_FSH BX_MAKEFOURCC('F', 'S', 'H', 0x4) #define BGFX_CHUNK_MAGIC_VSH BX_MAKEFOURCC('V', 'S', 'H', 0x4) - long int fsize(FILE* _file) - { - long int pos = ftell(_file); - fseek(_file, 0L, SEEK_END); - long int size = ftell(_file); - fseek(_file, pos, SEEK_SET); - return size; - } - static const char* s_ARB_shader_texture_lod[] = { "texture2DLod", @@ -106,6 +97,13 @@ namespace bgfx NULL }; + static const char* s_texelFetch[] = + { + "texelFetch", + "texelFetchOffset", + NULL + }; + const char* s_uniformTypeName[UniformType::Count] = { "int", @@ -126,7 +124,7 @@ namespace bgfx return "nointerpolation"; } - return _glsl; // noperspective + return _glsl; // centroid, noperspective } const char* getUniformTypeName(UniformType::Enum _enum) @@ -291,14 +289,23 @@ namespace bgfx File(const char* _filePath) : m_data(NULL) { - FILE* file = fopen(_filePath, "r"); - if (NULL != file) + bx::CrtFileReader reader; + if (bx::open(&reader, _filePath) ) { - m_size = fsize(file); + m_size = (uint32_t)bx::getSize(&reader); m_data = new char[m_size+1]; - m_size = (uint32_t)fread(m_data, 1, m_size, file); + m_size = (uint32_t)bx::read(&reader, m_data, m_size); + bx::close(&reader); + + if (m_data[0] == '\xef' + && m_data[1] == '\xbb' + && m_data[2] == '\xbf') + { + memmove(m_data, &m_data[3], m_size-3); + m_size -= 3; + } + m_data[m_size] = '\0'; - fclose(file); } } @@ -322,11 +329,12 @@ namespace bgfx uint32_t m_size; }; - void strInsert(char* _str, const char* _insert) + char* strInsert(char* _str, const char* _insert) { size_t len = strlen(_insert); memmove(&_str[len], _str, strlen(_str) ); memcpy(_str, _insert, len); + return _str + len; } void strReplace(char* _str, const char* _find, const char* _replace) @@ -946,8 +954,8 @@ namespace bgfx bool compiled = false; - FILE* file = fopen(filePath, "r"); - if (NULL == file) + bx::CrtFileReader reader; + if (!bx::open(&reader, filePath) ) { fprintf(stderr, "Unable to open file '%s'.\n", filePath); } @@ -995,7 +1003,8 @@ namespace bgfx if (0 == strncmp(typen, "flat", 4) || 0 == strncmp(typen, "smooth", 6) - || 0 == strncmp(typen, "noperspective", 13) ) + || 0 == strncmp(typen, "noperspective", 13) + || 0 == strncmp(typen, "centroid", 8) ) { interpolation = typen; typen = parse = bx::strws(bx::strword(parse) ); @@ -1056,15 +1065,24 @@ namespace bgfx char* data; char* input; { - const size_t padding = 1024; - uint32_t size = (uint32_t)fsize(file); + const size_t padding = 4096; + uint32_t size = (uint32_t)bx::getSize(&reader); data = new char[size+padding+1]; - size = (uint32_t)fread(data, 1, size, file); + size = (uint32_t)bx::read(&reader, data, size); + + if (data[0] == '\xef' + && data[1] == '\xbb' + && data[2] == '\xbf') + { + memmove(data, &data[3], size-3); + size -= 3; + } + // Compiler generates "error X3000: syntax error: unexpected end of file" // if input doesn't have empty line at EOF. data[size] = '\n'; memset(&data[size+1], 0, padding); - fclose(file); + bx::close(&reader); if (!raw) { @@ -1360,16 +1378,6 @@ namespace bgfx || 0 != essl || 0 != metal) { - if (120 == glsl - || 0 != essl) - { - preprocessor.writef( - "#define ivec2 vec2\n" - "#define ivec3 vec3\n" - "#define ivec4 vec4\n" - ); - } - if (0 == essl) { // bgfx shadow2D/Proj behave like EXT_shadow_samplers @@ -1447,9 +1455,10 @@ namespace bgfx if (hlsl < 4) { preprocessor.writef( + "#define centroid\n" "#define flat\n" - "#define smooth\n" "#define noperspective\n" + "#define smooth\n" ); } @@ -1457,12 +1466,13 @@ namespace bgfx if ('f' == shaderType) { - const char* brace = strstr(entry, "{"); - if (NULL != brace) + const char* insert = strstr(entry, "{"); + if (NULL != insert) { - strInsert(const_cast<char*>(brace+1), "\nvec4 bgfx_VoidFrag;\n"); + insert = strInsert(const_cast<char*>(insert+1), "\nvec4 bgfx_VoidFrag = vec4_splat(0.0);\n"); } + const bool hasFragColor = NULL != strstr(input, "gl_FragColor"); const bool hasFragCoord = NULL != strstr(input, "gl_FragCoord") || hlsl > 3 || hlsl == 2; const bool hasFragDepth = NULL != strstr(input, "gl_FragDepth"); const bool hasFrontFacing = NULL != strstr(input, "gl_FrontFacing"); @@ -1483,6 +1493,18 @@ namespace bgfx // GL errors when both gl_FragColor and gl_FragData is used. // This will trigger the same error with HLSL compiler too. preprocessor.writef("#define gl_FragColor gl_FragData_0_\n"); + + // If it has gl_FragData or gl_FragColor, color target at + // index 0 exists, otherwise shader is not modifying color + // targets. + hasFragData[0] |= hasFragColor || d3d < 11; + + if (NULL != insert + && d3d < 11 + && !hasFragColor) + { + insert = strInsert(const_cast<char*>(insert+1), "\ngl_FragColor = bgfx_VoidFrag;\n"); + } } preprocessor.writef("#define void_main()"); @@ -1512,11 +1534,9 @@ namespace bgfx } } - addFragData(preprocessor, input, 0, arg++ > 0); - const uint32_t maxRT = d3d > 9 ? BX_COUNTOF(hasFragData) : 4; - for (uint32_t ii = 1; ii < BX_COUNTOF(hasFragData); ++ii) + for (uint32_t ii = 0; ii < BX_COUNTOF(hasFragData); ++ii) { if (ii < maxRT) { @@ -1740,16 +1760,18 @@ namespace bgfx { std::string code; - const bool hasTextureLod = NULL != bx::findIdentifierMatch(input, s_ARB_shader_texture_lod /*EXT_shader_texture_lod*/); - const bool hasShader5 = NULL != bx::findIdentifierMatch(input, s_ARB_gpu_shader5); - const bool hasShaderPacking = NULL != bx::findIdentifierMatch(input, s_ARB_shading_language_packing); - const bool hasTextureMS = NULL != bx::findIdentifierMatch(input, s_ARB_texture_multisample); + const bool usesTextureLod = !!bx::findIdentifierMatch(input, s_ARB_shader_texture_lod /*EXT_shader_texture_lod*/); + const bool usesGpuShader5 = !!bx::findIdentifierMatch(input, s_ARB_gpu_shader5); + const bool usesPacking = !!bx::findIdentifierMatch(input, s_ARB_shading_language_packing); + const bool usesTextureMS = !!bx::findIdentifierMatch(input, s_ARB_texture_multisample); + const bool usesTexelFetch = !!bx::findIdentifierMatch(input, s_texelFetch); if (0 == essl) { - const bool need130 = 120 == glsl - && bx::findIdentifierMatch(input, s_130) - ; + const bool need130 = 120 == glsl && (false + || bx::findIdentifierMatch(input, s_130) + || usesTexelFetch + ); if (0 != metal) { @@ -1760,14 +1782,23 @@ namespace bgfx bx::stringPrintf(code, "#version %s\n", need130 ? "130" : profile); } - if (hasShader5) + if (130 > glsl) + { + bx::stringPrintf(code, + "#define ivec2 vec2\n" + "#define ivec3 vec3\n" + "#define ivec4 vec4\n" + ); + } + + if (usesGpuShader5) { bx::stringPrintf(code , "#extension GL_ARB_gpu_shader5 : enable\n" ); } - if (hasShaderPacking) + if (usesPacking) { bx::stringPrintf(code , "#extension GL_ARB_shading_language_packing : enable\n" @@ -1779,7 +1810,7 @@ namespace bgfx "#define bgfxShadow2DProj shadow2DProj\n" ); - if (hasTextureLod + if (usesTextureLod && 130 > glsl) { bx::stringPrintf(code @@ -1787,7 +1818,7 @@ namespace bgfx ); } - if (hasTextureMS) + if (usesTextureMS) { bx::stringPrintf(code , "#extension GL_ARB_texture_multisample : enable\n" @@ -1796,9 +1827,15 @@ namespace bgfx } else { + bx::stringPrintf(code, + "#define ivec2 vec2\n" + "#define ivec3 vec3\n" + "#define ivec4 vec4\n" + ); + // Pretend that all extensions are available. // This will be stripped later. - if (hasTextureLod) + if (usesTextureLod) { bx::stringPrintf(code , "#extension GL_EXT_shader_texture_lod : enable\n" @@ -1830,14 +1867,14 @@ namespace bgfx ); } - if (hasShader5) + if (usesGpuShader5) { bx::stringPrintf(code , "#extension GL_ARB_gpu_shader5 : enable\n" ); } - if (hasShaderPacking) + if (usesPacking) { bx::stringPrintf(code , "#extension GL_ARB_shading_language_packing : enable\n" diff --git a/3rdparty/bgfx/tools/texturec/texturec.cpp b/3rdparty/bgfx/tools/texturec/texturec.cpp index c1c271fddbc..687ccf82fdb 100644 --- a/3rdparty/bgfx/tools/texturec/texturec.cpp +++ b/3rdparty/bgfx/tools/texturec/texturec.cpp @@ -570,10 +570,13 @@ int main(int _argc, const char* _argv[]) const bool normalMap = cmdLine.hasArg('n', "normalmap"); const bool iqa = cmdLine.hasArg('\0', "iqa"); - uint32_t size = (uint32_t)bx::getSize(&reader); - const bgfx::Memory* mem = bgfx::alloc(size); - bx::read(&reader, mem->data, mem->size); - bx::close(&reader); + const bgfx::Memory* mem; + { + uint32_t size = (uint32_t)bx::getSize(&reader); + mem = bgfx::alloc(size); + bx::read(&reader, mem->data, mem->size); + bx::close(&reader); + } { using namespace bgfx; diff --git a/3rdparty/bgfx/tools/texturev/texturev.cpp b/3rdparty/bgfx/tools/texturev/texturev.cpp index 8d866f97799..faa10220d2f 100644 --- a/3rdparty/bgfx/tools/texturev/texturev.cpp +++ b/3rdparty/bgfx/tools/texturev/texturev.cpp @@ -33,12 +33,14 @@ namespace stl = tinystl; static const char* s_supportedExt[] = { + "bmp", "dds", "jpg", "jpeg", "hdr", "ktx", "png", + "psd", "pvr", "tga", }; diff --git a/3rdparty/bx/include/bx/crtimpl.h b/3rdparty/bx/include/bx/crtimpl.h index a4820334ee3..71b9e61e1c6 100644 --- a/3rdparty/bx/include/bx/crtimpl.h +++ b/3rdparty/bx/include/bx/crtimpl.h @@ -194,10 +194,10 @@ namespace bx #if BX_CONFIG_CRT_PROCESS -#if BX_COMPILER_MSVC_COMPATIBLE +#if BX_CRT_MSVC # define popen _popen # define pclose _pclose -#endif // BX_COMPILER_MSVC_COMPATIBLE +#endif // BX_CRT_MSVC class ProcessReader : public ReaderOpenI, public CloserI, public ReaderI { diff --git a/3rdparty/bx/include/bx/float4_langext.h b/3rdparty/bx/include/bx/float4_langext.h deleted file mode 100644 index c5c3dddfa02..00000000000 --- a/3rdparty/bx/include/bx/float4_langext.h +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Copyright 2010-2016 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bx#license-bsd-2-clause - */ - -#ifndef BX_FLOAT4_LANGEXT_H_HEADER_GUARD -#define BX_FLOAT4_LANGEXT_H_HEADER_GUARD - -#include <math.h> - -namespace bx -{ - typedef union float4_t - { - float __attribute__((vector_size(16))) vf; - int32_t __attribute__((vector_size(16))) vi; - uint32_t __attribute__((vector_size(16))) vu; - float fxyzw[4]; - int32_t ixyzw[4]; - uint32_t uxyzw[4]; - - } float4_t; - -#define ELEMx 0 -#define ELEMy 1 -#define ELEMz 2 -#define ELEMw 3 -#define IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ - BX_FLOAT4_FORCE_INLINE float4_t float4_swiz_##_x##_y##_z##_w(float4_t _a) \ - { \ - float4_t result; \ - result.vf = __builtin_shufflevector(_a.vf, _a.vf, ELEM##_x, ELEM##_y, ELEM##_z, ELEM##_w); \ - return result; \ - } - -#include "float4_swizzle.inl" - -#undef IMPLEMENT_SWIZZLE -#undef ELEMw -#undef ELEMz -#undef ELEMy -#undef ELEMx - -#define IMPLEMENT_TEST(_xyzw, _mask) \ - BX_FLOAT4_FORCE_INLINE bool float4_test_any_##_xyzw(float4_t _test) \ - { \ - uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ - | ( (_test.uxyzw[2]>>31)<<2) \ - | ( (_test.uxyzw[1]>>31)<<1) \ - | ( _test.uxyzw[0]>>31) \ - ; \ - return 0 != (tmp&(_mask) ); \ - } \ - \ - BX_FLOAT4_FORCE_INLINE bool float4_test_all_##_xyzw(float4_t _test) \ - { \ - uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ - | ( (_test.uxyzw[2]>>31)<<2) \ - | ( (_test.uxyzw[1]>>31)<<1) \ - | ( _test.uxyzw[0]>>31) \ - ; \ - return (_mask) == (tmp&(_mask) ); \ - } - -IMPLEMENT_TEST(x , 0x1); -IMPLEMENT_TEST(y , 0x2); -IMPLEMENT_TEST(xy , 0x3); -IMPLEMENT_TEST(z , 0x4); -IMPLEMENT_TEST(xz , 0x5); -IMPLEMENT_TEST(yz , 0x6); -IMPLEMENT_TEST(xyz , 0x7); -IMPLEMENT_TEST(w , 0x8); -IMPLEMENT_TEST(xw , 0x9); -IMPLEMENT_TEST(yw , 0xa); -IMPLEMENT_TEST(xyw , 0xb); -IMPLEMENT_TEST(zw , 0xc); -IMPLEMENT_TEST(xzw , 0xd); -IMPLEMENT_TEST(yzw , 0xe); -IMPLEMENT_TEST(xyzw , 0xf); - -#undef IMPLEMENT_TEST - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xyAB(float4_t _a, float4_t _b) - { - float4_t result; - result.vf = __builtin_shufflevector(_a.vf, _b.vf, 0, 1, 4, 5); - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_ABxy(float4_t _a, float4_t _b) - { - float4_t result; - result.vf = __builtin_shufflevector(_a.vf, _b.vf, 4, 5, 0, 1); - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_CDzw(float4_t _a, float4_t _b) - { - float4_t result; - result.vf = __builtin_shufflevector(_a.vf, _b.vf, 5, 7, 2, 3); - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_zwCD(float4_t _a, float4_t _b) - { - float4_t result; - result.vf = __builtin_shufflevector(_a.vf, _b.vf, 2, 3, 5, 7); - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xAyB(float4_t _a, float4_t _b) - { - float4_t result; - result.vf = __builtin_shufflevector(_a.vf, _b.vf, 0, 4, 1, 5); - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_yBxA(float4_t _a, float4_t _b) - { - float4_t result; - result.vf = __builtin_shufflevector(_a.vf, _b.vf, 1, 5, 0, 4); - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_zCwD(float4_t _a, float4_t _b) - { - float4_t result; - result.vf = __builtin_shufflevector(_a.vf, _b.vf, 2, 6, 3, 7); - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_CzDw(float4_t _a, float4_t _b) - { - float4_t result; - result.vf = __builtin_shufflevector(_a.vf, _b.vf, 6, 2, 7, 3); - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xAzC(float4_t _a, float4_t _b) - { - float4_t result; - result.vf = __builtin_shufflevector(_a.vf, _b.vf, 0, 4, 2, 6); - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_yBwD(float4_t _a, float4_t _b) - { - float4_t result; - result.vf = __builtin_shufflevector(_a.vf, _b.vf, 1, 5, 3, 7); - return result; - } - - BX_FLOAT4_FORCE_INLINE float float4_x(float4_t _a) - { - return _a.fxyzw[0]; - } - - BX_FLOAT4_FORCE_INLINE float float4_y(float4_t _a) - { - return _a.fxyzw[1]; - } - - BX_FLOAT4_FORCE_INLINE float float4_z(float4_t _a) - { - return _a.fxyzw[2]; - } - - BX_FLOAT4_FORCE_INLINE float float4_w(float4_t _a) - { - return _a.fxyzw[3]; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_ld(const void* _ptr) - { - const uint32_t* input = reinterpret_cast<const uint32_t*>(_ptr); - float4_t result; - result.uxyzw[0] = input[0]; - result.uxyzw[1] = input[1]; - result.uxyzw[2] = input[2]; - result.uxyzw[3] = input[3]; - return result; - } - - BX_FLOAT4_FORCE_INLINE void float4_st(void* _ptr, float4_t _a) - { - uint32_t* result = reinterpret_cast<uint32_t*>(_ptr); - result[0] = _a.uxyzw[0]; - result[1] = _a.uxyzw[1]; - result[2] = _a.uxyzw[2]; - result[3] = _a.uxyzw[3]; - } - - BX_FLOAT4_FORCE_INLINE void float4_stx(void* _ptr, float4_t _a) - { - uint32_t* result = reinterpret_cast<uint32_t*>(_ptr); - result[0] = _a.uxyzw[0]; - } - - BX_FLOAT4_FORCE_INLINE void float4_stream(void* _ptr, float4_t _a) - { - uint32_t* result = reinterpret_cast<uint32_t*>(_ptr); - result[0] = _a.uxyzw[0]; - result[1] = _a.uxyzw[1]; - result[2] = _a.uxyzw[2]; - result[3] = _a.uxyzw[3]; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_ld(float _x, float _y, float _z, float _w) - { - float4_t result; - result.vf = { _x, _y, _z, _w }; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) - { - float4_t result; - result.vu = { _x, _y, _z, _w }; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_splat(const void* _ptr) - { - const uint32_t val = *reinterpret_cast<const uint32_t*>(_ptr); - float4_t result; - result.vu = { val, val, val, val }; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_splat(float _a) - { - return float4_ld(_a, _a, _a, _a); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_isplat(uint32_t _a) - { - return float4_ild(_a, _a, _a, _a); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_zero() - { - return float4_ild(0, 0, 0, 0); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_itof(float4_t _a) - { - float4_t result; - result.vf = __builtin_convertvector(_a.vi, float __attribute__((vector_size(16))) ); - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_ftoi(float4_t _a) - { - float4_t result; - result.vi = __builtin_convertvector(_a.vf, int32_t __attribute__((vector_size(16))) ); - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_round(float4_t _a) - { - const float4_t tmp = float4_ftoi(_a); - const float4_t result = float4_itof(tmp); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_add(float4_t _a, float4_t _b) - { - float4_t result; - result.vf = _a.vf + _b.vf; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_sub(float4_t _a, float4_t _b) - { - float4_t result; - result.vf = _a.vf - _b.vf; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_mul(float4_t _a, float4_t _b) - { - float4_t result; - result.vf = _a.vf * _b.vf; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_div(float4_t _a, float4_t _b) - { - float4_t result; - result.vf = _a.vf / _b.vf; - return result; - } - -#if 0 - BX_FLOAT4_FORCE_INLINE float4_t float4_rcp_est(float4_t _a) - { - float4_t result; - const float4_t one = float4_splat(1.0f); - result.vf = one / _a.vf; - return result; - } -#endif // 0 - - BX_FLOAT4_FORCE_INLINE float4_t float4_sqrt(float4_t _a) - { - float4_t result; - result.vf[0] = sqrtf(_a.vf[0]); - result.vf[1] = sqrtf(_a.vf[1]); - result.vf[2] = sqrtf(_a.vf[2]); - result.vf[3] = sqrtf(_a.vf[3]); - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_rsqrt_est(float4_t _a) - { - float4_t result; - result.vf[0] = 1.0f / sqrtf(_a.vf[0]); - result.vf[1] = 1.0f / sqrtf(_a.vf[1]); - result.vf[2] = 1.0f / sqrtf(_a.vf[2]); - result.vf[3] = 1.0f / sqrtf(_a.vf[3]); - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_cmpeq(float4_t _a, float4_t _b) - { - float4_t result; - result.vi = _a.vf == _b.vf; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_cmplt(float4_t _a, float4_t _b) - { - float4_t result; - result.vi = _a.vf < _b.vf; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_cmple(float4_t _a, float4_t _b) - { - float4_t result; - result.vi = _a.vf <= _b.vf; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_cmpgt(float4_t _a, float4_t _b) - { - float4_t result; - result.vi = _a.vf > _b.vf; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_cmpge(float4_t _a, float4_t _b) - { - float4_t result; - result.vi = _a.vf >= _b.vf; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_and(float4_t _a, float4_t _b) - { - float4_t result; - result.vu = _a.vu & _b.vu; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_andc(float4_t _a, float4_t _b) - { - float4_t result; - result.vu = _a.vu & ~_b.vu; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_or(float4_t _a, float4_t _b) - { - float4_t result; - result.vu = _a.vu | _b.vu; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_xor(float4_t _a, float4_t _b) - { - float4_t result; - result.vu = _a.vu ^ _b.vu; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_sll(float4_t _a, int _count) - { - float4_t result; - const float4_t count = float4_isplat(_count); - result.vu = _a.vu << count.vi; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_srl(float4_t _a, int _count) - { - float4_t result; - const float4_t count = float4_isplat(_count); - result.vu = _a.vu >> count.vi; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_sra(float4_t _a, int _count) - { - float4_t result; - const float4_t count = float4_isplat(_count); - result.vi = _a.vi >> count.vi; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_icmpeq(float4_t _a, float4_t _b) - { - float4_t result; - result.vi = _a.vi == _b.vi; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_icmplt(float4_t _a, float4_t _b) - { - float4_t result; - result.vi = _a.vi < _b.vi; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_icmpgt(float4_t _a, float4_t _b) - { - float4_t result; - result.vi = _a.vi > _b.vi; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_iadd(float4_t _a, float4_t _b) - { - float4_t result; - result.vi = _a.vi + _b.vi; - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_isub(float4_t _a, float4_t _b) - { - float4_t result; - result.vi = _a.vi - _b.vi; - return result; - } - -} // namespace bx - -#define float4_rcp float4_rcp_ni -#define float4_orx float4_orx_ni -#define float4_orc float4_orc_ni -#define float4_neg float4_neg_ni -#define float4_madd float4_madd_ni -#define float4_nmsub float4_nmsub_ni -#define float4_div_nr float4_div_nr_ni -#define float4_selb float4_selb_ni -#define float4_sels float4_sels_ni -#define float4_not float4_not_ni -#define float4_abs float4_abs_ni -#define float4_clamp float4_clamp_ni -#define float4_lerp float4_lerp_ni -#define float4_rcp_est float4_rcp_ni -#define float4_rsqrt float4_rsqrt_ni -#define float4_rsqrt_nr float4_rsqrt_nr_ni -#define float4_rsqrt_carmack float4_rsqrt_carmack_ni -#define float4_sqrt_nr float4_sqrt_nr_ni -#define float4_log2 float4_log2_ni -#define float4_exp2 float4_exp2_ni -#define float4_pow float4_pow_ni -#define float4_cross3 float4_cross3_ni -#define float4_normalize3 float4_normalize3_ni -#define float4_dot3 float4_dot3_ni -#define float4_dot float4_dot_ni -#define float4_ceil float4_ceil_ni -#define float4_floor float4_floor_ni -#define float4_min float4_min_ni -#define float4_max float4_max_ni -#define float4_imin float4_imin_ni -#define float4_imax float4_imax_ni -#include "float4_ni.h" - -#endif // BX_FLOAT4_LANGEXT_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/float4_neon.h b/3rdparty/bx/include/bx/float4_neon.h deleted file mode 100644 index 3b6fa185296..00000000000 --- a/3rdparty/bx/include/bx/float4_neon.h +++ /dev/null @@ -1,525 +0,0 @@ -/* - * Copyright 2010-2016 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bx#license-bsd-2-clause - */ - -#ifndef BX_FLOAT4_NEON_H_HEADER_GUARD -#define BX_FLOAT4_NEON_H_HEADER_GUARD - -namespace bx -{ - typedef __builtin_neon_sf float4_t __attribute__( (__vector_size__(16) ) ); - - typedef __builtin_neon_sf _f32x2_t __attribute__( (__vector_size__( 8) ) ); - typedef __builtin_neon_si _i32x4_t __attribute__( (__vector_size__(16) ) ); - typedef __builtin_neon_usi _u32x4_t __attribute__( (__vector_size__(16) ) ); - -#define ELEMx 0 -#define ELEMy 1 -#define ELEMz 2 -#define ELEMw 3 -#define IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ - BX_FLOAT4_FORCE_INLINE float4_t float4_swiz_##_x##_y##_z##_w(float4_t _a) \ - { \ - return __builtin_shuffle(_a, (_u32x4_t){ ELEM##_x, ELEM##_y, ELEM##_z, ELEM##_w }); \ - } - -#include "float4_swizzle.inl" - -#undef IMPLEMENT_SWIZZLE -#undef ELEMw -#undef ELEMz -#undef ELEMy -#undef ELEMx - -#define IMPLEMENT_TEST(_xyzw, _swizzle) \ - BX_FLOAT4_FORCE_INLINE bool float4_test_any_##_xyzw(float4_t _test); \ - BX_FLOAT4_FORCE_INLINE bool float4_test_all_##_xyzw(float4_t _test); - -IMPLEMENT_TEST(x , xxxx); -IMPLEMENT_TEST(y , yyyy); -IMPLEMENT_TEST(xy , xyyy); -IMPLEMENT_TEST(z , zzzz); -IMPLEMENT_TEST(xz , xzzz); -IMPLEMENT_TEST(yz , yzzz); -IMPLEMENT_TEST(xyz , xyzz); -IMPLEMENT_TEST(w , wwww); -IMPLEMENT_TEST(xw , xwww); -IMPLEMENT_TEST(yw , ywww); -IMPLEMENT_TEST(xyw , xyww); -IMPLEMENT_TEST(zw , zwww); -IMPLEMENT_TEST(xzw , xzww); -IMPLEMENT_TEST(yzw , yzww); -IMPLEMENT_TEST(xyzw , xyzw); - -#undef IMPLEMENT_TEST - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xyAB(float4_t _a, float4_t _b) - { - return __builtin_shuffle(_a, _b, (_u32x4_t){ 0, 1, 4, 5 }); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_ABxy(float4_t _a, float4_t _b) - { - return __builtin_shuffle(_a, _b, (_u32x4_t){ 4, 5, 0, 1 }); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_CDzw(float4_t _a, float4_t _b) - { - return __builtin_shuffle(_a, _b, (_u32x4_t){ 6, 7, 2, 3 }); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_zwCD(float4_t _a, float4_t _b) - { - return __builtin_shuffle(_a, _b, (_u32x4_t){ 2, 3, 6, 7 }); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xAyB(float4_t _a, float4_t _b) - { - return __builtin_shuffle(_a, _b, (_u32x4_t){ 0, 4, 1, 5 }); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_yBxA(float4_t _a, float4_t _b) - { - return __builtin_shuffle(_a, _b, (_u32x4_t){ 1, 5, 0, 4 }); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_zCwD(float4_t _a, float4_t _b) - { - return __builtin_shuffle(_a, _b, (_u32x4_t){ 2, 6, 3, 7 }); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_CzDw(float4_t _a, float4_t _b) - { - return __builtin_shuffle(_a, _b, (_u32x4_t){ 6, 2, 7, 3 }); - } - - BX_FLOAT4_FORCE_INLINE float float4_x(float4_t _a) - { - return __builtin_neon_vget_lanev4sf(_a, 0, 3); - } - - BX_FLOAT4_FORCE_INLINE float float4_y(float4_t _a) - { - return __builtin_neon_vget_lanev4sf(_a, 1, 3); - } - - BX_FLOAT4_FORCE_INLINE float float4_z(float4_t _a) - { - return __builtin_neon_vget_lanev4sf(_a, 2, 3); - } - - BX_FLOAT4_FORCE_INLINE float float4_w(float4_t _a) - { - return __builtin_neon_vget_lanev4sf(_a, 3, 3); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_ld(const void* _ptr) - { - return __builtin_neon_vld1v4sf( (const __builtin_neon_sf*)_ptr); - } - - BX_FLOAT4_FORCE_INLINE void float4_st(void* _ptr, float4_t _a) - { - __builtin_neon_vst1v4sf( (__builtin_neon_sf*)_ptr, _a); - } - - BX_FLOAT4_FORCE_INLINE void float4_stx(void* _ptr, float4_t _a) - { - __builtin_neon_vst1_lanev4sf( (__builtin_neon_sf*)_ptr, _a, 0); - } - - BX_FLOAT4_FORCE_INLINE void float4_stream(void* _ptr, float4_t _a) - { - __builtin_neon_vst1v4sf( (__builtin_neon_sf*)_ptr, _a); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_ld(float _x, float _y, float _z, float _w) - { - const float4_t val[4] = {_x, _y, _z, _w}; - return float4_ld(val); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) - { - const uint32_t val[4] = {_x, _y, _z, _w}; - const _i32x4_t tmp = __builtin_neon_vld1v4si( (const __builtin_neon_si*)val); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_splat(const void* _ptr) - { - const float4_t tmp0 = __builtin_neon_vld1v4sf( (const __builtin_neon_sf *)_ptr); - const _f32x2_t tmp1 = __builtin_neon_vget_lowv4sf(tmp0); - const float4_t result = __builtin_neon_vdup_lanev4sf(tmp1, 0); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_splat(float _a) - { - return __builtin_neon_vdup_nv4sf(_a); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_isplat(uint32_t _a) - { - const _i32x4_t tmp = __builtin_neon_vdup_nv4si( (__builtin_neon_si)_a); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_zero() - { - return float4_isplat(0); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_itof(float4_t _a) - { - const _i32x4_t itof = __builtin_neon_vreinterpretv4siv4sf(_a); - const float4_t result = __builtin_neon_vcvtv4si(itof, 1); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_ftoi(float4_t _a) - { - const _i32x4_t ftoi = __builtin_neon_vcvtv4sf(_a, 1); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(ftoi); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_add(float4_t _a, float4_t _b) - { - return __builtin_neon_vaddv4sf(_a, _b, 3); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_sub(float4_t _a, float4_t _b) - { - return __builtin_neon_vsubv4sf(_a, _b, 3); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_mul(float4_t _a, float4_t _b) - { - return __builtin_neon_vmulv4sf(_a, _b, 3); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_rcp_est(float4_t _a) - { - return __builtin_neon_vrecpev4sf(_a, 3); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_rsqrt_est(float4_t _a) - { - return __builtin_neon_vrsqrtev4sf(_a, 3); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_cmpeq(float4_t _a, float4_t _b) - { - const _i32x4_t tmp = __builtin_neon_vceqv4sf(_a, _b, 3); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_cmplt(float4_t _a, float4_t _b) - { - const _i32x4_t tmp = __builtin_neon_vcgtv4sf(_b, _a, 3); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_cmple(float4_t _a, float4_t _b) - { - const _i32x4_t tmp = __builtin_neon_vcgev4sf(_b, _a, 3); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_cmpgt(float4_t _a, float4_t _b) - { - const _i32x4_t tmp = __builtin_neon_vcgtv4sf(_a, _b, 3); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_cmpge(float4_t _a, float4_t _b) - { - const _i32x4_t tmp = __builtin_neon_vcgev4sf(_a, _b, 3); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_min(float4_t _a, float4_t _b) - { - return __builtin_neon_vminv4sf(_a, _b, 3); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_max(float4_t _a, float4_t _b) - { - return __builtin_neon_vmaxv4sf(_a, _b, 3); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_and(float4_t _a, float4_t _b) - { - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); - const _i32x4_t tmp2 = __builtin_neon_vandv4si(tmp0, tmp1, 0); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_andc(float4_t _a, float4_t _b) - { - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); - const _i32x4_t tmp2 = __builtin_neon_vbicv4si(tmp0, tmp1, 0); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_or(float4_t _a, float4_t _b) - { - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); - const _i32x4_t tmp2 = __builtin_neon_vorrv4si(tmp0, tmp1, 0); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_xor(float4_t _a, float4_t _b) - { - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); - const _i32x4_t tmp2 = __builtin_neon_veorv4si(tmp0, tmp1, 0); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_sll(float4_t _a, int _count) - { - if (__builtin_constant_p(_count) ) - { - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t tmp1 = __builtin_neon_vshl_nv4si(tmp0, _count, 0); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp1); - - return result; - } - - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t shift = __builtin_neon_vdup_nv4si( (__builtin_neon_si)_count); - const _i32x4_t tmp1 = __builtin_neon_vshlv4si(tmp0, shift, 1); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp1); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_srl(float4_t _a, int _count) - { - if (__builtin_constant_p(_count) ) - { - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t tmp1 = __builtin_neon_vshr_nv4si(tmp0, _count, 0); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp1); - - return result; - } - - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t shift = __builtin_neon_vdup_nv4si( (__builtin_neon_si)-_count); - const _i32x4_t tmp1 = __builtin_neon_vshlv4si(tmp0, shift, 1); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp1); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_sra(float4_t _a, int _count) - { - if (__builtin_constant_p(_count) ) - { - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t tmp1 = __builtin_neon_vshr_nv4si(tmp0, _count, 1); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp1); - - return result; - } - - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t shift = __builtin_neon_vdup_nv4si( (__builtin_neon_si)-_count); - const _i32x4_t tmp1 = __builtin_neon_vshlv4si(tmp0, shift, 1); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp1); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_madd(float4_t _a, float4_t _b, float4_t _c) - { - return __builtin_neon_vmlav4sf(_c, _a, _b, 3); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_nmsub(float4_t _a, float4_t _b, float4_t _c) - { - return __builtin_neon_vmlsv4sf(_c, _a, _b, 3); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_icmpeq(float4_t _a, float4_t _b) - { - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); - const _i32x4_t tmp2 = __builtin_neon_vceqv4si(tmp0, tmp1, 1); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_icmplt(float4_t _a, float4_t _b) - { - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); - const _i32x4_t tmp2 = __builtin_neon_vcgtv4si(tmp1, tmp0, 1); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_icmpgt(float4_t _a, float4_t _b) - { - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); - const _i32x4_t tmp2 = __builtin_neon_vcgtv4si(tmp0, tmp1, 1); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_imin(float4_t _a, float4_t _b) - { - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); - const _i32x4_t tmp2 = __builtin_neon_vminv4si(tmp0, tmp1, 1); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_imax(float4_t _a, float4_t _b) - { - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); - const _i32x4_t tmp2 = __builtin_neon_vmaxv4si(tmp0, tmp1, 1); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_iadd(float4_t _a, float4_t _b) - { - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); - const _i32x4_t tmp2 = __builtin_neon_vaddv4si(tmp0, tmp1, 1); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_isub(float4_t _a, float4_t _b) - { - const _i32x4_t tmp0 = __builtin_neon_vreinterpretv4siv4sf(_a); - const _i32x4_t tmp1 = __builtin_neon_vreinterpretv4siv4sf(_b); - const _i32x4_t tmp2 = __builtin_neon_vsubv4si(tmp0, tmp1, 1); - const float4_t result = __builtin_neon_vreinterpretv4sfv4si(tmp2); - - return result; - } - -} // namespace bx - -#define float4_shuf_xAzC float4_shuf_xAzC_ni -#define float4_shuf_yBwD float4_shuf_yBwD_ni -#define float4_rcp float4_rcp_ni -#define float4_orx float4_orx_ni -#define float4_orc float4_orc_ni -#define float4_neg float4_neg_ni -#define float4_madd float4_madd_ni -#define float4_nmsub float4_nmsub_ni -#define float4_div_nr float4_div_nr_ni -#define float4_div float4_div_nr_ni -#define float4_selb float4_selb_ni -#define float4_sels float4_sels_ni -#define float4_not float4_not_ni -#define float4_abs float4_abs_ni -#define float4_clamp float4_clamp_ni -#define float4_lerp float4_lerp_ni -#define float4_rsqrt float4_rsqrt_ni -#define float4_rsqrt_nr float4_rsqrt_nr_ni -#define float4_rsqrt_carmack float4_rsqrt_carmack_ni -#define float4_sqrt_nr float4_sqrt_nr_ni -#define float4_sqrt float4_sqrt_nr_ni -#define float4_log2 float4_log2_ni -#define float4_exp2 float4_exp2_ni -#define float4_pow float4_pow_ni -#define float4_cross3 float4_cross3_ni -#define float4_normalize3 float4_normalize3_ni -#define float4_dot3 float4_dot3_ni -#define float4_dot float4_dot_ni -#define float4_ceil float4_ceil_ni -#define float4_floor float4_floor_ni - -#include "float4_ni.h" - -namespace bx -{ -#define IMPLEMENT_TEST(_xyzw, _swizzle) \ - BX_FLOAT4_FORCE_INLINE bool float4_test_any_##_xyzw(float4_t _test) \ - { \ - const float4_t tmp0 = float4_swiz_##_swizzle(_test); \ - return float4_test_any_ni(tmp0); \ - } \ - \ - BX_FLOAT4_FORCE_INLINE bool float4_test_all_##_xyzw(float4_t _test) \ - { \ - const float4_t tmp0 = float4_swiz_##_swizzle(_test); \ - return float4_test_all_ni(tmp0); \ - } - -IMPLEMENT_TEST(x , xxxx); -IMPLEMENT_TEST(y , yyyy); -IMPLEMENT_TEST(xy , xyyy); -IMPLEMENT_TEST(z , zzzz); -IMPLEMENT_TEST(xz , xzzz); -IMPLEMENT_TEST(yz , yzzz); -IMPLEMENT_TEST(xyz , xyzz); -IMPLEMENT_TEST(w , wwww); -IMPLEMENT_TEST(xw , xwww); -IMPLEMENT_TEST(yw , ywww); -IMPLEMENT_TEST(xyw , xyww); -IMPLEMENT_TEST(zw , zwww); -IMPLEMENT_TEST(xzw , xzww); -IMPLEMENT_TEST(yzw , yzww); - - BX_FLOAT4_FORCE_INLINE bool float4_test_any_xyzw(float4_t _test) - { - return float4_test_any_ni(_test); - } - - BX_FLOAT4_FORCE_INLINE bool float4_test_all_xyzw(float4_t _test) - { - return float4_test_all_ni(_test); - } - -#undef IMPLEMENT_TEST -} // namespace bx - -#endif // BX_FLOAT4_NEON_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/float4_ni.h b/3rdparty/bx/include/bx/float4_ni.h deleted file mode 100644 index 644fa6eb386..00000000000 --- a/3rdparty/bx/include/bx/float4_ni.h +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright 2010-2016 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bx#license-bsd-2-clause - */ - -#ifndef BX_FLOAT4_NI_H_HEADER_GUARD -#define BX_FLOAT4_NI_H_HEADER_GUARD - -namespace bx -{ - BX_FLOAT4_INLINE float4_t float4_rcp_ni(float4_t _a); - - BX_FLOAT4_INLINE float4_t float4_shuf_xAzC_ni(float4_t _a, float4_t _b) - { - const float4_t xAyB = float4_shuf_xAyB(_a, _b); - const float4_t zCwD = float4_shuf_zCwD(_a, _b); - const float4_t result = float4_shuf_xyAB(xAyB, zCwD); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_shuf_yBwD_ni(float4_t _a, float4_t _b) - { - const float4_t xAyB = float4_shuf_xAyB(_a, _b); - const float4_t zCwD = float4_shuf_zCwD(_a, _b); - const float4_t result = float4_shuf_zwCD(xAyB, zCwD); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_madd_ni(float4_t _a, float4_t _b, float4_t _c) - { - const float4_t mul = float4_mul(_a, _b); - const float4_t result = float4_add(mul, _c); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_nmsub_ni(float4_t _a, float4_t _b, float4_t _c) - { - const float4_t mul = float4_mul(_a, _b); - const float4_t result = float4_sub(_c, mul); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_div_nr_ni(float4_t _a, float4_t _b) - { - const float4_t oneish = float4_isplat(0x3f800001); - const float4_t est = float4_rcp_est(_b); - const float4_t iter0 = float4_mul(_a, est); - const float4_t tmp1 = float4_nmsub(_b, est, oneish); - const float4_t result = float4_madd(tmp1, iter0, iter0); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_rcp_ni(float4_t _a) - { - const float4_t one = float4_splat(1.0f); - const float4_t result = float4_div(one, _a); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_orx_ni(float4_t _a) - { - const float4_t zwxy = float4_swiz_zwxy(_a); - const float4_t tmp0 = float4_or(_a, zwxy); - const float4_t tmp1 = float4_swiz_yyyy(_a); - const float4_t tmp2 = float4_or(tmp0, tmp1); - const float4_t mf000 = float4_ild(UINT32_MAX, 0, 0, 0); - const float4_t result = float4_and(tmp2, mf000); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_orc_ni(float4_t _a, float4_t _b) - { - const float4_t aorb = float4_or(_a, _b); - const float4_t mffff = float4_isplat(UINT32_MAX); - const float4_t result = float4_xor(aorb, mffff); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_neg_ni(float4_t _a) - { - const float4_t zero = float4_zero(); - const float4_t result = float4_sub(zero, _a); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_selb_ni(float4_t _mask, float4_t _a, float4_t _b) - { - const float4_t sel_a = float4_and(_a, _mask); - const float4_t sel_b = float4_andc(_b, _mask); - const float4_t result = float4_or(sel_a, sel_b); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_sels_ni(float4_t _test, float4_t _a, float4_t _b) - { - const float4_t mask = float4_sra(_test, 31); - const float4_t result = float4_selb(mask, _a, _b); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_not_ni(float4_t _a) - { - const float4_t mffff = float4_isplat(UINT32_MAX); - const float4_t result = float4_xor(_a, mffff); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_min_ni(float4_t _a, float4_t _b) - { - const float4_t mask = float4_cmplt(_a, _b); - const float4_t result = float4_selb(mask, _a, _b); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_max_ni(float4_t _a, float4_t _b) - { - const float4_t mask = float4_cmpgt(_a, _b); - const float4_t result = float4_selb(mask, _a, _b); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_abs_ni(float4_t _a) - { - const float4_t a_neg = float4_neg(_a); - const float4_t result = float4_max(a_neg, _a); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_imin_ni(float4_t _a, float4_t _b) - { - const float4_t mask = float4_icmplt(_a, _b); - const float4_t result = float4_selb(mask, _a, _b); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_imax_ni(float4_t _a, float4_t _b) - { - const float4_t mask = float4_icmpgt(_a, _b); - const float4_t result = float4_selb(mask, _a, _b); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_clamp_ni(float4_t _a, float4_t _min, float4_t _max) - { - const float4_t tmp = float4_min(_a, _max); - const float4_t result = float4_max(tmp, _min); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_lerp_ni(float4_t _a, float4_t _b, float4_t _s) - { - const float4_t ba = float4_sub(_b, _a); - const float4_t result = float4_madd(_s, ba, _a); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_sqrt_nr_ni(float4_t _a) - { - const float4_t half = float4_splat(0.5f); - const float4_t one = float4_splat(1.0f); - const float4_t tmp0 = float4_rsqrt_est(_a); - const float4_t tmp1 = float4_mul(tmp0, _a); - const float4_t tmp2 = float4_mul(tmp1, half); - const float4_t tmp3 = float4_nmsub(tmp0, tmp1, one); - const float4_t result = float4_madd(tmp3, tmp2, tmp1); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_sqrt_nr1_ni(float4_t _a) - { - const float4_t half = float4_splat(0.5f); - - float4_t result = _a; - for (uint32_t ii = 0; ii < 11; ++ii) - { - const float4_t tmp1 = float4_div(_a, result); - const float4_t tmp2 = float4_add(tmp1, result); - result = float4_mul(tmp2, half); - } - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_rsqrt_ni(float4_t _a) - { - const float4_t one = float4_splat(1.0f); - const float4_t sqrt = float4_sqrt(_a); - const float4_t result = float4_div(one, sqrt); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_rsqrt_nr_ni(float4_t _a) - { - const float4_t rsqrt = float4_rsqrt_est(_a); - const float4_t iter0 = float4_mul(_a, rsqrt); - const float4_t iter1 = float4_mul(iter0, rsqrt); - const float4_t half = float4_splat(0.5f); - const float4_t half_rsqrt = float4_mul(half, rsqrt); - const float4_t three = float4_splat(3.0f); - const float4_t three_sub_iter1 = float4_sub(three, iter1); - const float4_t result = float4_mul(half_rsqrt, three_sub_iter1); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_rsqrt_carmack_ni(float4_t _a) - { - const float4_t half = float4_splat(0.5f); - const float4_t ah = float4_mul(half, _a); - const float4_t ashift = float4_sra(_a, 1); - const float4_t magic = float4_isplat(0x5f3759df); - const float4_t msuba = float4_isub(magic, ashift); - const float4_t msubasq = float4_mul(msuba, msuba); - const float4_t tmp0 = float4_splat(1.5f); - const float4_t tmp1 = float4_mul(ah, msubasq); - const float4_t tmp2 = float4_sub(tmp0, tmp1); - const float4_t result = float4_mul(msuba, tmp2); - - return result; - } - - namespace float4_logexp_detail - { - BX_FLOAT4_INLINE float4_t float4_poly1(float4_t _a, float _b, float _c) - { - const float4_t bbbb = float4_splat(_b); - const float4_t cccc = float4_splat(_c); - const float4_t result = float4_madd(cccc, _a, bbbb); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_poly2(float4_t _a, float _b, float _c, float _d) - { - const float4_t bbbb = float4_splat(_b); - const float4_t poly = float4_poly1(_a, _c, _d); - const float4_t result = float4_madd(poly, _a, bbbb); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_poly3(float4_t _a, float _b, float _c, float _d, float _e) - { - const float4_t bbbb = float4_splat(_b); - const float4_t poly = float4_poly2(_a, _c, _d, _e); - const float4_t result = float4_madd(poly, _a, bbbb); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_poly4(float4_t _a, float _b, float _c, float _d, float _e, float _f) - { - const float4_t bbbb = float4_splat(_b); - const float4_t poly = float4_poly3(_a, _c, _d, _e, _f); - const float4_t result = float4_madd(poly, _a, bbbb); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_poly5(float4_t _a, float _b, float _c, float _d, float _e, float _f, float _g) - { - const float4_t bbbb = float4_splat(_b); - const float4_t poly = float4_poly4(_a, _c, _d, _e, _f, _g); - const float4_t result = float4_madd(poly, _a, bbbb); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_logpoly(float4_t _a) - { -#if 1 - const float4_t result = float4_poly5(_a - , 3.11578814719469302614f, -3.32419399085241980044f - , 2.59883907202499966007f, -1.23152682416275988241f - , 0.318212422185251071475f, -0.0344359067839062357313f - ); -#elif 0 - const float4_t result = float4_poly4(_a - , 2.8882704548164776201f, -2.52074962577807006663f - , 1.48116647521213171641f, -0.465725644288844778798f - , 0.0596515482674574969533f - ); -#elif 0 - const float4_t result = float4_poly3(_a - , 2.61761038894603480148f, -1.75647175389045657003f - , 0.688243882994381274313f, -0.107254423828329604454f - ); -#else - const float4_t result = float4_poly2(_a - , 2.28330284476918490682f, -1.04913055217340124191f - , 0.204446009836232697516f - ); -#endif - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_exppoly(float4_t _a) - { -#if 1 - const float4_t result = float4_poly5(_a - , 9.9999994e-1f, 6.9315308e-1f - , 2.4015361e-1f, 5.5826318e-2f - , 8.9893397e-3f, 1.8775767e-3f - ); -#elif 0 - const float4_t result = float4_poly4(_a - , 1.0000026f, 6.9300383e-1f - , 2.4144275e-1f, 5.2011464e-2f - , 1.3534167e-2f - ); -#elif 0 - const float4_t result = float4_poly3(_a - , 9.9992520e-1f, 6.9583356e-1f - , 2.2606716e-1f, 7.8024521e-2f - ); -#else - const float4_t result = float4_poly2(_a - , 1.0017247f, 6.5763628e-1f - , 3.3718944e-1f - ); -#endif // 0 - - return result; - } - } // namespace float4_internal - - BX_FLOAT4_INLINE float4_t float4_log2_ni(float4_t _a) - { - const float4_t expmask = float4_isplat(0x7f800000); - const float4_t mantmask = float4_isplat(0x007fffff); - const float4_t one = float4_splat(1.0f); - - const float4_t c127 = float4_isplat(127); - const float4_t aexp = float4_and(_a, expmask); - const float4_t aexpsr = float4_srl(aexp, 23); - const float4_t tmp0 = float4_isub(aexpsr, c127); - const float4_t exp = float4_itof(tmp0); - - const float4_t amask = float4_and(_a, mantmask); - const float4_t mant = float4_or(amask, one); - - const float4_t poly = float4_logexp_detail::float4_logpoly(mant); - - const float4_t mandiff = float4_sub(mant, one); - const float4_t result = float4_madd(poly, mandiff, exp); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_exp2_ni(float4_t _a) - { - const float4_t min = float4_splat( 129.0f); - const float4_t max = float4_splat(-126.99999f); - const float4_t tmp0 = float4_min(_a, min); - const float4_t aaaa = float4_max(tmp0, max); - - const float4_t half = float4_splat(0.5f); - const float4_t tmp2 = float4_sub(aaaa, half); - const float4_t ipart = float4_ftoi(tmp2); - const float4_t iround = float4_itof(ipart); - const float4_t fpart = float4_sub(aaaa, iround); - - const float4_t c127 = float4_isplat(127); - const float4_t tmp5 = float4_iadd(ipart, c127); - const float4_t expipart = float4_sll(tmp5, 23); - - const float4_t expfpart = float4_logexp_detail::float4_exppoly(fpart); - - const float4_t result = float4_mul(expipart, expfpart); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_pow_ni(float4_t _a, float4_t _b) - { - const float4_t alog2 = float4_log2(_a); - const float4_t alog2b = float4_mul(alog2, _b); - const float4_t result = float4_exp2(alog2b); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_dot3_ni(float4_t _a, float4_t _b) - { - const float4_t xyzw = float4_mul(_a, _b); - const float4_t xxxx = float4_swiz_xxxx(xyzw); - const float4_t yyyy = float4_swiz_yyyy(xyzw); - const float4_t zzzz = float4_swiz_zzzz(xyzw); - const float4_t tmp1 = float4_add(xxxx, yyyy); - const float4_t result = float4_add(zzzz, tmp1); - return result; - } - - BX_FLOAT4_INLINE float4_t float4_cross3_ni(float4_t _a, float4_t _b) - { - // a.yzx * b.zxy - a.zxy * b.yzx == (a * b.yzx - a.yzx * b).yzx -#if 0 - const float4_t a_yzxw = float4_swiz_yzxw(_a); - const float4_t a_zxyw = float4_swiz_zxyw(_a); - const float4_t b_zxyw = float4_swiz_zxyw(_b); - const float4_t b_yzxw = float4_swiz_yzxw(_b); - const float4_t tmp = float4_mul(a_yzxw, b_zxyw); - const float4_t result = float4_nmsub(a_zxyw, b_yzxw, tmp); -#else - const float4_t a_yzxw = float4_swiz_yzxw(_a); - const float4_t b_yzxw = float4_swiz_yzxw(_b); - const float4_t tmp0 = float4_mul(_a, b_yzxw); - const float4_t tmp1 = float4_nmsub(a_yzxw, _b, tmp0); - const float4_t result = float4_swiz_yzxw(tmp1); -#endif - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_normalize3_ni(float4_t _a) - { - const float4_t dot3 = float4_dot3(_a, _a); - const float4_t invSqrt = float4_rsqrt(dot3); - const float4_t result = float4_mul(_a, invSqrt); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_dot_ni(float4_t _a, float4_t _b) - { - const float4_t xyzw = float4_mul(_a, _b); - const float4_t yzwx = float4_swiz_yzwx(xyzw); - const float4_t tmp0 = float4_add(xyzw, yzwx); - const float4_t zwxy = float4_swiz_zwxy(tmp0); - const float4_t result = float4_add(tmp0, zwxy); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_ceil_ni(float4_t _a) - { - const float4_t tmp0 = float4_ftoi(_a); - const float4_t tmp1 = float4_itof(tmp0); - const float4_t mask = float4_cmplt(tmp1, _a); - const float4_t one = float4_splat(1.0f); - const float4_t tmp2 = float4_and(one, mask); - const float4_t result = float4_add(tmp1, tmp2); - - return result; - } - - BX_FLOAT4_INLINE float4_t float4_floor_ni(float4_t _a) - { - const float4_t tmp0 = float4_ftoi(_a); - const float4_t tmp1 = float4_itof(tmp0); - const float4_t mask = float4_cmpgt(tmp1, _a); - const float4_t one = float4_splat(1.0f); - const float4_t tmp2 = float4_and(one, mask); - const float4_t result = float4_sub(tmp1, tmp2); - - return result; - } - - BX_FLOAT4_INLINE bool float4_test_any_ni(float4_t _a) - { - const float4_t mask = float4_sra(_a, 31); - const float4_t zwxy = float4_swiz_zwxy(mask); - const float4_t tmp0 = float4_or(mask, zwxy); - const float4_t tmp1 = float4_swiz_yyyy(tmp0); - const float4_t tmp2 = float4_or(tmp0, tmp1); - int res; - float4_stx(&res, tmp2); - return 0 != res; - } - - BX_FLOAT4_INLINE bool float4_test_all_ni(float4_t _a) - { - const float4_t bits = float4_sra(_a, 31); - const float4_t m1248 = float4_ild(1, 2, 4, 8); - const float4_t mask = float4_and(bits, m1248); - const float4_t zwxy = float4_swiz_zwxy(mask); - const float4_t tmp0 = float4_or(mask, zwxy); - const float4_t tmp1 = float4_swiz_yyyy(tmp0); - const float4_t tmp2 = float4_or(tmp0, tmp1); - int res; - float4_stx(&res, tmp2); - return 0xf == res; - } - -} // namespace bx - -#endif // BX_FLOAT4_NI_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/float4_sse.h b/3rdparty/bx/include/bx/float4_sse.h deleted file mode 100644 index 73272518efe..00000000000 --- a/3rdparty/bx/include/bx/float4_sse.h +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright 2010-2016 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bx#license-bsd-2-clause - */ - -#ifndef BX_FLOAT4_SSE_H_HEADER_GUARD -#define BX_FLOAT4_SSE_H_HEADER_GUARD - -#include <emmintrin.h> // __m128i -#if defined(__SSE4_1__) -# include <smmintrin.h> -#endif // defined(__SSE4_1__) -#include <xmmintrin.h> // __m128 - -namespace bx -{ - typedef __m128 float4_t; - -#define ELEMx 0 -#define ELEMy 1 -#define ELEMz 2 -#define ELEMw 3 -#define IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ - BX_FLOAT4_FORCE_INLINE float4_t float4_swiz_##_x##_y##_z##_w(float4_t _a) \ - { \ - return _mm_shuffle_ps( _a, _a, _MM_SHUFFLE(ELEM##_w, ELEM##_z, ELEM##_y, ELEM##_x ) ); \ - } - -#include "float4_swizzle.inl" - -#undef IMPLEMENT_SWIZZLE -#undef ELEMw -#undef ELEMz -#undef ELEMy -#undef ELEMx - -#define IMPLEMENT_TEST(_xyzw, _mask) \ - BX_FLOAT4_FORCE_INLINE bool float4_test_any_##_xyzw(float4_t _test) \ - { \ - return 0x0 != (_mm_movemask_ps(_test)&(_mask) ); \ - } \ - \ - BX_FLOAT4_FORCE_INLINE bool float4_test_all_##_xyzw(float4_t _test) \ - { \ - return (_mask) == (_mm_movemask_ps(_test)&(_mask) ); \ - } - -IMPLEMENT_TEST(x , 0x1); -IMPLEMENT_TEST(y , 0x2); -IMPLEMENT_TEST(xy , 0x3); -IMPLEMENT_TEST(z , 0x4); -IMPLEMENT_TEST(xz , 0x5); -IMPLEMENT_TEST(yz , 0x6); -IMPLEMENT_TEST(xyz , 0x7); -IMPLEMENT_TEST(w , 0x8); -IMPLEMENT_TEST(xw , 0x9); -IMPLEMENT_TEST(yw , 0xa); -IMPLEMENT_TEST(xyw , 0xb); -IMPLEMENT_TEST(zw , 0xc); -IMPLEMENT_TEST(xzw , 0xd); -IMPLEMENT_TEST(yzw , 0xe); -IMPLEMENT_TEST(xyzw , 0xf); - -#undef IMPLEMENT_TEST - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xyAB(float4_t _a, float4_t _b) - { - return _mm_movelh_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_ABxy(float4_t _a, float4_t _b) - { - return _mm_movelh_ps(_b, _a); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_CDzw(float4_t _a, float4_t _b) - { - return _mm_movehl_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_zwCD(float4_t _a, float4_t _b) - { - return _mm_movehl_ps(_b, _a); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xAyB(float4_t _a, float4_t _b) - { - return _mm_unpacklo_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_yBxA(float4_t _a, float4_t _b) - { - return _mm_unpacklo_ps(_b, _a); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_zCwD(float4_t _a, float4_t _b) - { - return _mm_unpackhi_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_CzDw(float4_t _a, float4_t _b) - { - return _mm_unpackhi_ps(_b, _a); - } - - BX_FLOAT4_FORCE_INLINE float float4_x(float4_t _a) - { - return _mm_cvtss_f32(_a); - } - - BX_FLOAT4_FORCE_INLINE float float4_y(float4_t _a) - { - const float4_t yyyy = float4_swiz_yyyy(_a); - const float result = _mm_cvtss_f32(yyyy); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float float4_z(float4_t _a) - { - const float4_t zzzz = float4_swiz_zzzz(_a); - const float result = _mm_cvtss_f32(zzzz); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float float4_w(float4_t _a) - { - const float4_t wwww = float4_swiz_wwww(_a); - const float result = _mm_cvtss_f32(wwww); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_ld(const void* _ptr) - { - return _mm_load_ps(reinterpret_cast<const float*>(_ptr) ); - } - - BX_FLOAT4_FORCE_INLINE void float4_st(void* _ptr, float4_t _a) - { - _mm_store_ps(reinterpret_cast<float*>(_ptr), _a); - } - - BX_FLOAT4_FORCE_INLINE void float4_stx(void* _ptr, float4_t _a) - { - _mm_store_ss(reinterpret_cast<float*>(_ptr), _a); - } - - BX_FLOAT4_FORCE_INLINE void float4_stream(void* _ptr, float4_t _a) - { - _mm_stream_ps(reinterpret_cast<float*>(_ptr), _a); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_ld(float _x, float _y, float _z, float _w) - { - return _mm_set_ps(_w, _z, _y, _x); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) - { - const __m128i set = _mm_set_epi32(_w, _z, _y, _x); - const float4_t result = _mm_castsi128_ps(set); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_splat(const void* _ptr) - { - const float4_t x___ = _mm_load_ss(reinterpret_cast<const float*>(_ptr) ); - const float4_t result = float4_swiz_xxxx(x___); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_splat(float _a) - { - return _mm_set1_ps(_a); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_isplat(uint32_t _a) - { - const __m128i splat = _mm_set1_epi32(_a); - const float4_t result = _mm_castsi128_ps(splat); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_zero() - { - return _mm_setzero_ps(); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_itof(float4_t _a) - { - const __m128i itof = _mm_castps_si128(_a); - const float4_t result = _mm_cvtepi32_ps(itof); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_ftoi(float4_t _a) - { - const __m128i ftoi = _mm_cvtps_epi32(_a); - const float4_t result = _mm_castsi128_ps(ftoi); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_round(float4_t _a) - { -#if defined(__SSE4_1__) - return _mm_round_ps(_a, _MM_FROUND_NINT); -#else - const __m128i round = _mm_cvtps_epi32(_a); - const float4_t result = _mm_cvtepi32_ps(round); - - return result; -#endif // defined(__SSE4_1__) - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_add(float4_t _a, float4_t _b) - { - return _mm_add_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_sub(float4_t _a, float4_t _b) - { - return _mm_sub_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_mul(float4_t _a, float4_t _b) - { - return _mm_mul_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_div(float4_t _a, float4_t _b) - { - return _mm_div_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_rcp_est(float4_t _a) - { - return _mm_rcp_ps(_a); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_sqrt(float4_t _a) - { - return _mm_sqrt_ps(_a); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_rsqrt_est(float4_t _a) - { - return _mm_rsqrt_ps(_a); - } - -#if defined(__SSE4_1__) - BX_FLOAT4_FORCE_INLINE float4_t float4_dot3(float4_t _a, float4_t _b) - { - return _mm_dp_ps(_a, _b, 0x77); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_dot(float4_t _a, float4_t _b) - { - return _mm_dp_ps(_a, _b, 0xFF); - } -#endif // defined(__SSE4__) - - BX_FLOAT4_FORCE_INLINE float4_t float4_cmpeq(float4_t _a, float4_t _b) - { - return _mm_cmpeq_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_cmplt(float4_t _a, float4_t _b) - { - return _mm_cmplt_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_cmple(float4_t _a, float4_t _b) - { - return _mm_cmple_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_cmpgt(float4_t _a, float4_t _b) - { - return _mm_cmpgt_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_cmpge(float4_t _a, float4_t _b) - { - return _mm_cmpge_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_min(float4_t _a, float4_t _b) - { - return _mm_min_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_max(float4_t _a, float4_t _b) - { - return _mm_max_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_and(float4_t _a, float4_t _b) - { - return _mm_and_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_andc(float4_t _a, float4_t _b) - { - return _mm_andnot_ps(_b, _a); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_or(float4_t _a, float4_t _b) - { - return _mm_or_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_xor(float4_t _a, float4_t _b) - { - return _mm_xor_ps(_a, _b); - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_sll(float4_t _a, int _count) - { - const __m128i a = _mm_castps_si128(_a); - const __m128i shift = _mm_slli_epi32(a, _count); - const float4_t result = _mm_castsi128_ps(shift); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_srl(float4_t _a, int _count) - { - const __m128i a = _mm_castps_si128(_a); - const __m128i shift = _mm_srli_epi32(a, _count); - const float4_t result = _mm_castsi128_ps(shift); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_sra(float4_t _a, int _count) - { - const __m128i a = _mm_castps_si128(_a); - const __m128i shift = _mm_srai_epi32(a, _count); - const float4_t result = _mm_castsi128_ps(shift); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_icmpeq(float4_t _a, float4_t _b) - { - const __m128i tmp0 = _mm_castps_si128(_a); - const __m128i tmp1 = _mm_castps_si128(_b); - const __m128i tmp2 = _mm_cmpeq_epi32(tmp0, tmp1); - const float4_t result = _mm_castsi128_ps(tmp2); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_icmplt(float4_t _a, float4_t _b) - { - const __m128i tmp0 = _mm_castps_si128(_a); - const __m128i tmp1 = _mm_castps_si128(_b); - const __m128i tmp2 = _mm_cmplt_epi32(tmp0, tmp1); - const float4_t result = _mm_castsi128_ps(tmp2); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_icmpgt(float4_t _a, float4_t _b) - { - const __m128i tmp0 = _mm_castps_si128(_a); - const __m128i tmp1 = _mm_castps_si128(_b); - const __m128i tmp2 = _mm_cmpgt_epi32(tmp0, tmp1); - const float4_t result = _mm_castsi128_ps(tmp2); - - return result; - } - -#if defined(__SSE4_1__) - BX_FLOAT4_FORCE_INLINE float4_t float4_imin(float4_t _a, float4_t _b) - { - const __m128i tmp0 = _mm_castps_si128(_a); - const __m128i tmp1 = _mm_castps_si128(_b); - const __m128i tmp2 = _mm_min_epi32(tmp0, tmp1); - const float4_t result = _mm_castsi128_ps(tmp2); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_imax(float4_t _a, float4_t _b) - { - const __m128i tmp0 = _mm_castps_si128(_a); - const __m128i tmp1 = _mm_castps_si128(_b); - const __m128i tmp2 = _mm_max_epi32(tmp0, tmp1); - const float4_t result = _mm_castsi128_ps(tmp2); - - return result; - } -#endif // defined(__SSE4_1__) - - BX_FLOAT4_FORCE_INLINE float4_t float4_iadd(float4_t _a, float4_t _b) - { - const __m128i a = _mm_castps_si128(_a); - const __m128i b = _mm_castps_si128(_b); - const __m128i add = _mm_add_epi32(a, b); - const float4_t result = _mm_castsi128_ps(add); - - return result; - } - - BX_FLOAT4_FORCE_INLINE float4_t float4_isub(float4_t _a, float4_t _b) - { - const __m128i a = _mm_castps_si128(_a); - const __m128i b = _mm_castps_si128(_b); - const __m128i sub = _mm_sub_epi32(a, b); - const float4_t result = _mm_castsi128_ps(sub); - - return result; - } - -} // namespace bx - -#define float4_shuf_xAzC float4_shuf_xAzC_ni -#define float4_shuf_yBwD float4_shuf_yBwD_ni -#define float4_rcp float4_rcp_ni -#define float4_orx float4_orx_ni -#define float4_orc float4_orc_ni -#define float4_neg float4_neg_ni -#define float4_madd float4_madd_ni -#define float4_nmsub float4_nmsub_ni -#define float4_div_nr float4_div_nr_ni -#define float4_selb float4_selb_ni -#define float4_sels float4_sels_ni -#define float4_not float4_not_ni -#define float4_abs float4_abs_ni -#define float4_clamp float4_clamp_ni -#define float4_lerp float4_lerp_ni -#define float4_rsqrt float4_rsqrt_ni -#define float4_rsqrt_nr float4_rsqrt_nr_ni -#define float4_rsqrt_carmack float4_rsqrt_carmack_ni -#define float4_sqrt_nr float4_sqrt_nr_ni -#define float4_log2 float4_log2_ni -#define float4_exp2 float4_exp2_ni -#define float4_pow float4_pow_ni -#define float4_cross3 float4_cross3_ni -#define float4_normalize3 float4_normalize3_ni -#define float4_ceil float4_ceil_ni -#define float4_floor float4_floor_ni - -#if !defined(__SSE4_1__) -# define float4_dot3 float4_dot3_ni -# define float4_dot float4_dot_ni -# define float4_imin float4_imin_ni -# define float4_imax float4_imax_ni -#endif // defined(__SSE4_1__) - -#include "float4_ni.h" - -#endif // BX_FLOAT4_SSE_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/float4_swizzle.inl b/3rdparty/bx/include/bx/float4_swizzle.inl deleted file mode 100644 index e53b8f020b2..00000000000 --- a/3rdparty/bx/include/bx/float4_swizzle.inl +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright 2010-2015 Branimir Karadzic. All rights reserved. - * License: http://www.opensource.org/licenses/BSD-2-Clause - */ - -#ifndef BX_FLOAT4_T_H_HEADER_GUARD -# error "xmacro file, must be included from float4_*.h" -#endif // BX_FLOAT4_T_H_HEADER_GUARD - -// included from float4_t.h -IMPLEMENT_SWIZZLE(x, x, x, x) -IMPLEMENT_SWIZZLE(x, x, x, y) -IMPLEMENT_SWIZZLE(x, x, x, z) -IMPLEMENT_SWIZZLE(x, x, x, w) -IMPLEMENT_SWIZZLE(x, x, y, x) -IMPLEMENT_SWIZZLE(x, x, y, y) -IMPLEMENT_SWIZZLE(x, x, y, z) -IMPLEMENT_SWIZZLE(x, x, y, w) -IMPLEMENT_SWIZZLE(x, x, z, x) -IMPLEMENT_SWIZZLE(x, x, z, y) -IMPLEMENT_SWIZZLE(x, x, z, z) -IMPLEMENT_SWIZZLE(x, x, z, w) -IMPLEMENT_SWIZZLE(x, x, w, x) -IMPLEMENT_SWIZZLE(x, x, w, y) -IMPLEMENT_SWIZZLE(x, x, w, z) -IMPLEMENT_SWIZZLE(x, x, w, w) -IMPLEMENT_SWIZZLE(x, y, x, x) -IMPLEMENT_SWIZZLE(x, y, x, y) -IMPLEMENT_SWIZZLE(x, y, x, z) -IMPLEMENT_SWIZZLE(x, y, x, w) -IMPLEMENT_SWIZZLE(x, y, y, x) -IMPLEMENT_SWIZZLE(x, y, y, y) -IMPLEMENT_SWIZZLE(x, y, y, z) -IMPLEMENT_SWIZZLE(x, y, y, w) -IMPLEMENT_SWIZZLE(x, y, z, x) -IMPLEMENT_SWIZZLE(x, y, z, y) -IMPLEMENT_SWIZZLE(x, y, z, z) -// IMPLEMENT_SWIZZLE(x, y, z, w) -IMPLEMENT_SWIZZLE(x, y, w, x) -IMPLEMENT_SWIZZLE(x, y, w, y) -IMPLEMENT_SWIZZLE(x, y, w, z) -IMPLEMENT_SWIZZLE(x, y, w, w) -IMPLEMENT_SWIZZLE(x, z, x, x) -IMPLEMENT_SWIZZLE(x, z, x, y) -IMPLEMENT_SWIZZLE(x, z, x, z) -IMPLEMENT_SWIZZLE(x, z, x, w) -IMPLEMENT_SWIZZLE(x, z, y, x) -IMPLEMENT_SWIZZLE(x, z, y, y) -IMPLEMENT_SWIZZLE(x, z, y, z) -IMPLEMENT_SWIZZLE(x, z, y, w) -IMPLEMENT_SWIZZLE(x, z, z, x) -IMPLEMENT_SWIZZLE(x, z, z, y) -IMPLEMENT_SWIZZLE(x, z, z, z) -IMPLEMENT_SWIZZLE(x, z, z, w) -IMPLEMENT_SWIZZLE(x, z, w, x) -IMPLEMENT_SWIZZLE(x, z, w, y) -IMPLEMENT_SWIZZLE(x, z, w, z) -IMPLEMENT_SWIZZLE(x, z, w, w) -IMPLEMENT_SWIZZLE(x, w, x, x) -IMPLEMENT_SWIZZLE(x, w, x, y) -IMPLEMENT_SWIZZLE(x, w, x, z) -IMPLEMENT_SWIZZLE(x, w, x, w) -IMPLEMENT_SWIZZLE(x, w, y, x) -IMPLEMENT_SWIZZLE(x, w, y, y) -IMPLEMENT_SWIZZLE(x, w, y, z) -IMPLEMENT_SWIZZLE(x, w, y, w) -IMPLEMENT_SWIZZLE(x, w, z, x) -IMPLEMENT_SWIZZLE(x, w, z, y) -IMPLEMENT_SWIZZLE(x, w, z, z) -IMPLEMENT_SWIZZLE(x, w, z, w) -IMPLEMENT_SWIZZLE(x, w, w, x) -IMPLEMENT_SWIZZLE(x, w, w, y) -IMPLEMENT_SWIZZLE(x, w, w, z) -IMPLEMENT_SWIZZLE(x, w, w, w) -IMPLEMENT_SWIZZLE(y, x, x, x) -IMPLEMENT_SWIZZLE(y, x, x, y) -IMPLEMENT_SWIZZLE(y, x, x, z) -IMPLEMENT_SWIZZLE(y, x, x, w) -IMPLEMENT_SWIZZLE(y, x, y, x) -IMPLEMENT_SWIZZLE(y, x, y, y) -IMPLEMENT_SWIZZLE(y, x, y, z) -IMPLEMENT_SWIZZLE(y, x, y, w) -IMPLEMENT_SWIZZLE(y, x, z, x) -IMPLEMENT_SWIZZLE(y, x, z, y) -IMPLEMENT_SWIZZLE(y, x, z, z) -IMPLEMENT_SWIZZLE(y, x, z, w) -IMPLEMENT_SWIZZLE(y, x, w, x) -IMPLEMENT_SWIZZLE(y, x, w, y) -IMPLEMENT_SWIZZLE(y, x, w, z) -IMPLEMENT_SWIZZLE(y, x, w, w) -IMPLEMENT_SWIZZLE(y, y, x, x) -IMPLEMENT_SWIZZLE(y, y, x, y) -IMPLEMENT_SWIZZLE(y, y, x, z) -IMPLEMENT_SWIZZLE(y, y, x, w) -IMPLEMENT_SWIZZLE(y, y, y, x) -IMPLEMENT_SWIZZLE(y, y, y, y) -IMPLEMENT_SWIZZLE(y, y, y, z) -IMPLEMENT_SWIZZLE(y, y, y, w) -IMPLEMENT_SWIZZLE(y, y, z, x) -IMPLEMENT_SWIZZLE(y, y, z, y) -IMPLEMENT_SWIZZLE(y, y, z, z) -IMPLEMENT_SWIZZLE(y, y, z, w) -IMPLEMENT_SWIZZLE(y, y, w, x) -IMPLEMENT_SWIZZLE(y, y, w, y) -IMPLEMENT_SWIZZLE(y, y, w, z) -IMPLEMENT_SWIZZLE(y, y, w, w) -IMPLEMENT_SWIZZLE(y, z, x, x) -IMPLEMENT_SWIZZLE(y, z, x, y) -IMPLEMENT_SWIZZLE(y, z, x, z) -IMPLEMENT_SWIZZLE(y, z, x, w) -IMPLEMENT_SWIZZLE(y, z, y, x) -IMPLEMENT_SWIZZLE(y, z, y, y) -IMPLEMENT_SWIZZLE(y, z, y, z) -IMPLEMENT_SWIZZLE(y, z, y, w) -IMPLEMENT_SWIZZLE(y, z, z, x) -IMPLEMENT_SWIZZLE(y, z, z, y) -IMPLEMENT_SWIZZLE(y, z, z, z) -IMPLEMENT_SWIZZLE(y, z, z, w) -IMPLEMENT_SWIZZLE(y, z, w, x) -IMPLEMENT_SWIZZLE(y, z, w, y) -IMPLEMENT_SWIZZLE(y, z, w, z) -IMPLEMENT_SWIZZLE(y, z, w, w) -IMPLEMENT_SWIZZLE(y, w, x, x) -IMPLEMENT_SWIZZLE(y, w, x, y) -IMPLEMENT_SWIZZLE(y, w, x, z) -IMPLEMENT_SWIZZLE(y, w, x, w) -IMPLEMENT_SWIZZLE(y, w, y, x) -IMPLEMENT_SWIZZLE(y, w, y, y) -IMPLEMENT_SWIZZLE(y, w, y, z) -IMPLEMENT_SWIZZLE(y, w, y, w) -IMPLEMENT_SWIZZLE(y, w, z, x) -IMPLEMENT_SWIZZLE(y, w, z, y) -IMPLEMENT_SWIZZLE(y, w, z, z) -IMPLEMENT_SWIZZLE(y, w, z, w) -IMPLEMENT_SWIZZLE(y, w, w, x) -IMPLEMENT_SWIZZLE(y, w, w, y) -IMPLEMENT_SWIZZLE(y, w, w, z) -IMPLEMENT_SWIZZLE(y, w, w, w) -IMPLEMENT_SWIZZLE(z, x, x, x) -IMPLEMENT_SWIZZLE(z, x, x, y) -IMPLEMENT_SWIZZLE(z, x, x, z) -IMPLEMENT_SWIZZLE(z, x, x, w) -IMPLEMENT_SWIZZLE(z, x, y, x) -IMPLEMENT_SWIZZLE(z, x, y, y) -IMPLEMENT_SWIZZLE(z, x, y, z) -IMPLEMENT_SWIZZLE(z, x, y, w) -IMPLEMENT_SWIZZLE(z, x, z, x) -IMPLEMENT_SWIZZLE(z, x, z, y) -IMPLEMENT_SWIZZLE(z, x, z, z) -IMPLEMENT_SWIZZLE(z, x, z, w) -IMPLEMENT_SWIZZLE(z, x, w, x) -IMPLEMENT_SWIZZLE(z, x, w, y) -IMPLEMENT_SWIZZLE(z, x, w, z) -IMPLEMENT_SWIZZLE(z, x, w, w) -IMPLEMENT_SWIZZLE(z, y, x, x) -IMPLEMENT_SWIZZLE(z, y, x, y) -IMPLEMENT_SWIZZLE(z, y, x, z) -IMPLEMENT_SWIZZLE(z, y, x, w) -IMPLEMENT_SWIZZLE(z, y, y, x) -IMPLEMENT_SWIZZLE(z, y, y, y) -IMPLEMENT_SWIZZLE(z, y, y, z) -IMPLEMENT_SWIZZLE(z, y, y, w) -IMPLEMENT_SWIZZLE(z, y, z, x) -IMPLEMENT_SWIZZLE(z, y, z, y) -IMPLEMENT_SWIZZLE(z, y, z, z) -IMPLEMENT_SWIZZLE(z, y, z, w) -IMPLEMENT_SWIZZLE(z, y, w, x) -IMPLEMENT_SWIZZLE(z, y, w, y) -IMPLEMENT_SWIZZLE(z, y, w, z) -IMPLEMENT_SWIZZLE(z, y, w, w) -IMPLEMENT_SWIZZLE(z, z, x, x) -IMPLEMENT_SWIZZLE(z, z, x, y) -IMPLEMENT_SWIZZLE(z, z, x, z) -IMPLEMENT_SWIZZLE(z, z, x, w) -IMPLEMENT_SWIZZLE(z, z, y, x) -IMPLEMENT_SWIZZLE(z, z, y, y) -IMPLEMENT_SWIZZLE(z, z, y, z) -IMPLEMENT_SWIZZLE(z, z, y, w) -IMPLEMENT_SWIZZLE(z, z, z, x) -IMPLEMENT_SWIZZLE(z, z, z, y) -IMPLEMENT_SWIZZLE(z, z, z, z) -IMPLEMENT_SWIZZLE(z, z, z, w) -IMPLEMENT_SWIZZLE(z, z, w, x) -IMPLEMENT_SWIZZLE(z, z, w, y) -IMPLEMENT_SWIZZLE(z, z, w, z) -IMPLEMENT_SWIZZLE(z, z, w, w) -IMPLEMENT_SWIZZLE(z, w, x, x) -IMPLEMENT_SWIZZLE(z, w, x, y) -IMPLEMENT_SWIZZLE(z, w, x, z) -IMPLEMENT_SWIZZLE(z, w, x, w) -IMPLEMENT_SWIZZLE(z, w, y, x) -IMPLEMENT_SWIZZLE(z, w, y, y) -IMPLEMENT_SWIZZLE(z, w, y, z) -IMPLEMENT_SWIZZLE(z, w, y, w) -IMPLEMENT_SWIZZLE(z, w, z, x) -IMPLEMENT_SWIZZLE(z, w, z, y) -IMPLEMENT_SWIZZLE(z, w, z, z) -IMPLEMENT_SWIZZLE(z, w, z, w) -IMPLEMENT_SWIZZLE(z, w, w, x) -IMPLEMENT_SWIZZLE(z, w, w, y) -IMPLEMENT_SWIZZLE(z, w, w, z) -IMPLEMENT_SWIZZLE(z, w, w, w) -IMPLEMENT_SWIZZLE(w, x, x, x) -IMPLEMENT_SWIZZLE(w, x, x, y) -IMPLEMENT_SWIZZLE(w, x, x, z) -IMPLEMENT_SWIZZLE(w, x, x, w) -IMPLEMENT_SWIZZLE(w, x, y, x) -IMPLEMENT_SWIZZLE(w, x, y, y) -IMPLEMENT_SWIZZLE(w, x, y, z) -IMPLEMENT_SWIZZLE(w, x, y, w) -IMPLEMENT_SWIZZLE(w, x, z, x) -IMPLEMENT_SWIZZLE(w, x, z, y) -IMPLEMENT_SWIZZLE(w, x, z, z) -IMPLEMENT_SWIZZLE(w, x, z, w) -IMPLEMENT_SWIZZLE(w, x, w, x) -IMPLEMENT_SWIZZLE(w, x, w, y) -IMPLEMENT_SWIZZLE(w, x, w, z) -IMPLEMENT_SWIZZLE(w, x, w, w) -IMPLEMENT_SWIZZLE(w, y, x, x) -IMPLEMENT_SWIZZLE(w, y, x, y) -IMPLEMENT_SWIZZLE(w, y, x, z) -IMPLEMENT_SWIZZLE(w, y, x, w) -IMPLEMENT_SWIZZLE(w, y, y, x) -IMPLEMENT_SWIZZLE(w, y, y, y) -IMPLEMENT_SWIZZLE(w, y, y, z) -IMPLEMENT_SWIZZLE(w, y, y, w) -IMPLEMENT_SWIZZLE(w, y, z, x) -IMPLEMENT_SWIZZLE(w, y, z, y) -IMPLEMENT_SWIZZLE(w, y, z, z) -IMPLEMENT_SWIZZLE(w, y, z, w) -IMPLEMENT_SWIZZLE(w, y, w, x) -IMPLEMENT_SWIZZLE(w, y, w, y) -IMPLEMENT_SWIZZLE(w, y, w, z) -IMPLEMENT_SWIZZLE(w, y, w, w) -IMPLEMENT_SWIZZLE(w, z, x, x) -IMPLEMENT_SWIZZLE(w, z, x, y) -IMPLEMENT_SWIZZLE(w, z, x, z) -IMPLEMENT_SWIZZLE(w, z, x, w) -IMPLEMENT_SWIZZLE(w, z, y, x) -IMPLEMENT_SWIZZLE(w, z, y, y) -IMPLEMENT_SWIZZLE(w, z, y, z) -IMPLEMENT_SWIZZLE(w, z, y, w) -IMPLEMENT_SWIZZLE(w, z, z, x) -IMPLEMENT_SWIZZLE(w, z, z, y) -IMPLEMENT_SWIZZLE(w, z, z, z) -IMPLEMENT_SWIZZLE(w, z, z, w) -IMPLEMENT_SWIZZLE(w, z, w, x) -IMPLEMENT_SWIZZLE(w, z, w, y) -IMPLEMENT_SWIZZLE(w, z, w, z) -IMPLEMENT_SWIZZLE(w, z, w, w) -IMPLEMENT_SWIZZLE(w, w, x, x) -IMPLEMENT_SWIZZLE(w, w, x, y) -IMPLEMENT_SWIZZLE(w, w, x, z) -IMPLEMENT_SWIZZLE(w, w, x, w) -IMPLEMENT_SWIZZLE(w, w, y, x) -IMPLEMENT_SWIZZLE(w, w, y, y) -IMPLEMENT_SWIZZLE(w, w, y, z) -IMPLEMENT_SWIZZLE(w, w, y, w) -IMPLEMENT_SWIZZLE(w, w, z, x) -IMPLEMENT_SWIZZLE(w, w, z, y) -IMPLEMENT_SWIZZLE(w, w, z, z) -IMPLEMENT_SWIZZLE(w, w, z, w) -IMPLEMENT_SWIZZLE(w, w, w, x) -IMPLEMENT_SWIZZLE(w, w, w, y) -IMPLEMENT_SWIZZLE(w, w, w, z) -IMPLEMENT_SWIZZLE(w, w, w, w) diff --git a/3rdparty/bx/include/bx/float4_t.h b/3rdparty/bx/include/bx/float4_t.h deleted file mode 100644 index 78fd4e8ebb5..00000000000 --- a/3rdparty/bx/include/bx/float4_t.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2010-2016 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bx#license-bsd-2-clause - */ - -#ifndef BX_FLOAT4_T_H_HEADER_GUARD -#define BX_FLOAT4_T_H_HEADER_GUARD - -#include "bx.h" - -#define BX_FLOAT4_FORCE_INLINE BX_FORCE_INLINE -#define BX_FLOAT4_INLINE static inline - -#if defined(__SSE2__) || (BX_COMPILER_MSVC && (BX_ARCH_64BIT || _M_IX86_FP >= 2) ) -# include "float4_sse.h" -#elif defined(__ARM_NEON__) && !BX_COMPILER_CLANG -# include "float4_neon.h" -#elif BX_COMPILER_CLANG \ - && !BX_PLATFORM_EMSCRIPTEN \ - && !BX_PLATFORM_IOS \ - && BX_CLANG_HAS_EXTENSION(attribute_ext_vector_type) -# include "float4_langext.h" -#else -# ifndef BX_FLOAT4_WARN_REFERENCE_IMPL -# define BX_FLOAT4_WARN_REFERENCE_IMPL 0 -# endif // BX_FLOAT4_WARN_REFERENCE_IMPL - -# if BX_FLOAT4_WARN_REFERENCE_IMPL -# pragma message("************************************\nUsing SIMD reference implementation!\n************************************") -# endif // BX_FLOAT4_WARN_REFERENCE_IMPL - -# include "float4_ref.h" -#endif // - -#endif // BX_FLOAT4_T_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/float4x4_t.h b/3rdparty/bx/include/bx/float4x4_t.h index e1bc4e1ca61..269dd633d3d 100644 --- a/3rdparty/bx/include/bx/float4x4_t.h +++ b/3rdparty/bx/include/bx/float4x4_t.h @@ -6,151 +6,151 @@ #ifndef BX_FLOAT4X4_H_HEADER_GUARD #define BX_FLOAT4X4_H_HEADER_GUARD -#include "float4_t.h" +#include "simd_t.h" namespace bx { BX_ALIGN_DECL_16(struct) float4x4_t { - float4_t col[4]; + simd128_t col[4]; }; - BX_FLOAT4_FORCE_INLINE float4_t float4_mul_xyz1(float4_t _a, const float4x4_t* _b) + BX_SIMD_FORCE_INLINE simd128_t simd_mul_xyz1(simd128_t _a, const float4x4_t* _b) { - const float4_t xxxx = float4_swiz_xxxx(_a); - const float4_t yyyy = float4_swiz_yyyy(_a); - const float4_t zzzz = float4_swiz_zzzz(_a); - const float4_t col0 = float4_mul(_b->col[0], xxxx); - const float4_t col1 = float4_mul(_b->col[1], yyyy); - const float4_t col2 = float4_madd(_b->col[2], zzzz, col0); - const float4_t col3 = float4_add(_b->col[3], col1); - const float4_t result = float4_add(col2, col3); + const simd128_t xxxx = simd_swiz_xxxx(_a); + const simd128_t yyyy = simd_swiz_yyyy(_a); + const simd128_t zzzz = simd_swiz_zzzz(_a); + const simd128_t col0 = simd_mul(_b->col[0], xxxx); + const simd128_t col1 = simd_mul(_b->col[1], yyyy); + const simd128_t col2 = simd_madd(_b->col[2], zzzz, col0); + const simd128_t col3 = simd_add(_b->col[3], col1); + const simd128_t result = simd_add(col2, col3); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_mul(float4_t _a, const float4x4_t* _b) + BX_SIMD_FORCE_INLINE simd128_t simd_mul(simd128_t _a, const float4x4_t* _b) { - const float4_t xxxx = float4_swiz_xxxx(_a); - const float4_t yyyy = float4_swiz_yyyy(_a); - const float4_t zzzz = float4_swiz_zzzz(_a); - const float4_t wwww = float4_swiz_wwww(_a); - const float4_t col0 = float4_mul(_b->col[0], xxxx); - const float4_t col1 = float4_mul(_b->col[1], yyyy); - const float4_t col2 = float4_madd(_b->col[2], zzzz, col0); - const float4_t col3 = float4_madd(_b->col[3], wwww, col1); - const float4_t result = float4_add(col2, col3); + const simd128_t xxxx = simd_swiz_xxxx(_a); + const simd128_t yyyy = simd_swiz_yyyy(_a); + const simd128_t zzzz = simd_swiz_zzzz(_a); + const simd128_t wwww = simd_swiz_wwww(_a); + const simd128_t col0 = simd_mul(_b->col[0], xxxx); + const simd128_t col1 = simd_mul(_b->col[1], yyyy); + const simd128_t col2 = simd_madd(_b->col[2], zzzz, col0); + const simd128_t col3 = simd_madd(_b->col[3], wwww, col1); + const simd128_t result = simd_add(col2, col3); return result; } - BX_FLOAT4_INLINE void float4x4_mul(float4x4_t* __restrict _result, const float4x4_t* __restrict _a, const float4x4_t* __restrict _b) + BX_SIMD_INLINE void float4x4_mul(float4x4_t* __restrict _result, const float4x4_t* __restrict _a, const float4x4_t* __restrict _b) { - _result->col[0] = float4_mul(_a->col[0], _b); - _result->col[1] = float4_mul(_a->col[1], _b); - _result->col[2] = float4_mul(_a->col[2], _b); - _result->col[3] = float4_mul(_a->col[3], _b); + _result->col[0] = simd_mul(_a->col[0], _b); + _result->col[1] = simd_mul(_a->col[1], _b); + _result->col[2] = simd_mul(_a->col[2], _b); + _result->col[3] = simd_mul(_a->col[3], _b); } - BX_FLOAT4_FORCE_INLINE void float4x4_transpose(float4x4_t* __restrict _result, const float4x4_t* __restrict _mtx) + BX_SIMD_FORCE_INLINE void float4x4_transpose(float4x4_t* __restrict _result, const float4x4_t* __restrict _mtx) { - const float4_t aibj = float4_shuf_xAyB(_mtx->col[0], _mtx->col[2]); // aibj - const float4_t emfn = float4_shuf_xAyB(_mtx->col[1], _mtx->col[3]); // emfn - const float4_t ckdl = float4_shuf_zCwD(_mtx->col[0], _mtx->col[2]); // ckdl - const float4_t gohp = float4_shuf_zCwD(_mtx->col[1], _mtx->col[3]); // gohp - _result->col[0] = float4_shuf_xAyB(aibj, emfn); // aeim - _result->col[1] = float4_shuf_zCwD(aibj, emfn); // bfjn - _result->col[2] = float4_shuf_xAyB(ckdl, gohp); // cgko - _result->col[3] = float4_shuf_zCwD(ckdl, gohp); // dhlp + const simd128_t aibj = simd_shuf_xAyB(_mtx->col[0], _mtx->col[2]); // aibj + const simd128_t emfn = simd_shuf_xAyB(_mtx->col[1], _mtx->col[3]); // emfn + const simd128_t ckdl = simd_shuf_zCwD(_mtx->col[0], _mtx->col[2]); // ckdl + const simd128_t gohp = simd_shuf_zCwD(_mtx->col[1], _mtx->col[3]); // gohp + _result->col[0] = simd_shuf_xAyB(aibj, emfn); // aeim + _result->col[1] = simd_shuf_zCwD(aibj, emfn); // bfjn + _result->col[2] = simd_shuf_xAyB(ckdl, gohp); // cgko + _result->col[3] = simd_shuf_zCwD(ckdl, gohp); // dhlp } - BX_FLOAT4_INLINE void float4x4_inverse(float4x4_t* __restrict _result, const float4x4_t* __restrict _a) + BX_SIMD_INLINE void float4x4_inverse(float4x4_t* __restrict _result, const float4x4_t* __restrict _a) { - const float4_t tmp0 = float4_shuf_xAzC(_a->col[0], _a->col[1]); - const float4_t tmp1 = float4_shuf_xAzC(_a->col[2], _a->col[3]); - const float4_t tmp2 = float4_shuf_yBwD(_a->col[0], _a->col[1]); - const float4_t tmp3 = float4_shuf_yBwD(_a->col[2], _a->col[3]); - const float4_t t0 = float4_shuf_xyAB(tmp0, tmp1); - const float4_t t1 = float4_shuf_xyAB(tmp3, tmp2); - const float4_t t2 = float4_shuf_zwCD(tmp0, tmp1); - const float4_t t3 = float4_shuf_zwCD(tmp3, tmp2); - - const float4_t t23 = float4_mul(t2, t3); - const float4_t t23_yxwz = float4_swiz_yxwz(t23); - const float4_t t23_wzyx = float4_swiz_wzyx(t23); - - float4_t cof0, cof1, cof2, cof3; - - const float4_t zero = float4_zero(); - cof0 = float4_nmsub(t1, t23_yxwz, zero); - cof0 = float4_madd(t1, t23_wzyx, cof0); - - cof1 = float4_nmsub(t0, t23_yxwz, zero); - cof1 = float4_madd(t0, t23_wzyx, cof1); - cof1 = float4_swiz_zwxy(cof1); - - const float4_t t12 = float4_mul(t1, t2); - const float4_t t12_yxwz = float4_swiz_yxwz(t12); - const float4_t t12_wzyx = float4_swiz_wzyx(t12); - - cof0 = float4_madd(t3, t12_yxwz, cof0); - cof0 = float4_nmsub(t3, t12_wzyx, cof0); - - cof3 = float4_mul(t0, t12_yxwz); - cof3 = float4_nmsub(t0, t12_wzyx, cof3); - cof3 = float4_swiz_zwxy(cof3); - - const float4_t t1_zwxy = float4_swiz_zwxy(t1); - const float4_t t2_zwxy = float4_swiz_zwxy(t2); - - const float4_t t13 = float4_mul(t1_zwxy, t3); - const float4_t t13_yxwz = float4_swiz_yxwz(t13); - const float4_t t13_wzyx = float4_swiz_wzyx(t13); - - cof0 = float4_madd(t2_zwxy, t13_yxwz, cof0); - cof0 = float4_nmsub(t2_zwxy, t13_wzyx, cof0); - - cof2 = float4_mul(t0, t13_yxwz); - cof2 = float4_nmsub(t0, t13_wzyx, cof2); - cof2 = float4_swiz_zwxy(cof2); - - const float4_t t01 = float4_mul(t0, t1); - const float4_t t01_yxwz = float4_swiz_yxwz(t01); - const float4_t t01_wzyx = float4_swiz_wzyx(t01); - - cof2 = float4_nmsub(t3, t01_yxwz, cof2); - cof2 = float4_madd(t3, t01_wzyx, cof2); - - cof3 = float4_madd(t2_zwxy, t01_yxwz, cof3); - cof3 = float4_nmsub(t2_zwxy, t01_wzyx, cof3); - - const float4_t t03 = float4_mul(t0, t3); - const float4_t t03_yxwz = float4_swiz_yxwz(t03); - const float4_t t03_wzyx = float4_swiz_wzyx(t03); - - cof1 = float4_nmsub(t2_zwxy, t03_yxwz, cof1); - cof1 = float4_madd(t2_zwxy, t03_wzyx, cof1); - - cof2 = float4_madd(t1, t03_yxwz, cof2); - cof2 = float4_nmsub(t1, t03_wzyx, cof2); - - const float4_t t02 = float4_mul(t0, t2_zwxy); - const float4_t t02_yxwz = float4_swiz_yxwz(t02); - const float4_t t02_wzyx = float4_swiz_wzyx(t02); - - cof1 = float4_madd(t3, t02_yxwz, cof1); - cof1 = float4_nmsub(t3, t02_wzyx, cof1); - - cof3 = float4_nmsub(t1, t02_yxwz, cof3); - cof3 = float4_madd(t1, t02_wzyx, cof3); - - const float4_t det = float4_dot(t0, cof0); - const float4_t invdet = float4_rcp(det); - - _result->col[0] = float4_mul(cof0, invdet); - _result->col[1] = float4_mul(cof1, invdet); - _result->col[2] = float4_mul(cof2, invdet); - _result->col[3] = float4_mul(cof3, invdet); + const simd128_t tmp0 = simd_shuf_xAzC(_a->col[0], _a->col[1]); + const simd128_t tmp1 = simd_shuf_xAzC(_a->col[2], _a->col[3]); + const simd128_t tmp2 = simd_shuf_yBwD(_a->col[0], _a->col[1]); + const simd128_t tmp3 = simd_shuf_yBwD(_a->col[2], _a->col[3]); + const simd128_t t0 = simd_shuf_xyAB(tmp0, tmp1); + const simd128_t t1 = simd_shuf_xyAB(tmp3, tmp2); + const simd128_t t2 = simd_shuf_zwCD(tmp0, tmp1); + const simd128_t t3 = simd_shuf_zwCD(tmp3, tmp2); + + const simd128_t t23 = simd_mul(t2, t3); + const simd128_t t23_yxwz = simd_swiz_yxwz(t23); + const simd128_t t23_wzyx = simd_swiz_wzyx(t23); + + simd128_t cof0, cof1, cof2, cof3; + + const simd128_t zero = simd_zero(); + cof0 = simd_nmsub(t1, t23_yxwz, zero); + cof0 = simd_madd(t1, t23_wzyx, cof0); + + cof1 = simd_nmsub(t0, t23_yxwz, zero); + cof1 = simd_madd(t0, t23_wzyx, cof1); + cof1 = simd_swiz_zwxy(cof1); + + const simd128_t t12 = simd_mul(t1, t2); + const simd128_t t12_yxwz = simd_swiz_yxwz(t12); + const simd128_t t12_wzyx = simd_swiz_wzyx(t12); + + cof0 = simd_madd(t3, t12_yxwz, cof0); + cof0 = simd_nmsub(t3, t12_wzyx, cof0); + + cof3 = simd_mul(t0, t12_yxwz); + cof3 = simd_nmsub(t0, t12_wzyx, cof3); + cof3 = simd_swiz_zwxy(cof3); + + const simd128_t t1_zwxy = simd_swiz_zwxy(t1); + const simd128_t t2_zwxy = simd_swiz_zwxy(t2); + + const simd128_t t13 = simd_mul(t1_zwxy, t3); + const simd128_t t13_yxwz = simd_swiz_yxwz(t13); + const simd128_t t13_wzyx = simd_swiz_wzyx(t13); + + cof0 = simd_madd(t2_zwxy, t13_yxwz, cof0); + cof0 = simd_nmsub(t2_zwxy, t13_wzyx, cof0); + + cof2 = simd_mul(t0, t13_yxwz); + cof2 = simd_nmsub(t0, t13_wzyx, cof2); + cof2 = simd_swiz_zwxy(cof2); + + const simd128_t t01 = simd_mul(t0, t1); + const simd128_t t01_yxwz = simd_swiz_yxwz(t01); + const simd128_t t01_wzyx = simd_swiz_wzyx(t01); + + cof2 = simd_nmsub(t3, t01_yxwz, cof2); + cof2 = simd_madd(t3, t01_wzyx, cof2); + + cof3 = simd_madd(t2_zwxy, t01_yxwz, cof3); + cof3 = simd_nmsub(t2_zwxy, t01_wzyx, cof3); + + const simd128_t t03 = simd_mul(t0, t3); + const simd128_t t03_yxwz = simd_swiz_yxwz(t03); + const simd128_t t03_wzyx = simd_swiz_wzyx(t03); + + cof1 = simd_nmsub(t2_zwxy, t03_yxwz, cof1); + cof1 = simd_madd(t2_zwxy, t03_wzyx, cof1); + + cof2 = simd_madd(t1, t03_yxwz, cof2); + cof2 = simd_nmsub(t1, t03_wzyx, cof2); + + const simd128_t t02 = simd_mul(t0, t2_zwxy); + const simd128_t t02_yxwz = simd_swiz_yxwz(t02); + const simd128_t t02_wzyx = simd_swiz_wzyx(t02); + + cof1 = simd_madd(t3, t02_yxwz, cof1); + cof1 = simd_nmsub(t3, t02_wzyx, cof1); + + cof3 = simd_nmsub(t1, t02_yxwz, cof3); + cof3 = simd_madd(t1, t02_wzyx, cof3); + + const simd128_t det = simd_dot(t0, cof0); + const simd128_t invdet = simd_rcp(det); + + _result->col[0] = simd_mul(cof0, invdet); + _result->col[1] = simd_mul(cof1, invdet); + _result->col[2] = simd_mul(cof2, invdet); + _result->col[3] = simd_mul(cof3, invdet); } } // namespace bx diff --git a/3rdparty/bx/include/bx/fpumath.h b/3rdparty/bx/include/bx/fpumath.h index 5f64564f688..7d7a2671bb2 100644 --- a/3rdparty/bx/include/bx/fpumath.h +++ b/3rdparty/bx/include/bx/fpumath.h @@ -341,7 +341,7 @@ namespace bx _result[2] = 1.0f / _a[2]; } - inline void vec3TangentFrame(const float* _n, float* _t, float* _b) + inline void vec3TangentFrame(const float* __restrict _n, float* __restrict _t, float* __restrict _b) { const float nx = _n[0]; const float ny = _n[1]; @@ -550,6 +550,30 @@ namespace bx _result[15] = 1.0f; } + inline void mtxScale(float* _result, float _scale) + { + mtxScale(_result, _scale, _scale, _scale); + } + + inline void mtxFromNormal(float* __restrict _result, const float* __restrict _normal, float _scale, const float* __restrict _pos) + { + float tangent[3]; + float bitangent[3]; + vec3TangentFrame(_normal, tangent, bitangent); + + vec3Mul(&_result[ 0], bitangent, _scale); + vec3Mul(&_result[ 4], _normal, _scale); + vec3Mul(&_result[ 8], tangent, _scale); + + _result[ 3] = 0.0f; + _result[ 7] = 0.0f; + _result[11] = 0.0f; + _result[12] = _pos[0]; + _result[13] = _pos[1]; + _result[14] = _pos[2]; + _result[15] = 1.0f; + } + inline void mtxQuat(float* __restrict _result, const float* __restrict _quat) { const float x = _quat[0]; diff --git a/3rdparty/bx/include/bx/handlealloc.h b/3rdparty/bx/include/bx/handlealloc.h index 7b10209ab2d..aad39cdd6f3 100644 --- a/3rdparty/bx/include/bx/handlealloc.h +++ b/3rdparty/bx/include/bx/handlealloc.h @@ -151,8 +151,6 @@ namespace bx static const uint16_t invalid = UINT16_MAX; HandleListT() - : m_front(invalid) - , m_back(invalid) { reset(); } @@ -250,6 +248,8 @@ namespace bx void reset() { memset(m_links, 0xff, sizeof(m_links) ); + m_front = invalid; + m_back = invalid; } private: diff --git a/3rdparty/bx/include/bx/macros.h b/3rdparty/bx/include/bx/macros.h index b4eaeae9287..870f8726738 100644 --- a/3rdparty/bx/include/bx/macros.h +++ b/3rdparty/bx/include/bx/macros.h @@ -63,7 +63,7 @@ #if BX_COMPILER_GCC || BX_COMPILER_CLANG # define BX_ALIGN_DECL(_align, _decl) _decl __attribute__( (aligned(_align) ) ) # define BX_ALLOW_UNUSED __attribute__( (unused) ) -# define BX_FORCE_INLINE __extension__ static __inline __attribute__( (__always_inline__) ) +# define BX_FORCE_INLINE inline __attribute__( (__always_inline__) ) # define BX_FUNCTION __PRETTY_FUNCTION__ # define BX_LIKELY(_x) __builtin_expect(!!(_x), 1) # define BX_UNLIKELY(_x) __builtin_expect(!!(_x), 0) @@ -71,7 +71,7 @@ # define BX_NO_RETURN __attribute__( (noreturn) ) # define BX_NO_VTABLE # define BX_OVERRIDE -# define BX_PRINTF_ARGS(_format, _args) __attribute__ ( (format(__printf__, _format, _args) ) ) +# define BX_PRINTF_ARGS(_format, _args) __attribute__( (format(__printf__, _format, _args) ) ) # if BX_CLANG_HAS_FEATURE(cxx_thread_local) # define BX_THREAD_LOCAL __thread # endif // BX_COMPILER_CLANG @@ -79,9 +79,9 @@ # define BX_THREAD_LOCAL __thread # endif // BX_COMPILER_GCC # define BX_ATTRIBUTE(_x) __attribute__( (_x) ) -# if BX_COMPILER_MSVC_COMPATIBLE +# if BX_CRT_MSVC # define __stdcall -# endif // BX_COMPILER_MSVC_COMPATIBLE +# endif // BX_CRT_MSVC #elif BX_COMPILER_MSVC # define BX_ALIGN_DECL(_align, _decl) __declspec(align(_align) ) _decl # define BX_ALLOW_UNUSED diff --git a/3rdparty/bx/include/bx/os.h b/3rdparty/bx/include/bx/os.h index 80ce4d5c5f9..0bdeb3c1eba 100644 --- a/3rdparty/bx/include/bx/os.h +++ b/3rdparty/bx/include/bx/os.h @@ -53,17 +53,17 @@ # elif BX_PLATFORM_OSX # include <mach/mach.h> // mach_task_basic_info # elif BX_PLATFORM_HURD -# include <pthread/pthread.h> // pthread_self +# include <unistd.h> // getpid # elif BX_PLATFORM_ANDROID # include "debug.h" // getTid is not implemented... # endif // BX_PLATFORM_ANDROID #endif // BX_PLATFORM_ -#if BX_COMPILER_MSVC_COMPATIBLE +#if BX_CRT_MSVC # include <direct.h> // _getcwd #else # include <unistd.h> // getcwd -#endif // BX_COMPILER_MSVC +#endif // BX_CRT_MSVC #if BX_PLATFORM_OSX # define BX_DL_EXT "dylib" @@ -259,7 +259,7 @@ namespace bx || BX_PLATFORM_WINRT BX_UNUSED(_path); return -1; -#elif BX_COMPILER_MSVC_COMPATIBLE +#elif BX_CRT_MSVC return ::_chdir(_path); #else return ::chdir(_path); @@ -273,7 +273,7 @@ namespace bx || BX_PLATFORM_WINRT BX_UNUSED(_buffer, _size); return NULL; -#elif BX_COMPILER_MSVC_COMPATIBLE +#elif BX_CRT_MSVC return ::_getcwd(_buffer, (int)_size); #else return ::getcwd(_buffer, _size); diff --git a/3rdparty/bx/include/bx/platform.h b/3rdparty/bx/include/bx/platform.h index 1c7b7d01414..02a80045285 100644 --- a/3rdparty/bx/include/bx/platform.h +++ b/3rdparty/bx/include/bx/platform.h @@ -15,7 +15,6 @@ #define BX_COMPILER_CLANG_ANALYZER 0 #define BX_COMPILER_GCC 0 #define BX_COMPILER_MSVC 0 -#define BX_COMPILER_MSVC_COMPATIBLE (BX_CRT_MSVC) // Endianess #define BX_CPU_ENDIAN_BIG 0 diff --git a/3rdparty/bx/include/bx/readerwriter.h b/3rdparty/bx/include/bx/readerwriter.h index 5460505a42e..47c5899d3f1 100644 --- a/3rdparty/bx/include/bx/readerwriter.h +++ b/3rdparty/bx/include/bx/readerwriter.h @@ -16,7 +16,7 @@ #include "error.h" #include "uint32_t.h" -#if BX_COMPILER_MSVC_COMPATIBLE +#if BX_CRT_MSVC # define fseeko64 _fseeki64 # define ftello64 _ftelli64 #elif BX_PLATFORM_ANDROID || BX_PLATFORM_BSD || BX_PLATFORM_IOS || BX_PLATFORM_OSX || BX_PLATFORM_QNX @@ -401,7 +401,7 @@ namespace bx } int64_t remainder = m_top-m_pos; - int32_t size = uint32_min(_size, int32_t(remainder > INT32_MAX ? INT32_MAX : remainder) ); + int32_t size = uint32_min(_size, uint32_t(int64_min(remainder, INT32_MAX) ) ); m_pos += size; if (size != _size) { @@ -454,7 +454,7 @@ namespace bx BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); int64_t remainder = m_top-m_pos; - int32_t size = uint32_min(_size, int32_t(remainder > INT32_MAX ? INT32_MAX : remainder) ); + int32_t size = uint32_min(_size, uint32_t(int64_min(remainder, INT32_MAX) ) ); memcpy(_data, &m_data[m_pos], size); m_pos += size; if (size != _size) @@ -535,7 +535,7 @@ namespace bx } int64_t remainder = m_size-m_pos; - int32_t size = uint32_min(_size, int32_t(remainder > INT32_MAX ? INT32_MAX : remainder) ); + int32_t size = uint32_min(_size, uint32_t(int64_min(remainder, INT32_MAX) ) ); memcpy(&m_data[m_pos], _data, size); m_pos += size; m_top = int64_max(m_top, m_pos); diff --git a/3rdparty/bx/include/bx/simd128_langext.inl b/3rdparty/bx/include/bx/simd128_langext.inl new file mode 100644 index 00000000000..c89e6123349 --- /dev/null +++ b/3rdparty/bx/include/bx/simd128_langext.inl @@ -0,0 +1,515 @@ +/* + * Copyright 2010-2016 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#ifndef BX_SIMD128_LANGEXT_H_HEADER_GUARD +#define BX_SIMD128_LANGEXT_H_HEADER_GUARD + +#define simd_rcp simd_rcp_ni +#define simd_orx simd_orx_ni +#define simd_orc simd_orc_ni +#define simd_neg simd_neg_ni +#define simd_madd simd_madd_ni +#define simd_nmsub simd_nmsub_ni +#define simd_div_nr simd_div_nr_ni +#define simd_selb simd_selb_ni +#define simd_sels simd_sels_ni +#define simd_not simd_not_ni +#define simd_abs simd_abs_ni +#define simd_clamp simd_clamp_ni +#define simd_lerp simd_lerp_ni +#define simd_rcp_est simd_rcp_ni +#define simd_rsqrt simd_rsqrt_ni +#define simd_rsqrt_nr simd_rsqrt_nr_ni +#define simd_rsqrt_carmack simd_rsqrt_carmack_ni +#define simd_sqrt_nr simd_sqrt_nr_ni +#define simd_log2 simd_log2_ni +#define simd_exp2 simd_exp2_ni +#define simd_pow simd_pow_ni +#define simd_cross3 simd_cross3_ni +#define simd_normalize3 simd_normalize3_ni +#define simd_dot3 simd_dot3_ni +#define simd_dot simd_dot_ni +#define simd_ceil simd_ceil_ni +#define simd_floor simd_floor_ni +#define simd_min simd_min_ni +#define simd_max simd_max_ni +#define simd_imin simd_imin_ni +#define simd_imax simd_imax_ni + +#include "simd_ni.inl" + +namespace bx +{ +#define ELEMx 0 +#define ELEMy 1 +#define ELEMz 2 +#define ELEMw 3 +#define BX_SIMD128_IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ + template<> \ + BX_SIMD_FORCE_INLINE simd128_langext_t simd_swiz_##_x##_y##_z##_w(simd128_langext_t _a) \ + { \ + simd128_langext_t result; \ + result.vf = __builtin_shufflevector(_a.vf, _a.vf, ELEM##_x, ELEM##_y, ELEM##_z, ELEM##_w); \ + return result; \ + } + +#include "simd128_swizzle.inl" + +#undef BX_SIMD128_IMPLEMENT_SWIZZLE +#undef ELEMw +#undef ELEMz +#undef ELEMy +#undef ELEMx + +#define BX_SIMD128_IMPLEMENT_TEST(_xyzw, _mask) \ + template<> \ + BX_SIMD_FORCE_INLINE bool simd_test_any_##_xyzw(simd128_langext_t _test) \ + { \ + uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ + | ( (_test.uxyzw[2]>>31)<<2) \ + | ( (_test.uxyzw[1]>>31)<<1) \ + | ( _test.uxyzw[0]>>31) \ + ; \ + return 0 != (tmp&(_mask) ); \ + } \ + \ + template<> \ + BX_SIMD_FORCE_INLINE bool simd_test_all_##_xyzw(simd128_langext_t _test) \ + { \ + uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ + | ( (_test.uxyzw[2]>>31)<<2) \ + | ( (_test.uxyzw[1]>>31)<<1) \ + | ( _test.uxyzw[0]>>31) \ + ; \ + return (_mask) == (tmp&(_mask) ); \ + } + +BX_SIMD128_IMPLEMENT_TEST(x , 0x1); +BX_SIMD128_IMPLEMENT_TEST(y , 0x2); +BX_SIMD128_IMPLEMENT_TEST(xy , 0x3); +BX_SIMD128_IMPLEMENT_TEST(z , 0x4); +BX_SIMD128_IMPLEMENT_TEST(xz , 0x5); +BX_SIMD128_IMPLEMENT_TEST(yz , 0x6); +BX_SIMD128_IMPLEMENT_TEST(xyz , 0x7); +BX_SIMD128_IMPLEMENT_TEST(w , 0x8); +BX_SIMD128_IMPLEMENT_TEST(xw , 0x9); +BX_SIMD128_IMPLEMENT_TEST(yw , 0xa); +BX_SIMD128_IMPLEMENT_TEST(xyw , 0xb); +BX_SIMD128_IMPLEMENT_TEST(zw , 0xc); +BX_SIMD128_IMPLEMENT_TEST(xzw , 0xd); +BX_SIMD128_IMPLEMENT_TEST(yzw , 0xe); +BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf); + +#undef BX_SIMD128_IMPLEMENT_TEST + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_shuf_xyAB(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 0, 1, 4, 5); + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_shuf_ABxy(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 4, 5, 0, 1); + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_shuf_CDzw(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 6, 7, 2, 3); + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_shuf_zwCD(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 2, 3, 6, 7); + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_shuf_xAyB(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 0, 4, 1, 5); + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_shuf_yBxA(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 1, 5, 0, 4); + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_shuf_zCwD(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 2, 6, 3, 7); + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_shuf_CzDw(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 6, 2, 7, 3); + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_shuf_xAzC(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 0, 4, 2, 6); + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_shuf_yBwD(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vf = __builtin_shufflevector(_a.vf, _b.vf, 1, 5, 3, 7); + return result; + } + + template<> + BX_SIMD_FORCE_INLINE float simd_x(simd128_langext_t _a) + { + return _a.fxyzw[0]; + } + + template<> + BX_SIMD_FORCE_INLINE float simd_y(simd128_langext_t _a) + { + return _a.fxyzw[1]; + } + + template<> + BX_SIMD_FORCE_INLINE float simd_z(simd128_langext_t _a) + { + return _a.fxyzw[2]; + } + + template<> + BX_SIMD_FORCE_INLINE float simd_w(simd128_langext_t _a) + { + return _a.fxyzw[3]; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_ld(const void* _ptr) + { + const uint32_t* input = reinterpret_cast<const uint32_t*>(_ptr); + simd128_langext_t result; + result.uxyzw[0] = input[0]; + result.uxyzw[1] = input[1]; + result.uxyzw[2] = input[2]; + result.uxyzw[3] = input[3]; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE void simd_st(void* _ptr, simd128_langext_t _a) + { + uint32_t* result = reinterpret_cast<uint32_t*>(_ptr); + result[0] = _a.uxyzw[0]; + result[1] = _a.uxyzw[1]; + result[2] = _a.uxyzw[2]; + result[3] = _a.uxyzw[3]; + } + + template<> + BX_SIMD_FORCE_INLINE void simd_stx(void* _ptr, simd128_langext_t _a) + { + uint32_t* result = reinterpret_cast<uint32_t*>(_ptr); + result[0] = _a.uxyzw[0]; + } + + template<> + BX_SIMD_FORCE_INLINE void simd_stream(void* _ptr, simd128_langext_t _a) + { + uint32_t* result = reinterpret_cast<uint32_t*>(_ptr); + result[0] = _a.uxyzw[0]; + result[1] = _a.uxyzw[1]; + result[2] = _a.uxyzw[2]; + result[3] = _a.uxyzw[3]; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_ld(float _x, float _y, float _z, float _w) + { + simd128_langext_t result; + result.vf = (float __attribute__((vector_size(16)))){ _x, _y, _z, _w }; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) + { + simd128_langext_t result; + result.vu = (uint32_t __attribute__((vector_size(16)))){ _x, _y, _z, _w }; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_splat(const void* _ptr) + { + const uint32_t val = *reinterpret_cast<const uint32_t*>(_ptr); + simd128_langext_t result; + result.vu = (uint32_t __attribute__((vector_size(16)))){ val, val, val, val }; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_splat(float _a) + { + return simd_ld<simd128_langext_t>(_a, _a, _a, _a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_isplat(uint32_t _a) + { + return simd_ild<simd128_langext_t>(_a, _a, _a, _a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_zero() + { + return simd_ild<simd128_langext_t>(0, 0, 0, 0); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_itof(simd128_langext_t _a) + { + simd128_langext_t result; + result.vf = __builtin_convertvector(_a.vi, float __attribute__((vector_size(16))) ); + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_ftoi(simd128_langext_t _a) + { + simd128_langext_t result; + result.vi = __builtin_convertvector(_a.vf, int32_t __attribute__((vector_size(16))) ); + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_round(simd128_langext_t _a) + { + const simd128_langext_t tmp = simd_ftoi(_a); + const simd128_langext_t result = simd_itof(tmp); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_add(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vf = _a.vf + _b.vf; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_sub(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vf = _a.vf - _b.vf; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_mul(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vf = _a.vf * _b.vf; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_div(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vf = _a.vf / _b.vf; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_sqrt(simd128_langext_t _a) + { + simd128_langext_t result; + result.vf[0] = sqrtf(_a.vf[0]); + result.vf[1] = sqrtf(_a.vf[1]); + result.vf[2] = sqrtf(_a.vf[2]); + result.vf[3] = sqrtf(_a.vf[3]); + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_rsqrt_est(simd128_langext_t _a) + { + simd128_langext_t result; + result.vf[0] = 1.0f / sqrtf(_a.vf[0]); + result.vf[1] = 1.0f / sqrtf(_a.vf[1]); + result.vf[2] = 1.0f / sqrtf(_a.vf[2]); + result.vf[3] = 1.0f / sqrtf(_a.vf[3]); + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_cmpeq(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vi = _a.vf == _b.vf; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_cmplt(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vi = _a.vf < _b.vf; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_cmple(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vi = _a.vf <= _b.vf; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_cmpgt(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vi = _a.vf > _b.vf; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_cmpge(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vi = _a.vf >= _b.vf; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_and(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vu = _a.vu & _b.vu; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_andc(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vu = _a.vu & ~_b.vu; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_or(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vu = _a.vu | _b.vu; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_xor(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vu = _a.vu ^ _b.vu; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_sll(simd128_langext_t _a, int _count) + { + simd128_langext_t result; + const simd128_langext_t count = simd_isplat<simd128_langext_t>(_count); + result.vu = _a.vu << count.vi; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_srl(simd128_langext_t _a, int _count) + { + simd128_langext_t result; + const simd128_langext_t count = simd_isplat<simd128_langext_t>(_count); + result.vu = _a.vu >> count.vi; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_sra(simd128_langext_t _a, int _count) + { + simd128_langext_t result; + const simd128_langext_t count = simd_isplat<simd128_langext_t>(_count); + result.vi = _a.vi >> count.vi; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_icmpeq(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vi = _a.vi == _b.vi; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_icmplt(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vi = _a.vi < _b.vi; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_icmpgt(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vi = _a.vi > _b.vi; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_iadd(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vi = _a.vi + _b.vi; + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_langext_t simd_isub(simd128_langext_t _a, simd128_langext_t _b) + { + simd128_langext_t result; + result.vi = _a.vi - _b.vi; + return result; + } + + typedef simd128_langext_t simd128_t; + +} // namespace bx + +#endif // BX_SIMD128_LANGEXT_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/simd128_neon.inl b/3rdparty/bx/include/bx/simd128_neon.inl new file mode 100644 index 00000000000..1dd0d1f12b2 --- /dev/null +++ b/3rdparty/bx/include/bx/simd128_neon.inl @@ -0,0 +1,562 @@ +/* + * Copyright 2010-2016 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#ifndef BX_SIMD128_NEON_H_HEADER_GUARD +#define BX_SIMD128_NEON_H_HEADER_GUARD + +#define simd_rcp simd_rcp_ni +#define simd_orx simd_orx_ni +#define simd_orc simd_orc_ni +#define simd_neg simd_neg_ni +#define simd_madd simd_madd_ni +#define simd_nmsub simd_nmsub_ni +#define simd_div_nr simd_div_nr_ni +#define simd_div simd_div_nr_ni +#define simd_selb simd_selb_ni +#define simd_sels simd_sels_ni +#define simd_not simd_not_ni +#define simd_abs simd_abs_ni +#define simd_clamp simd_clamp_ni +#define simd_lerp simd_lerp_ni +#define simd_rsqrt simd_rsqrt_ni +#define simd_rsqrt_nr simd_rsqrt_nr_ni +#define simd_rsqrt_carmack simd_rsqrt_carmack_ni +#define simd_sqrt_nr simd_sqrt_nr_ni +#define simd_sqrt simd_sqrt_nr_ni +#define simd_log2 simd_log2_ni +#define simd_exp2 simd_exp2_ni +#define simd_pow simd_pow_ni +#define simd_cross3 simd_cross3_ni +#define simd_normalize3 simd_normalize3_ni +#define simd_dot3 simd_dot3_ni +#define simd_dot simd_dot_ni +#define simd_ceil simd_ceil_ni +#define simd_floor simd_floor_ni + +#include "simd_ni.inl" + +namespace bx +{ +#define ELEMx 0 +#define ELEMy 1 +#define ELEMz 2 +#define ELEMw 3 +#define BX_SIMD128_IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ + template<> \ + BX_SIMD_FORCE_INLINE simd128_neon_t simd_swiz_##_x##_y##_z##_w(simd128_neon_t _a) \ + { \ + return __builtin_shuffle(_a, (uint32x4_t){ ELEM##_x, ELEM##_y, ELEM##_z, ELEM##_w }); \ + } + +#include "simd128_swizzle.inl" + +#undef BX_SIMD128_IMPLEMENT_SWIZZLE +#undef ELEMw +#undef ELEMz +#undef ELEMy +#undef ELEMx + +#define BX_SIMD128_IMPLEMENT_TEST(_xyzw, _swizzle) \ + template<> \ + BX_SIMD_FORCE_INLINE bool simd_test_any_##_xyzw(simd128_neon_t _test) \ + { \ + const simd128_neon_t tmp0 = simd_swiz_##_swizzle(_test); \ + return simd_test_any_ni(tmp0); \ + } \ + \ + template<> \ + BX_SIMD_FORCE_INLINE bool simd_test_all_##_xyzw(simd128_neon_t _test) \ + { \ + const simd128_neon_t tmp0 = simd_swiz_##_swizzle(_test); \ + return simd_test_all_ni(tmp0); \ + } + +BX_SIMD128_IMPLEMENT_TEST(x, xxxx); +BX_SIMD128_IMPLEMENT_TEST(y, yyyy); +BX_SIMD128_IMPLEMENT_TEST(xy, xyyy); +BX_SIMD128_IMPLEMENT_TEST(z, zzzz); +BX_SIMD128_IMPLEMENT_TEST(xz, xzzz); +BX_SIMD128_IMPLEMENT_TEST(yz, yzzz); +BX_SIMD128_IMPLEMENT_TEST(xyz, xyzz); +BX_SIMD128_IMPLEMENT_TEST(w, wwww); +BX_SIMD128_IMPLEMENT_TEST(xw, xwww); +BX_SIMD128_IMPLEMENT_TEST(yw, ywww); +BX_SIMD128_IMPLEMENT_TEST(xyw, xyww); +BX_SIMD128_IMPLEMENT_TEST(zw, zwww); +BX_SIMD128_IMPLEMENT_TEST(xzw, xzww); +BX_SIMD128_IMPLEMENT_TEST(yzw, yzww); +#undef BX_SIMD128_IMPLEMENT_TEST + + template<> + BX_SIMD_FORCE_INLINE bool simd_test_any_xyzw(simd128_neon_t _test) + { + return simd_test_any_ni(_test); + } + + template<> + BX_SIMD_FORCE_INLINE bool simd_test_all_xyzw(simd128_neon_t _test) + { + return simd_test_all_ni(_test); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_xyAB(simd128_neon_t _a, simd128_neon_t _b) + { + return __builtin_shuffle(_a, _b, (uint32x4_t){ 0, 1, 4, 5 }); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_ABxy(simd128_neon_t _a, simd128_neon_t _b) + { + return __builtin_shuffle(_a, _b, (uint32x4_t){ 4, 5, 0, 1 }); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_CDzw(simd128_neon_t _a, simd128_neon_t _b) + { + return __builtin_shuffle(_a, _b, (uint32x4_t){ 6, 7, 2, 3 }); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_zwCD(simd128_neon_t _a, simd128_neon_t _b) + { + return __builtin_shuffle(_a, _b, (uint32x4_t){ 2, 3, 6, 7 }); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_xAyB(simd128_neon_t _a, simd128_neon_t _b) + { + return __builtin_shuffle(_a, _b, (uint32x4_t){ 0, 4, 1, 5 }); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_yBxA(simd128_neon_t _a, simd128_neon_t _b) + { + return __builtin_shuffle(_a, _b, (uint32x4_t){ 1, 5, 0, 4 }); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_zCwD(simd128_neon_t _a, simd128_neon_t _b) + { + return __builtin_shuffle(_a, _b, (uint32x4_t){ 2, 6, 3, 7 }); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_CzDw(simd128_neon_t _a, simd128_neon_t _b) + { + return __builtin_shuffle(_a, _b, (uint32x4_t){ 6, 2, 7, 3 }); + } + + template<> + BX_SIMD_FORCE_INLINE float simd_x(simd128_neon_t _a) + { + return vgetq_lane_f32(_a, 0); + } + + template<> + BX_SIMD_FORCE_INLINE float simd_y(simd128_neon_t _a) + { + return vgetq_lane_f32(_a, 1); + } + + template<> + BX_SIMD_FORCE_INLINE float simd_z(simd128_neon_t _a) + { + return vgetq_lane_f32(_a, 2); + } + + template<> + BX_SIMD_FORCE_INLINE float simd_w(simd128_neon_t _a) + { + return vgetq_lane_f32(_a, 3); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_ld(const void* _ptr) + { + return vld1q_f32( (const float32_t*)_ptr); + } + + template<> + BX_SIMD_FORCE_INLINE void simd_st(void* _ptr, simd128_neon_t _a) + { + vst1q_f32( (float32_t*)_ptr, _a); + } + + template<> + BX_SIMD_FORCE_INLINE void simd_stx(void* _ptr, simd128_neon_t _a) + { + vst1q_lane_f32( (float32_t*)_ptr, _a, 0); + } + + template<> + BX_SIMD_FORCE_INLINE void simd_stream(void* _ptr, simd128_neon_t _a) + { + vst1q_f32( (float32_t*)_ptr, _a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_ld(float _x, float _y, float _z, float _w) + { + const float32_t val[4] = {_x, _y, _z, _w}; + return simd_ld<simd128_neon_t>(val); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) + { + const uint32_t val[4] = {_x, _y, _z, _w}; + const uint32x4_t tmp = vld1q_u32(val); + const simd128_neon_t result = vreinterpretq_f32_u32(tmp); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_splat(const void* _ptr) + { + const simd128_neon_t tmp0 = vld1q_f32( (const float32_t*)_ptr); + const float32x2_t tmp1 = vget_low_f32(tmp0); + const simd128_neon_t result = vdupq_lane_f32(tmp1, 0); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_splat(float _a) + { + return vdupq_n_f32(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_isplat(uint32_t _a) + { + const int32x4_t tmp = vdupq_n_s32(_a); + const simd128_neon_t result = vreinterpretq_f32_s32(tmp); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_zero() + { + return simd_isplat<simd128_neon_t>(0); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_itof(simd128_neon_t _a) + { + const int32x4_t itof = vreinterpretq_s32_f32(_a); + const simd128_neon_t result = vcvtq_f32_s32(itof); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_ftoi(simd128_neon_t _a) + { + const int32x4_t ftoi = vcvtq_s32_f32(_a); + const simd128_neon_t result = vreinterpretq_f32_s32(ftoi); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_add(simd128_neon_t _a, simd128_neon_t _b) + { + return vaddq_f32(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_sub(simd128_neon_t _a, simd128_neon_t _b) + { + return vsubq_f32(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_mul(simd128_neon_t _a, simd128_neon_t _b) + { + return vmulq_f32(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_rcp_est(simd128_neon_t _a) + { + return vrecpeq_f32(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_rsqrt_est(simd128_neon_t _a) + { + return vrsqrteq_f32(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_cmpeq(simd128_neon_t _a, simd128_neon_t _b) + { + const uint32x4_t tmp = vceqq_f32(_a, _b); + const simd128_neon_t result = vreinterpretq_f32_u32(tmp); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_cmplt(simd128_neon_t _a, simd128_neon_t _b) + { + const uint32x4_t tmp = vcltq_f32(_a, _b); + const simd128_neon_t result = vreinterpretq_f32_u32(tmp); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_cmple(simd128_neon_t _a, simd128_neon_t _b) + { + const uint32x4_t tmp = vcleq_f32(_a, _b); + const simd128_neon_t result = vreinterpretq_f32_u32(tmp); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_cmpgt(simd128_neon_t _a, simd128_neon_t _b) + { + const uint32x4_t tmp = vcgtq_f32(_a, _b); + const simd128_neon_t result = vreinterpretq_f32_u32(tmp); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_cmpge(simd128_neon_t _a, simd128_neon_t _b) + { + const uint32x4_t tmp = vcgeq_f32(_a, _b); + const simd128_neon_t result = vreinterpretq_f32_u32(tmp); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_min(simd128_neon_t _a, simd128_neon_t _b) + { + return vminq_f32(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_max(simd128_neon_t _a, simd128_neon_t _b) + { + return vmaxq_f32(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_and(simd128_neon_t _a, simd128_neon_t _b) + { + const int32x4_t tmp0 = vreinterpretq_s32_f32(_a); + const int32x4_t tmp1 = vreinterpretq_s32_f32(_b); + const int32x4_t tmp2 = vandq_s32(tmp0, tmp1); + const simd128_neon_t result = vreinterpretq_f32_s32(tmp2); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_andc(simd128_neon_t _a, simd128_neon_t _b) + { + const int32x4_t tmp0 = vreinterpretq_s32_f32(_a); + const int32x4_t tmp1 = vreinterpretq_s32_f32(_b); + const int32x4_t tmp2 = vbicq_s32(tmp0, tmp1); + const simd128_neon_t result = vreinterpretq_f32_s32(tmp2); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_or(simd128_neon_t _a, simd128_neon_t _b) + { + const int32x4_t tmp0 = vreinterpretq_s32_f32(_a); + const int32x4_t tmp1 = vreinterpretq_s32_f32(_b); + const int32x4_t tmp2 = vorrq_s32(tmp0, tmp1); + const simd128_neon_t result = vreinterpretq_f32_s32(tmp2); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_xor(simd128_neon_t _a, simd128_neon_t _b) + { + const int32x4_t tmp0 = vreinterpretq_s32_f32(_a); + const int32x4_t tmp1 = vreinterpretq_s32_f32(_b); + const int32x4_t tmp2 = veorq_s32(tmp0, tmp1); + const simd128_neon_t result = vreinterpretq_f32_s32(tmp2); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_sll(simd128_neon_t _a, int _count) + { + if (__builtin_constant_p(_count) ) + { + const uint32x4_t tmp0 = vreinterpretq_u32_f32(_a); + const uint32x4_t tmp1 = vshlq_n_u32(tmp0, _count); + const simd128_neon_t result = vreinterpretq_f32_u32(tmp1); + + return result; + } + + const uint32x4_t tmp0 = vreinterpretq_u32_f32(_a); + const int32x4_t shift = vdupq_n_s32(_count); + const uint32x4_t tmp1 = vshlq_u32(tmp0, shift); + const simd128_neon_t result = vreinterpretq_f32_u32(tmp1); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_srl(simd128_neon_t _a, int _count) + { + if (__builtin_constant_p(_count) ) + { + const uint32x4_t tmp0 = vreinterpretq_u32_f32(_a); + const uint32x4_t tmp1 = vshrq_n_u32(tmp0, _count); + const simd128_neon_t result = vreinterpretq_f32_u32(tmp1); + + return result; + } + + const uint32x4_t tmp0 = vreinterpretq_u32_f32(_a); + const int32x4_t shift = vdupq_n_s32(-_count); + const uint32x4_t tmp1 = vshlq_u32(tmp0, shift); + const simd128_neon_t result = vreinterpretq_f32_u32(tmp1); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_sra(simd128_neon_t _a, int _count) + { + if (__builtin_constant_p(_count) ) + { + const int32x4_t tmp0 = vreinterpretq_s32_f32(_a); + const int32x4_t tmp1 = vshrq_n_s32(tmp0, _count); + const simd128_neon_t result = vreinterpretq_f32_s32(tmp1); + + return result; + } + + const int32x4_t tmp0 = vreinterpretq_s32_f32(_a); + const int32x4_t shift = vdupq_n_s32(-_count); + const int32x4_t tmp1 = vshlq_s32(tmp0, shift); + const simd128_neon_t result = vreinterpretq_f32_s32(tmp1); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_madd(simd128_neon_t _a, simd128_neon_t _b, simd128_neon_t _c) + { + return vmlaq_f32(_c, _a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_nmsub(simd128_neon_t _a, simd128_neon_t _b, simd128_neon_t _c) + { + return vmlsq_f32(_c, _a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_icmpeq(simd128_neon_t _a, simd128_neon_t _b) + { + const int32x4_t tmp0 = vreinterpretq_s32_f32(_a); + const int32x4_t tmp1 = vreinterpretq_s32_f32(_b); + const uint32x4_t tmp2 = vceqq_s32(tmp0, tmp1); + const simd128_neon_t result = vreinterpretq_f32_u32(tmp2); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_icmplt(simd128_neon_t _a, simd128_neon_t _b) + { + const int32x4_t tmp0 = vreinterpretq_s32_f32(_a); + const int32x4_t tmp1 = vreinterpretq_s32_f32(_b); + const uint32x4_t tmp2 = vcltq_s32(tmp0, tmp1); + const simd128_neon_t result = vreinterpretq_f32_u32(tmp2); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_icmpgt(simd128_neon_t _a, simd128_neon_t _b) + { + const int32x4_t tmp0 = vreinterpretq_s32_f32(_a); + const int32x4_t tmp1 = vreinterpretq_s32_f32(_b); + const uint32x4_t tmp2 = vcgtq_s32(tmp0, tmp1); + const simd128_neon_t result = vreinterpretq_f32_u32(tmp2); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_imin(simd128_neon_t _a, simd128_neon_t _b) + { + const int32x4_t tmp0 = vreinterpretq_s32_f32(_a); + const int32x4_t tmp1 = vreinterpretq_s32_f32(_b); + const int32x4_t tmp2 = vminq_s32(tmp0, tmp1); + const simd128_neon_t result = vreinterpretq_f32_s32(tmp2); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_imax(simd128_neon_t _a, simd128_neon_t _b) + { + const int32x4_t tmp0 = vreinterpretq_s32_f32(_a); + const int32x4_t tmp1 = vreinterpretq_s32_f32(_b); + const int32x4_t tmp2 = vmaxq_s32(tmp0, tmp1); + const simd128_neon_t result = vreinterpretq_f32_s32(tmp2); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_iadd(simd128_neon_t _a, simd128_neon_t _b) + { + const int32x4_t tmp0 = vreinterpretq_s32_f32(_a); + const int32x4_t tmp1 = vreinterpretq_s32_f32(_b); + const int32x4_t tmp2 = vaddq_s32(tmp0, tmp1); + const simd128_neon_t result = vreinterpretq_f32_s32(tmp2); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_neon_t simd_isub(simd128_neon_t _a, simd128_neon_t _b) + { + const int32x4_t tmp0 = vreinterpretq_s32_f32(_a); + const int32x4_t tmp1 = vreinterpretq_s32_f32(_b); + const int32x4_t tmp2 = vsubq_s32(tmp0, tmp1); + const simd128_neon_t result = vreinterpretq_f32_s32(tmp2); + + return result; + } + + template<> + BX_SIMD_INLINE simd128_neon_t simd_shuf_xAzC(simd128_neon_t _a, simd128_neon_t _b) + { + return simd_shuf_xAzC_ni(_a, _b); + } + + template<> + BX_SIMD_INLINE simd128_neon_t simd_shuf_yBwD(simd128_neon_t _a, simd128_neon_t _b) + { + return simd_shuf_yBwD_ni(_a, _b); + } + + typedef simd128_neon_t simd128_t; + +} // namespace bx + +#endif // BX_SIMD128_NEON_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/float4_ref.h b/3rdparty/bx/include/bx/simd128_ref.inl index e54862ca371..da08f5088b6 100644 --- a/3rdparty/bx/include/bx/float4_ref.h +++ b/3rdparty/bx/include/bx/simd128_ref.inl @@ -3,29 +3,53 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ -#ifndef BX_FLOAT4_REF_H_HEADER_GUARD -#define BX_FLOAT4_REF_H_HEADER_GUARD +#ifndef BX_SIMD128_REF_H_HEADER_GUARD +#define BX_SIMD128_REF_H_HEADER_GUARD #include <math.h> // sqrtf +#define simd_shuf_xAzC simd_shuf_xAzC_ni +#define simd_shuf_yBwD simd_shuf_yBwD_ni +#define simd_rcp simd_rcp_ni +#define simd_orx simd_orx_ni +#define simd_orc simd_orc_ni +#define simd_neg simd_neg_ni +#define simd_madd simd_madd_ni +#define simd_nmsub simd_nmsub_ni +#define simd_div_nr simd_div_nr_ni +#define simd_selb simd_selb_ni +#define simd_sels simd_sels_ni +#define simd_not simd_not_ni +#define simd_abs simd_abs_ni +#define simd_clamp simd_clamp_ni +#define simd_lerp simd_lerp_ni +#define simd_rsqrt simd_rsqrt_ni +#define simd_rsqrt_nr simd_rsqrt_nr_ni +#define simd_rsqrt_carmack simd_rsqrt_carmack_ni +#define simd_sqrt_nr simd_sqrt_nr_ni +#define simd_log2 simd_log2_ni +#define simd_exp2 simd_exp2_ni +#define simd_pow simd_pow_ni +#define simd_cross3 simd_cross3_ni +#define simd_normalize3 simd_normalize3_ni +#define simd_dot3 simd_dot3_ni +#define simd_dot simd_dot_ni +#define simd_ceil simd_ceil_ni +#define simd_floor simd_floor_ni + +#include "simd_ni.inl" + namespace bx { - typedef union float4_t - { - float fxyzw[4]; - int32_t ixyzw[4]; - uint32_t uxyzw[4]; - - } float4_t; - #define ELEMx 0 #define ELEMy 1 #define ELEMz 2 #define ELEMw 3 -#define IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ - BX_FLOAT4_FORCE_INLINE float4_t float4_swiz_##_x##_y##_z##_w(float4_t _a) \ +#define BX_SIMD128_IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ + template<> \ + BX_SIMD_FORCE_INLINE simd128_ref_t simd_swiz_##_x##_y##_z##_w(simd128_ref_t _a) \ { \ - float4_t result; \ + simd128_ref_t result; \ result.ixyzw[0] = _a.ixyzw[ELEM##_x]; \ result.ixyzw[1] = _a.ixyzw[ELEM##_y]; \ result.ixyzw[2] = _a.ixyzw[ELEM##_z]; \ @@ -33,16 +57,17 @@ namespace bx return result; \ } -#include "float4_swizzle.inl" +#include "simd128_swizzle.inl" -#undef IMPLEMENT_SWIZZLE +#undef BX_SIMD128_IMPLEMENT_SWIZZLE #undef ELEMw #undef ELEMz #undef ELEMy #undef ELEMx -#define IMPLEMENT_TEST(_xyzw, _mask) \ - BX_FLOAT4_FORCE_INLINE bool float4_test_any_##_xyzw(float4_t _test) \ +#define BX_SIMD128_IMPLEMENT_TEST(_xyzw, _mask) \ + template<> \ + BX_SIMD_FORCE_INLINE bool simd_test_any_##_xyzw(simd128_ref_t _test) \ { \ uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ | ( (_test.uxyzw[2]>>31)<<2) \ @@ -52,7 +77,8 @@ namespace bx return 0 != (tmp&(_mask) ); \ } \ \ - BX_FLOAT4_FORCE_INLINE bool float4_test_all_##_xyzw(float4_t _test) \ + template<> \ + BX_SIMD_FORCE_INLINE bool simd_test_all_##_xyzw(simd128_ref_t _test) \ { \ uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \ | ( (_test.uxyzw[2]>>31)<<2) \ @@ -62,27 +88,28 @@ namespace bx return (_mask) == (tmp&(_mask) ); \ } -IMPLEMENT_TEST(x , 0x1); -IMPLEMENT_TEST(y , 0x2); -IMPLEMENT_TEST(xy , 0x3); -IMPLEMENT_TEST(z , 0x4); -IMPLEMENT_TEST(xz , 0x5); -IMPLEMENT_TEST(yz , 0x6); -IMPLEMENT_TEST(xyz , 0x7); -IMPLEMENT_TEST(w , 0x8); -IMPLEMENT_TEST(xw , 0x9); -IMPLEMENT_TEST(yw , 0xa); -IMPLEMENT_TEST(xyw , 0xb); -IMPLEMENT_TEST(zw , 0xc); -IMPLEMENT_TEST(xzw , 0xd); -IMPLEMENT_TEST(yzw , 0xe); -IMPLEMENT_TEST(xyzw , 0xf); - -#undef IMPLEMENT_TEST - - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xyAB(float4_t _a, float4_t _b) - { - float4_t result; +BX_SIMD128_IMPLEMENT_TEST(x , 0x1); +BX_SIMD128_IMPLEMENT_TEST(y , 0x2); +BX_SIMD128_IMPLEMENT_TEST(xy , 0x3); +BX_SIMD128_IMPLEMENT_TEST(z , 0x4); +BX_SIMD128_IMPLEMENT_TEST(xz , 0x5); +BX_SIMD128_IMPLEMENT_TEST(yz , 0x6); +BX_SIMD128_IMPLEMENT_TEST(xyz , 0x7); +BX_SIMD128_IMPLEMENT_TEST(w , 0x8); +BX_SIMD128_IMPLEMENT_TEST(xw , 0x9); +BX_SIMD128_IMPLEMENT_TEST(yw , 0xa); +BX_SIMD128_IMPLEMENT_TEST(xyw , 0xb); +BX_SIMD128_IMPLEMENT_TEST(zw , 0xc); +BX_SIMD128_IMPLEMENT_TEST(xzw , 0xd); +BX_SIMD128_IMPLEMENT_TEST(yzw , 0xe); +BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf); + +#undef BX_SIMD128_IMPLEMENT_TEST + + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_xyAB(simd128_ref_t _a, simd128_ref_t _b) + { + simd128_ref_t result; result.uxyzw[0] = _a.uxyzw[0]; result.uxyzw[1] = _a.uxyzw[1]; result.uxyzw[2] = _b.uxyzw[0]; @@ -90,9 +117,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_ABxy(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_ABxy(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.uxyzw[0] = _b.uxyzw[0]; result.uxyzw[1] = _b.uxyzw[1]; result.uxyzw[2] = _a.uxyzw[0]; @@ -100,9 +128,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_CDzw(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_CDzw(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.uxyzw[0] = _b.uxyzw[2]; result.uxyzw[1] = _b.uxyzw[3]; result.uxyzw[2] = _a.uxyzw[2]; @@ -110,9 +139,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_zwCD(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_zwCD(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.uxyzw[0] = _a.uxyzw[2]; result.uxyzw[1] = _a.uxyzw[3]; result.uxyzw[2] = _b.uxyzw[2]; @@ -120,9 +150,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_xAyB(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_xAyB(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.uxyzw[0] = _a.uxyzw[0]; result.uxyzw[1] = _b.uxyzw[0]; result.uxyzw[2] = _a.uxyzw[1]; @@ -130,9 +161,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_yBxA(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_yBxA(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.uxyzw[0] = _a.uxyzw[1]; result.uxyzw[1] = _b.uxyzw[1]; result.uxyzw[2] = _a.uxyzw[0]; @@ -140,9 +172,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_zCwD(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_zCwD(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.uxyzw[0] = _a.uxyzw[2]; result.uxyzw[1] = _b.uxyzw[2]; result.uxyzw[2] = _a.uxyzw[3]; @@ -150,9 +183,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_shuf_CzDw(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_CzDw(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.uxyzw[0] = _b.uxyzw[2]; result.uxyzw[1] = _a.uxyzw[2]; result.uxyzw[2] = _b.uxyzw[3]; @@ -160,30 +194,35 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float float4_x(float4_t _a) + template<> + BX_SIMD_FORCE_INLINE float simd_x(simd128_ref_t _a) { return _a.fxyzw[0]; } - BX_FLOAT4_FORCE_INLINE float float4_y(float4_t _a) + template<> + BX_SIMD_FORCE_INLINE float simd_y(simd128_ref_t _a) { return _a.fxyzw[1]; } - BX_FLOAT4_FORCE_INLINE float float4_z(float4_t _a) + template<> + BX_SIMD_FORCE_INLINE float simd_z(simd128_ref_t _a) { return _a.fxyzw[2]; } - BX_FLOAT4_FORCE_INLINE float float4_w(float4_t _a) + template<> + BX_SIMD_FORCE_INLINE float simd_w(simd128_ref_t _a) { return _a.fxyzw[3]; } - BX_FLOAT4_FORCE_INLINE float4_t float4_ld(const void* _ptr) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_ld(const void* _ptr) { const uint32_t* input = reinterpret_cast<const uint32_t*>(_ptr); - float4_t result; + simd128_ref_t result; result.uxyzw[0] = input[0]; result.uxyzw[1] = input[1]; result.uxyzw[2] = input[2]; @@ -191,7 +230,8 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE void float4_st(void* _ptr, float4_t _a) + template<> + BX_SIMD_FORCE_INLINE void simd_st(void* _ptr, simd128_ref_t _a) { uint32_t* result = reinterpret_cast<uint32_t*>(_ptr); result[0] = _a.uxyzw[0]; @@ -200,13 +240,15 @@ IMPLEMENT_TEST(xyzw , 0xf); result[3] = _a.uxyzw[3]; } - BX_FLOAT4_FORCE_INLINE void float4_stx(void* _ptr, float4_t _a) + template<> + BX_SIMD_FORCE_INLINE void simd_stx(void* _ptr, simd128_ref_t _a) { uint32_t* result = reinterpret_cast<uint32_t*>(_ptr); result[0] = _a.uxyzw[0]; } - BX_FLOAT4_FORCE_INLINE void float4_stream(void* _ptr, float4_t _a) + template<> + BX_SIMD_FORCE_INLINE void simd_stream(void* _ptr, simd128_ref_t _a) { uint32_t* result = reinterpret_cast<uint32_t*>(_ptr); result[0] = _a.uxyzw[0]; @@ -215,9 +257,10 @@ IMPLEMENT_TEST(xyzw , 0xf); result[3] = _a.uxyzw[3]; } - BX_FLOAT4_FORCE_INLINE float4_t float4_ld(float _x, float _y, float _z, float _w) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_ld(float _x, float _y, float _z, float _w) { - float4_t result; + simd128_ref_t result; result.fxyzw[0] = _x; result.fxyzw[1] = _y; result.fxyzw[2] = _z; @@ -225,9 +268,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) { - float4_t result; + simd128_ref_t result; result.uxyzw[0] = _x; result.uxyzw[1] = _y; result.uxyzw[2] = _z; @@ -235,10 +279,11 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_splat(const void* _ptr) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_splat(const void* _ptr) { const uint32_t val = *reinterpret_cast<const uint32_t*>(_ptr); - float4_t result; + simd128_ref_t result; result.uxyzw[0] = val; result.uxyzw[1] = val; result.uxyzw[2] = val; @@ -246,24 +291,28 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_splat(float _a) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_splat(float _a) { - return float4_ld(_a, _a, _a, _a); + return simd_ld<simd128_ref_t>(_a, _a, _a, _a); } - BX_FLOAT4_FORCE_INLINE float4_t float4_isplat(uint32_t _a) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_isplat(uint32_t _a) { - return float4_ild(_a, _a, _a, _a); + return simd_ild<simd128_ref_t>(_a, _a, _a, _a); } - BX_FLOAT4_FORCE_INLINE float4_t float4_zero() + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_zero() { - return float4_ild(0, 0, 0, 0); + return simd_ild<simd128_ref_t>(0, 0, 0, 0); } - BX_FLOAT4_FORCE_INLINE float4_t float4_itof(float4_t _a) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_itof(simd128_ref_t _a) { - float4_t result; + simd128_ref_t result; result.fxyzw[0] = (float)_a.ixyzw[0]; result.fxyzw[1] = (float)_a.ixyzw[1]; result.fxyzw[2] = (float)_a.ixyzw[2]; @@ -271,9 +320,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_ftoi(float4_t _a) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_ftoi(simd128_ref_t _a) { - float4_t result; + simd128_ref_t result; result.ixyzw[0] = (int)_a.fxyzw[0]; result.ixyzw[1] = (int)_a.fxyzw[1]; result.ixyzw[2] = (int)_a.fxyzw[2]; @@ -281,17 +331,16 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_round(float4_t _a) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_round(simd128_ref_t _a) { - const float4_t tmp = float4_ftoi(_a); - const float4_t result = float4_itof(tmp); - - return result; + return simd_round_ni(_a); } - BX_FLOAT4_FORCE_INLINE float4_t float4_add(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_add(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.fxyzw[0] = _a.fxyzw[0] + _b.fxyzw[0]; result.fxyzw[1] = _a.fxyzw[1] + _b.fxyzw[1]; result.fxyzw[2] = _a.fxyzw[2] + _b.fxyzw[2]; @@ -299,9 +348,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_sub(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_sub(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.fxyzw[0] = _a.fxyzw[0] - _b.fxyzw[0]; result.fxyzw[1] = _a.fxyzw[1] - _b.fxyzw[1]; result.fxyzw[2] = _a.fxyzw[2] - _b.fxyzw[2]; @@ -309,9 +359,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_mul(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_mul(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.fxyzw[0] = _a.fxyzw[0] * _b.fxyzw[0]; result.fxyzw[1] = _a.fxyzw[1] * _b.fxyzw[1]; result.fxyzw[2] = _a.fxyzw[2] * _b.fxyzw[2]; @@ -319,9 +370,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_div(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_div(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.fxyzw[0] = _a.fxyzw[0] / _b.fxyzw[0]; result.fxyzw[1] = _a.fxyzw[1] / _b.fxyzw[1]; result.fxyzw[2] = _a.fxyzw[2] / _b.fxyzw[2]; @@ -329,9 +381,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_rcp_est(float4_t _a) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_rcp_est(simd128_ref_t _a) { - float4_t result; + simd128_ref_t result; result.fxyzw[0] = 1.0f / _a.fxyzw[0]; result.fxyzw[1] = 1.0f / _a.fxyzw[1]; result.fxyzw[2] = 1.0f / _a.fxyzw[2]; @@ -339,9 +392,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_sqrt(float4_t _a) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_sqrt(simd128_ref_t _a) { - float4_t result; + simd128_ref_t result; result.fxyzw[0] = sqrtf(_a.fxyzw[0]); result.fxyzw[1] = sqrtf(_a.fxyzw[1]); result.fxyzw[2] = sqrtf(_a.fxyzw[2]); @@ -349,9 +403,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_rsqrt_est(float4_t _a) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_rsqrt_est(simd128_ref_t _a) { - float4_t result; + simd128_ref_t result; result.fxyzw[0] = 1.0f / sqrtf(_a.fxyzw[0]); result.fxyzw[1] = 1.0f / sqrtf(_a.fxyzw[1]); result.fxyzw[2] = 1.0f / sqrtf(_a.fxyzw[2]); @@ -359,9 +414,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_cmpeq(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_cmpeq(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.ixyzw[0] = _a.fxyzw[0] == _b.fxyzw[0] ? 0xffffffff : 0x0; result.ixyzw[1] = _a.fxyzw[1] == _b.fxyzw[1] ? 0xffffffff : 0x0; result.ixyzw[2] = _a.fxyzw[2] == _b.fxyzw[2] ? 0xffffffff : 0x0; @@ -369,9 +425,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_cmplt(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_cmplt(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.ixyzw[0] = _a.fxyzw[0] < _b.fxyzw[0] ? 0xffffffff : 0x0; result.ixyzw[1] = _a.fxyzw[1] < _b.fxyzw[1] ? 0xffffffff : 0x0; result.ixyzw[2] = _a.fxyzw[2] < _b.fxyzw[2] ? 0xffffffff : 0x0; @@ -379,9 +436,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_cmple(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_cmple(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.ixyzw[0] = _a.fxyzw[0] <= _b.fxyzw[0] ? 0xffffffff : 0x0; result.ixyzw[1] = _a.fxyzw[1] <= _b.fxyzw[1] ? 0xffffffff : 0x0; result.ixyzw[2] = _a.fxyzw[2] <= _b.fxyzw[2] ? 0xffffffff : 0x0; @@ -389,9 +447,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_cmpgt(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_cmpgt(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.ixyzw[0] = _a.fxyzw[0] > _b.fxyzw[0] ? 0xffffffff : 0x0; result.ixyzw[1] = _a.fxyzw[1] > _b.fxyzw[1] ? 0xffffffff : 0x0; result.ixyzw[2] = _a.fxyzw[2] > _b.fxyzw[2] ? 0xffffffff : 0x0; @@ -399,9 +458,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_cmpge(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_cmpge(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.ixyzw[0] = _a.fxyzw[0] >= _b.fxyzw[0] ? 0xffffffff : 0x0; result.ixyzw[1] = _a.fxyzw[1] >= _b.fxyzw[1] ? 0xffffffff : 0x0; result.ixyzw[2] = _a.fxyzw[2] >= _b.fxyzw[2] ? 0xffffffff : 0x0; @@ -409,9 +469,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_min(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_min(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.fxyzw[0] = _a.fxyzw[0] < _b.fxyzw[0] ? _a.fxyzw[0] : _b.fxyzw[0]; result.fxyzw[1] = _a.fxyzw[1] < _b.fxyzw[1] ? _a.fxyzw[1] : _b.fxyzw[1]; result.fxyzw[2] = _a.fxyzw[2] < _b.fxyzw[2] ? _a.fxyzw[2] : _b.fxyzw[2]; @@ -419,9 +480,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_max(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_max(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.fxyzw[0] = _a.fxyzw[0] > _b.fxyzw[0] ? _a.fxyzw[0] : _b.fxyzw[0]; result.fxyzw[1] = _a.fxyzw[1] > _b.fxyzw[1] ? _a.fxyzw[1] : _b.fxyzw[1]; result.fxyzw[2] = _a.fxyzw[2] > _b.fxyzw[2] ? _a.fxyzw[2] : _b.fxyzw[2]; @@ -429,9 +491,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_and(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_and(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.uxyzw[0] = _a.uxyzw[0] & _b.uxyzw[0]; result.uxyzw[1] = _a.uxyzw[1] & _b.uxyzw[1]; result.uxyzw[2] = _a.uxyzw[2] & _b.uxyzw[2]; @@ -439,9 +502,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_andc(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_andc(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.uxyzw[0] = _a.uxyzw[0] & ~_b.uxyzw[0]; result.uxyzw[1] = _a.uxyzw[1] & ~_b.uxyzw[1]; result.uxyzw[2] = _a.uxyzw[2] & ~_b.uxyzw[2]; @@ -449,9 +513,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_or(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_or(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.uxyzw[0] = _a.uxyzw[0] | _b.uxyzw[0]; result.uxyzw[1] = _a.uxyzw[1] | _b.uxyzw[1]; result.uxyzw[2] = _a.uxyzw[2] | _b.uxyzw[2]; @@ -459,9 +524,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_xor(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_xor(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.uxyzw[0] = _a.uxyzw[0] ^ _b.uxyzw[0]; result.uxyzw[1] = _a.uxyzw[1] ^ _b.uxyzw[1]; result.uxyzw[2] = _a.uxyzw[2] ^ _b.uxyzw[2]; @@ -469,9 +535,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_sll(float4_t _a, int _count) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_sll(simd128_ref_t _a, int _count) { - float4_t result; + simd128_ref_t result; result.uxyzw[0] = _a.uxyzw[0] << _count; result.uxyzw[1] = _a.uxyzw[1] << _count; result.uxyzw[2] = _a.uxyzw[2] << _count; @@ -479,9 +546,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_srl(float4_t _a, int _count) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_srl(simd128_ref_t _a, int _count) { - float4_t result; + simd128_ref_t result; result.uxyzw[0] = _a.uxyzw[0] >> _count; result.uxyzw[1] = _a.uxyzw[1] >> _count; result.uxyzw[2] = _a.uxyzw[2] >> _count; @@ -489,9 +557,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_sra(float4_t _a, int _count) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_sra(simd128_ref_t _a, int _count) { - float4_t result; + simd128_ref_t result; result.ixyzw[0] = _a.ixyzw[0] >> _count; result.ixyzw[1] = _a.ixyzw[1] >> _count; result.ixyzw[2] = _a.ixyzw[2] >> _count; @@ -499,9 +568,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_icmpeq(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_icmpeq(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.ixyzw[0] = _a.ixyzw[0] == _b.ixyzw[0] ? 0xffffffff : 0x0; result.ixyzw[1] = _a.ixyzw[1] == _b.ixyzw[1] ? 0xffffffff : 0x0; result.ixyzw[2] = _a.ixyzw[2] == _b.ixyzw[2] ? 0xffffffff : 0x0; @@ -509,9 +579,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_icmplt(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_icmplt(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.ixyzw[0] = _a.ixyzw[0] < _b.ixyzw[0] ? 0xffffffff : 0x0; result.ixyzw[1] = _a.ixyzw[1] < _b.ixyzw[1] ? 0xffffffff : 0x0; result.ixyzw[2] = _a.ixyzw[2] < _b.ixyzw[2] ? 0xffffffff : 0x0; @@ -519,9 +590,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_icmpgt(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_icmpgt(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.ixyzw[0] = _a.ixyzw[0] > _b.ixyzw[0] ? 0xffffffff : 0x0; result.ixyzw[1] = _a.ixyzw[1] > _b.ixyzw[1] ? 0xffffffff : 0x0; result.ixyzw[2] = _a.ixyzw[2] > _b.ixyzw[2] ? 0xffffffff : 0x0; @@ -529,9 +601,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_imin(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_imin(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.ixyzw[0] = _a.ixyzw[0] < _b.ixyzw[0] ? _a.ixyzw[0] : _b.ixyzw[0]; result.ixyzw[1] = _a.ixyzw[1] < _b.ixyzw[1] ? _a.ixyzw[1] : _b.ixyzw[1]; result.ixyzw[2] = _a.ixyzw[2] < _b.ixyzw[2] ? _a.ixyzw[2] : _b.ixyzw[2]; @@ -539,9 +612,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_imax(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_imax(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.ixyzw[0] = _a.ixyzw[0] > _b.ixyzw[0] ? _a.ixyzw[0] : _b.ixyzw[0]; result.ixyzw[1] = _a.ixyzw[1] > _b.ixyzw[1] ? _a.ixyzw[1] : _b.ixyzw[1]; result.ixyzw[2] = _a.ixyzw[2] > _b.ixyzw[2] ? _a.ixyzw[2] : _b.ixyzw[2]; @@ -549,9 +623,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_iadd(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_iadd(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.ixyzw[0] = _a.ixyzw[0] + _b.ixyzw[0]; result.ixyzw[1] = _a.ixyzw[1] + _b.ixyzw[1]; result.ixyzw[2] = _a.ixyzw[2] + _b.ixyzw[2]; @@ -559,9 +634,10 @@ IMPLEMENT_TEST(xyzw , 0xf); return result; } - BX_FLOAT4_FORCE_INLINE float4_t float4_isub(float4_t _a, float4_t _b) + template<> + BX_SIMD_FORCE_INLINE simd128_ref_t simd_isub(simd128_ref_t _a, simd128_ref_t _b) { - float4_t result; + simd128_ref_t result; result.ixyzw[0] = _a.ixyzw[0] - _b.ixyzw[0]; result.ixyzw[1] = _a.ixyzw[1] - _b.ixyzw[1]; result.ixyzw[2] = _a.ixyzw[2] - _b.ixyzw[2]; @@ -571,34 +647,4 @@ IMPLEMENT_TEST(xyzw , 0xf); } // namespace bx -#define float4_shuf_xAzC float4_shuf_xAzC_ni -#define float4_shuf_yBwD float4_shuf_yBwD_ni -#define float4_rcp float4_rcp_ni -#define float4_orx float4_orx_ni -#define float4_orc float4_orc_ni -#define float4_neg float4_neg_ni -#define float4_madd float4_madd_ni -#define float4_nmsub float4_nmsub_ni -#define float4_div_nr float4_div_nr_ni -#define float4_selb float4_selb_ni -#define float4_sels float4_sels_ni -#define float4_not float4_not_ni -#define float4_abs float4_abs_ni -#define float4_clamp float4_clamp_ni -#define float4_lerp float4_lerp_ni -#define float4_rsqrt float4_rsqrt_ni -#define float4_rsqrt_nr float4_rsqrt_nr_ni -#define float4_rsqrt_carmack float4_rsqrt_carmack_ni -#define float4_sqrt_nr float4_sqrt_nr_ni -#define float4_log2 float4_log2_ni -#define float4_exp2 float4_exp2_ni -#define float4_pow float4_pow_ni -#define float4_cross3 float4_cross3_ni -#define float4_normalize3 float4_normalize3_ni -#define float4_dot3 float4_dot3_ni -#define float4_dot float4_dot_ni -#define float4_ceil float4_ceil_ni -#define float4_floor float4_floor_ni -#include "float4_ni.h" - -#endif // BX_FLOAT4_REF_H_HEADER_GUARD +#endif // BX_SIMD128_REF_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/simd128_sse.inl b/3rdparty/bx/include/bx/simd128_sse.inl new file mode 100644 index 00000000000..b0ed8520ab4 --- /dev/null +++ b/3rdparty/bx/include/bx/simd128_sse.inl @@ -0,0 +1,647 @@ +/* + * Copyright 2010-2016 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#ifndef BX_SIMD128_SSE_H_HEADER_GUARD +#define BX_SIMD128_SSE_H_HEADER_GUARD + +#include "simd_ni.inl" + +namespace bx +{ +#define ELEMx 0 +#define ELEMy 1 +#define ELEMz 2 +#define ELEMw 3 +#define BX_SIMD128_IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ + template<> \ + BX_SIMD_FORCE_INLINE simd128_sse_t simd_swiz_##_x##_y##_z##_w(simd128_sse_t _a) \ + { \ + return _mm_shuffle_ps( _a, _a, _MM_SHUFFLE(ELEM##_w, ELEM##_z, ELEM##_y, ELEM##_x ) ); \ + } + +#include "simd128_swizzle.inl" + +#undef BX_SIMD128_IMPLEMENT_SWIZZLE +#undef ELEMw +#undef ELEMz +#undef ELEMy +#undef ELEMx + +#define BX_SIMD128_IMPLEMENT_TEST(_xyzw, _mask) \ + template<> \ + BX_SIMD_FORCE_INLINE bool simd_test_any_##_xyzw(simd128_sse_t _test) \ + { \ + return 0x0 != (_mm_movemask_ps(_test)&(_mask) ); \ + } \ + \ + template<> \ + BX_SIMD_FORCE_INLINE bool simd_test_all_##_xyzw(simd128_sse_t _test) \ + { \ + return (_mask) == (_mm_movemask_ps(_test)&(_mask) ); \ + } + +BX_SIMD128_IMPLEMENT_TEST(x , 0x1); +BX_SIMD128_IMPLEMENT_TEST(y , 0x2); +BX_SIMD128_IMPLEMENT_TEST(xy , 0x3); +BX_SIMD128_IMPLEMENT_TEST(z , 0x4); +BX_SIMD128_IMPLEMENT_TEST(xz , 0x5); +BX_SIMD128_IMPLEMENT_TEST(yz , 0x6); +BX_SIMD128_IMPLEMENT_TEST(xyz , 0x7); +BX_SIMD128_IMPLEMENT_TEST(w , 0x8); +BX_SIMD128_IMPLEMENT_TEST(xw , 0x9); +BX_SIMD128_IMPLEMENT_TEST(yw , 0xa); +BX_SIMD128_IMPLEMENT_TEST(xyw , 0xb); +BX_SIMD128_IMPLEMENT_TEST(zw , 0xc); +BX_SIMD128_IMPLEMENT_TEST(xzw , 0xd); +BX_SIMD128_IMPLEMENT_TEST(yzw , 0xe); +BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf); + +#undef BX_SIMD128_IMPLEMENT_TEST + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_shuf_xyAB(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_movelh_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_shuf_ABxy(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_movelh_ps(_b, _a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_shuf_CDzw(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_movehl_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_shuf_zwCD(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_movehl_ps(_b, _a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_shuf_xAyB(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_unpacklo_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_shuf_yBxA(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_unpacklo_ps(_b, _a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_shuf_zCwD(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_unpackhi_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_shuf_CzDw(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_unpackhi_ps(_b, _a); + } + + template<> + BX_SIMD_FORCE_INLINE float simd_x(simd128_sse_t _a) + { + return _mm_cvtss_f32(_a); + } + + template<> + BX_SIMD_FORCE_INLINE float simd_y(simd128_sse_t _a) + { + const simd128_sse_t yyyy = simd_swiz_yyyy(_a); + const float result = _mm_cvtss_f32(yyyy); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE float simd_z(simd128_sse_t _a) + { + const simd128_sse_t zzzz = simd_swiz_zzzz(_a); + const float result = _mm_cvtss_f32(zzzz); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE float simd_w(simd128_sse_t _a) + { + const simd128_sse_t wwww = simd_swiz_wwww(_a); + const float result = _mm_cvtss_f32(wwww); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_ld(const void* _ptr) + { + return _mm_load_ps(reinterpret_cast<const float*>(_ptr) ); + } + + template<> + BX_SIMD_FORCE_INLINE void simd_st(void* _ptr, simd128_sse_t _a) + { + _mm_store_ps(reinterpret_cast<float*>(_ptr), _a); + } + + template<> + BX_SIMD_FORCE_INLINE void simd_stx(void* _ptr, simd128_sse_t _a) + { + _mm_store_ss(reinterpret_cast<float*>(_ptr), _a); + } + + template<> + BX_SIMD_FORCE_INLINE void simd_stream(void* _ptr, simd128_sse_t _a) + { + _mm_stream_ps(reinterpret_cast<float*>(_ptr), _a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_ld(float _x, float _y, float _z, float _w) + { + return _mm_set_ps(_w, _z, _y, _x); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) + { + const __m128i set = _mm_set_epi32(_w, _z, _y, _x); + const simd128_sse_t result = _mm_castsi128_ps(set); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_splat(const void* _ptr) + { + const simd128_sse_t x___ = _mm_load_ss(reinterpret_cast<const float*>(_ptr) ); + const simd128_sse_t result = simd_swiz_xxxx(x___); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_splat(float _a) + { + return _mm_set1_ps(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_isplat(uint32_t _a) + { + const __m128i splat = _mm_set1_epi32(_a); + const simd128_sse_t result = _mm_castsi128_ps(splat); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_zero() + { + return _mm_setzero_ps(); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_itof(simd128_sse_t _a) + { + const __m128i itof = _mm_castps_si128(_a); + const simd128_sse_t result = _mm_cvtepi32_ps(itof); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_ftoi(simd128_sse_t _a) + { + const __m128i ftoi = _mm_cvtps_epi32(_a); + const simd128_sse_t result = _mm_castsi128_ps(ftoi); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_round(simd128_sse_t _a) + { +#if defined(__SSE4_1__) + return _mm_round_ps(_a, _MM_FROUND_NINT); +#else + const __m128i round = _mm_cvtps_epi32(_a); + const simd128_sse_t result = _mm_cvtepi32_ps(round); + + return result; +#endif // defined(__SSE4_1__) + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_add(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_add_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_sub(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_sub_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_mul(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_mul_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_div(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_div_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_rcp_est(simd128_sse_t _a) + { + return _mm_rcp_ps(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_sqrt(simd128_sse_t _a) + { + return _mm_sqrt_ps(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_rsqrt_est(simd128_sse_t _a) + { + return _mm_rsqrt_ps(_a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_dot3(simd128_sse_t _a, simd128_sse_t _b) + { +#if defined(__SSE4_1__) + return _mm_dp_ps(_a, _b, 0x77); +#else + return simd_dot3_ni(_a, _b); +#endif // defined(__SSE4__) + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_dot(simd128_sse_t _a, simd128_sse_t _b) + { +#if defined(__SSE4_1__) + return _mm_dp_ps(_a, _b, 0xFF); +#else + return simd_dot_ni(_a, _b); +#endif // defined(__SSE4__) + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_cmpeq(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_cmpeq_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_cmplt(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_cmplt_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_cmple(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_cmple_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_cmpgt(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_cmpgt_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_cmpge(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_cmpge_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_min(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_min_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_max(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_max_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_and(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_and_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_andc(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_andnot_ps(_b, _a); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_or(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_or_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_xor(simd128_sse_t _a, simd128_sse_t _b) + { + return _mm_xor_ps(_a, _b); + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_sll(simd128_sse_t _a, int _count) + { + const __m128i a = _mm_castps_si128(_a); + const __m128i shift = _mm_slli_epi32(a, _count); + const simd128_sse_t result = _mm_castsi128_ps(shift); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_srl(simd128_sse_t _a, int _count) + { + const __m128i a = _mm_castps_si128(_a); + const __m128i shift = _mm_srli_epi32(a, _count); + const simd128_sse_t result = _mm_castsi128_ps(shift); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_sra(simd128_sse_t _a, int _count) + { + const __m128i a = _mm_castps_si128(_a); + const __m128i shift = _mm_srai_epi32(a, _count); + const simd128_sse_t result = _mm_castsi128_ps(shift); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_icmpeq(simd128_sse_t _a, simd128_sse_t _b) + { + const __m128i tmp0 = _mm_castps_si128(_a); + const __m128i tmp1 = _mm_castps_si128(_b); + const __m128i tmp2 = _mm_cmpeq_epi32(tmp0, tmp1); + const simd128_sse_t result = _mm_castsi128_ps(tmp2); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_icmplt(simd128_sse_t _a, simd128_sse_t _b) + { + const __m128i tmp0 = _mm_castps_si128(_a); + const __m128i tmp1 = _mm_castps_si128(_b); + const __m128i tmp2 = _mm_cmplt_epi32(tmp0, tmp1); + const simd128_sse_t result = _mm_castsi128_ps(tmp2); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_icmpgt(simd128_sse_t _a, simd128_sse_t _b) + { + const __m128i tmp0 = _mm_castps_si128(_a); + const __m128i tmp1 = _mm_castps_si128(_b); + const __m128i tmp2 = _mm_cmpgt_epi32(tmp0, tmp1); + const simd128_sse_t result = _mm_castsi128_ps(tmp2); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_imin(simd128_sse_t _a, simd128_sse_t _b) + { +#if defined(__SSE4_1__) + const __m128i tmp0 = _mm_castps_si128(_a); + const __m128i tmp1 = _mm_castps_si128(_b); + const __m128i tmp2 = _mm_min_epi32(tmp0, tmp1); + const simd128_sse_t result = _mm_castsi128_ps(tmp2); + + return result; +#else + return simd_imin_ni(_a, _b); +#endif // defined(__SSE4_1__) + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_imax(simd128_sse_t _a, simd128_sse_t _b) + { +#if defined(__SSE4_1__) + const __m128i tmp0 = _mm_castps_si128(_a); + const __m128i tmp1 = _mm_castps_si128(_b); + const __m128i tmp2 = _mm_max_epi32(tmp0, tmp1); + const simd128_sse_t result = _mm_castsi128_ps(tmp2); + + return result; +#else + return simd_imax_ni(_a, _b); +#endif // defined(__SSE4_1__) + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_iadd(simd128_sse_t _a, simd128_sse_t _b) + { + const __m128i a = _mm_castps_si128(_a); + const __m128i b = _mm_castps_si128(_b); + const __m128i add = _mm_add_epi32(a, b); + const simd128_sse_t result = _mm_castsi128_ps(add); + + return result; + } + + template<> + BX_SIMD_FORCE_INLINE simd128_sse_t simd_isub(simd128_sse_t _a, simd128_sse_t _b) + { + const __m128i a = _mm_castps_si128(_a); + const __m128i b = _mm_castps_si128(_b); + const __m128i sub = _mm_sub_epi32(a, b); + const simd128_sse_t result = _mm_castsi128_ps(sub); + + return result; + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_shuf_xAzC(simd128_sse_t _a, simd128_sse_t _b) + { + return simd_shuf_xAzC_ni(_a, _b); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_shuf_yBwD(simd128_sse_t _a, simd128_sse_t _b) + { + return simd_shuf_yBwD_ni(_a, _b); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_rcp(simd128_sse_t _a) + { + return simd_rcp_ni(_a); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_orx(simd128_sse_t _a) + { + return simd_orx_ni(_a); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_orc(simd128_sse_t _a, simd128_sse_t _b) + { + return simd_orc_ni(_a, _b); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_neg(simd128_sse_t _a) + { + return simd_neg_ni(_a); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_madd(simd128_sse_t _a, simd128_sse_t _b, simd128_sse_t _c) + { + return simd_madd_ni(_a, _b, _c); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_nmsub(simd128_sse_t _a, simd128_sse_t _b, simd128_sse_t _c) + { + return simd_nmsub_ni(_a, _b, _c); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_div_nr(simd128_sse_t _a, simd128_sse_t _b) + { + return simd_div_nr_ni(_a, _b); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_selb(simd128_sse_t _mask, simd128_sse_t _a, simd128_sse_t _b) + { + return simd_selb_ni(_mask, _a, _b); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_sels(simd128_sse_t _test, simd128_sse_t _a, simd128_sse_t _b) + { + return simd_sels_ni(_test, _a, _b); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_not(simd128_sse_t _a) + { + return simd_not_ni(_a); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_abs(simd128_sse_t _a) + { + return simd_abs_ni(_a); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_clamp(simd128_sse_t _a, simd128_sse_t _min, simd128_sse_t _max) + { + return simd_clamp_ni(_a, _min, _max); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_lerp(simd128_sse_t _a, simd128_sse_t _b, simd128_sse_t _s) + { + return simd_lerp_ni(_a, _b, _s); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_rsqrt(simd128_sse_t _a) + { + return simd_rsqrt_ni(_a); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_rsqrt_nr(simd128_sse_t _a) + { + return simd_rsqrt_nr_ni(_a); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_rsqrt_carmack(simd128_sse_t _a) + { + return simd_rsqrt_carmack_ni(_a); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_sqrt_nr(simd128_sse_t _a) + { + return simd_sqrt_nr_ni(_a); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_log2(simd128_sse_t _a) + { + return simd_log2_ni(_a); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_exp2(simd128_sse_t _a) + { + return simd_exp2_ni(_a); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_pow(simd128_sse_t _a, simd128_sse_t _b) + { + return simd_pow_ni(_a, _b); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_cross3(simd128_sse_t _a, simd128_sse_t _b) + { + return simd_cross3_ni(_a, _b); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_normalize3(simd128_sse_t _a) + { + return simd_normalize3_ni(_a); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_ceil(simd128_sse_t _a) + { + return simd_ceil_ni(_a); + } + + template<> + BX_SIMD_INLINE simd128_sse_t simd_floor(simd128_sse_t _a) + { + return simd_floor_ni(_a); + } + + typedef simd128_sse_t simd128_t; + +} // namespace bx + +#endif // BX_SIMD128_SSE_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/simd128_swizzle.inl b/3rdparty/bx/include/bx/simd128_swizzle.inl new file mode 100644 index 00000000000..4185be81b60 --- /dev/null +++ b/3rdparty/bx/include/bx/simd128_swizzle.inl @@ -0,0 +1,266 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef BX_SIMD_T_H_HEADER_GUARD +# error "xmacro file, must be included from simd_*.h" +#endif // BX_FLOAT4_T_H_HEADER_GUARD + +// included from float4_t.h +BX_SIMD128_IMPLEMENT_SWIZZLE(x, x, x, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, x, x, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, x, x, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, x, x, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, x, y, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, x, y, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, x, y, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, x, y, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, x, z, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, x, z, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, x, z, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, x, z, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, x, w, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, x, w, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, x, w, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, x, w, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, y, x, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, y, x, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, y, x, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, y, x, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, y, y, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, y, y, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, y, y, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, y, y, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, y, z, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, y, z, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, y, z, z) +// BX_SIMD128_IMPLEMENT_SWIZZLE(x, y, z, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, y, w, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, y, w, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, y, w, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, y, w, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, z, x, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, z, x, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, z, x, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, z, x, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, z, y, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, z, y, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, z, y, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, z, y, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, z, z, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, z, z, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, z, z, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, z, z, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, z, w, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, z, w, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, z, w, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, z, w, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, w, x, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, w, x, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, w, x, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, w, x, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, w, y, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, w, y, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, w, y, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, w, y, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, w, z, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, w, z, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, w, z, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, w, z, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, w, w, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, w, w, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, w, w, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(x, w, w, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, x, x, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, x, x, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, x, x, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, x, x, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, x, y, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, x, y, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, x, y, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, x, y, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, x, z, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, x, z, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, x, z, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, x, z, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, x, w, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, x, w, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, x, w, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, x, w, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, y, x, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, y, x, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, y, x, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, y, x, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, y, y, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, y, y, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, y, y, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, y, y, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, y, z, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, y, z, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, y, z, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, y, z, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, y, w, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, y, w, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, y, w, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, y, w, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, z, x, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, z, x, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, z, x, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, z, x, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, z, y, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, z, y, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, z, y, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, z, y, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, z, z, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, z, z, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, z, z, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, z, z, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, z, w, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, z, w, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, z, w, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, z, w, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, w, x, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, w, x, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, w, x, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, w, x, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, w, y, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, w, y, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, w, y, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, w, y, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, w, z, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, w, z, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, w, z, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, w, z, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, w, w, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, w, w, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, w, w, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(y, w, w, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, x, x, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, x, x, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, x, x, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, x, x, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, x, y, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, x, y, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, x, y, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, x, y, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, x, z, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, x, z, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, x, z, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, x, z, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, x, w, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, x, w, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, x, w, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, x, w, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, y, x, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, y, x, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, y, x, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, y, x, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, y, y, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, y, y, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, y, y, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, y, y, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, y, z, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, y, z, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, y, z, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, y, z, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, y, w, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, y, w, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, y, w, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, y, w, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, z, x, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, z, x, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, z, x, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, z, x, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, z, y, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, z, y, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, z, y, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, z, y, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, z, z, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, z, z, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, z, z, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, z, z, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, z, w, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, z, w, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, z, w, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, z, w, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, w, x, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, w, x, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, w, x, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, w, x, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, w, y, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, w, y, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, w, y, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, w, y, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, w, z, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, w, z, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, w, z, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, w, z, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, w, w, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, w, w, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, w, w, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(z, w, w, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, x, x, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, x, x, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, x, x, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, x, x, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, x, y, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, x, y, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, x, y, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, x, y, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, x, z, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, x, z, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, x, z, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, x, z, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, x, w, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, x, w, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, x, w, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, x, w, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, y, x, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, y, x, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, y, x, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, y, x, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, y, y, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, y, y, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, y, y, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, y, y, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, y, z, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, y, z, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, y, z, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, y, z, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, y, w, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, y, w, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, y, w, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, y, w, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, z, x, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, z, x, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, z, x, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, z, x, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, z, y, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, z, y, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, z, y, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, z, y, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, z, z, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, z, z, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, z, z, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, z, z, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, z, w, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, z, w, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, z, w, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, z, w, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, w, x, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, w, x, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, w, x, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, w, x, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, w, y, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, w, y, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, w, y, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, w, y, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, w, z, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, w, z, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, w, z, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, w, z, w) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, w, w, x) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, w, w, y) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, w, w, z) +BX_SIMD128_IMPLEMENT_SWIZZLE(w, w, w, w) diff --git a/3rdparty/bx/include/bx/simd256_avx.inl b/3rdparty/bx/include/bx/simd256_avx.inl new file mode 100644 index 00000000000..c0f925e4160 --- /dev/null +++ b/3rdparty/bx/include/bx/simd256_avx.inl @@ -0,0 +1,9 @@ +/* + * Copyright 2010-2016 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#ifndef BX_SIMD256_AVX_H_HEADER_GUARD +#define BX_SIMD256_AVX_H_HEADER_GUARD + +#endif // BX_SIMD256_AVX_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/simd256_ref.inl b/3rdparty/bx/include/bx/simd256_ref.inl new file mode 100644 index 00000000000..84ecd6e5f9f --- /dev/null +++ b/3rdparty/bx/include/bx/simd256_ref.inl @@ -0,0 +1,9 @@ +/* + * Copyright 2010-2016 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#ifndef BX_SIMD256_REF_H_HEADER_GUARD +#define BX_SIMD256_REF_H_HEADER_GUARD + +#endif // BX_SIMD256_REF_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/simd_ni.inl b/3rdparty/bx/include/bx/simd_ni.inl new file mode 100644 index 00000000000..cab10861e5e --- /dev/null +++ b/3rdparty/bx/include/bx/simd_ni.inl @@ -0,0 +1,558 @@ +/* + * Copyright 2010-2016 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#ifndef BX_SIMD_NI_H_HEADER_GUARD +#define BX_SIMD_NI_H_HEADER_GUARD + +namespace bx +{ + template<typename Ty> + BX_SIMD_INLINE Ty simd_shuf_xAzC_ni(Ty _a, Ty _b) + { + const Ty xAyB = simd_shuf_xAyB(_a, _b); + const Ty zCwD = simd_shuf_zCwD(_a, _b); + const Ty result = simd_shuf_xyAB(xAyB, zCwD); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_shuf_yBwD_ni(Ty _a, Ty _b) + { + const Ty xAyB = simd_shuf_xAyB(_a, _b); + const Ty zCwD = simd_shuf_zCwD(_a, _b); + const Ty result = simd_shuf_zwCD(xAyB, zCwD); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_madd_ni(Ty _a, Ty _b, Ty _c) + { + const Ty mul = simd_mul(_a, _b); + const Ty result = simd_add(mul, _c); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_nmsub_ni(Ty _a, Ty _b, Ty _c) + { + const Ty mul = simd_mul(_a, _b); + const Ty result = simd_sub(_c, mul); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_div_nr_ni(Ty _a, Ty _b) + { + const Ty oneish = simd_isplat<Ty>(0x3f800001); + const Ty est = simd_rcp_est(_b); + const Ty iter0 = simd_mul(_a, est); + const Ty tmp1 = simd_nmsub(_b, est, oneish); + const Ty result = simd_madd(tmp1, iter0, iter0); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_rcp_ni(Ty _a) + { + const Ty one = simd_splat<Ty>(1.0f); + const Ty result = simd_div(one, _a); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_orx_ni(Ty _a) + { + const Ty zwxy = simd_swiz_zwxy(_a); + const Ty tmp0 = simd_or(_a, zwxy); + const Ty tmp1 = simd_swiz_yyyy(_a); + const Ty tmp2 = simd_or(tmp0, tmp1); + const Ty mf000 = simd_ild<Ty>(UINT32_MAX, 0, 0, 0); + const Ty result = simd_and(tmp2, mf000); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_orc_ni(Ty _a, Ty _b) + { + const Ty aorb = simd_or(_a, _b); + const Ty mffff = simd_isplat<Ty>(UINT32_MAX); + const Ty result = simd_xor(aorb, mffff); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_neg_ni(Ty _a) + { + const Ty zero = simd_zero<Ty>(); + const Ty result = simd_sub(zero, _a); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_selb_ni(Ty _mask, Ty _a, Ty _b) + { + const Ty sel_a = simd_and(_a, _mask); + const Ty sel_b = simd_andc(_b, _mask); + const Ty result = simd_or(sel_a, sel_b); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_sels_ni(Ty _test, Ty _a, Ty _b) + { + const Ty mask = simd_sra(_test, 31); + const Ty result = simd_selb(mask, _a, _b); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_not_ni(Ty _a) + { + const Ty mffff = simd_isplat<Ty>(UINT32_MAX); + const Ty result = simd_xor(_a, mffff); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_min_ni(Ty _a, Ty _b) + { + const Ty mask = simd_cmplt(_a, _b); + const Ty result = simd_selb(mask, _a, _b); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_max_ni(Ty _a, Ty _b) + { + const Ty mask = simd_cmpgt(_a, _b); + const Ty result = simd_selb(mask, _a, _b); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_abs_ni(Ty _a) + { + const Ty a_neg = simd_neg(_a); + const Ty result = simd_max(a_neg, _a); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_imin_ni(Ty _a, Ty _b) + { + const Ty mask = simd_icmplt(_a, _b); + const Ty result = simd_selb(mask, _a, _b); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_imax_ni(Ty _a, Ty _b) + { + const Ty mask = simd_icmpgt(_a, _b); + const Ty result = simd_selb(mask, _a, _b); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_clamp_ni(Ty _a, Ty _min, Ty _max) + { + const Ty tmp = simd_min(_a, _max); + const Ty result = simd_max(tmp, _min); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_lerp_ni(Ty _a, Ty _b, Ty _s) + { + const Ty ba = simd_sub(_b, _a); + const Ty result = simd_madd(_s, ba, _a); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_sqrt_nr_ni(Ty _a) + { + const Ty half = simd_splat<Ty>(0.5f); + const Ty one = simd_splat<Ty>(1.0f); + const Ty tmp0 = simd_rsqrt_est(_a); + const Ty tmp1 = simd_mul(tmp0, _a); + const Ty tmp2 = simd_mul(tmp1, half); + const Ty tmp3 = simd_nmsub(tmp0, tmp1, one); + const Ty result = simd_madd(tmp3, tmp2, tmp1); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_sqrt_nr1_ni(Ty _a) + { + const Ty half = simd_splat<Ty>(0.5f); + + Ty result = _a; + for (uint32_t ii = 0; ii < 11; ++ii) + { + const Ty tmp1 = simd_div(_a, result); + const Ty tmp2 = simd_add(tmp1, result); + result = simd_mul(tmp2, half); + } + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_rsqrt_ni(Ty _a) + { + const Ty one = simd_splat<Ty>(1.0f); + const Ty sqrt = simd_sqrt(_a); + const Ty result = simd_div(one, sqrt); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_rsqrt_nr_ni(Ty _a) + { + const Ty rsqrt = simd_rsqrt_est(_a); + const Ty iter0 = simd_mul(_a, rsqrt); + const Ty iter1 = simd_mul(iter0, rsqrt); + const Ty half = simd_splat<Ty>(0.5f); + const Ty half_rsqrt = simd_mul(half, rsqrt); + const Ty three = simd_splat<Ty>(3.0f); + const Ty three_sub_iter1 = simd_sub(three, iter1); + const Ty result = simd_mul(half_rsqrt, three_sub_iter1); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_rsqrt_carmack_ni(Ty _a) + { + const Ty half = simd_splat<Ty>(0.5f); + const Ty ah = simd_mul(half, _a); + const Ty ashift = simd_sra(_a, 1); + const Ty magic = simd_isplat<Ty>(0x5f3759df); + const Ty msuba = simd_isub(magic, ashift); + const Ty msubasq = simd_mul(msuba, msuba); + const Ty tmp0 = simd_splat<Ty>(1.5f); + const Ty tmp1 = simd_mul(ah, msubasq); + const Ty tmp2 = simd_sub(tmp0, tmp1); + const Ty result = simd_mul(msuba, tmp2); + + return result; + } + + namespace simd_logexp_detail + { + template<typename Ty> + BX_SIMD_INLINE Ty simd_poly1(Ty _a, float _b, float _c) + { + const Ty bbbb = simd_splat<Ty>(_b); + const Ty cccc = simd_splat<Ty>(_c); + const Ty result = simd_madd(cccc, _a, bbbb); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_poly2(Ty _a, float _b, float _c, float _d) + { + const Ty bbbb = simd_splat<Ty>(_b); + const Ty poly = simd_poly1(_a, _c, _d); + const Ty result = simd_madd(poly, _a, bbbb); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_poly3(Ty _a, float _b, float _c, float _d, float _e) + { + const Ty bbbb = simd_splat<Ty>(_b); + const Ty poly = simd_poly2(_a, _c, _d, _e); + const Ty result = simd_madd(poly, _a, bbbb); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_poly4(Ty _a, float _b, float _c, float _d, float _e, float _f) + { + const Ty bbbb = simd_splat<Ty>(_b); + const Ty poly = simd_poly3(_a, _c, _d, _e, _f); + const Ty result = simd_madd(poly, _a, bbbb); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_poly5(Ty _a, float _b, float _c, float _d, float _e, float _f, float _g) + { + const Ty bbbb = simd_splat<Ty>(_b); + const Ty poly = simd_poly4(_a, _c, _d, _e, _f, _g); + const Ty result = simd_madd(poly, _a, bbbb); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_logpoly(Ty _a) + { +#if 1 + const Ty result = simd_poly5(_a + , 3.11578814719469302614f, -3.32419399085241980044f + , 2.59883907202499966007f, -1.23152682416275988241f + , 0.318212422185251071475f, -0.0344359067839062357313f + ); +#elif 0 + const Ty result = simd_poly4(_a + , 2.8882704548164776201f, -2.52074962577807006663f + , 1.48116647521213171641f, -0.465725644288844778798f + , 0.0596515482674574969533f + ); +#elif 0 + const Ty result = simd_poly3(_a + , 2.61761038894603480148f, -1.75647175389045657003f + , 0.688243882994381274313f, -0.107254423828329604454f + ); +#else + const Ty result = simd_poly2(_a + , 2.28330284476918490682f, -1.04913055217340124191f + , 0.204446009836232697516f + ); +#endif + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_exppoly(Ty _a) + { +#if 1 + const Ty result = simd_poly5(_a + , 9.9999994e-1f, 6.9315308e-1f + , 2.4015361e-1f, 5.5826318e-2f + , 8.9893397e-3f, 1.8775767e-3f + ); +#elif 0 + const Ty result = simd_poly4(_a + , 1.0000026f, 6.9300383e-1f + , 2.4144275e-1f, 5.2011464e-2f + , 1.3534167e-2f + ); +#elif 0 + const Ty result = simd_poly3(_a + , 9.9992520e-1f, 6.9583356e-1f + , 2.2606716e-1f, 7.8024521e-2f + ); +#else + const Ty result = simd_poly2(_a + , 1.0017247f, 6.5763628e-1f + , 3.3718944e-1f + ); +#endif // 0 + + return result; + } + } // namespace simd_internal + + template<typename Ty> + BX_SIMD_INLINE Ty simd_log2_ni(Ty _a) + { + const Ty expmask = simd_isplat<Ty>(0x7f800000); + const Ty mantmask = simd_isplat<Ty>(0x007fffff); + const Ty one = simd_splat<Ty>(1.0f); + + const Ty c127 = simd_isplat<Ty>(127); + const Ty aexp = simd_and(_a, expmask); + const Ty aexpsr = simd_srl(aexp, 23); + const Ty tmp0 = simd_isub(aexpsr, c127); + const Ty exp = simd_itof(tmp0); + + const Ty amask = simd_and(_a, mantmask); + const Ty mant = simd_or(amask, one); + + const Ty poly = simd_logexp_detail::simd_logpoly(mant); + + const Ty mandiff = simd_sub(mant, one); + const Ty result = simd_madd(poly, mandiff, exp); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_exp2_ni(Ty _a) + { + const Ty min = simd_splat<Ty>( 129.0f); + const Ty max = simd_splat<Ty>(-126.99999f); + const Ty tmp0 = simd_min(_a, min); + const Ty aaaa = simd_max(tmp0, max); + + const Ty half = simd_splat<Ty>(0.5f); + const Ty tmp2 = simd_sub(aaaa, half); + const Ty ipart = simd_ftoi(tmp2); + const Ty iround = simd_itof(ipart); + const Ty fpart = simd_sub(aaaa, iround); + + const Ty c127 = simd_isplat<Ty>(127); + const Ty tmp5 = simd_iadd(ipart, c127); + const Ty expipart = simd_sll(tmp5, 23); + + const Ty expfpart = simd_logexp_detail::simd_exppoly(fpart); + + const Ty result = simd_mul(expipart, expfpart); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_pow_ni(Ty _a, Ty _b) + { + const Ty alog2 = simd_log2(_a); + const Ty alog2b = simd_mul(alog2, _b); + const Ty result = simd_exp2(alog2b); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_dot3_ni(Ty _a, Ty _b) + { + const Ty xyzw = simd_mul(_a, _b); + const Ty xxxx = simd_swiz_xxxx(xyzw); + const Ty yyyy = simd_swiz_yyyy(xyzw); + const Ty zzzz = simd_swiz_zzzz(xyzw); + const Ty tmp1 = simd_add(xxxx, yyyy); + const Ty result = simd_add(zzzz, tmp1); + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_cross3_ni(Ty _a, Ty _b) + { + // a.yzx * b.zxy - a.zxy * b.yzx == (a * b.yzx - a.yzx * b).yzx +#if 0 + const Ty a_yzxw = simd_swiz_yzxw(_a); + const Ty a_zxyw = simd_swiz_zxyw(_a); + const Ty b_zxyw = simd_swiz_zxyw(_b); + const Ty b_yzxw = simd_swiz_yzxw(_b); + const Ty tmp = simd_mul(a_yzxw, b_zxyw); + const Ty result = simd_nmsub(a_zxyw, b_yzxw, tmp); +#else + const Ty a_yzxw = simd_swiz_yzxw(_a); + const Ty b_yzxw = simd_swiz_yzxw(_b); + const Ty tmp0 = simd_mul(_a, b_yzxw); + const Ty tmp1 = simd_nmsub(a_yzxw, _b, tmp0); + const Ty result = simd_swiz_yzxw(tmp1); +#endif + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_normalize3_ni(Ty _a) + { + const Ty dot3 = simd_dot3(_a, _a); + const Ty invSqrt = simd_rsqrt(dot3); + const Ty result = simd_mul(_a, invSqrt); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_dot_ni(Ty _a, Ty _b) + { + const Ty xyzw = simd_mul(_a, _b); + const Ty yzwx = simd_swiz_yzwx(xyzw); + const Ty tmp0 = simd_add(xyzw, yzwx); + const Ty zwxy = simd_swiz_zwxy(tmp0); + const Ty result = simd_add(tmp0, zwxy); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_ceil_ni(Ty _a) + { + const Ty tmp0 = simd_ftoi(_a); + const Ty tmp1 = simd_itof(tmp0); + const Ty mask = simd_cmplt(tmp1, _a); + const Ty one = simd_splat<Ty>(1.0f); + const Ty tmp2 = simd_and(one, mask); + const Ty result = simd_add(tmp1, tmp2); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE Ty simd_floor_ni(Ty _a) + { + const Ty tmp0 = simd_ftoi(_a); + const Ty tmp1 = simd_itof(tmp0); + const Ty mask = simd_cmpgt(tmp1, _a); + const Ty one = simd_splat<Ty>(1.0f); + const Ty tmp2 = simd_and(one, mask); + const Ty result = simd_sub(tmp1, tmp2); + + return result; + } + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_round_ni(Ty _a) + { + const Ty tmp = simd_ftoi(_a); + const Ty result = simd_itof(tmp); + + return result; + } + + template<typename Ty> + BX_SIMD_INLINE bool simd_test_any_ni(Ty _a) + { + const Ty mask = simd_sra(_a, 31); + const Ty zwxy = simd_swiz_zwxy(mask); + const Ty tmp0 = simd_or(mask, zwxy); + const Ty tmp1 = simd_swiz_yyyy(tmp0); + const Ty tmp2 = simd_or(tmp0, tmp1); + int res; + simd_stx(&res, tmp2); + return 0 != res; + } + + template<typename Ty> + BX_SIMD_INLINE bool simd_test_all_ni(Ty _a) + { + const Ty bits = simd_sra(_a, 31); + const Ty m1248 = simd_ild<Ty>(1, 2, 4, 8); + const Ty mask = simd_and(bits, m1248); + const Ty zwxy = simd_swiz_zwxy(mask); + const Ty tmp0 = simd_or(mask, zwxy); + const Ty tmp1 = simd_swiz_yyyy(tmp0); + const Ty tmp2 = simd_or(tmp0, tmp1); + int res; + simd_stx(&res, tmp2); + return 0xf == res; + } + +} // namespace bx + +#endif // BX_SIMD_NI_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/simd_t.h b/3rdparty/bx/include/bx/simd_t.h new file mode 100644 index 00000000000..a2884f6e734 --- /dev/null +++ b/3rdparty/bx/include/bx/simd_t.h @@ -0,0 +1,438 @@ +/* + * Copyright 2010-2016 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#ifndef BX_SIMD_T_H_HEADER_GUARD +#define BX_SIMD_T_H_HEADER_GUARD + +#include "bx.h" + +#define BX_SIMD_FORCE_INLINE BX_FORCE_INLINE +#define BX_SIMD_INLINE inline + +#define BX_SIMD_AVX 0 +#define BX_SIMD_LANGEXT 0 +#define BX_SIMD_NEON 0 +#define BX_SIMD_SSE 0 + +#if defined(__AVX__) || defined(__AVX2__) +# include <immintrin.h> +# undef BX_SIMD_AVX +# define BX_SIMD_AVX 1 +#endif // + +#if defined(__SSE2__) || (BX_COMPILER_MSVC && (BX_ARCH_64BIT || _M_IX86_FP >= 2) ) +# include <emmintrin.h> // __m128i +# if defined(__SSE4_1__) +# include <smmintrin.h> +# endif // defined(__SSE4_1__) +# include <xmmintrin.h> // __m128 +# undef BX_SIMD_SSE +# define BX_SIMD_SSE 1 +#elif defined(__ARM_NEON__) && !BX_COMPILER_CLANG +# include <arm_neon.h> +# undef BX_SIMD_NEON +# define BX_SIMD_NEON 1 +#elif BX_COMPILER_CLANG \ + && !BX_PLATFORM_EMSCRIPTEN \ + && !BX_PLATFORM_IOS \ + && BX_CLANG_HAS_EXTENSION(attribute_ext_vector_type) +# include <math.h> +# undef BX_SIMD_LANGEXT +# define BX_SIMD_LANGEXT 1 +#endif // + +namespace bx +{ +#define ELEMx 0 +#define ELEMy 1 +#define ELEMz 2 +#define ELEMw 3 +#define BX_SIMD128_IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ + template<typename Ty> \ + BX_SIMD_FORCE_INLINE Ty simd_swiz_##_x##_y##_z##_w(Ty _a); +#include "simd128_swizzle.inl" + +#undef BX_SIMD128_IMPLEMENT_SWIZZLE +#undef ELEMw +#undef ELEMz +#undef ELEMy +#undef ELEMx + +#define BX_SIMD128_IMPLEMENT_TEST(_xyzw) \ + template<typename Ty> \ + BX_SIMD_FORCE_INLINE bool simd_test_any_##_xyzw(Ty _test); \ + \ + template<typename Ty> \ + BX_SIMD_FORCE_INLINE bool simd_test_all_##_xyzw(Ty _test) + +BX_SIMD128_IMPLEMENT_TEST(x ); +BX_SIMD128_IMPLEMENT_TEST(y ); +BX_SIMD128_IMPLEMENT_TEST(xy ); +BX_SIMD128_IMPLEMENT_TEST(z ); +BX_SIMD128_IMPLEMENT_TEST(xz ); +BX_SIMD128_IMPLEMENT_TEST(yz ); +BX_SIMD128_IMPLEMENT_TEST(xyz ); +BX_SIMD128_IMPLEMENT_TEST(w ); +BX_SIMD128_IMPLEMENT_TEST(xw ); +BX_SIMD128_IMPLEMENT_TEST(yw ); +BX_SIMD128_IMPLEMENT_TEST(xyw ); +BX_SIMD128_IMPLEMENT_TEST(zw ); +BX_SIMD128_IMPLEMENT_TEST(xzw ); +BX_SIMD128_IMPLEMENT_TEST(yzw ); +BX_SIMD128_IMPLEMENT_TEST(xyzw); +#undef BX_SIMD128_IMPLEMENT_TEST + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_shuf_xyAB(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_shuf_ABxy(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_shuf_CDzw(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_shuf_zwCD(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_shuf_xAyB(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_shuf_yBxA(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_shuf_zCwD(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_shuf_CzDw(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE float simd_x(Ty _a); + + template<typename Ty> + BX_SIMD_FORCE_INLINE float simd_y(Ty _a); + + template<typename Ty> + BX_SIMD_FORCE_INLINE float simd_z(Ty _a); + + template<typename Ty> + BX_SIMD_FORCE_INLINE float simd_w(Ty _a); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_ld(const void* _ptr); + + template<typename Ty> + BX_SIMD_FORCE_INLINE void simd_st(void* _ptr, Ty _a); + + template<typename Ty> + BX_SIMD_FORCE_INLINE void simd_stx(void* _ptr, Ty _a); + + template<typename Ty> + BX_SIMD_FORCE_INLINE void simd_stream(void* _ptr, Ty _a); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_ld(float _x, float _y, float _z, float _w); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_splat(const void* _ptr); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_splat(float _a); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_isplat(uint32_t _a); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_zero(); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_itof(Ty _a); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_ftoi(Ty _a); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_round(Ty _a); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_add(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_sub(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_mul(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_div(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_rcp_est(Ty _a); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_sqrt(Ty _a); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_rsqrt_est(Ty _a); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_dot3(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_dot(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_cmpeq(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_cmplt(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_cmple(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_cmpgt(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_cmpge(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_min(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_max(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_and(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_andc(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_or(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_xor(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_sll(Ty _a, int _count); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_srl(Ty _a, int _count); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_sra(Ty _a, int _count); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_icmpeq(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_icmplt(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_icmpgt(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_imin(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_imax(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_iadd(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_FORCE_INLINE Ty simd_isub(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_shuf_xAzC(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_shuf_yBwD(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_rcp(Ty _a); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_orx(Ty _a); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_orc(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_neg(Ty _a); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_madd(Ty _a, Ty _b, Ty _c); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_nmsub(Ty _a, Ty _b, Ty _c); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_div_nr(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_selb(Ty _mask, Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_sels(Ty _test, Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_not(Ty _a); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_abs(Ty _a); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_clamp(Ty _a, Ty _min, Ty _max); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_lerp(Ty _a, Ty _b, Ty _s); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_rsqrt(Ty _a); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_rsqrt_nr(Ty _a); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_rsqrt_carmack(Ty _a); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_sqrt_nr(Ty _a); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_log2(Ty _a); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_exp2(Ty _a); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_pow(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_cross3(Ty _a, Ty _b); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_normalize3(Ty _a); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_ceil(Ty _a); + + template<typename Ty> + BX_SIMD_INLINE Ty simd_floor(Ty _a); + +#if BX_SIMD_AVX + typedef __m256 simd256_avx_t; +#endif // BX_SIMD_SSE + +#if BX_SIMD_LANGEXT + union simd128_langext_t + { + float __attribute__((vector_size(16))) vf; + int32_t __attribute__((vector_size(16))) vi; + uint32_t __attribute__((vector_size(16))) vu; + float fxyzw[4]; + int32_t ixyzw[4]; + uint32_t uxyzw[4]; + + }; +#endif // BX_SIMD_LANGEXT + +#if BX_SIMD_NEON + typedef float32x4_t simd128_neon_t; +#endif // BX_SIMD_NEON + +#if BX_SIMD_SSE + typedef __m128 simd128_sse_t; +#endif // BX_SIMD_SSE + + union simd128_ref_t + { + float fxyzw[4]; + int32_t ixyzw[4]; + uint32_t uxyzw[4]; + + }; + +} // namespace bx + +#if BX_SIMD_AVX +# include "simd256_avx.inl" +#endif // BX_SIMD_AVX + +#if BX_SIMD_LANGEXT +# include "simd128_langext.inl" +#endif // BX_SIMD_LANGEXT + +#if BX_SIMD_NEON +# include "simd128_neon.inl" +#endif // BX_SIMD_NEON + +#if BX_SIMD_SSE +# include "simd128_sse.inl" +#endif // BX_SIMD_SSE + +#include "simd128_ref.inl" +#include "simd256_ref.inl" + +namespace bx +{ +#if !( BX_SIMD_AVX \ + || BX_SIMD_LANGEXT \ + || BX_SIMD_NEON \ + || BX_SIMD_SSE \ + ) +# ifndef BX_SIMD_WARN_REFERENCE_IMPL +# define BX_SIMD_WARN_REFERENCE_IMPL 0 +# endif // BX_SIMD_WARN_REFERENCE_IMPL + +# if BX_SIMD_WARN_REFERENCE_IMPL +# pragma message("************************************\nUsing SIMD reference implementation!\n************************************") +# endif // BX_SIMD_WARN_REFERENCE_IMPL + + typedef simd128_ref_t simd128_t; +#endif // + + BX_SIMD_FORCE_INLINE simd128_t simd_zero() + { + return simd_zero<simd128_t>(); + } + + BX_SIMD_FORCE_INLINE simd128_t simd_ld(const void* _ptr) + { + return simd_ld<simd128_t>(_ptr); + } + + BX_SIMD_FORCE_INLINE simd128_t simd_ld(float _x, float _y, float _z, float _w) + { + return simd_ld<simd128_t>(_x, _y, _z, _w); + } + + BX_SIMD_FORCE_INLINE simd128_t simd_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) + { + return simd_ild<simd128_t>(_x, _y, _z, _w); + } + + BX_SIMD_FORCE_INLINE simd128_t simd_splat(const void* _ptr) + { + return simd_splat<simd128_t>(_ptr); + } + + BX_SIMD_FORCE_INLINE simd128_t simd_splat(float _a) + { + return simd_splat<simd128_t>(_a); + } + + BX_SIMD_FORCE_INLINE simd128_t simd_isplat(uint32_t _a) + { + return simd_isplat<simd128_t>(_a); + } +} // namespace bx + +#endif // BX_SIMD_T_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/string.h b/3rdparty/bx/include/bx/string.h index 937f15d1def..1bd322528b3 100644 --- a/3rdparty/bx/include/bx/string.h +++ b/3rdparty/bx/include/bx/string.h @@ -30,7 +30,7 @@ namespace bx /// Case insensitive string compare. inline int32_t stricmp(const char* _a, const char* _b) { -#if BX_COMPILER_MSVC_COMPATIBLE +#if BX_CRT_MSVC return ::_stricmp(_a, _b); #else return ::strcasecmp(_a, _b); diff --git a/3rdparty/bx/scripts/bx.lua b/3rdparty/bx/scripts/bx.lua index aa09b050f8a..8cae8b419e8 100644 --- a/3rdparty/bx/scripts/bx.lua +++ b/3rdparty/bx/scripts/bx.lua @@ -21,4 +21,5 @@ project "bx" files { "../include/**.h", + "../include/**.inl", } diff --git a/3rdparty/bx/scripts/toolchain.lua b/3rdparty/bx/scripts/toolchain.lua index 5ff98ccf8c1..0f751dd3aa4 100644 --- a/3rdparty/bx/scripts/toolchain.lua +++ b/3rdparty/bx/scripts/toolchain.lua @@ -717,7 +717,7 @@ function toolchain(_buildDir, _libDir) "NoImportLib", } includedirs { - "$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.8/include", + "$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/include", "$(ANDROID_NDK_ROOT)/sources/android/native_app_glue", } linkoptions { @@ -811,10 +811,10 @@ function toolchain(_buildDir, _libDir) objdir (path.join(_buildDir, "android-mips/obj")) libdirs { path.join(_libDir, "lib/android-mips"), - "$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.8/libs/mips", + "$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/libs/mips", } includedirs { - "$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.8/libs/mips/include", + "$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/libs/mips/include", } buildoptions { "--sysroot=" .. path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-mips"), @@ -832,10 +832,10 @@ function toolchain(_buildDir, _libDir) objdir (path.join(_buildDir, "android-x86/obj")) libdirs { path.join(_libDir, "lib/android-x86"), - "$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.8/libs/x86", + "$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/libs/x86", } includedirs { - "$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.8/libs/x86/include", + "$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/libs/x86/include", } buildoptions { "--sysroot=" .. path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-x86"), diff --git a/3rdparty/bx/tests/float4_t.cpp b/3rdparty/bx/tests/float4_t.cpp deleted file mode 100644 index 3bdfb1976b1..00000000000 --- a/3rdparty/bx/tests/float4_t.cpp +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright 2010-2016 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bx#license-bsd-2-clause - */ - -#include "test.h" -#include <bx/float4_t.h> -#include <bx/fpumath.h> -#include <string.h> - -using namespace bx; - -union float4_cast -{ - bx::float4_t f4; - float f[4]; - uint32_t ui[4]; - int32_t i[4]; - char c[16]; -}; - -void float4_check_bool(const char* _str, bool _a, bool _0) -{ - DBG("%s %d == %d" - , _str - , _a - , _0 - ); - - CHECK_EQUAL(_a, _0); -} - -void float4_check_int32(const char* _str, bx::float4_t _a, int32_t _0, int32_t _1, int32_t _2, int32_t _3) -{ - float4_cast c; c.f4 = _a; - DBG("%s (%d, %d, %d, %d) == (%d, %d, %d, %d)" - , _str - , c.i[0], c.i[1], c.i[2], c.i[3] - , _0, _1, _2, _3 - ); - - CHECK_EQUAL(c.i[0], _0); - CHECK_EQUAL(c.i[1], _1); - CHECK_EQUAL(c.i[2], _2); - CHECK_EQUAL(c.i[3], _3); -} - -void float4_check_uint32(const char* _str, bx::float4_t _a, uint32_t _0, uint32_t _1, uint32_t _2, uint32_t _3) -{ - float4_cast c; c.f4 = _a; - - DBG("%s (0x%08x, 0x%08x, 0x%08x, 0x%08x) == (0x%08x, 0x%08x, 0x%08x, 0x%08x)" - , _str - , c.ui[0], c.ui[1], c.ui[2], c.ui[3] - , _0, _1, _2, _3 - ); - - CHECK_EQUAL(c.ui[0], _0); - CHECK_EQUAL(c.ui[1], _1); - CHECK_EQUAL(c.ui[2], _2); - CHECK_EQUAL(c.ui[3], _3); -} - -void float4_check_float(const char* _str, bx::float4_t _a, float _0, float _1, float _2, float _3) -{ - float4_cast c; c.f4 = _a; - - DBG("%s (%f, %f, %f, %f) == (%f, %f, %f, %f)" - , _str - , c.f[0], c.f[1], c.f[2], c.f[3] - , _0, _1, _2, _3 - ); - - CHECK(bx::fequal(c.f[0], _0, 0.0001f) ); - CHECK(bx::fequal(c.f[1], _1, 0.0001f) ); - CHECK(bx::fequal(c.f[2], _2, 0.0001f) ); - CHECK(bx::fequal(c.f[3], _3, 0.0001f) ); -} - -void float4_check_string(const char* _str, bx::float4_t _a) -{ - float4_cast c; c.f4 = _a; - const char test[5] = { c.c[0], c.c[4], c.c[8], c.c[12], '\0' }; - - DBG("%s %s", _str, test); - - CHECK(0 == strcmp(_str, test) ); -} - -TEST(float4_swizzle) -{ - const float4_t xyzw = float4_ild(0x78787878, 0x79797979, 0x7a7a7a7a, 0x77777777); - -#define ELEMx 0 -#define ELEMy 1 -#define ELEMz 2 -#define ELEMw 3 -#define IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ - float4_check_string("" #_x #_y #_z #_w "", float4_swiz_##_x##_y##_z##_w(xyzw) ); \ - -#include <bx/float4_swizzle.inl> - -#undef IMPLEMENT_SWIZZLE -#undef ELEMw -#undef ELEMz -#undef ELEMy -#undef ELEMx -} - -TEST(float4_shuffle) -{ - const float4_t xyzw = float4_ild(0x78787878, 0x79797979, 0x7a7a7a7a, 0x77777777); - const float4_t ABCD = float4_ild(0x41414141, 0x42424242, 0x43434343, 0x44444444); - float4_check_string("xyAB", float4_shuf_xyAB(xyzw, ABCD) ); - float4_check_string("ABxy", float4_shuf_ABxy(xyzw, ABCD) ); - float4_check_string("zwCD", float4_shuf_zwCD(xyzw, ABCD) ); - float4_check_string("CDzw", float4_shuf_CDzw(xyzw, ABCD) ); - float4_check_string("xAyB", float4_shuf_xAyB(xyzw, ABCD) ); - float4_check_string("zCwD", float4_shuf_zCwD(xyzw, ABCD) ); - float4_check_string("xAzC", float4_shuf_xAzC(xyzw, ABCD) ); - float4_check_string("yBwD", float4_shuf_yBwD(xyzw, ABCD) ); - float4_check_string("CzDw", float4_shuf_CzDw(xyzw, ABCD) ); -} - -TEST(float4_compare) -{ - float4_check_uint32("cmpeq" - , float4_cmpeq(float4_ld(1.0f, 2.0f, 3.0f, 4.0f), float4_ld(0.0f, 2.0f, 0.0f, 3.0f) ) - , 0, 0xffffffff, 0, 0 - ); - - float4_check_uint32("cmplt" - , float4_cmplt(float4_ld(1.0f, 2.0f, 3.0f, 4.0f), float4_ld(0.0f, 2.0f, 0.0f, 3.0f) ) - , 0, 0, 0, 0 - ); - - float4_check_uint32("cmple" - , float4_cmple(float4_ld(1.0f, 2.0f, 3.0f, 4.0f), float4_ld(0.0f, 2.0f, 0.0f, 3.0f) ) - , 0, 0xffffffff, 0, 0 - ); - - float4_check_uint32("cmpgt" - , float4_cmpgt(float4_ld(1.0f, 2.0f, 3.0f, 4.0f), float4_ld(0.0f, 2.0f, 0.0f, 3.0f) ) - , 0xffffffff, 0, 0xffffffff, 0xffffffff - ); - - float4_check_uint32("cmpge" - , float4_cmpge(float4_ld(1.0f, 2.0f, 3.0f, 4.0f), float4_ld(0.0f, 2.0f, 0.0f, 3.0f) ) - , 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff - ); - - float4_check_uint32("icmpeq" - , float4_icmpeq(float4_ild(0, 1, 2, 3), float4_ild(0, uint32_t(-2), 1, 3) ) - , 0xffffffff, 0, 0, 0xffffffff - ); - - float4_check_uint32("icmplt" - , float4_icmplt(float4_ild(0, 1, 2, 3), float4_ild(0, uint32_t(-2), 1, 3) ) - , 0, 0, 0, 0 - ); - - float4_check_uint32("icmpgt" - , float4_icmpgt(float4_ild(0, 1, 2, 3), float4_ild(0, uint32_t(-2), 1, 3) ) - , 0, 0xffffffff, 0xffffffff, 0 - ); -} - -TEST(float4_test) -{ - float4_check_bool("test_any_xyzw" - , float4_test_any_xyzw(float4_ild(0xffffffff, 0, 0, 0) ) - , true - ); - - float4_check_bool("test_all_xyzw" - , float4_test_all_xyzw(float4_ild(0xffffffff, 0, 0xffffffff, 0) ) - , false - ); - - float4_check_bool("test_all_xyzw" - , float4_test_all_xyzw(float4_ild(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff) ) - , true - ); - - float4_check_bool("test_all_xw" - , float4_test_all_xw(float4_ild(0xffffffff, 0, 0, 0xffffffff) ) - , true - ); - - float4_check_bool("test_all_xzw" - , float4_test_all_xzw(float4_ild(0xffffffff, 0, 0, 0xffffffff) ) - , false - ); -} - -TEST(float4_load) -{ - float4_check_float("ld" - , float4_ld(0.0f, 1.0f, 2.0f, 3.0f) - , 0.0f, 1.0f, 2.0f, 3.0f - ); - - float4_check_int32("ild" - , float4_ild(uint32_t(-1), 0, 1, 2) - , uint32_t(-1), 0, 1, 2 - ); - - float4_check_int32("ild" - , float4_ild(uint32_t(-1), uint32_t(-2), uint32_t(-3), uint32_t(-4) ) - , uint32_t(-1), uint32_t(-2), uint32_t(-3), uint32_t(-4) - ); - - float4_check_uint32("zero", float4_zero() - , 0, 0, 0, 0 - ); - - float4_check_uint32("isplat", float4_isplat(0x80000001) - , 0x80000001, 0x80000001, 0x80000001, 0x80000001 - ); - - float4_check_float("isplat", float4_splat(1.0f) - , 1.0f, 1.0f, 1.0f, 1.0f - ); -} - -TEST(float4_arithmetic) -{ - float4_check_float("madd" - , float4_madd(float4_ld(0.0f, 1.0f, 2.0f, 3.0f), float4_ld(4.0f, 5.0f, 6.0f, 7.0f), float4_ld(8.0f, 9.0f, 10.0f, 11.0f) ) - , 8.0f, 14.0f, 22.0f, 32.0f - ); - - float4_check_float("cross3" - , float4_cross3(float4_ld(1.0f, 0.0f, 0.0f, 0.0f), float4_ld(0.0f, 1.0f, 0.0f, 0.0f) ) - , 0.0f, 0.0f, 1.0f, 0.0f - ); -} - -TEST(float4_sqrt) -{ - float4_check_float("float4_sqrt" - , float4_sqrt(float4_ld(1.0f, 16.0f, 65536.0f, 123456.0f) ) - , 1.0f, 4.0f, 256.0f, 351.363060096f - ); - - float4_check_float("float4_sqrt_nr_ni" - , float4_sqrt_nr_ni(float4_ld(1.0f, 16.0f, 65536.0f, 123456.0f) ) - , 1.0f, 4.0f, 256.0f, 351.363060096f - ); - - float4_check_float("float4_sqrt_nr1_ni" - , float4_sqrt_nr1_ni(float4_ld(1.0f, 16.0f, 65536.0f, 123456.0f) ) - , 1.0f, 4.0f, 256.0f, 351.363060096f - ); -} - -TEST(float4) -{ - const float4_t isplat = float4_isplat(0x80000001); - float4_check_uint32("sll" - , float4_sll(isplat, 1) - , 0x00000002, 0x00000002, 0x00000002, 0x00000002 - ); - - float4_check_uint32("srl" - , float4_srl(isplat, 1) - , 0x40000000, 0x40000000, 0x40000000, 0x40000000 - ); - - float4_check_uint32("sra" - , float4_sra(isplat, 1) - , 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000 - ); - - float4_check_uint32("and" - , float4_and(float4_isplat(0x55555555), float4_isplat(0xaaaaaaaa) ) - , 0, 0, 0, 0 - ); - - float4_check_uint32("or " - , float4_or(float4_isplat(0x55555555), float4_isplat(0xaaaaaaaa) ) - , uint32_t(-1), uint32_t(-1), uint32_t(-1), uint32_t(-1) - ); - - float4_check_uint32("xor" - , float4_or(float4_isplat(0x55555555), float4_isplat(0xaaaaaaaa) ) - , uint32_t(-1), uint32_t(-1), uint32_t(-1), uint32_t(-1) - ); - - float4_check_int32("imin" - , float4_imin(float4_ild(0, 1, 2, 3), float4_ild(uint32_t(-1), 2, uint32_t(-2), 1) ) - , uint32_t(-1), 1, uint32_t(-2), 1 - ); - - float4_check_float("min" - , float4_min(float4_ld(0.0f, 1.0f, 2.0f, 3.0f), float4_ld(-1.0f, 2.0f, -2.0f, 1.0f) ) - , -1.0f, 1.0f, -2.0f, 1.0f - ); - - float4_check_int32("imax" - , float4_imax(float4_ild(0, 1, 2, 3), float4_ild(uint32_t(-1), 2, uint32_t(-2), 1) ) - , 0, 2, 2, 3 - ); - - float4_check_float("max" - , float4_max(float4_ld(0.0f, 1.0f, 2.0f, 3.0f), float4_ld(-1.0f, 2.0f, -2.0f, 1.0f) ) - , 0.0f, 2.0f, 2.0f, 3.0f - ); -} diff --git a/3rdparty/bx/tests/simd_t.cpp b/3rdparty/bx/tests/simd_t.cpp new file mode 100644 index 00000000000..999438a234a --- /dev/null +++ b/3rdparty/bx/tests/simd_t.cpp @@ -0,0 +1,309 @@ +/* + * Copyright 2010-2016 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "test.h" +#include <bx/simd_t.h> +#include <bx/fpumath.h> +#include <string.h> + +using namespace bx; + +union simd_cast +{ + bx::simd128_t f4; + float f[4]; + uint32_t ui[4]; + int32_t i[4]; + char c[16]; +}; + +void simd_check_bool(const char* _str, bool _a, bool _0) +{ + DBG("%s %d == %d" + , _str + , _a + , _0 + ); + + CHECK_EQUAL(_a, _0); +} + +void simd_check_int32(const char* _str, bx::simd128_t _a, int32_t _0, int32_t _1, int32_t _2, int32_t _3) +{ + simd_cast c; c.f4 = _a; + DBG("%s (%d, %d, %d, %d) == (%d, %d, %d, %d)" + , _str + , c.i[0], c.i[1], c.i[2], c.i[3] + , _0, _1, _2, _3 + ); + + CHECK_EQUAL(c.i[0], _0); + CHECK_EQUAL(c.i[1], _1); + CHECK_EQUAL(c.i[2], _2); + CHECK_EQUAL(c.i[3], _3); +} + +void simd_check_uint32(const char* _str, bx::simd128_t _a, uint32_t _0, uint32_t _1, uint32_t _2, uint32_t _3) +{ + simd_cast c; c.f4 = _a; + + DBG("%s (0x%08x, 0x%08x, 0x%08x, 0x%08x) == (0x%08x, 0x%08x, 0x%08x, 0x%08x)" + , _str + , c.ui[0], c.ui[1], c.ui[2], c.ui[3] + , _0, _1, _2, _3 + ); + + CHECK_EQUAL(c.ui[0], _0); + CHECK_EQUAL(c.ui[1], _1); + CHECK_EQUAL(c.ui[2], _2); + CHECK_EQUAL(c.ui[3], _3); +} + +void simd_check_float(const char* _str, bx::simd128_t _a, float _0, float _1, float _2, float _3) +{ + simd_cast c; c.f4 = _a; + + DBG("%s (%f, %f, %f, %f) == (%f, %f, %f, %f)" + , _str + , c.f[0], c.f[1], c.f[2], c.f[3] + , _0, _1, _2, _3 + ); + + CHECK(bx::fequal(c.f[0], _0, 0.0001f) ); + CHECK(bx::fequal(c.f[1], _1, 0.0001f) ); + CHECK(bx::fequal(c.f[2], _2, 0.0001f) ); + CHECK(bx::fequal(c.f[3], _3, 0.0001f) ); +} + +void simd_check_string(const char* _str, bx::simd128_t _a) +{ + simd_cast c; c.f4 = _a; + const char test[5] = { c.c[0], c.c[4], c.c[8], c.c[12], '\0' }; + + DBG("%s %s", _str, test); + + CHECK(0 == strcmp(_str, test) ); +} + +TEST(simd_swizzle) +{ + const simd128_t xyzw = simd_ild(0x78787878, 0x79797979, 0x7a7a7a7a, 0x77777777); + +#define ELEMx 0 +#define ELEMy 1 +#define ELEMz 2 +#define ELEMw 3 +#define BX_SIMD128_IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \ + simd_check_string("" #_x #_y #_z #_w "", simd_swiz_##_x##_y##_z##_w(xyzw) ); \ + +#include <bx/simd128_swizzle.inl> + +#undef BX_SIMD128_IMPLEMENT_SWIZZLE +#undef ELEMw +#undef ELEMz +#undef ELEMy +#undef ELEMx +} + +TEST(simd_shuffle) +{ + const simd128_t xyzw = simd_ild(0x78787878, 0x79797979, 0x7a7a7a7a, 0x77777777); + const simd128_t ABCD = simd_ild(0x41414141, 0x42424242, 0x43434343, 0x44444444); + simd_check_string("xyAB", simd_shuf_xyAB(xyzw, ABCD) ); + simd_check_string("ABxy", simd_shuf_ABxy(xyzw, ABCD) ); + simd_check_string("zwCD", simd_shuf_zwCD(xyzw, ABCD) ); + simd_check_string("CDzw", simd_shuf_CDzw(xyzw, ABCD) ); + simd_check_string("xAyB", simd_shuf_xAyB(xyzw, ABCD) ); + simd_check_string("zCwD", simd_shuf_zCwD(xyzw, ABCD) ); + simd_check_string("xAzC", simd_shuf_xAzC(xyzw, ABCD) ); + simd_check_string("yBwD", simd_shuf_yBwD(xyzw, ABCD) ); + simd_check_string("CzDw", simd_shuf_CzDw(xyzw, ABCD) ); +} + +TEST(simd_compare) +{ + simd_check_uint32("cmpeq" + , simd_cmpeq(simd_ld(1.0f, 2.0f, 3.0f, 4.0f), simd_ld(0.0f, 2.0f, 0.0f, 3.0f) ) + , 0, 0xffffffff, 0, 0 + ); + + simd_check_uint32("cmplt" + , simd_cmplt(simd_ld(1.0f, 2.0f, 3.0f, 4.0f), simd_ld(0.0f, 2.0f, 0.0f, 3.0f) ) + , 0, 0, 0, 0 + ); + + simd_check_uint32("cmple" + , simd_cmple(simd_ld(1.0f, 2.0f, 3.0f, 4.0f), simd_ld(0.0f, 2.0f, 0.0f, 3.0f) ) + , 0, 0xffffffff, 0, 0 + ); + + simd_check_uint32("cmpgt" + , simd_cmpgt(simd_ld(1.0f, 2.0f, 3.0f, 4.0f), simd_ld(0.0f, 2.0f, 0.0f, 3.0f) ) + , 0xffffffff, 0, 0xffffffff, 0xffffffff + ); + + simd_check_uint32("cmpge" + , simd_cmpge(simd_ld(1.0f, 2.0f, 3.0f, 4.0f), simd_ld(0.0f, 2.0f, 0.0f, 3.0f) ) + , 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff + ); + + simd_check_uint32("icmpeq" + , simd_icmpeq(simd_ild(0, 1, 2, 3), simd_ild(0, uint32_t(-2), 1, 3) ) + , 0xffffffff, 0, 0, 0xffffffff + ); + + simd_check_uint32("icmplt" + , simd_icmplt(simd_ild(0, 1, 2, 3), simd_ild(0, uint32_t(-2), 1, 3) ) + , 0, 0, 0, 0 + ); + + simd_check_uint32("icmpgt" + , simd_icmpgt(simd_ild(0, 1, 2, 3), simd_ild(0, uint32_t(-2), 1, 3) ) + , 0, 0xffffffff, 0xffffffff, 0 + ); +} + +TEST(simd_test) +{ + simd_check_bool("test_any_xyzw" + , simd_test_any_xyzw(simd_ild(0xffffffff, 0, 0, 0) ) + , true + ); + + simd_check_bool("test_all_xyzw" + , simd_test_all_xyzw(simd_ild(0xffffffff, 0, 0xffffffff, 0) ) + , false + ); + + simd_check_bool("test_all_xyzw" + , simd_test_all_xyzw(simd_ild(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff) ) + , true + ); + + simd_check_bool("test_all_xw" + , simd_test_all_xw(simd_ild(0xffffffff, 0, 0, 0xffffffff) ) + , true + ); + + simd_check_bool("test_all_xzw" + , simd_test_all_xzw(simd_ild(0xffffffff, 0, 0, 0xffffffff) ) + , false + ); +} + +TEST(simd_load) +{ + simd_check_float("ld" + , simd_ld(0.0f, 1.0f, 2.0f, 3.0f) + , 0.0f, 1.0f, 2.0f, 3.0f + ); + + simd_check_int32("ild" + , simd_ild(uint32_t(-1), 0, 1, 2) + , uint32_t(-1), 0, 1, 2 + ); + + simd_check_int32("ild" + , simd_ild(uint32_t(-1), uint32_t(-2), uint32_t(-3), uint32_t(-4) ) + , uint32_t(-1), uint32_t(-2), uint32_t(-3), uint32_t(-4) + ); + + simd_check_uint32("zero", simd_zero() + , 0, 0, 0, 0 + ); + + simd_check_uint32("isplat", simd_isplat(0x80000001) + , 0x80000001, 0x80000001, 0x80000001, 0x80000001 + ); + + simd_check_float("isplat", simd_splat(1.0f) + , 1.0f, 1.0f, 1.0f, 1.0f + ); +} + +TEST(simd_arithmetic) +{ + simd_check_float("madd" + , simd_madd(simd_ld(0.0f, 1.0f, 2.0f, 3.0f), simd_ld(4.0f, 5.0f, 6.0f, 7.0f), simd_ld(8.0f, 9.0f, 10.0f, 11.0f) ) + , 8.0f, 14.0f, 22.0f, 32.0f + ); + + simd_check_float("cross3" + , simd_cross3(simd_ld(1.0f, 0.0f, 0.0f, 0.0f), simd_ld(0.0f, 1.0f, 0.0f, 0.0f) ) + , 0.0f, 0.0f, 1.0f, 0.0f + ); +} + +TEST(simd_sqrt) +{ + simd_check_float("simd_sqrt" + , simd_sqrt(simd_ld(1.0f, 16.0f, 65536.0f, 123456.0f) ) + , 1.0f, 4.0f, 256.0f, 351.363060096f + ); + + simd_check_float("simd_sqrt_nr_ni" + , simd_sqrt_nr_ni(simd_ld(1.0f, 16.0f, 65536.0f, 123456.0f) ) + , 1.0f, 4.0f, 256.0f, 351.363060096f + ); + + simd_check_float("simd_sqrt_nr1_ni" + , simd_sqrt_nr1_ni(simd_ld(1.0f, 16.0f, 65536.0f, 123456.0f) ) + , 1.0f, 4.0f, 256.0f, 351.363060096f + ); +} + +TEST(float4) +{ + const simd128_t isplat = simd_isplat(0x80000001); + simd_check_uint32("sll" + , simd_sll(isplat, 1) + , 0x00000002, 0x00000002, 0x00000002, 0x00000002 + ); + + simd_check_uint32("srl" + , simd_srl(isplat, 1) + , 0x40000000, 0x40000000, 0x40000000, 0x40000000 + ); + + simd_check_uint32("sra" + , simd_sra(isplat, 1) + , 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000 + ); + + simd_check_uint32("and" + , simd_and(simd_isplat(0x55555555), simd_isplat(0xaaaaaaaa) ) + , 0, 0, 0, 0 + ); + + simd_check_uint32("or " + , simd_or(simd_isplat(0x55555555), simd_isplat(0xaaaaaaaa) ) + , uint32_t(-1), uint32_t(-1), uint32_t(-1), uint32_t(-1) + ); + + simd_check_uint32("xor" + , simd_or(simd_isplat(0x55555555), simd_isplat(0xaaaaaaaa) ) + , uint32_t(-1), uint32_t(-1), uint32_t(-1), uint32_t(-1) + ); + + simd_check_int32("imin" + , simd_imin(simd_ild(0, 1, 2, 3), simd_ild(uint32_t(-1), 2, uint32_t(-2), 1) ) + , uint32_t(-1), 1, uint32_t(-2), 1 + ); + + simd_check_float("min" + , simd_min(simd_ld(0.0f, 1.0f, 2.0f, 3.0f), simd_ld(-1.0f, 2.0f, -2.0f, 1.0f) ) + , -1.0f, 1.0f, -2.0f, 1.0f + ); + + simd_check_int32("imax" + , simd_imax(simd_ild(0, 1, 2, 3), simd_ild(uint32_t(-1), 2, uint32_t(-2), 1) ) + , 0, 2, 2, 3 + ); + + simd_check_float("max" + , simd_max(simd_ld(0.0f, 1.0f, 2.0f, 3.0f), simd_ld(-1.0f, 2.0f, -2.0f, 1.0f) ) + , 0.0f, 2.0f, 2.0f, 3.0f + ); +} diff --git a/3rdparty/bx/tests/vector_nodefault.cpp b/3rdparty/bx/tests/vector_nodefault.cpp index 4a8bc8cf1dd..1340b0c0b3d 100644 --- a/3rdparty/bx/tests/vector_nodefault.cpp +++ b/3rdparty/bx/tests/vector_nodefault.cpp @@ -33,10 +33,14 @@ #include <string.h> #include <stdlib.h> +#if !BX_CRT_MSVC +# define _strdup strdup +#endif // !BX_CRT_MSVC + struct nodefault { - nodefault(const char* s) { data = strdup(s); } + nodefault(const char* s) { data = _strdup(s); } ~nodefault() { free(data); } - nodefault(const nodefault& other) { data = 0; if (other.data) data = strdup(other.data); } + nodefault(const nodefault& other) { data = 0; if (other.data) data = _strdup(other.data); } nodefault& operator=(const nodefault& other) { nodefault(other).swap(*this); return *this; } void swap(nodefault& other) { std::swap(data, other.data); } @@ -148,7 +152,7 @@ TEST(vector_nodefault_popback) { v.push_back("24"); CHECK(v.back() == "24"); - + v.pop_back(); CHECK(v.back() == "12"); diff --git a/3rdparty/bx/tools/bin/darwin/genie b/3rdparty/bx/tools/bin/darwin/genie Binary files differindex a092d05c1d2..ca02eb91450 100755 --- a/3rdparty/bx/tools/bin/darwin/genie +++ b/3rdparty/bx/tools/bin/darwin/genie diff --git a/3rdparty/bx/tools/bin/linux/genie b/3rdparty/bx/tools/bin/linux/genie Binary files differindex b497f5dc9b1..7b68c735e1b 100755 --- a/3rdparty/bx/tools/bin/linux/genie +++ b/3rdparty/bx/tools/bin/linux/genie diff --git a/3rdparty/bx/tools/bin/windows/genie.exe b/3rdparty/bx/tools/bin/windows/genie.exe Binary files differindex 8111412afcf..1fd05d21798 100644 --- a/3rdparty/bx/tools/bin/windows/genie.exe +++ b/3rdparty/bx/tools/bin/windows/genie.exe diff --git a/scripts/src/3rdparty.lua b/scripts/src/3rdparty.lua index e3c29933220..2dacc9b8b81 100644 --- a/scripts/src/3rdparty.lua +++ b/scripts/src/3rdparty.lua @@ -735,8 +735,16 @@ end configuration { } + local version = str_to_version(_OPTIONS["gcc_version"]) + if _OPTIONS["gcc"]~=nil and string.find(_OPTIONS["gcc"], "gcc") then + if version >= 60000 then + buildoptions_cpp { + "-Wno-misleading-indentation", + } + end + end + if _OPTIONS["targetos"]=="windows" then - local version = str_to_version(_OPTIONS["gcc_version"]) if _OPTIONS["gcc"]~=nil and string.find(_OPTIONS["gcc"], "clang") then buildoptions { "-Wno-unknown-attributes", @@ -747,7 +755,6 @@ end end if _OPTIONS["targetos"]=="macosx" then - local version = str_to_version(_OPTIONS["gcc_version"]) if _OPTIONS["gcc"]~=nil and string.find(_OPTIONS["gcc"], "clang") then buildoptions { "-Wno-switch", |