From 7712a5df4fee4cbde3db72fb244c9d7d18538dcd Mon Sep 17 00:00:00 2001 From: Jamil Halabi Date: Fri, 3 May 2024 14:01:23 +1200 Subject: [PATCH] Supported shader barycentric coords on OpenGL, Vulkan and Metal --- .../glslang/glslang/HLSL/hlslParseHelper.cpp | 2 + .../glslang/glslang/HLSL/hlslScanContext.cpp | 2 + 3rdparty/spirv-cross/spirv_msl.cpp | 5 +- bindings/bf/bgfx.bf | 53 +++++++------ bindings/cs/bgfx.cs | 53 +++++++------ bindings/d/package.d | 51 ++++++------ bindings/zig/bgfx.zig | 51 ++++++------ examples/28-wireframe/fs_wf_mesh_bc.sc | 79 +++++++++++++++++++ examples/28-wireframe/fs_wf_wireframe_bc.sc | 27 +++++++ examples/28-wireframe/vs_wf_mesh_bc.sc | 20 +++++ examples/28-wireframe/vs_wf_wireframe_bc.sc | 18 +++++ examples/28-wireframe/wireframe.cpp | 79 ++++++++++++++++++- include/bgfx/defines.h | 49 ++++++------ scripts/bgfx.idl | 3 +- src/bgfx.cpp | 3 + src/renderer_d3d12.cpp | 4 + src/renderer_gl.cpp | 58 ++++++++++++++ src/renderer_mtl.h | 5 ++ src/renderer_mtl.mm | 1 + src/renderer_noop.cpp | 1 + src/renderer_vk.cpp | 14 ++++ tools/shaderc/shaderc.cpp | 59 ++++++++++++++ 22 files changed, 512 insertions(+), 125 deletions(-) create mode 100644 examples/28-wireframe/fs_wf_mesh_bc.sc create mode 100644 examples/28-wireframe/fs_wf_wireframe_bc.sc create mode 100644 examples/28-wireframe/vs_wf_mesh_bc.sc create mode 100644 examples/28-wireframe/vs_wf_wireframe_bc.sc diff --git a/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp b/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp index 35eb222ce..72ddf8120 100644 --- a/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp +++ b/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp @@ -9522,6 +9522,8 @@ bool HlslParseContext::isInputBuiltIn(const TQualifier& qualifier) const case EbvSampleMask: case EbvSamplePosition: case EbvViewportIndex: + case EbvBaryCoordEXT: + case EbvBaryCoordNoPerspEXT: return language == EShLangFragment; case EbvGlobalInvocationId: case EbvLocalInvocationIndex: diff --git a/3rdparty/glslang/glslang/HLSL/hlslScanContext.cpp b/3rdparty/glslang/glslang/HLSL/hlslScanContext.cpp index e9edb6197..14b02ef4e 100644 --- a/3rdparty/glslang/glslang/HLSL/hlslScanContext.cpp +++ b/3rdparty/glslang/glslang/HLSL/hlslScanContext.cpp @@ -526,6 +526,8 @@ void HlslScanContext::fillInKeywordMap() (*SemanticMap)["SV_DEPTHGREATEREQUAL"] = EbvFragDepthGreater; (*SemanticMap)["SV_DEPTHLESSEQUAL"] = EbvFragDepthLesser; (*SemanticMap)["SV_STENCILREF"] = EbvFragStencilRef; + (*SemanticMap)["SV_BARYCENTRICS"] = EbvBaryCoordEXT; + (*SemanticMap)["SV_BARYCENTRICS1"] = EbvBaryCoordNoPerspEXT; } void HlslScanContext::deleteKeywordMap() diff --git a/3rdparty/spirv-cross/spirv_msl.cpp b/3rdparty/spirv-cross/spirv_msl.cpp index acc66eef9..dd8ee1d3a 100644 --- a/3rdparty/spirv-cross/spirv_msl.cpp +++ b/3rdparty/spirv-cross/spirv_msl.cpp @@ -12758,7 +12758,7 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in else quals = member_location_attribute_qualifier(type, index); - if (builtin == BuiltInBaryCoordKHR || builtin == BuiltInBaryCoordNoPerspKHR) + if (builtin == BuiltInBaryCoordKHR) { if (has_member_decoration(type.self, index, DecorationFlat) || has_member_decoration(type.self, index, DecorationCentroid) || @@ -12776,6 +12776,8 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in // FragCoord builtin; it's always noperspective on Metal. if (!type_is_integral(mbr_type) && (!is_builtin || builtin != BuiltInFragCoord)) { + if (builtin != BuiltInBaryCoordKHR && builtin != BuiltInBaryCoordNoPerspKHR) + { if (has_member_decoration(type.self, index, DecorationFlat)) { if (!quals.empty()) @@ -12807,6 +12809,7 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in quals += "center_no_perspective"; } } + } if (!quals.empty()) return " [[" + quals + "]]"; diff --git a/bindings/bf/bgfx.bf b/bindings/bf/bgfx.bf index 22159e4fd..867ffc2df 100644 --- a/bindings/bf/bgfx.bf +++ b/bindings/bf/bgfx.bf @@ -1051,121 +1051,126 @@ public static class bgfx /// FragmentOrdering = 0x0000000000000080, + /// + /// Fragment barycentric coordinates are available in fragment shader. + /// + FragmentBarycentric = 0x0000000000000100, + /// /// Graphics debugger is present. /// - GraphicsDebugger = 0x0000000000000100, + GraphicsDebugger = 0x0000000000000200, /// /// HDR10 rendering is supported. /// - Hdr10 = 0x0000000000000200, + Hdr10 = 0x0000000000000400, /// /// HiDPI rendering is supported. /// - Hidpi = 0x0000000000000400, + Hidpi = 0x0000000000000800, /// /// Image Read/Write is supported. /// - ImageRw = 0x0000000000000800, + ImageRw = 0x0000000000001000, /// /// 32-bit indices are supported. /// - Index32 = 0x0000000000001000, + Index32 = 0x0000000000002000, /// /// Instancing is supported. /// - Instancing = 0x0000000000002000, + Instancing = 0x0000000000004000, /// /// Occlusion query is supported. /// - OcclusionQuery = 0x0000000000004000, + OcclusionQuery = 0x0000000000008000, /// /// PrimitiveID is available in fragment shader. /// - PrimitiveId = 0x0000000000008000, + PrimitiveId = 0x0000000000010000, /// /// Renderer is on separate thread. /// - RendererMultithreaded = 0x0000000000010000, + RendererMultithreaded = 0x0000000000020000, /// /// Multiple windows are supported. /// - SwapChain = 0x0000000000020000, + SwapChain = 0x0000000000040000, /// /// Texture blit is supported. /// - TextureBlit = 0x0000000000040000, + TextureBlit = 0x0000000000080000, /// /// Texture compare less equal mode is supported. /// - TextureCompareLequal = 0x0000000000080000, - TextureCompareReserved = 0x0000000000100000, + TextureCompareLequal = 0x0000000000100000, + TextureCompareReserved = 0x0000000000200000, /// /// Cubemap texture array is supported. /// - TextureCubeArray = 0x0000000000200000, + TextureCubeArray = 0x0000000000400000, /// /// CPU direct access to GPU texture memory. /// - TextureDirectAccess = 0x0000000000400000, + TextureDirectAccess = 0x0000000000800000, /// /// Read-back texture is supported. /// - TextureReadBack = 0x0000000000800000, + TextureReadBack = 0x0000000001000000, /// /// 2D texture array is supported. /// - Texture2dArray = 0x0000000001000000, + Texture2dArray = 0x0000000002000000, /// /// 3D textures are supported. /// - Texture3d = 0x0000000002000000, + Texture3d = 0x0000000004000000, /// /// Transparent back buffer supported. /// - TransparentBackbuffer = 0x0000000004000000, + TransparentBackbuffer = 0x0000000008000000, /// /// Vertex attribute half-float is supported. /// - VertexAttribHalf = 0x0000000008000000, + VertexAttribHalf = 0x0000000010000000, /// /// Vertex attribute 10_10_10_2 is supported. /// - VertexAttribUint10 = 0x0000000010000000, + VertexAttribUint10 = 0x0000000020000000, /// /// Rendering with VertexID only is supported. /// - VertexId = 0x0000000020000000, + VertexId = 0x0000000040000000, /// /// Viewport layer is available in vertex shader. /// - ViewportLayerArray = 0x0000000040000000, + ViewportLayerArray = 0x0000000080000000, /// /// All texture compare modes are supported. /// - TextureCompareAll = 0x0000000000180000, + TextureCompareAll = 0x0000000000300000, } [AllowDuplicates] diff --git a/bindings/cs/bgfx.cs b/bindings/cs/bgfx.cs index 683412345..4fca70364 100644 --- a/bindings/cs/bgfx.cs +++ b/bindings/cs/bgfx.cs @@ -1050,121 +1050,126 @@ public static partial class bgfx /// FragmentOrdering = 0x0000000000000080, + /// + /// Fragment barycentric coordinates are available in fragment shader. + /// + FragmentBarycentric = 0x0000000000000100, + /// /// Graphics debugger is present. /// - GraphicsDebugger = 0x0000000000000100, + GraphicsDebugger = 0x0000000000000200, /// /// HDR10 rendering is supported. /// - Hdr10 = 0x0000000000000200, + Hdr10 = 0x0000000000000400, /// /// HiDPI rendering is supported. /// - Hidpi = 0x0000000000000400, + Hidpi = 0x0000000000000800, /// /// Image Read/Write is supported. /// - ImageRw = 0x0000000000000800, + ImageRw = 0x0000000000001000, /// /// 32-bit indices are supported. /// - Index32 = 0x0000000000001000, + Index32 = 0x0000000000002000, /// /// Instancing is supported. /// - Instancing = 0x0000000000002000, + Instancing = 0x0000000000004000, /// /// Occlusion query is supported. /// - OcclusionQuery = 0x0000000000004000, + OcclusionQuery = 0x0000000000008000, /// /// PrimitiveID is available in fragment shader. /// - PrimitiveId = 0x0000000000008000, + PrimitiveId = 0x0000000000010000, /// /// Renderer is on separate thread. /// - RendererMultithreaded = 0x0000000000010000, + RendererMultithreaded = 0x0000000000020000, /// /// Multiple windows are supported. /// - SwapChain = 0x0000000000020000, + SwapChain = 0x0000000000040000, /// /// Texture blit is supported. /// - TextureBlit = 0x0000000000040000, + TextureBlit = 0x0000000000080000, /// /// Texture compare less equal mode is supported. /// - TextureCompareLequal = 0x0000000000080000, - TextureCompareReserved = 0x0000000000100000, + TextureCompareLequal = 0x0000000000100000, + TextureCompareReserved = 0x0000000000200000, /// /// Cubemap texture array is supported. /// - TextureCubeArray = 0x0000000000200000, + TextureCubeArray = 0x0000000000400000, /// /// CPU direct access to GPU texture memory. /// - TextureDirectAccess = 0x0000000000400000, + TextureDirectAccess = 0x0000000000800000, /// /// Read-back texture is supported. /// - TextureReadBack = 0x0000000000800000, + TextureReadBack = 0x0000000001000000, /// /// 2D texture array is supported. /// - Texture2dArray = 0x0000000001000000, + Texture2dArray = 0x0000000002000000, /// /// 3D textures are supported. /// - Texture3d = 0x0000000002000000, + Texture3d = 0x0000000004000000, /// /// Transparent back buffer supported. /// - TransparentBackbuffer = 0x0000000004000000, + TransparentBackbuffer = 0x0000000008000000, /// /// Vertex attribute half-float is supported. /// - VertexAttribHalf = 0x0000000008000000, + VertexAttribHalf = 0x0000000010000000, /// /// Vertex attribute 10_10_10_2 is supported. /// - VertexAttribUint10 = 0x0000000010000000, + VertexAttribUint10 = 0x0000000020000000, /// /// Rendering with VertexID only is supported. /// - VertexId = 0x0000000020000000, + VertexId = 0x0000000040000000, /// /// Viewport layer is available in vertex shader. /// - ViewportLayerArray = 0x0000000040000000, + ViewportLayerArray = 0x0000000080000000, /// /// All texture compare modes are supported. /// - TextureCompareAll = 0x0000000000180000, + TextureCompareAll = 0x0000000000300000, } [Flags] diff --git a/bindings/d/package.d b/bindings/d/package.d index c26af2ad1..8225822f5 100644 --- a/bindings/d/package.d +++ b/bindings/d/package.d @@ -10,7 +10,7 @@ import bindbc.bgfx.config; import bindbc.common.types: c_int64, c_uint64, va_list; static import bgfx.fakeenum; -enum uint apiVersion = 128; +enum uint apiVersion = 129; alias ViewID = ushort; @@ -500,30 +500,31 @@ enum CapFlags: CapFlags_{ drawIndirectCount = 0x0000_0000_0000_0020, ///Draw indirect with indirect count is supported. fragmentDepth = 0x0000_0000_0000_0040, ///Fragment depth is available in fragment shader. fragmentOrdering = 0x0000_0000_0000_0080, ///Fragment ordering is available in fragment shader. - graphicsDebugger = 0x0000_0000_0000_0100, ///Graphics debugger is present. - hdr10 = 0x0000_0000_0000_0200, ///HDR10 rendering is supported. - hiDPI = 0x0000_0000_0000_0400, ///HiDPI rendering is supported. - imageRW = 0x0000_0000_0000_0800, ///Image Read/Write is supported. - index32 = 0x0000_0000_0000_1000, ///32-bit indices are supported. - instancing = 0x0000_0000_0000_2000, ///Instancing is supported. - occlusionQuery = 0x0000_0000_0000_4000, ///Occlusion query is supported. - primitiveID = 0x0000_0000_0000_8000, ///PrimitiveID is available in fragment shader. - rendererMultithreaded = 0x0000_0000_0001_0000, ///Renderer is on separate thread. - swapChain = 0x0000_0000_0002_0000, ///Multiple windows are supported. - textureBlit = 0x0000_0000_0004_0000, ///Texture blit is supported. - textureCompareLEqual = 0x0000_0000_0008_0000, ///Texture compare less equal mode is supported. - textureCompareReserved = 0x0000_0000_0010_0000, - textureCubeArray = 0x0000_0000_0020_0000, ///Cubemap texture array is supported. - textureDirectAccess = 0x0000_0000_0040_0000, ///CPU direct access to GPU texture memory. - textureReadBack = 0x0000_0000_0080_0000, ///Read-back texture is supported. - texture2DArray = 0x0000_0000_0100_0000, ///2D texture array is supported. - texture3D = 0x0000_0000_0200_0000, ///3D textures are supported. - transparentBackbuffer = 0x0000_0000_0400_0000, ///Transparent back buffer supported. - vertexAttribHalf = 0x0000_0000_0800_0000, ///Vertex attribute half-float is supported. - vertexAttribUint10 = 0x0000_0000_1000_0000, ///Vertex attribute 10_10_10_2 is supported. - vertexID = 0x0000_0000_2000_0000, ///Rendering with VertexID only is supported. - viewportLayerArray = 0x0000_0000_4000_0000, ///Viewport layer is available in vertex shader. - textureCompareAll = 0x0000_0000_0018_0000, ///All texture compare modes are supported. + fragmentBarycentric = 0x0000_0000_0000_0100, ///Fragment barycentric coordinates are available in fragment shader. + graphicsDebugger = 0x0000_0000_0000_0200, ///Graphics debugger is present. + hdr10 = 0x0000_0000_0000_0400, ///HDR10 rendering is supported. + hiDPI = 0x0000_0000_0000_0800, ///HiDPI rendering is supported. + imageRW = 0x0000_0000_0000_1000, ///Image Read/Write is supported. + index32 = 0x0000_0000_0000_2000, ///32-bit indices are supported. + instancing = 0x0000_0000_0000_4000, ///Instancing is supported. + occlusionQuery = 0x0000_0000_0000_8000, ///Occlusion query is supported. + primitiveID = 0x0000_0000_0001_0000, ///PrimitiveID is available in fragment shader. + rendererMultithreaded = 0x0000_0000_0002_0000, ///Renderer is on separate thread. + swapChain = 0x0000_0000_0004_0000, ///Multiple windows are supported. + textureBlit = 0x0000_0000_0008_0000, ///Texture blit is supported. + textureCompareLEqual = 0x0000_0000_0010_0000, ///Texture compare less equal mode is supported. + textureCompareReserved = 0x0000_0000_0020_0000, + textureCubeArray = 0x0000_0000_0040_0000, ///Cubemap texture array is supported. + textureDirectAccess = 0x0000_0000_0080_0000, ///CPU direct access to GPU texture memory. + textureReadBack = 0x0000_0000_0100_0000, ///Read-back texture is supported. + texture2DArray = 0x0000_0000_0200_0000, ///2D texture array is supported. + texture3D = 0x0000_0000_0400_0000, ///3D textures are supported. + transparentBackbuffer = 0x0000_0000_0800_0000, ///Transparent back buffer supported. + vertexAttribHalf = 0x0000_0000_1000_0000, ///Vertex attribute half-float is supported. + vertexAttribUint10 = 0x0000_0000_2000_0000, ///Vertex attribute 10_10_10_2 is supported. + vertexID = 0x0000_0000_4000_0000, ///Rendering with VertexID only is supported. + viewportLayerArray = 0x0000_0000_8000_0000, ///Viewport layer is available in vertex shader. + textureCompareAll = 0x0000_0000_0030_0000, ///All texture compare modes are supported. } alias CapsFormat_ = uint; diff --git a/bindings/zig/bgfx.zig b/bindings/zig/bgfx.zig index 0dd08f5e7..3b29f8530 100644 --- a/bindings/zig/bgfx.zig +++ b/bindings/zig/bgfx.zig @@ -650,75 +650,78 @@ pub const CapsFlags_FragmentDepth: CapsFlags = 0x0000000000000040; /// Fragment ordering is available in fragment shader. pub const CapsFlags_FragmentOrdering: CapsFlags = 0x0000000000000080; +/// Fragment barycentric coordinates are available in fragment shader. +pub const CapsFlags_FragmentBarycentric: CapsFlags = 0x0000000000000100; + /// Graphics debugger is present. -pub const CapsFlags_GraphicsDebugger: CapsFlags = 0x0000000000000100; +pub const CapsFlags_GraphicsDebugger: CapsFlags = 0x0000000000000200; /// HDR10 rendering is supported. -pub const CapsFlags_Hdr10: CapsFlags = 0x0000000000000200; +pub const CapsFlags_Hdr10: CapsFlags = 0x0000000000000400; /// HiDPI rendering is supported. -pub const CapsFlags_Hidpi: CapsFlags = 0x0000000000000400; +pub const CapsFlags_Hidpi: CapsFlags = 0x0000000000000800; /// Image Read/Write is supported. -pub const CapsFlags_ImageRw: CapsFlags = 0x0000000000000800; +pub const CapsFlags_ImageRw: CapsFlags = 0x0000000000001000; /// 32-bit indices are supported. -pub const CapsFlags_Index32: CapsFlags = 0x0000000000001000; +pub const CapsFlags_Index32: CapsFlags = 0x0000000000002000; /// Instancing is supported. -pub const CapsFlags_Instancing: CapsFlags = 0x0000000000002000; +pub const CapsFlags_Instancing: CapsFlags = 0x0000000000004000; /// Occlusion query is supported. -pub const CapsFlags_OcclusionQuery: CapsFlags = 0x0000000000004000; +pub const CapsFlags_OcclusionQuery: CapsFlags = 0x0000000000008000; /// PrimitiveID is available in fragment shader. -pub const CapsFlags_PrimitiveId: CapsFlags = 0x0000000000008000; +pub const CapsFlags_PrimitiveId: CapsFlags = 0x0000000000010000; /// Renderer is on separate thread. -pub const CapsFlags_RendererMultithreaded: CapsFlags = 0x0000000000010000; +pub const CapsFlags_RendererMultithreaded: CapsFlags = 0x0000000000020000; /// Multiple windows are supported. -pub const CapsFlags_SwapChain: CapsFlags = 0x0000000000020000; +pub const CapsFlags_SwapChain: CapsFlags = 0x0000000000040000; /// Texture blit is supported. -pub const CapsFlags_TextureBlit: CapsFlags = 0x0000000000040000; +pub const CapsFlags_TextureBlit: CapsFlags = 0x0000000000080000; /// Texture compare less equal mode is supported. -pub const CapsFlags_TextureCompareLequal: CapsFlags = 0x0000000000080000; -pub const CapsFlags_TextureCompareReserved: CapsFlags = 0x0000000000100000; +pub const CapsFlags_TextureCompareLequal: CapsFlags = 0x0000000000100000; +pub const CapsFlags_TextureCompareReserved: CapsFlags = 0x0000000000200000; /// Cubemap texture array is supported. -pub const CapsFlags_TextureCubeArray: CapsFlags = 0x0000000000200000; +pub const CapsFlags_TextureCubeArray: CapsFlags = 0x0000000000400000; /// CPU direct access to GPU texture memory. -pub const CapsFlags_TextureDirectAccess: CapsFlags = 0x0000000000400000; +pub const CapsFlags_TextureDirectAccess: CapsFlags = 0x0000000000800000; /// Read-back texture is supported. -pub const CapsFlags_TextureReadBack: CapsFlags = 0x0000000000800000; +pub const CapsFlags_TextureReadBack: CapsFlags = 0x0000000001000000; /// 2D texture array is supported. -pub const CapsFlags_Texture2DArray: CapsFlags = 0x0000000001000000; +pub const CapsFlags_Texture2DArray: CapsFlags = 0x0000000002000000; /// 3D textures are supported. -pub const CapsFlags_Texture3D: CapsFlags = 0x0000000002000000; +pub const CapsFlags_Texture3D: CapsFlags = 0x0000000004000000; /// Transparent back buffer supported. -pub const CapsFlags_TransparentBackbuffer: CapsFlags = 0x0000000004000000; +pub const CapsFlags_TransparentBackbuffer: CapsFlags = 0x0000000008000000; /// Vertex attribute half-float is supported. -pub const CapsFlags_VertexAttribHalf: CapsFlags = 0x0000000008000000; +pub const CapsFlags_VertexAttribHalf: CapsFlags = 0x0000000010000000; /// Vertex attribute 10_10_10_2 is supported. -pub const CapsFlags_VertexAttribUint10: CapsFlags = 0x0000000010000000; +pub const CapsFlags_VertexAttribUint10: CapsFlags = 0x0000000020000000; /// Rendering with VertexID only is supported. -pub const CapsFlags_VertexId: CapsFlags = 0x0000000020000000; +pub const CapsFlags_VertexId: CapsFlags = 0x0000000040000000; /// Viewport layer is available in vertex shader. -pub const CapsFlags_ViewportLayerArray: CapsFlags = 0x0000000040000000; +pub const CapsFlags_ViewportLayerArray: CapsFlags = 0x0000000080000000; /// All texture compare modes are supported. -pub const CapsFlags_TextureCompareAll: CapsFlags = 0x0000000000180000; +pub const CapsFlags_TextureCompareAll: CapsFlags = 0x0000000000300000; pub const CapsFormatFlags = u32; /// Texture format is not supported. diff --git a/examples/28-wireframe/fs_wf_mesh_bc.sc b/examples/28-wireframe/fs_wf_mesh_bc.sc new file mode 100644 index 000000000..ec743cffe --- /dev/null +++ b/examples/28-wireframe/fs_wf_mesh_bc.sc @@ -0,0 +1,79 @@ +$input v_view, v_normal + +/* + * Copyright 2016 Dario Manesku. All rights reserved. + * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE + */ + +#include "../common/common.sh" +#include "uniforms.sh" + +vec3 evalSh(vec3 _dir) +{ +# define k01 0.2820947918 // sqrt( 1/PI)/2 +# define k02 0.4886025119 // sqrt( 3/PI)/2 +# define k03 1.0925484306 // sqrt(15/PI)/2 +# define k04 0.3153915652 // sqrt( 5/PI)/4 +# define k05 0.5462742153 // sqrt(15/PI)/4 + + vec3 shEnv[9]; + shEnv[0] = vec3( 0.967757057878229854, 0.976516067990363390, 0.891218272348969998); /* Band 0 */ + shEnv[1] = vec3(-0.384163503608655643, -0.423492289131209787, -0.425532726148547868); /* Band 1 */ + shEnv[2] = vec3( 0.055906294587354334, 0.056627436881069373, 0.069969936396987467); + shEnv[3] = vec3( 0.120985157386215209, 0.119297994074027414, 0.117111965829213599); + shEnv[4] = vec3(-0.176711633774331106, -0.170331404095516392, -0.151345020570876621); /* Band 2 */ + shEnv[5] = vec3(-0.124682114349692147, -0.119340785411183953, -0.096300354204368860); + shEnv[6] = vec3( 0.001852378550138503, -0.032592784164597745, -0.088204495001329680); + shEnv[7] = vec3( 0.296365482782109446, 0.281268696656263029, 0.243328223888495510); + shEnv[8] = vec3(-0.079826665303240341, -0.109340956251195970, -0.157208859664677764); + + vec3 nn = _dir.zxy; + + float sh[9]; + sh[0] = k01; + sh[1] = -k02*nn.y; + sh[2] = k02*nn.z; + sh[3] = -k02*nn.x; + sh[4] = k03*nn.y*nn.x; + sh[5] = -k03*nn.y*nn.z; + sh[6] = k04*(3.0*nn.z*nn.z-1.0); + sh[7] = -k03*nn.x*nn.z; + sh[8] = k05*(nn.x*nn.x-nn.y*nn.y); + + vec3 rgb = vec3_splat(0.0); + rgb += shEnv[0] * sh[0] * 1.0; + rgb += shEnv[1] * sh[1] * 2.0/2.5; + rgb += shEnv[2] * sh[2] * 2.0/2.5; + rgb += shEnv[3] * sh[3] * 2.0/2.5; + rgb += shEnv[4] * sh[4] * 1.0/2.5; + rgb += shEnv[5] * sh[5] * 0.5; + rgb += shEnv[6] * sh[6] * 0.5; + rgb += shEnv[7] * sh[7] * 0.5; + rgb += shEnv[8] * sh[8] * 0.5; + + return rgb; +} + +void main() +{ + vec3 nn = normalize(v_normal); + vec3 col = evalSh(nn); + + if (0.0 != u_drawEdges) + { + vec3 wfColor = u_wfColor; + float wfOpacity = u_wfOpacity; + float thickness = u_wfThickness; + + vec3 bc = gl_BaryCoord; + vec3 fw = abs(dFdx(bc)) + abs(dFdy(bc)); + vec3 val = smoothstep(vec3_splat(0.0), fw*thickness, bc); + float edge = min(min(val.x, val.y), val.z); // Gets to 0.0 when close to edges. + + vec3 edgeCol = mix(col, wfColor, wfOpacity); + col = mix(edgeCol, col, edge); + } + + gl_FragColor.xyz = col; + gl_FragColor.w = 1.0; +} diff --git a/examples/28-wireframe/fs_wf_wireframe_bc.sc b/examples/28-wireframe/fs_wf_wireframe_bc.sc new file mode 100644 index 000000000..0b9258392 --- /dev/null +++ b/examples/28-wireframe/fs_wf_wireframe_bc.sc @@ -0,0 +1,27 @@ +$input v_view + +/* + * Copyright 2016 Dario Manesku. All rights reserved. + * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE + */ + +#include "../common/common.sh" +#include "uniforms.sh" + +void main() +{ + vec3 color = u_wfColor; + float opacity = u_wfOpacity; + float thickness = u_wfThickness; + + if (gl_FrontFacing) { opacity *= 0.5; } + + vec3 bc = gl_BaryCoord; + vec3 fw = abs(dFdx(bc)) + abs(dFdy(bc)); + vec3 val = smoothstep(vec3_splat(0.0), fw*thickness, bc); + float edge = min(min(val.x, val.y), val.z); // Gets to 0.0 around the edges. + + vec4 rgba = vec4(color, (1.0-edge)*opacity); + gl_FragColor = rgba; +} + diff --git a/examples/28-wireframe/vs_wf_mesh_bc.sc b/examples/28-wireframe/vs_wf_mesh_bc.sc new file mode 100644 index 000000000..7189543e0 --- /dev/null +++ b/examples/28-wireframe/vs_wf_mesh_bc.sc @@ -0,0 +1,20 @@ +$input a_position, a_normal +$output v_view, v_normal + +/* + * Copyright 2016 Dario Manesku. All rights reserved. + * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE + */ + +#include "../common/common.sh" +#include "uniforms.sh" + +void main() +{ + gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) ); + + v_view = u_camPos - mul(u_model[0], vec4(a_position, 1.0) ).xyz; + + vec3 normal = a_normal.xyz*2.0 - 1.0; + v_normal = mul(u_model[0], vec4(normal, 0.0) ).xyz; +} diff --git a/examples/28-wireframe/vs_wf_wireframe_bc.sc b/examples/28-wireframe/vs_wf_wireframe_bc.sc new file mode 100644 index 000000000..1d10ced57 --- /dev/null +++ b/examples/28-wireframe/vs_wf_wireframe_bc.sc @@ -0,0 +1,18 @@ +$input a_position +$output v_view + +/* + * Copyright 2016 Dario Manesku. All rights reserved. + * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE + */ + +#include "../common/common.sh" +#include "uniforms.sh" + +void main() +{ + gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) ); + + v_view = u_camPos - mul(u_model[0], vec4(a_position, 1.0) ).xyz; +} + diff --git a/examples/28-wireframe/wireframe.cpp b/examples/28-wireframe/wireframe.cpp index 75001cda5..cc2c99d75 100644 --- a/examples/28-wireframe/wireframe.cpp +++ b/examples/28-wireframe/wireframe.cpp @@ -6,6 +6,7 @@ #include "common.h" #include "bgfx_utils.h" #include "imgui/imgui.h" +#include "entry/dialog.h" namespace { @@ -299,6 +300,8 @@ public: init.resolution.reset = m_reset; bgfx::init(init); + m_hasBaryCoord = bgfx::getCaps()->supported & BGFX_CAPS_FRAGMENT_BARYCENTRIC; + // Enable m_debug text. bgfx::setDebug(m_debug); @@ -310,6 +313,11 @@ public: , 0 ); + if (m_hasBaryCoord) + { + m_wfProgramBc = loadProgram("vs_wf_wireframe_bc", "fs_wf_wireframe_bc"); + m_meshProgramBc = loadProgram("vs_wf_mesh_bc", "fs_wf_mesh_bc"); + } m_wfProgram = loadProgram("vs_wf_wireframe", "fs_wf_wireframe"); m_meshProgram = loadProgram("vs_wf_mesh", "fs_wf_mesh"); @@ -339,6 +347,11 @@ public: m_meshes[1].destroy(); m_meshes[2].destroy(); + if (m_hasBaryCoord) + { + bgfx::destroy(m_wfProgramBc); + bgfx::destroy(m_meshProgramBc); + } bgfx::destroy(m_wfProgram); bgfx::destroy(m_meshProgram); @@ -395,6 +408,35 @@ public: ImGui::RadioButton("Wireframe", &m_drawMode, 1); ImGui::RadioButton("Shaded", &m_drawMode, 2); + static bool wfBaryCoordEnabled = false; + if (!m_hasBaryCoord) + { + ImGui::BeginDisabled(); + } + + ImGui::Separator(); + + ImGui::Checkbox("Shader barycentric coords", &wfBaryCoordEnabled); + + if (!m_hasBaryCoord) + { + ImGui::EndDisabled(); + + static const bx::StringView url = R"(https://vulkan.gpuinfo.org/listdevicescoverage.php?extensionname=VK_KHR_fragment_shader_barycentric&extensionfeature=fragmentShaderBarycentric&platform=all)"; + + ImGui::TextWrapped("Your GPU/backend doesn't support this feature yet."); + ImGui::TextWrapped("For a list of supported GPUs please click below:"); + + if (ImGui::SmallButton(ICON_FA_LINK) ) + { + openUrl(url); + } + else if (ImGui::IsItemHovered() ) + { + ImGui::SetTooltip("%.*s", url.getLength(), url.getPtr() ); + } + } + const bool wfEnabled = (DrawMode::Shaded != m_drawMode); if ( wfEnabled ) { @@ -475,7 +517,22 @@ public: | BGFX_STATE_MSAA | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) ; - meshSubmit(m_meshes[m_meshSelection].m_mesh, 0, m_wfProgram, m_meshes[m_meshSelection].m_mtx, state); + if (wfBaryCoordEnabled && m_hasBaryCoord) + { + meshSubmit(m_meshes[m_meshSelection].m_mesh, + 0, + m_wfProgramBc, + m_meshes[m_meshSelection].m_mtx, + state); + } + else + { + meshSubmit(m_meshes[m_meshSelection].m_mesh, + 0, + m_wfProgram, + m_meshes[m_meshSelection].m_mtx, + state); + } } else { @@ -487,7 +544,22 @@ public: | BGFX_STATE_CULL_CCW | BGFX_STATE_MSAA ; - meshSubmit(m_meshes[m_meshSelection].m_mesh, 0, m_meshProgram, m_meshes[m_meshSelection].m_mtx, state); + if (wfBaryCoordEnabled && m_hasBaryCoord) + { + meshSubmit(m_meshes[m_meshSelection].m_mesh, + 0, + m_meshProgramBc, + m_meshes[m_meshSelection].m_mtx, + state); + } + else + { + meshSubmit(m_meshes[m_meshSelection].m_mesh, + 0, + m_meshProgram, + m_meshes[m_meshSelection].m_mtx, + state); + } } // Advance to next frame. Rendering thread will be kicked to @@ -502,6 +574,8 @@ public: entry::MouseState m_mouseState; + bgfx::ProgramHandle m_wfProgramBc; + bgfx::ProgramHandle m_meshProgramBc; bgfx::ProgramHandle m_wfProgram; bgfx::ProgramHandle m_meshProgram; @@ -520,6 +594,7 @@ public: MeshMtx m_meshes[3]; int32_t m_meshSelection; int32_t m_drawMode; // Holds data for 'DrawMode'. + bool m_hasBaryCoord; }; } // namespace diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h index ce3830f25..b658984f5 100644 --- a/include/bgfx/defines.h +++ b/include/bgfx/defines.h @@ -15,7 +15,7 @@ #ifndef BGFX_DEFINES_H_HEADER_GUARD #define BGFX_DEFINES_H_HEADER_GUARD -#define BGFX_API_VERSION UINT32_C(128) +#define BGFX_API_VERSION UINT32_C(129) /** * Color RGB/alpha/depth write. When it's not specified write will be disabled. @@ -470,29 +470,30 @@ #define BGFX_CAPS_DRAW_INDIRECT_COUNT UINT64_C(0x0000000000000020) //!< Draw indirect with indirect count is supported. #define BGFX_CAPS_FRAGMENT_DEPTH UINT64_C(0x0000000000000040) //!< Fragment depth is available in fragment shader. #define BGFX_CAPS_FRAGMENT_ORDERING UINT64_C(0x0000000000000080) //!< Fragment ordering is available in fragment shader. -#define BGFX_CAPS_GRAPHICS_DEBUGGER UINT64_C(0x0000000000000100) //!< Graphics debugger is present. -#define BGFX_CAPS_HDR10 UINT64_C(0x0000000000000200) //!< HDR10 rendering is supported. -#define BGFX_CAPS_HIDPI UINT64_C(0x0000000000000400) //!< HiDPI rendering is supported. -#define BGFX_CAPS_IMAGE_RW UINT64_C(0x0000000000000800) //!< Image Read/Write is supported. -#define BGFX_CAPS_INDEX32 UINT64_C(0x0000000000001000) //!< 32-bit indices are supported. -#define BGFX_CAPS_INSTANCING UINT64_C(0x0000000000002000) //!< Instancing is supported. -#define BGFX_CAPS_OCCLUSION_QUERY UINT64_C(0x0000000000004000) //!< Occlusion query is supported. -#define BGFX_CAPS_PRIMITIVE_ID UINT64_C(0x0000000000008000) //!< PrimitiveID is available in fragment shader. -#define BGFX_CAPS_RENDERER_MULTITHREADED UINT64_C(0x0000000000010000) //!< Renderer is on separate thread. -#define BGFX_CAPS_SWAP_CHAIN UINT64_C(0x0000000000020000) //!< Multiple windows are supported. -#define BGFX_CAPS_TEXTURE_BLIT UINT64_C(0x0000000000040000) //!< Texture blit is supported. -#define BGFX_CAPS_TEXTURE_COMPARE_LEQUAL UINT64_C(0x0000000000080000) //!< Texture compare less equal mode is supported. -#define BGFX_CAPS_TEXTURE_COMPARE_RESERVED UINT64_C(0x0000000000100000) -#define BGFX_CAPS_TEXTURE_CUBE_ARRAY UINT64_C(0x0000000000200000) //!< Cubemap texture array is supported. -#define BGFX_CAPS_TEXTURE_DIRECT_ACCESS UINT64_C(0x0000000000400000) //!< CPU direct access to GPU texture memory. -#define BGFX_CAPS_TEXTURE_READ_BACK UINT64_C(0x0000000000800000) //!< Read-back texture is supported. -#define BGFX_CAPS_TEXTURE_2D_ARRAY UINT64_C(0x0000000001000000) //!< 2D texture array is supported. -#define BGFX_CAPS_TEXTURE_3D UINT64_C(0x0000000002000000) //!< 3D textures are supported. -#define BGFX_CAPS_TRANSPARENT_BACKBUFFER UINT64_C(0x0000000004000000) //!< Transparent back buffer supported. -#define BGFX_CAPS_VERTEX_ATTRIB_HALF UINT64_C(0x0000000008000000) //!< Vertex attribute half-float is supported. -#define BGFX_CAPS_VERTEX_ATTRIB_UINT10 UINT64_C(0x0000000010000000) //!< Vertex attribute 10_10_10_2 is supported. -#define BGFX_CAPS_VERTEX_ID UINT64_C(0x0000000020000000) //!< Rendering with VertexID only is supported. -#define BGFX_CAPS_VIEWPORT_LAYER_ARRAY UINT64_C(0x0000000040000000) //!< Viewport layer is available in vertex shader. +#define BGFX_CAPS_FRAGMENT_BARYCENTRIC UINT64_C(0x0000000000000100) //!< Fragment barycentric coordinates are available in fragment shader. +#define BGFX_CAPS_GRAPHICS_DEBUGGER UINT64_C(0x0000000000000200) //!< Graphics debugger is present. +#define BGFX_CAPS_HDR10 UINT64_C(0x0000000000000400) //!< HDR10 rendering is supported. +#define BGFX_CAPS_HIDPI UINT64_C(0x0000000000000800) //!< HiDPI rendering is supported. +#define BGFX_CAPS_IMAGE_RW UINT64_C(0x0000000000001000) //!< Image Read/Write is supported. +#define BGFX_CAPS_INDEX32 UINT64_C(0x0000000000002000) //!< 32-bit indices are supported. +#define BGFX_CAPS_INSTANCING UINT64_C(0x0000000000004000) //!< Instancing is supported. +#define BGFX_CAPS_OCCLUSION_QUERY UINT64_C(0x0000000000008000) //!< Occlusion query is supported. +#define BGFX_CAPS_PRIMITIVE_ID UINT64_C(0x0000000000010000) //!< PrimitiveID is available in fragment shader. +#define BGFX_CAPS_RENDERER_MULTITHREADED UINT64_C(0x0000000000020000) //!< Renderer is on separate thread. +#define BGFX_CAPS_SWAP_CHAIN UINT64_C(0x0000000000040000) //!< Multiple windows are supported. +#define BGFX_CAPS_TEXTURE_BLIT UINT64_C(0x0000000000080000) //!< Texture blit is supported. +#define BGFX_CAPS_TEXTURE_COMPARE_LEQUAL UINT64_C(0x0000000000100000) //!< Texture compare less equal mode is supported. +#define BGFX_CAPS_TEXTURE_COMPARE_RESERVED UINT64_C(0x0000000000200000) +#define BGFX_CAPS_TEXTURE_CUBE_ARRAY UINT64_C(0x0000000000400000) //!< Cubemap texture array is supported. +#define BGFX_CAPS_TEXTURE_DIRECT_ACCESS UINT64_C(0x0000000000800000) //!< CPU direct access to GPU texture memory. +#define BGFX_CAPS_TEXTURE_READ_BACK UINT64_C(0x0000000001000000) //!< Read-back texture is supported. +#define BGFX_CAPS_TEXTURE_2D_ARRAY UINT64_C(0x0000000002000000) //!< 2D texture array is supported. +#define BGFX_CAPS_TEXTURE_3D UINT64_C(0x0000000004000000) //!< 3D textures are supported. +#define BGFX_CAPS_TRANSPARENT_BACKBUFFER UINT64_C(0x0000000008000000) //!< Transparent back buffer supported. +#define BGFX_CAPS_VERTEX_ATTRIB_HALF UINT64_C(0x0000000010000000) //!< Vertex attribute half-float is supported. +#define BGFX_CAPS_VERTEX_ATTRIB_UINT10 UINT64_C(0x0000000020000000) //!< Vertex attribute 10_10_10_2 is supported. +#define BGFX_CAPS_VERTEX_ID UINT64_C(0x0000000040000000) //!< Rendering with VertexID only is supported. +#define BGFX_CAPS_VIEWPORT_LAYER_ARRAY UINT64_C(0x0000000080000000) //!< Viewport layer is available in vertex shader. /// All texture compare modes are supported. #define BGFX_CAPS_TEXTURE_COMPARE_ALL (0 \ | BGFX_CAPS_TEXTURE_COMPARE_RESERVED \ diff --git a/scripts/bgfx.idl b/scripts/bgfx.idl index a98da9d36..5b25d87cf 100644 --- a/scripts/bgfx.idl +++ b/scripts/bgfx.idl @@ -1,7 +1,7 @@ -- vim: syntax=lua -- bgfx interface -version(128) +version(129) typedef "bool" typedef "char" @@ -373,6 +373,7 @@ flag.Caps { bits = 64, base = 1, name = "Caps" } .DrawIndirectCount --- Draw indirect with indirect count is supported. .FragmentDepth --- Fragment depth is available in fragment shader. .FragmentOrdering --- Fragment ordering is available in fragment shader. + .FragmentBarycentric --- Fragment barycentric coordinates are available in fragment shader. .GraphicsDebugger --- Graphics debugger is present. .Hdr10 --- HDR10 rendering is supported. .Hidpi --- HiDPI rendering is supported. diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 00e90c17b..769ac68a9 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -1566,6 +1566,7 @@ namespace bgfx CAPS_FLAGS(BGFX_CAPS_VERTEX_ID), CAPS_FLAGS(BGFX_CAPS_PRIMITIVE_ID), CAPS_FLAGS(BGFX_CAPS_VIEWPORT_LAYER_ARRAY), + CAPS_FLAGS(BGFX_CAPS_FRAGMENT_BARYCENTRIC), #undef CAPS_FLAGS }; @@ -5794,6 +5795,7 @@ BX_STATIC_ASSERT( (0 | BGFX_CAPS_PRIMITIVE_ID | BGFX_CAPS_VIEWPORT_LAYER_ARRAY | BGFX_CAPS_DRAW_INDIRECT_COUNT + | BGFX_CAPS_FRAGMENT_BARYCENTRIC ) == (0 ^ BGFX_CAPS_ALPHA_TO_COVERAGE ^ BGFX_CAPS_BLEND_INDEPENDENT @@ -5822,6 +5824,7 @@ BX_STATIC_ASSERT( (0 ^ BGFX_CAPS_PRIMITIVE_ID ^ BGFX_CAPS_VIEWPORT_LAYER_ARRAY ^ BGFX_CAPS_DRAW_INDIRECT_COUNT + ^ BGFX_CAPS_FRAGMENT_BARYCENTRIC ) ); #undef FLAGS_MASK_TEST diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index d3d33369b..ec82c46b0 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -982,6 +982,7 @@ namespace bgfx { namespace d3d12 } DX_CHECK(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &m_options, sizeof(m_options) ) ); + //DX_CHECK(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS3, &m_options3, sizeof(m_options3) ) ); BX_TRACE("D3D12 options:"); BX_TRACE("\tTiledResourcesTier %d", m_options.TiledResourcesTier); BX_TRACE("\tResourceBindingTier %d", m_options.ResourceBindingTier); @@ -989,6 +990,7 @@ namespace bgfx { namespace d3d12 BX_TRACE("\tConservativeRasterizationTier %d", m_options.ConservativeRasterizationTier); BX_TRACE("\tCrossNodeSharingTier %d", m_options.CrossNodeSharingTier); BX_TRACE("\tResourceHeapTier %d", m_options.ResourceHeapTier); + //BX_TRACE("\tBarycentricsSupported %d", m_options3.BarycentricsSupported); for (D3D12_FEATURE_DATA_D3D12_OPTIONS1 options1; SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS1, &options1, sizeof(options1)));) { @@ -1373,6 +1375,7 @@ namespace bgfx { namespace d3d12 | BGFX_CAPS_VIEWPORT_LAYER_ARRAY | BGFX_CAPS_DRAW_INDIRECT_COUNT | BGFX_CAPS_PRIMITIVE_ID + //| (m_options3.BarycentricsSupported ? BGFX_CAPS_FRAGMENT_BARYCENTRIC : 0) ); g_caps.limits.maxTextureSize = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; g_caps.limits.maxTextureLayers = D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; @@ -3580,6 +3583,7 @@ namespace bgfx { namespace d3d12 D3D_DRIVER_TYPE m_driverType; D3D12_FEATURE_DATA_ARCHITECTURE m_architecture; D3D12_FEATURE_DATA_D3D12_OPTIONS m_options; + //D3D12_FEATURE_DATA_D3D12_OPTIONS3 m_options3; Dxgi::SwapChainI* m_swapChain; ID3D12Resource* m_msaaRt; diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index d480188a3..f36d93f3c 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -623,6 +623,7 @@ namespace bgfx { namespace gl EXT_draw_instanced, EXT_instanced_arrays, EXT_frag_depth, + EXT_fragment_shader_barycentric, EXT_framebuffer_blit, EXT_framebuffer_object, EXT_framebuffer_sRGB, @@ -676,6 +677,7 @@ namespace bgfx { namespace gl NV_copy_image, NV_draw_buffers, NV_draw_instanced, + NV_fragment_shader_barycentric, NV_instanced_arrays, NV_occlusion_query, NV_texture_border_clamp, @@ -841,6 +843,7 @@ namespace bgfx { namespace gl { "EXT_draw_instanced", false, true }, // GLES2 extension. { "EXT_instanced_arrays", false, true }, // GLES2 extension. { "EXT_frag_depth", false, true }, // GLES2 extension. + { "EXT_fragment_shader_barycentric", BGFX_CONFIG_RENDERER_OPENGL >= 46, true }, { "EXT_framebuffer_blit", BGFX_CONFIG_RENDERER_OPENGL >= 30, true }, { "EXT_framebuffer_object", BGFX_CONFIG_RENDERER_OPENGL >= 30, true }, { "EXT_framebuffer_sRGB", BGFX_CONFIG_RENDERER_OPENGL >= 30, true }, @@ -894,6 +897,7 @@ namespace bgfx { namespace gl { "NV_copy_image", false, true }, { "NV_draw_buffers", false, true }, // GLES2 extension. { "NV_draw_instanced", false, true }, // GLES2 extension. + { "NV_fragment_shader_barycentric", BGFX_CONFIG_RENDERER_OPENGL >= 46, true }, { "NV_instanced_arrays", false, true }, // GLES2 extension. { "NV_occlusion_query", false, true }, { "NV_texture_border_clamp", false, true }, // GLES2 extension. @@ -1083,6 +1087,13 @@ namespace bgfx { namespace gl NULL }; + static const char* s_EXT_fragment_shader_barycentric[] = + { + "gl_BaryCoord", + "gl_BaryCoordNoPersp", + NULL + }; + static void GL_APIENTRY stubVertexAttribDivisor(GLuint /*_index*/, GLuint /*_divisor*/) { } @@ -2833,6 +2844,12 @@ namespace bgfx { namespace gl ? BGFX_CAPS_FRAGMENT_ORDERING : 0 ; + g_caps.supported |= false + || s_extension[Extension::EXT_fragment_shader_barycentric].m_supported + || s_extension[Extension::NV_fragment_shader_barycentric].m_supported + ? BGFX_CAPS_FRAGMENT_BARYCENTRIC + : 0 + ; g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL || m_gles3) || s_extension[Extension::OES_element_index_uint].m_supported ? BGFX_CAPS_INDEX32 @@ -6881,6 +6898,47 @@ namespace bgfx { namespace gl code = temp; } + else if (GL_FRAGMENT_SHADER == m_type) + { + if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL >= 46)) + { + int32_t codeLen = (int32_t)bx::strLen(code); + int32_t tempLen = codeLen + (4<<10); + char* temp = (char*)alloca(tempLen); + bx::StaticMemoryBlockWriter writer(temp, tempLen); + + bx::write(&writer + , "#version 460\n" + , &err + ); + + if (!bx::findIdentifierMatch(code, s_EXT_fragment_shader_barycentric).isEmpty()) + { + if (s_extension[Extension::NV_fragment_shader_barycentric].m_supported) + { + bx::write(&writer, + "#extension GL_NV_fragment_shader_barycentric : require\n" + "#define gl_BaryCoord gl_BaryCoordNV\n" + "#define gl_BaryCoordNoPersp gl_BaryCoordNoPerspNV\n", &err + ); + } + else if (s_extension[Extension::EXT_fragment_shader_barycentric].m_supported) + { + bx::write(&writer, + "#extension GL_EXT_fragment_shader_barycentric : require\n" + "#define gl_BaryCoord gl_BaryCoordEXT\n" + "#define gl_BaryCoordNoPersp gl_BaryCoordNoPerspEXT\n", &err + ); + } + } + + int32_t verLen = bx::strLen("#version 460\n"); + bx::write(&writer, code.getPtr()+verLen, codeLen-verLen, &err); + bx::write(&writer, '\0', &err); + + code = temp; + } + } { const GLchar* str = (const GLchar*)code.getPtr(); diff --git a/src/renderer_mtl.h b/src/renderer_mtl.h index 51aca7c28..e15320988 100644 --- a/src/renderer_mtl.h +++ b/src/renderer_mtl.h @@ -408,6 +408,11 @@ namespace bgfx { namespace mtl return m_obj.depth24Stencil8PixelFormatSupported; #endif // BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS } + + bool supportsShaderBarycentricCoordinates() + { + return [m_obj supportsShaderBarycentricCoordinates]; + } MTL_CLASS_END MTL_CLASS(Function) diff --git a/src/renderer_mtl.mm b/src/renderer_mtl.mm index 3971ff87e..ea7b1587b 100644 --- a/src/renderer_mtl.mm +++ b/src/renderer_mtl.mm @@ -712,6 +712,7 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa ? BGFX_CAPS_PRIMITIVE_ID : 0 ; + g_caps.supported |= m_device.supportsShaderBarycentricCoordinates() ? BGFX_CAPS_FRAGMENT_BARYCENTRIC : 0; // Reference(s): // - Metal feature set tables diff --git a/src/renderer_noop.cpp b/src/renderer_noop.cpp index f92649696..e0f249103 100644 --- a/src/renderer_noop.cpp +++ b/src/renderer_noop.cpp @@ -43,6 +43,7 @@ namespace bgfx { namespace noop | BGFX_CAPS_VERTEX_ATTRIB_UINT10 | BGFX_CAPS_VERTEX_ID | BGFX_CAPS_VIEWPORT_LAYER_ARRAY + | BGFX_CAPS_FRAGMENT_BARYCENTRIC ; // Pretend all features are available for all texture formats. diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index 82d7f14e7..da5d43ca5 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -375,6 +375,7 @@ VK_IMPORT_DEVICE # elif BX_PLATFORM_NX NN_vi_surface, # endif + KHR_fragment_shader_barycentric, Count }; @@ -413,6 +414,7 @@ VK_IMPORT_DEVICE # elif BX_PLATFORM_NX { VK_NN_VI_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count }, # endif + { "VK_KHR_fragment_shader_barycentric", 1, false, false, true, Layer::Count }, }; BX_STATIC_ASSERT(Extension::Count == BX_COUNTOF(s_extension) ); @@ -1175,9 +1177,11 @@ VK_IMPORT_DEVICE const void* nextFeatures = NULL; VkPhysicalDeviceLineRasterizationFeaturesEXT lineRasterizationFeatures; VkPhysicalDeviceCustomBorderColorFeaturesEXT customBorderColorFeatures; + VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR fragmentShaderBarycentricFeatures; bx::memSet(&lineRasterizationFeatures, 0, sizeof(lineRasterizationFeatures) ); bx::memSet(&customBorderColorFeatures, 0, sizeof(customBorderColorFeatures) ); + bx::memSet(&fragmentShaderBarycentricFeatures, 0, sizeof(fragmentShaderBarycentricFeatures) ); m_fbh.idx = kInvalidHandle; bx::memSet(m_uniforms, 0, sizeof(m_uniforms) ); @@ -1243,6 +1247,7 @@ VK_IMPORT s_extension[Extension::EXT_shader_viewport_index_layer].m_initialize = !!(_init.capabilities & BGFX_CAPS_VIEWPORT_LAYER_ARRAY); s_extension[Extension::EXT_conservative_rasterization ].m_initialize = !!(_init.capabilities & BGFX_CAPS_CONSERVATIVE_RASTER ); s_extension[Extension::KHR_draw_indirect_count ].m_initialize = !!(_init.capabilities & BGFX_CAPS_DRAW_INDIRECT_COUNT ); + s_extension[Extension::KHR_fragment_shader_barycentric].m_initialize = !!(_init.capabilities & BGFX_CAPS_FRAGMENT_BARYCENTRIC); dumpExtensions(VK_NULL_HANDLE, s_extension); @@ -1576,6 +1581,14 @@ VK_IMPORT_INSTANCE customBorderColorFeatures.pNext = NULL; } + if (s_extension[Extension::KHR_fragment_shader_barycentric].m_supported) + { + next->pNext = (VkBaseOutStructure*)&fragmentShaderBarycentricFeatures; + next = (VkBaseOutStructure*)&fragmentShaderBarycentricFeatures; + fragmentShaderBarycentricFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR; + fragmentShaderBarycentricFeatures.pNext = NULL; + } + nextFeatures = deviceFeatures2.pNext; vkGetPhysicalDeviceFeatures2KHR(m_physicalDevice, &deviceFeatures2); @@ -1652,6 +1665,7 @@ VK_IMPORT_INSTANCE | (s_extension[Extension::EXT_conservative_rasterization ].m_supported ? BGFX_CAPS_CONSERVATIVE_RASTER : 0) | (s_extension[Extension::EXT_shader_viewport_index_layer].m_supported ? BGFX_CAPS_VIEWPORT_LAYER_ARRAY : 0) | (s_extension[Extension::KHR_draw_indirect_count ].m_supported && indirectDrawSupport ? BGFX_CAPS_DRAW_INDIRECT_COUNT : 0) + | (s_extension[Extension::KHR_fragment_shader_barycentric].m_supported ? BGFX_CAPS_FRAGMENT_BARYCENTRIC : 0) ; const uint32_t maxAttachments = bx::min(m_deviceProperties.limits.maxFragmentOutputAttachments, m_deviceProperties.limits.maxColorAttachments); diff --git a/tools/shaderc/shaderc.cpp b/tools/shaderc/shaderc.cpp index 34480f00d..e3ab17a55 100644 --- a/tools/shaderc/shaderc.cpp +++ b/tools/shaderc/shaderc.cpp @@ -173,6 +173,13 @@ namespace bgfx // "shadow1DProjLod", }; + static const char* s_EXT_fragment_shader_barycentric[] = + { + "gl_BaryCoord", + "gl_BaryCoordNoPersp", + NULL + }; + static const char* s_EXT_shader_texture_lod[] = { "texture2DLod", @@ -1754,6 +1761,8 @@ namespace bgfx } else { + bool hasBaryCoord = !bx::findIdentifierMatch(input, s_EXT_fragment_shader_barycentric).isEmpty(); + if (profile->lang == ShadingLang::GLSL || profile->lang == ShadingLang::ESSL) { @@ -1766,6 +1775,10 @@ namespace bgfx "#define shadow2DProj(_sampler, _coord) bgfxShadow2DProj(_sampler, _coord).x\n" ); } + else + { + hasBaryCoord = false; + } // gl_FragColor and gl_FragData are deprecated for essl > 300 if (profile->lang == ShadingLang::ESSL @@ -1793,6 +1806,14 @@ namespace bgfx } } + if (!hasBaryCoord) + { + preprocessor.writef( + "#define gl_BaryCoord vec3_splat(0.0)\n" + "#define gl_BaryCoordNoPersp vec3_splat(0.0)\n" + ); + } + for (InOut::const_iterator it = shaderInputs.begin(), itEnd = shaderInputs.end(); it != itEnd; ++it) { VaryingMap::const_iterator varyingIt = varyingMap.find(*it); @@ -1844,6 +1865,8 @@ namespace bgfx if (profile->lang == ShadingLang::PSSL) { preprocessor.writef(getPsslPreamble() ); + + hasBaryCoord = false; } preprocessor.writef( @@ -1925,6 +1948,22 @@ namespace bgfx } } + if (profile->lang == ShadingLang::HLSL) + { + if (profile->id < 610) + { + hasBaryCoord = false; + } + } + + if (!hasBaryCoord) + { + preprocessor.writef( + "#define gl_BaryCoord vec3_splat(0.0)\n" + "#define gl_BaryCoordNoPersp vec3_splat(0.0)\n" + ); + } + preprocessor.writef("#define void_main()"); preprocessor.writef(" \\\n\tvoid main("); @@ -2011,6 +2050,18 @@ namespace bgfx } } + if (hasBaryCoord) + { + preprocessor.writef( + " \\\n\t%sfloat3 gl_BaryCoord : SV_Barycentrics" + , arg++ > 0 ? ", " : " " + ); + preprocessor.writef( + " \\\n\t%snoperspective float3 gl_BaryCoordNoPersp : SV_Barycentrics1" + , arg++ > 0 ? ", " : " " + ); + } + preprocessor.writef( " \\\n\t)\n" ); @@ -2251,6 +2302,14 @@ namespace bgfx } } + if ('f' == _options.shaderType) + { + if (hasBaryCoord && profile->lang == ShadingLang::GLSL) + { + glsl_profile = 450; + } + } + if (glsl_profile < 400) { const bool usesTextureLod = false