From 2e51cb6aa9175da003f2ec99092f32133d11db5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Thu, 10 Sep 2026 22:22:53 -0700 Subject: [PATCH] Added depth control, sample mask, and read-only depth/stencil attachments. (#3971) --- .../SPIRV/NonSemanticShaderDebugInfo100.h | 171 ++++++++++++++ bindings/bf/bgfx.bf | 120 +++++++++- bindings/c3/bgfx.c3 | 76 ++++++- bindings/cs/bgfx.cs | 120 +++++++++- bindings/d/package.d | 101 ++++++++- bindings/py/bgfx.py | 41 +++- bindings/py/bgfx.pyi | 60 ++++- bindings/zig/bgfx.zig | 124 ++++++++-- docs/bgfx.rst | 8 +- examples/08-update/update.cpp | 2 +- examples/21-deferred/deferred.cpp | 2 +- examples/25-c99/helloworld.c | 2 +- .../gpudrivenrendering.cpp | 2 +- examples/52-layered/layered.cpp | 8 +- examples/common/entry/entry.cpp | 1 - include/bgfx/bgfx.h | 114 +++++++++- include/bgfx/c99/bgfx.h | 116 +++++++++- include/bgfx/defines.h | 12 +- scripts/bgfx.idl | 92 +++++++- scripts/bindings-d.lua | 2 +- src/bgfx.cpp | 75 +++++-- src/bgfx.idl.inl | 59 ++++- src/bgfx_p.h | 200 +++++++++++++++-- src/config.h | 4 + src/glimports.h | 9 + src/renderer.h | 4 + src/renderer_d3d11.cpp | 105 +++++---- src/renderer_d3d12.cpp | 99 +++++--- src/renderer_gl.cpp | 153 +++++++++++-- src/renderer_gl.h | 4 + src/renderer_mtl.cpp | 126 +++++++---- src/renderer_mtl.h | 19 +- src/renderer_vk.cpp | 212 +++++++++++++----- src/renderer_webgpu.cpp | 76 ++++--- src/renderer_webgpu.h | 5 + tools/shaderc/shaderc_metal.cpp | 27 +++ 36 files changed, 1996 insertions(+), 355 deletions(-) create mode 100644 3rdparty/glslang/SPIRV/NonSemanticShaderDebugInfo100.h diff --git a/3rdparty/glslang/SPIRV/NonSemanticShaderDebugInfo100.h b/3rdparty/glslang/SPIRV/NonSemanticShaderDebugInfo100.h new file mode 100644 index 000000000..f74abcb64 --- /dev/null +++ b/3rdparty/glslang/SPIRV/NonSemanticShaderDebugInfo100.h @@ -0,0 +1,171 @@ +// Copyright (c) 2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are 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 Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +#ifndef SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_ +#define SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NonSemanticShaderDebugInfo100Version = 100, + NonSemanticShaderDebugInfo100Version_BitWidthPadding = 0x7fffffff +}; +enum { + NonSemanticShaderDebugInfo100Revision = 6, + NonSemanticShaderDebugInfo100Revision_BitWidthPadding = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100Instructions { + NonSemanticShaderDebugInfo100DebugInfoNone = 0, + NonSemanticShaderDebugInfo100DebugCompilationUnit = 1, + NonSemanticShaderDebugInfo100DebugTypeBasic = 2, + NonSemanticShaderDebugInfo100DebugTypePointer = 3, + NonSemanticShaderDebugInfo100DebugTypeQualifier = 4, + NonSemanticShaderDebugInfo100DebugTypeArray = 5, + NonSemanticShaderDebugInfo100DebugTypeVector = 6, + NonSemanticShaderDebugInfo100DebugTypedef = 7, + NonSemanticShaderDebugInfo100DebugTypeFunction = 8, + NonSemanticShaderDebugInfo100DebugTypeEnum = 9, + NonSemanticShaderDebugInfo100DebugTypeComposite = 10, + NonSemanticShaderDebugInfo100DebugTypeMember = 11, + NonSemanticShaderDebugInfo100DebugTypeInheritance = 12, + NonSemanticShaderDebugInfo100DebugTypePtrToMember = 13, + NonSemanticShaderDebugInfo100DebugTypeTemplate = 14, + NonSemanticShaderDebugInfo100DebugTypeTemplateParameter = 15, + NonSemanticShaderDebugInfo100DebugTypeTemplateTemplateParameter = 16, + NonSemanticShaderDebugInfo100DebugTypeTemplateParameterPack = 17, + NonSemanticShaderDebugInfo100DebugGlobalVariable = 18, + NonSemanticShaderDebugInfo100DebugFunctionDeclaration = 19, + NonSemanticShaderDebugInfo100DebugFunction = 20, + NonSemanticShaderDebugInfo100DebugLexicalBlock = 21, + NonSemanticShaderDebugInfo100DebugLexicalBlockDiscriminator = 22, + NonSemanticShaderDebugInfo100DebugScope = 23, + NonSemanticShaderDebugInfo100DebugNoScope = 24, + NonSemanticShaderDebugInfo100DebugInlinedAt = 25, + NonSemanticShaderDebugInfo100DebugLocalVariable = 26, + NonSemanticShaderDebugInfo100DebugInlinedVariable = 27, + NonSemanticShaderDebugInfo100DebugDeclare = 28, + NonSemanticShaderDebugInfo100DebugValue = 29, + NonSemanticShaderDebugInfo100DebugOperation = 30, + NonSemanticShaderDebugInfo100DebugExpression = 31, + NonSemanticShaderDebugInfo100DebugMacroDef = 32, + NonSemanticShaderDebugInfo100DebugMacroUndef = 33, + NonSemanticShaderDebugInfo100DebugImportedEntity = 34, + NonSemanticShaderDebugInfo100DebugSource = 35, + NonSemanticShaderDebugInfo100DebugFunctionDefinition = 101, + NonSemanticShaderDebugInfo100DebugSourceContinued = 102, + NonSemanticShaderDebugInfo100DebugLine = 103, + NonSemanticShaderDebugInfo100DebugNoLine = 104, + NonSemanticShaderDebugInfo100DebugBuildIdentifier = 105, + NonSemanticShaderDebugInfo100DebugStoragePath = 106, + NonSemanticShaderDebugInfo100DebugEntryPoint = 107, + NonSemanticShaderDebugInfo100DebugTypeMatrix = 108, + NonSemanticShaderDebugInfo100InstructionsMax = 0x7fffffff +}; + + +enum NonSemanticShaderDebugInfo100DebugInfoFlags { + NonSemanticShaderDebugInfo100None = 0x0000, + NonSemanticShaderDebugInfo100FlagIsProtected = 0x01, + NonSemanticShaderDebugInfo100FlagIsPrivate = 0x02, + NonSemanticShaderDebugInfo100FlagIsPublic = 0x03, + NonSemanticShaderDebugInfo100FlagIsLocal = 0x04, + NonSemanticShaderDebugInfo100FlagIsDefinition = 0x08, + NonSemanticShaderDebugInfo100FlagFwdDecl = 0x10, + NonSemanticShaderDebugInfo100FlagArtificial = 0x20, + NonSemanticShaderDebugInfo100FlagExplicit = 0x40, + NonSemanticShaderDebugInfo100FlagPrototyped = 0x80, + NonSemanticShaderDebugInfo100FlagObjectPointer = 0x100, + NonSemanticShaderDebugInfo100FlagStaticMember = 0x200, + NonSemanticShaderDebugInfo100FlagIndirectVariable = 0x400, + NonSemanticShaderDebugInfo100FlagLValueReference = 0x800, + NonSemanticShaderDebugInfo100FlagRValueReference = 0x1000, + NonSemanticShaderDebugInfo100FlagIsOptimized = 0x2000, + NonSemanticShaderDebugInfo100FlagIsEnumClass = 0x4000, + NonSemanticShaderDebugInfo100FlagTypePassByValue = 0x8000, + NonSemanticShaderDebugInfo100FlagTypePassByReference = 0x10000, + NonSemanticShaderDebugInfo100FlagUnknownPhysicalLayout = 0x20000, + NonSemanticShaderDebugInfo100DebugInfoFlagsMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100BuildIdentifierFlags { + NonSemanticShaderDebugInfo100IdentifierPossibleDuplicates = 0x01, + NonSemanticShaderDebugInfo100BuildIdentifierFlagsMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugBaseTypeAttributeEncoding { + NonSemanticShaderDebugInfo100Unspecified = 0, + NonSemanticShaderDebugInfo100Address = 1, + NonSemanticShaderDebugInfo100Boolean = 2, + NonSemanticShaderDebugInfo100Float = 3, + NonSemanticShaderDebugInfo100Signed = 4, + NonSemanticShaderDebugInfo100SignedChar = 5, + NonSemanticShaderDebugInfo100Unsigned = 6, + NonSemanticShaderDebugInfo100UnsignedChar = 7, + NonSemanticShaderDebugInfo100DebugBaseTypeAttributeEncodingMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugCompositeType { + NonSemanticShaderDebugInfo100Class = 0, + NonSemanticShaderDebugInfo100Structure = 1, + NonSemanticShaderDebugInfo100Union = 2, + NonSemanticShaderDebugInfo100DebugCompositeTypeMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugTypeQualifier { + NonSemanticShaderDebugInfo100ConstType = 0, + NonSemanticShaderDebugInfo100VolatileType = 1, + NonSemanticShaderDebugInfo100RestrictType = 2, + NonSemanticShaderDebugInfo100AtomicType = 3, + NonSemanticShaderDebugInfo100DebugTypeQualifierMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugOperation { + NonSemanticShaderDebugInfo100Deref = 0, + NonSemanticShaderDebugInfo100Plus = 1, + NonSemanticShaderDebugInfo100Minus = 2, + NonSemanticShaderDebugInfo100PlusUconst = 3, + NonSemanticShaderDebugInfo100BitPiece = 4, + NonSemanticShaderDebugInfo100Swap = 5, + NonSemanticShaderDebugInfo100Xderef = 6, + NonSemanticShaderDebugInfo100StackValue = 7, + NonSemanticShaderDebugInfo100Constu = 8, + NonSemanticShaderDebugInfo100Fragment = 9, + NonSemanticShaderDebugInfo100DebugOperationMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugImportedEntity { + NonSemanticShaderDebugInfo100ImportedModule = 0, + NonSemanticShaderDebugInfo100ImportedDeclaration = 1, + NonSemanticShaderDebugInfo100DebugImportedEntityMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_ diff --git a/bindings/bf/bgfx.bf b/bindings/bf/bgfx.bf index 06ab157c7..4d4e8edd9 100644 --- a/bindings/bf/bgfx.bf +++ b/bindings/bf/bgfx.bf @@ -939,11 +939,6 @@ public static class bgfx /// Hidpi = 0x00020000, - /// - /// Enable depth clamp. - /// - DepthClamp = 0x00040000, - /// /// Suspend rendering. /// @@ -1324,10 +1319,10 @@ public static class bgfx } [AllowDuplicates] - public enum ResolveFlags : uint32 + public enum AttachmentFlags : uint32 { /// - /// No resolve flags. + /// No attachment flags. /// None = 0x00000000, @@ -1335,6 +1330,17 @@ public static class bgfx /// Auto-generate mip maps on resolve. /// AutoGenMips = 0x00000001, + + /// + /// Bind the depth aspect read-only (read-only depth-stencil view) so the + /// attachment can be sampled as a texture in the same pass. + /// + ReadOnlyDepth = 0x00000002, + + /// + /// Bind the stencil aspect read-only. + /// + ReadOnlyStencil = 0x00000004, } [AllowDuplicates] @@ -2810,7 +2816,7 @@ public static class bgfx public uint16 mip; public uint16 layer; public uint16 numLayers; - public uint8 resolve; + public uint8 flags; } [CRepr] @@ -3028,10 +3034,10 @@ public static class bgfx /// Cubemap side or depth layer/slice to use. /// Number of texture layer/slice(s) in array to use. /// Mip level. - /// Resolve flags. See: `BGFX_RESOLVE_*` + /// Attachment flags. See: `BGFX_ATTACHMENT_*` /// [LinkName("bgfx_attachment_init")] - public static extern void attachment_init(Attachment* _this, TextureHandle _handle, Access _access, uint16 _layer, uint16 _numLayers, uint16 _mip, uint8 _resolve); + public static extern void attachment_init(Attachment* _this, TextureHandle _handle, Access _access, uint16 _layer, uint16 _numLayers, uint16 _mip, uint8 _flags); /// /// Start VertexLayout. @@ -4317,9 +4323,11 @@ public static class bgfx /// Position y from the top corner of the window. Can be negative to place view origin outside of the window. /// Width of view port region. /// Height of view port region. + /// Viewport minimum depth (maps clip-space z=0). + /// Viewport maximum depth (maps clip-space z=1). /// [LinkName("bgfx_set_view_rect")] - public static extern void set_view_rect(ViewId _id, int16 _x, int16 _y, uint16 _width, uint16 _height); + public static extern void set_view_rect(ViewId _id, int16 _x, int16 _y, uint16 _width, uint16 _height, float _minDepth, float _maxDepth); /// /// Set view rectangle. Draw primitive outside view will be clipped. @@ -4347,6 +4355,30 @@ public static class bgfx [LinkName("bgfx_set_view_scissor")] public static extern void set_view_scissor(ViewId _id, uint16 _x, uint16 _y, uint16 _width, uint16 _height); + /// + /// Set view depth bias. Applies to all draws in the view unless overridden per-draw + /// with `bgfx::setDepthControl`. + /// + /// + /// View id. + /// Constant depth bias. + /// Slope-scaled depth bias. + /// Depth bias clamp. + /// + [LinkName("bgfx_set_view_depth_bias")] + public static extern void set_view_depth_bias(ViewId _id, int32 _constant, float _slopeScale, float _clamp); + + /// + /// Set view multisample coverage mask. Combined with the per-draw mask set by + /// `bgfx::setSampleMask`, so a draw can narrow the view's mask but not widen it. + /// + /// + /// View id. + /// Sample coverage mask. + /// + [LinkName("bgfx_set_view_sample_mask")] + public static extern void set_view_sample_mask(ViewId _id, uint32 _mask); + /// /// Set view clear flags. /// @@ -4563,6 +4595,17 @@ public static class bgfx [LinkName("bgfx_encoder_set_stencil")] public static extern void encoder_set_stencil(Encoder* _this, uint32 _fstencil, uint32 _bstencil); + /// + /// Set multisample coverage mask for draw primitive. Samples whose bit is clear + /// in the mask are never written, regardless of the coverage the rasterizer + /// computes. Only has an effect when rendering to a multisampled target. + /// + /// + /// Sample coverage mask. + /// + [LinkName("bgfx_encoder_set_sample_mask")] + public static extern void encoder_set_sample_mask(Encoder* _this, uint32 _mask); + /// /// Set scissor for draw primitive. /// @@ -4592,6 +4635,28 @@ public static class bgfx [LinkName("bgfx_encoder_set_scissor_cached")] public static extern void encoder_set_scissor_cached(Encoder* _this, uint16 _cache); + /// + /// Set depth control (depth bias and depth clip) for draw primitive. Overrides the + /// view depth bias for this draw. + /// + /// + /// Constant depth bias. + /// Slope-scaled depth bias. + /// Depth bias clamp. + /// Disable depth clipping and clamp NDC depth to the [0,1] range instead. + /// + [LinkName("bgfx_encoder_set_depth_control")] + public static extern uint16 encoder_set_depth_control(Encoder* _this, int32 _constant, float _slopeScale, float _clamp, bool _depthClamp); + + /// + /// Set depth control from depth-control cache for draw primitive. + /// + /// + /// Index in depth control cache. + /// + [LinkName("bgfx_encoder_set_depth_control_cached")] + public static extern void encoder_set_depth_control_cached(Encoder* _this, uint16 _cache); + /// /// Set model matrix for draw primitive. If it is not called, /// the model will be rendered with an identity model matrix. @@ -5287,6 +5352,17 @@ public static class bgfx [LinkName("bgfx_set_stencil")] public static extern void set_stencil(uint32 _fstencil, uint32 _bstencil); + /// + /// Set multisample coverage mask for draw primitive. Samples whose bit is clear + /// in the mask are never written, regardless of the coverage the rasterizer + /// computes. Only has an effect when rendering to a multisampled target. + /// + /// + /// Sample coverage mask. + /// + [LinkName("bgfx_set_sample_mask")] + public static extern void set_sample_mask(uint32 _mask); + /// /// Set scissor for draw primitive. /// @@ -5316,6 +5392,28 @@ public static class bgfx [LinkName("bgfx_set_scissor_cached")] public static extern void set_scissor_cached(uint16 _cache); + /// + /// Set depth control (depth bias and depth clip) for draw primitive. Overrides the + /// view depth bias for this draw. + /// + /// + /// Constant depth bias. + /// Slope-scaled depth bias. + /// Depth bias clamp. + /// Disable depth clipping and clamp NDC depth to the [0,1] range instead. + /// + [LinkName("bgfx_set_depth_control")] + public static extern uint16 set_depth_control(int32 _constant, float _slopeScale, float _clamp, bool _depthClamp); + + /// + /// Set depth control from depth-control cache for draw primitive. + /// + /// + /// Index in depth control cache. + /// + [LinkName("bgfx_set_depth_control_cached")] + public static extern void set_depth_control_cached(uint16 _cache); + /// /// Set model matrix for draw primitive. If it is not called, /// the model will be rendered with an identity model matrix. diff --git a/bindings/c3/bgfx.c3 b/bindings/c3/bgfx.c3 index 74eed2e31..002561d1f 100644 --- a/bindings/c3/bgfx.c3 +++ b/bindings/c3/bgfx.c3 @@ -597,9 +597,6 @@ constdef ResetFlags : inline uint // Enable HiDPI rendering. HIDPI = 0x00020000, - // Enable depth clamp. - DEPTHCLAMP = 0x00040000, - // Suspend rendering. SUSPEND = 0x00080000, @@ -839,13 +836,20 @@ constdef VideoDecodeFrameFlags : inline uint LOOP = 0x00000008, } -constdef ResolveFlags : inline uint +constdef AttachmentFlags : inline uint { - // No resolve flags. + // No attachment flags. NONE = 0x00000000, // Auto-generate mip maps on resolve. AUTOGENMIPS = 0x00000001, + + // Bind the depth aspect read-only (read-only depth-stencil view) so the + // attachment can be sampled as a texture in the same pass. + READONLYDEPTH = 0x00000002, + + // Bind the stencil aspect read-only. + READONLYSTENCIL = 0x00000004, } constdef PciIdFlags : inline ushort @@ -2128,8 +2132,8 @@ struct Attachment ushort layer; // Number of texture layer/slice(s) in array to use. ushort numLayers; - // Resolve flags. See: `BGFX_RESOLVE_*` - char resolve; + // Attachment flags. See: `BGFX_ATTACHMENT_*` + char flags; } // Transform data. @@ -2365,8 +2369,8 @@ extern fn void buffer_region_init_buffer(BufferRegion* _this, BufferHandle _hand // _layer : `Cubemap side or depth layer/slice to use.` // _numLayers : `Number of texture layer/slice(s) in array to use.` // _mip : `Mip level.` -// _resolve : `Resolve flags. See: `BGFX_RESOLVE_*`` -extern fn void attachment_init(Attachment* _this, TextureHandle _handle, Access _access, ushort _layer, ushort _numLayers, ushort _mip, char _resolve) @cname("bgfx_attachment_init"); +// _flags : `Attachment flags. See: `BGFX_ATTACHMENT_*`` +extern fn void attachment_init(Attachment* _this, TextureHandle _handle, Access _access, ushort _layer, ushort _numLayers, ushort _mip, char _flags) @cname("bgfx_attachment_init"); // Start VertexLayout. // _rendererType : `Renderer backend type. See: `bgfx::RendererType`` @@ -3160,7 +3164,9 @@ extern fn void set_view_name(ushort _id, ZString _name, int _len) @cname("bgfx_s // _y : `Position y from the top corner of the window. Can be negative to place view origin outside of the window.` // _width : `Width of view port region.` // _height : `Height of view port region.` -extern fn void set_view_rect(ushort _id, short _x, short _y, ushort _width, ushort _height) @cname("bgfx_set_view_rect"); +// _minDepth : `Viewport minimum depth (maps clip-space z=0).` +// _maxDepth : `Viewport maximum depth (maps clip-space z=1).` +extern fn void set_view_rect(ushort _id, short _x, short _y, ushort _width, ushort _height, float _minDepth, float _maxDepth) @cname("bgfx_set_view_rect"); // Set view rectangle. Draw primitive outside view will be clipped. // _id : `View id.` @@ -3178,6 +3184,20 @@ extern fn void set_view_rect_ratio(ushort _id, short _x, short _y, BackbufferRat // _height : `Height of view scissor region.` extern fn void set_view_scissor(ushort _id, ushort _x, ushort _y, ushort _width, ushort _height) @cname("bgfx_set_view_scissor"); +// Set view depth bias. Applies to all draws in the view unless overridden per-draw +// with `bgfx::setDepthControl`. +// _id : `View id.` +// _constant : `Constant depth bias.` +// _slopeScale : `Slope-scaled depth bias.` +// _clamp : `Depth bias clamp.` +extern fn void set_view_depth_bias(ushort _id, int _constant, float _slopeScale, float _clamp) @cname("bgfx_set_view_depth_bias"); + +// Set view multisample coverage mask. Combined with the per-draw mask set by +// `bgfx::setSampleMask`, so a draw can narrow the view's mask but not widen it. +// _id : `View id.` +// _mask : `Sample coverage mask.` +extern fn void set_view_sample_mask(ushort _id, uint _mask) @cname("bgfx_set_view_sample_mask"); + // Set view clear flags. // _id : `View id.` // _flags : `Clear flags. Use `BGFX_CLEAR_NONE` to remove any clear operation. See: `BGFX_CLEAR_*`.` @@ -3324,6 +3344,12 @@ extern fn void encoder_set_condition(Encoder* _this, OcclusionQueryHandle _handl // _bstencil : `Back stencil state. If back is set to `BGFX_STENCIL_NONE` _fstencil is applied to both front and back facing primitives.` extern fn void encoder_set_stencil(Encoder* _this, uint _fstencil, uint _bstencil) @cname("bgfx_encoder_set_stencil"); +// Set multisample coverage mask for draw primitive. Samples whose bit is clear +// in the mask are never written, regardless of the coverage the rasterizer +// computes. Only has an effect when rendering to a multisampled target. +// _mask : `Sample coverage mask.` +extern fn void encoder_set_sample_mask(Encoder* _this, uint _mask) @cname("bgfx_encoder_set_sample_mask"); + // Set scissor for draw primitive. // // @remark @@ -3343,6 +3369,18 @@ extern fn ushort encoder_set_scissor(Encoder* _this, ushort _x, ushort _y, ushor // _cache : `Index in scissor cache.` extern fn void encoder_set_scissor_cached(Encoder* _this, ushort _cache) @cname("bgfx_encoder_set_scissor_cached"); +// Set depth control (depth bias and depth clip) for draw primitive. Overrides the +// view depth bias for this draw. +// _constant : `Constant depth bias.` +// _slopeScale : `Slope-scaled depth bias.` +// _clamp : `Depth bias clamp.` +// _depthClamp : `Disable depth clipping and clamp NDC depth to the [0,1] range instead.` +extern fn ushort encoder_set_depth_control(Encoder* _this, int _constant, float _slopeScale, float _clamp, bool _depthClamp) @cname("bgfx_encoder_set_depth_control"); + +// Set depth control from depth-control cache for draw primitive. +// _cache : `Index in depth control cache.` +extern fn void encoder_set_depth_control_cached(Encoder* _this, ushort _cache) @cname("bgfx_encoder_set_depth_control_cached"); + // Set model matrix for draw primitive. If it is not called, // the model will be rendered with an identity model matrix. // _mtx : `Pointer to first matrix in array.` @@ -3799,6 +3837,12 @@ extern fn void set_condition(OcclusionQueryHandle _handle, bool _visible) @cname // _bstencil : `Back stencil state. If back is set to `BGFX_STENCIL_NONE` _fstencil is applied to both front and back facing primitives.` extern fn void set_stencil(uint _fstencil, uint _bstencil) @cname("bgfx_set_stencil"); +// Set multisample coverage mask for draw primitive. Samples whose bit is clear +// in the mask are never written, regardless of the coverage the rasterizer +// computes. Only has an effect when rendering to a multisampled target. +// _mask : `Sample coverage mask.` +extern fn void set_sample_mask(uint _mask) @cname("bgfx_set_sample_mask"); + // Set scissor for draw primitive. // // @remark @@ -3818,6 +3862,18 @@ extern fn ushort set_scissor(ushort _x, ushort _y, ushort _width, ushort _height // _cache : `Index in scissor cache.` extern fn void set_scissor_cached(ushort _cache) @cname("bgfx_set_scissor_cached"); +// Set depth control (depth bias and depth clip) for draw primitive. Overrides the +// view depth bias for this draw. +// _constant : `Constant depth bias.` +// _slopeScale : `Slope-scaled depth bias.` +// _clamp : `Depth bias clamp.` +// _depthClamp : `Disable depth clipping and clamp NDC depth to the [0,1] range instead.` +extern fn ushort set_depth_control(int _constant, float _slopeScale, float _clamp, bool _depthClamp) @cname("bgfx_set_depth_control"); + +// Set depth control from depth-control cache for draw primitive. +// _cache : `Index in depth control cache.` +extern fn void set_depth_control_cached(ushort _cache) @cname("bgfx_set_depth_control_cached"); + // Set model matrix for draw primitive. If it is not called, // the model will be rendered with an identity model matrix. // _mtx : `Pointer to first matrix in array.` diff --git a/bindings/cs/bgfx.cs b/bindings/cs/bgfx.cs index 0542035bf..7f344cec4 100644 --- a/bindings/cs/bgfx.cs +++ b/bindings/cs/bgfx.cs @@ -938,11 +938,6 @@ public static partial class bgfx /// Hidpi = 0x00020000, - /// - /// Enable depth clamp. - /// - DepthClamp = 0x00040000, - /// /// Suspend rendering. /// @@ -1323,10 +1318,10 @@ public static partial class bgfx } [Flags] - public enum ResolveFlags : uint + public enum AttachmentFlags : uint { /// - /// No resolve flags. + /// No attachment flags. /// None = 0x00000000, @@ -1334,6 +1329,17 @@ public static partial class bgfx /// Auto-generate mip maps on resolve. /// AutoGenMips = 0x00000001, + + /// + /// Bind the depth aspect read-only (read-only depth-stencil view) so the + /// attachment can be sampled as a texture in the same pass. + /// + ReadOnlyDepth = 0x00000002, + + /// + /// Bind the stencil aspect read-only. + /// + ReadOnlyStencil = 0x00000004, } [Flags] @@ -2771,7 +2777,7 @@ public static partial class bgfx public ushort mip; public ushort layer; public ushort numLayers; - public byte resolve; + public byte flags; } public unsafe struct Transform @@ -2970,10 +2976,10 @@ public static partial class bgfx /// Cubemap side or depth layer/slice to use. /// Number of texture layer/slice(s) in array to use. /// Mip level. - /// Resolve flags. See: `BGFX_RESOLVE_*` + /// Attachment flags. See: `BGFX_ATTACHMENT_*` /// [DllImport(DllName, EntryPoint="bgfx_attachment_init", CallingConvention = CallingConvention.Cdecl)] - public static extern unsafe void attachment_init(Attachment* _this, TextureHandle _handle, Access _access, ushort _layer, ushort _numLayers, ushort _mip, byte _resolve); + public static extern unsafe void attachment_init(Attachment* _this, TextureHandle _handle, Access _access, ushort _layer, ushort _numLayers, ushort _mip, byte _flags); /// /// Start VertexLayout. @@ -4264,9 +4270,11 @@ public static partial class bgfx /// Position y from the top corner of the window. Can be negative to place view origin outside of the window. /// Width of view port region. /// Height of view port region. + /// Viewport minimum depth (maps clip-space z=0). + /// Viewport maximum depth (maps clip-space z=1). /// [DllImport(DllName, EntryPoint="bgfx_set_view_rect", CallingConvention = CallingConvention.Cdecl)] - public static extern unsafe void set_view_rect(ushort _id, short _x, short _y, ushort _width, ushort _height); + public static extern unsafe void set_view_rect(ushort _id, short _x, short _y, ushort _width, ushort _height, float _minDepth, float _maxDepth); /// /// Set view rectangle. Draw primitive outside view will be clipped. @@ -4294,6 +4302,30 @@ public static partial class bgfx [DllImport(DllName, EntryPoint="bgfx_set_view_scissor", CallingConvention = CallingConvention.Cdecl)] public static extern unsafe void set_view_scissor(ushort _id, ushort _x, ushort _y, ushort _width, ushort _height); + /// + /// Set view depth bias. Applies to all draws in the view unless overridden per-draw + /// with `bgfx::setDepthControl`. + /// + /// + /// View id. + /// Constant depth bias. + /// Slope-scaled depth bias. + /// Depth bias clamp. + /// + [DllImport(DllName, EntryPoint="bgfx_set_view_depth_bias", CallingConvention = CallingConvention.Cdecl)] + public static extern unsafe void set_view_depth_bias(ushort _id, int _constant, float _slopeScale, float _clamp); + + /// + /// Set view multisample coverage mask. Combined with the per-draw mask set by + /// `bgfx::setSampleMask`, so a draw can narrow the view's mask but not widen it. + /// + /// + /// View id. + /// Sample coverage mask. + /// + [DllImport(DllName, EntryPoint="bgfx_set_view_sample_mask", CallingConvention = CallingConvention.Cdecl)] + public static extern unsafe void set_view_sample_mask(ushort _id, uint _mask); + /// /// Set view clear flags. /// @@ -4510,6 +4542,17 @@ public static partial class bgfx [DllImport(DllName, EntryPoint="bgfx_encoder_set_stencil", CallingConvention = CallingConvention.Cdecl)] public static extern unsafe void encoder_set_stencil(Encoder* _this, uint _fstencil, uint _bstencil); + /// + /// Set multisample coverage mask for draw primitive. Samples whose bit is clear + /// in the mask are never written, regardless of the coverage the rasterizer + /// computes. Only has an effect when rendering to a multisampled target. + /// + /// + /// Sample coverage mask. + /// + [DllImport(DllName, EntryPoint="bgfx_encoder_set_sample_mask", CallingConvention = CallingConvention.Cdecl)] + public static extern unsafe void encoder_set_sample_mask(Encoder* _this, uint _mask); + /// /// Set scissor for draw primitive. /// @@ -4539,6 +4582,28 @@ public static partial class bgfx [DllImport(DllName, EntryPoint="bgfx_encoder_set_scissor_cached", CallingConvention = CallingConvention.Cdecl)] public static extern unsafe void encoder_set_scissor_cached(Encoder* _this, ushort _cache); + /// + /// Set depth control (depth bias and depth clip) for draw primitive. Overrides the + /// view depth bias for this draw. + /// + /// + /// Constant depth bias. + /// Slope-scaled depth bias. + /// Depth bias clamp. + /// Disable depth clipping and clamp NDC depth to the [0,1] range instead. + /// + [DllImport(DllName, EntryPoint="bgfx_encoder_set_depth_control", CallingConvention = CallingConvention.Cdecl)] + public static extern unsafe ushort encoder_set_depth_control(Encoder* _this, int _constant, float _slopeScale, float _clamp, bool _depthClamp); + + /// + /// Set depth control from depth-control cache for draw primitive. + /// + /// + /// Index in depth control cache. + /// + [DllImport(DllName, EntryPoint="bgfx_encoder_set_depth_control_cached", CallingConvention = CallingConvention.Cdecl)] + public static extern unsafe void encoder_set_depth_control_cached(Encoder* _this, ushort _cache); + /// /// Set model matrix for draw primitive. If it is not called, /// the model will be rendered with an identity model matrix. @@ -5234,6 +5299,17 @@ public static partial class bgfx [DllImport(DllName, EntryPoint="bgfx_set_stencil", CallingConvention = CallingConvention.Cdecl)] public static extern unsafe void set_stencil(uint _fstencil, uint _bstencil); + /// + /// Set multisample coverage mask for draw primitive. Samples whose bit is clear + /// in the mask are never written, regardless of the coverage the rasterizer + /// computes. Only has an effect when rendering to a multisampled target. + /// + /// + /// Sample coverage mask. + /// + [DllImport(DllName, EntryPoint="bgfx_set_sample_mask", CallingConvention = CallingConvention.Cdecl)] + public static extern unsafe void set_sample_mask(uint _mask); + /// /// Set scissor for draw primitive. /// @@ -5263,6 +5339,28 @@ public static partial class bgfx [DllImport(DllName, EntryPoint="bgfx_set_scissor_cached", CallingConvention = CallingConvention.Cdecl)] public static extern unsafe void set_scissor_cached(ushort _cache); + /// + /// Set depth control (depth bias and depth clip) for draw primitive. Overrides the + /// view depth bias for this draw. + /// + /// + /// Constant depth bias. + /// Slope-scaled depth bias. + /// Depth bias clamp. + /// Disable depth clipping and clamp NDC depth to the [0,1] range instead. + /// + [DllImport(DllName, EntryPoint="bgfx_set_depth_control", CallingConvention = CallingConvention.Cdecl)] + public static extern unsafe ushort set_depth_control(int _constant, float _slopeScale, float _clamp, bool _depthClamp); + + /// + /// Set depth control from depth-control cache for draw primitive. + /// + /// + /// Index in depth control cache. + /// + [DllImport(DllName, EntryPoint="bgfx_set_depth_control_cached", CallingConvention = CallingConvention.Cdecl)] + public static extern unsafe void set_depth_control_cached(ushort _cache); + /// /// Set model matrix for draw primitive. If it is not called, /// the model will be rendered with an identity model matrix. diff --git a/bindings/d/package.d b/bindings/d/package.d index 59e1b8bc4..1c538f182 100644 --- a/bindings/d/package.d +++ b/bindings/d/package.d @@ -9,7 +9,7 @@ import bindbc.common.types: c_int64, c_uint64, va_list; import bindbc.bgfx.config; static import bgfx.impl; -enum uint apiVersion = 159; +enum uint apiVersion = 160; alias ViewID = ushort; @@ -455,7 +455,6 @@ enum Reset: Reset_{ srgbBackbuffer = 0x0000_8000, ///Enable sRGB backbuffer. hdr10 = 0x0001_0000, ///Enable HDR10 rendering. hiDPI = 0x0002_0000, ///Enable HiDPI rendering. - depthClamp = 0x0004_0000, ///Enable depth clamp. suspend = 0x0008_0000, ///Suspend rendering. transparentBackbuffer = 0x0010_0000, ///Transparent backbuffer. Availability depends on: `BGFX_CAPS_TRANSPARENT_BACKBUFFER`. } @@ -601,10 +600,16 @@ enum VideoDecodeFrame: VideoDecodeFrame_{ loop = 0x08, } -alias Resolve_ = ubyte; -enum Resolve: Resolve_{ - none = 0x00, ///No resolve flags. - autoGenMIPs = 0x01, ///Auto-generate mip maps on resolve. +alias Attachment_ = ubyte; +enum Attachment: Attachment_{ + none = 0x00, ///No attachment flags. + autoGenMIPs = 0x01, ///Auto-generate mip maps on resolve. + /** + Bind the depth aspect read-only (read-only depth-stencil view) so the + attachment can be sampled as a texture in the same pass. + */ + readOnlyDepth = 0x02, + readOnlyStencil = 0x04, ///Bind the stencil aspect read-only. } alias PCIID_ = ushort; @@ -1644,7 +1649,7 @@ extern(C++, "bgfx") struct Attachment{ ushort mip; ///Mip level. ushort layer; ///Cubemap side or depth layer/slice to use. ushort numLayers; ///Number of texture layer/slice(s) in array to use. - ubyte resolve; ///Resolve flags. See: `BGFX_RESOLVE_*` + ubyte flags; ///Attachment flags. See: `BGFX_ATTACHMENT_*` extern(D) mixin(joinFnBinds((){ FnBind[] ret = [ /** @@ -1655,9 +1660,9 @@ extern(C++, "bgfx") struct Attachment{ layer = Cubemap side or depth layer/slice to use. numLayers = Number of texture layer/slice(s) in array to use. mip = Mip level. - resolve = Resolve flags. See: `BGFX_RESOLVE_*` + flags = Attachment flags. See: `BGFX_ATTACHMENT_*` */ - {q{void}, q{init}, q{TextureHandle handle, bgfx.impl.Access.Enum access=Access.write, ushort layer=0, ushort numLayers=1, ushort mip=0, ubyte resolve=Resolve.autoGenMIPs}, ext: `C++`}, + {q{void}, q{init}, q{TextureHandle handle, bgfx.impl.Access.Enum access=Access.write, ushort layer=0, ushort numLayers=1, ushort mip=0, ubyte flags=Attachment.autoGenMIPs}, ext: `C++`}, ]; return ret; }())); @@ -1875,6 +1880,15 @@ extern(C++, "bgfx") struct Encoder{ */ {q{void}, q{setStencil}, q{uint fStencil, uint bStencil=Stencil.none}, ext: `C++`}, + /** + Set multisample coverage mask for draw primitive. Samples whose bit is clear + in the mask are never written, regardless of the coverage the rasterizer + computes. Only has an effect when rendering to a multisampled target. + Params: + mask = Sample coverage mask. + */ + {q{void}, q{setSampleMask}, q{uint mask=uint.max}, ext: `C++`}, + /** Set scissor for draw primitive. @@ -1900,6 +1914,24 @@ extern(C++, "bgfx") struct Encoder{ */ {q{void}, q{setScissor}, q{ushort cache=ushort.max}, ext: `C++`}, + /** + Set depth control (depth bias and depth clip) for draw primitive. Overrides the + view depth bias for this draw. + Params: + constant = Constant depth bias. + slopeScale = Slope-scaled depth bias. + clamp = Depth bias clamp. + depthClamp = Disable depth clipping and clamp NDC depth to the [0,1] range instead. + */ + {q{ushort}, q{setDepthControl}, q{int constant, float slopeScale, float clamp=0.0f, bool depthClamp=false}, ext: `C++`}, + + /** + Set depth control from depth-control cache for draw primitive. + Params: + cache = Index in depth control cache. + */ + {q{void}, q{setDepthControl}, q{ushort cache=ushort.max}, ext: `C++`}, + /** Set model matrix for draw primitive. If it is not called, the model will be rendered with an identity model matrix. @@ -3596,8 +3628,10 @@ mixin(joinFnBinds((){ negative to place view origin outside of the window. width = Width of view port region. height = Height of view port region. + minDepth = Viewport minimum depth (maps clip-space z=0). + maxDepth = Viewport maximum depth (maps clip-space z=1). */ - {q{void}, q{setViewRect}, q{ViewID id, short x, short y, ushort width, ushort height}, ext: `C++, "bgfx"`}, + {q{void}, q{setViewRect}, q{ViewID id, short x, short y, ushort width, ushort height, float minDepth=0.0f, float maxDepth=1.0f}, ext: `C++, "bgfx"`}, /** * Set view rectangle. Draw primitive outside view will be clipped. @@ -3624,6 +3658,26 @@ mixin(joinFnBinds((){ */ {q{void}, q{setViewScissor}, q{ViewID id, ushort x=0, ushort y=0, ushort width=0, ushort height=0}, ext: `C++, "bgfx"`}, + /** + * Set view depth bias. Applies to all draws in the view unless overridden per-draw + * with `bgfx::setDepthControl`. + Params: + id = View id. + constant = Constant depth bias. + slopeScale = Slope-scaled depth bias. + clamp = Depth bias clamp. + */ + {q{void}, q{setViewDepthBias}, q{ViewID id, int constant=0, float slopeScale=0.0f, float clamp=0.0f}, ext: `C++, "bgfx"`}, + + /** + * Set view multisample coverage mask. Combined with the per-draw mask set by + * `bgfx::setSampleMask`, so a draw can narrow the view's mask but not widen it. + Params: + id = View id. + mask = Sample coverage mask. + */ + {q{void}, q{setViewSampleMask}, q{ViewID id, uint mask=uint.max}, ext: `C++, "bgfx"`}, + /** * Set view clear flags. Params: @@ -3925,6 +3979,15 @@ mixin(joinFnBinds((){ */ {q{void}, q{setStencil}, q{uint fStencil, uint bStencil=Stencil.none}, ext: `C++, "bgfx"`}, + /** + * Set multisample coverage mask for draw primitive. Samples whose bit is clear + * in the mask are never written, regardless of the coverage the rasterizer + * computes. Only has an effect when rendering to a multisampled target. + Params: + mask = Sample coverage mask. + */ + {q{void}, q{setSampleMask}, q{uint mask=uint.max}, ext: `C++, "bgfx"`}, + /** * Set scissor for draw primitive. * @@ -3950,6 +4013,24 @@ mixin(joinFnBinds((){ */ {q{void}, q{setScissor}, q{ushort cache=ushort.max}, ext: `C++, "bgfx"`}, + /** + * Set depth control (depth bias and depth clip) for draw primitive. Overrides the + * view depth bias for this draw. + Params: + constant = Constant depth bias. + slopeScale = Slope-scaled depth bias. + clamp = Depth bias clamp. + depthClamp = Disable depth clipping and clamp NDC depth to the [0,1] range instead. + */ + {q{ushort}, q{setDepthControl}, q{int constant, float slopeScale, float clamp=0.0f, bool depthClamp=false}, ext: `C++, "bgfx"`}, + + /** + * Set depth control from depth-control cache for draw primitive. + Params: + cache = Index in depth control cache. + */ + {q{void}, q{setDepthControl}, q{ushort cache=ushort.max}, ext: `C++, "bgfx"`}, + /** * Set model matrix for draw primitive. If it is not called, * the model will be rendered with an identity model matrix. diff --git a/bindings/py/bgfx.py b/bindings/py/bgfx.py index acfee736b..6c1864fbe 100644 --- a/bindings/py/bgfx.py +++ b/bindings/py/bgfx.py @@ -492,7 +492,6 @@ class ResetFlags(enum.IntFlag): SrgbBackbuffer = 0x8000 Hdr10 = 0x10000 Hidpi = 0x20000 - DepthClamp = 0x40000 Suspend = 0x80000 TransparentBackbuffer = 0x100000 FullscreenShift = 0x0 @@ -621,9 +620,11 @@ class VideoDecodeFrameFlags(enum.IntFlag): Final = 0x4 Loop = 0x8 -class ResolveFlags(enum.IntFlag): +class AttachmentFlags(enum.IntFlag): None_ = 0x0 AutoGenMips = 0x1 + ReadOnlyDepth = 0x2 + ReadOnlyStencil = 0x4 class PciIdFlags(enum.IntFlag): None_ = 0x0 @@ -1019,7 +1020,7 @@ Attachment._fields_ = [ ("mip", ctypes.c_uint16), ("layer", ctypes.c_uint16), ("numLayers", ctypes.c_uint16), - ("resolve", ctypes.c_uint8), + ("flags", ctypes.c_uint8), ] Transform._fields_ = [ @@ -1513,7 +1514,7 @@ def _bind(lib): bgfx_set_view_name.restype = None global bgfx_set_view_rect bgfx_set_view_rect = lib.bgfx_set_view_rect - bgfx_set_view_rect.argtypes = [ctypes.c_uint16, ctypes.c_int16, ctypes.c_int16, ctypes.c_uint16, ctypes.c_uint16] + bgfx_set_view_rect.argtypes = [ctypes.c_uint16, ctypes.c_int16, ctypes.c_int16, ctypes.c_uint16, ctypes.c_uint16, ctypes.c_float, ctypes.c_float] bgfx_set_view_rect.restype = None global bgfx_set_view_rect_ratio bgfx_set_view_rect_ratio = lib.bgfx_set_view_rect_ratio @@ -1523,6 +1524,14 @@ def _bind(lib): bgfx_set_view_scissor = lib.bgfx_set_view_scissor bgfx_set_view_scissor.argtypes = [ctypes.c_uint16, ctypes.c_uint16, ctypes.c_uint16, ctypes.c_uint16, ctypes.c_uint16] bgfx_set_view_scissor.restype = None + global bgfx_set_view_depth_bias + bgfx_set_view_depth_bias = lib.bgfx_set_view_depth_bias + bgfx_set_view_depth_bias.argtypes = [ctypes.c_uint16, ctypes.c_int32, ctypes.c_float, ctypes.c_float] + bgfx_set_view_depth_bias.restype = None + global bgfx_set_view_sample_mask + bgfx_set_view_sample_mask = lib.bgfx_set_view_sample_mask + bgfx_set_view_sample_mask.argtypes = [ctypes.c_uint16, ctypes.c_uint32] + bgfx_set_view_sample_mask.restype = None global bgfx_set_view_clear bgfx_set_view_clear = lib.bgfx_set_view_clear bgfx_set_view_clear.argtypes = [ctypes.c_uint16, ctypes.c_uint16, ctypes.c_uint32, ctypes.c_float, ctypes.c_uint8] @@ -1579,6 +1588,10 @@ def _bind(lib): bgfx_encoder_set_stencil = lib.bgfx_encoder_set_stencil bgfx_encoder_set_stencil.argtypes = [ctypes.POINTER(Encoder), ctypes.c_uint32, ctypes.c_uint32] bgfx_encoder_set_stencil.restype = None + global bgfx_encoder_set_sample_mask + bgfx_encoder_set_sample_mask = lib.bgfx_encoder_set_sample_mask + bgfx_encoder_set_sample_mask.argtypes = [ctypes.POINTER(Encoder), ctypes.c_uint32] + bgfx_encoder_set_sample_mask.restype = None global bgfx_encoder_set_scissor bgfx_encoder_set_scissor = lib.bgfx_encoder_set_scissor bgfx_encoder_set_scissor.argtypes = [ctypes.POINTER(Encoder), ctypes.c_uint16, ctypes.c_uint16, ctypes.c_uint16, ctypes.c_uint16] @@ -1587,6 +1600,14 @@ def _bind(lib): bgfx_encoder_set_scissor_cached = lib.bgfx_encoder_set_scissor_cached bgfx_encoder_set_scissor_cached.argtypes = [ctypes.POINTER(Encoder), ctypes.c_uint16] bgfx_encoder_set_scissor_cached.restype = None + global bgfx_encoder_set_depth_control + bgfx_encoder_set_depth_control = lib.bgfx_encoder_set_depth_control + bgfx_encoder_set_depth_control.argtypes = [ctypes.POINTER(Encoder), ctypes.c_int32, ctypes.c_float, ctypes.c_float, ctypes.c_bool] + bgfx_encoder_set_depth_control.restype = ctypes.c_uint16 + global bgfx_encoder_set_depth_control_cached + bgfx_encoder_set_depth_control_cached = lib.bgfx_encoder_set_depth_control_cached + bgfx_encoder_set_depth_control_cached.argtypes = [ctypes.POINTER(Encoder), ctypes.c_uint16] + bgfx_encoder_set_depth_control_cached.restype = None global bgfx_encoder_set_transform bgfx_encoder_set_transform = lib.bgfx_encoder_set_transform bgfx_encoder_set_transform.argtypes = [ctypes.POINTER(Encoder), ctypes.c_void_p, ctypes.c_uint16] @@ -1779,6 +1800,10 @@ def _bind(lib): bgfx_set_stencil = lib.bgfx_set_stencil bgfx_set_stencil.argtypes = [ctypes.c_uint32, ctypes.c_uint32] bgfx_set_stencil.restype = None + global bgfx_set_sample_mask + bgfx_set_sample_mask = lib.bgfx_set_sample_mask + bgfx_set_sample_mask.argtypes = [ctypes.c_uint32] + bgfx_set_sample_mask.restype = None global bgfx_set_scissor bgfx_set_scissor = lib.bgfx_set_scissor bgfx_set_scissor.argtypes = [ctypes.c_uint16, ctypes.c_uint16, ctypes.c_uint16, ctypes.c_uint16] @@ -1787,6 +1812,14 @@ def _bind(lib): bgfx_set_scissor_cached = lib.bgfx_set_scissor_cached bgfx_set_scissor_cached.argtypes = [ctypes.c_uint16] bgfx_set_scissor_cached.restype = None + global bgfx_set_depth_control + bgfx_set_depth_control = lib.bgfx_set_depth_control + bgfx_set_depth_control.argtypes = [ctypes.c_int32, ctypes.c_float, ctypes.c_float, ctypes.c_bool] + bgfx_set_depth_control.restype = ctypes.c_uint16 + global bgfx_set_depth_control_cached + bgfx_set_depth_control_cached = lib.bgfx_set_depth_control_cached + bgfx_set_depth_control_cached.argtypes = [ctypes.c_uint16] + bgfx_set_depth_control_cached.restype = None global bgfx_set_transform bgfx_set_transform = lib.bgfx_set_transform bgfx_set_transform.argtypes = [ctypes.c_void_p, ctypes.c_uint16] diff --git a/bindings/py/bgfx.pyi b/bindings/py/bgfx.pyi index 67c34cc93..7a8a5e5e1 100644 --- a/bindings/py/bgfx.pyi +++ b/bindings/py/bgfx.pyi @@ -903,8 +903,6 @@ class ResetFlags(enum.IntFlag): Hdr10 = 0x10000 # Enable HiDPI rendering. Hidpi = 0x20000 - # Enable depth clamp. - DepthClamp = 0x40000 # Suspend rendering. Suspend = 0x80000 # Transparent backbuffer. Availability depends on: `BGFX_CAPS_TRANSPARENT_BACKBUFFER`. @@ -1140,11 +1138,16 @@ class VideoDecodeFrameFlags(enum.IntFlag): # the last displayable picture. Loop = 0x8 -class ResolveFlags(enum.IntFlag): - # No resolve flags. +class AttachmentFlags(enum.IntFlag): + # No attachment flags. None_ = 0x0 # Auto-generate mip maps on resolve. AutoGenMips = 0x1 + # Bind the depth aspect read-only (read-only depth-stencil view) so the + # attachment can be sampled as a texture in the same pass. + ReadOnlyDepth = 0x2 + # Bind the stencil aspect read-only. + ReadOnlyStencil = 0x4 class PciIdFlags(enum.IntFlag): # Autoselect adapter. @@ -1654,8 +1657,8 @@ class Attachment(ctypes.Structure): layer: int # Number of texture layer/slice(s) in array to use. numLayers: int - # Resolve flags. See: `BGFX_RESOLVE_*` - resolve: int + # Attachment flags. See: `BGFX_ATTACHMENT_*` + flags: int # Transform data. class Transform(ctypes.Structure): @@ -1913,7 +1916,7 @@ def bgfx_attachment_init( _layer: int, _numLayers: int, _mip: int, - _resolve: int, + _flags: int, /, ) -> None: ... @@ -2550,7 +2553,16 @@ def bgfx_set_palette_color_rgba8(_index: int, _rgba: int, /) -> None: ... def bgfx_set_view_name(_id: int, _name: Optional[bytes], _len: int, /) -> None: ... # Set view rectangle. Draw primitive outside view will be clipped. -def bgfx_set_view_rect(_id: int, _x: int, _y: int, _width: int, _height: int, /) -> None: ... +def bgfx_set_view_rect( + _id: int, + _x: int, + _y: int, + _width: int, + _height: int, + _minDepth: float, + _maxDepth: float, + /, +) -> None: ... # Set view rectangle. Draw primitive outside view will be clipped. def bgfx_set_view_rect_ratio(_id: int, _x: int, _y: int, _ratio: Union[BackbufferRatio, int], /) -> None: ... @@ -2559,6 +2571,14 @@ def bgfx_set_view_rect_ratio(_id: int, _x: int, _y: int, _ratio: Union[Backbuffe # _x, _y, _width and _height are set to 0, scissor will be disabled. def bgfx_set_view_scissor(_id: int, _x: int, _y: int, _width: int, _height: int, /) -> None: ... +# Set view depth bias. Applies to all draws in the view unless overridden per-draw +# with `bgfx::setDepthControl`. +def bgfx_set_view_depth_bias(_id: int, _constant: int, _slopeScale: float, _clamp: float, /) -> None: ... + +# Set view multisample coverage mask. Combined with the per-draw mask set by +# `bgfx::setSampleMask`, so a draw can narrow the view's mask but not widen it. +def bgfx_set_view_sample_mask(_id: int, _mask: int, /) -> None: ... + # Set view clear flags. def bgfx_set_view_clear(_id: int, _flags: int, _rgba: int, _depth: float, _stencil: int, /) -> None: ... @@ -2679,6 +2699,11 @@ def bgfx_encoder_set_condition(_this: Optional[Union[Encoder, _Pointer[Encoder], # Set stencil test state. def bgfx_encoder_set_stencil(_this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], _fstencil: int, _bstencil: int, /) -> None: ... +# Set multisample coverage mask for draw primitive. Samples whose bit is clear +# in the mask are never written, regardless of the coverage the rasterizer +# computes. Only has an effect when rendering to a multisampled target. +def bgfx_encoder_set_sample_mask(_this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], _mask: int, /) -> None: ... + # Set scissor for draw primitive. # # @remark @@ -2693,6 +2718,13 @@ def bgfx_encoder_set_scissor(_this: Optional[Union[Encoder, _Pointer[Encoder], c # def bgfx_encoder_set_scissor_cached(_this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], _cache: int, /) -> None: ... +# Set depth control (depth bias and depth clip) for draw primitive. Overrides the +# view depth bias for this draw. +def bgfx_encoder_set_depth_control(_this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], _constant: int, _slopeScale: float, _clamp: float, _depthClamp: bool, /) -> int: ... + +# Set depth control from depth-control cache for draw primitive. +def bgfx_encoder_set_depth_control_cached(_this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], _cache: int, /) -> None: ... + # Set model matrix for draw primitive. If it is not called, # the model will be rendered with an identity model matrix. def bgfx_encoder_set_transform(_this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], _mtx: Any, _num: int, /) -> int: ... @@ -3086,6 +3118,11 @@ def bgfx_set_condition(_handle: OcclusionQueryHandle, _visible: bool, /) -> None # Set stencil test state. def bgfx_set_stencil(_fstencil: int, _bstencil: int, /) -> None: ... +# Set multisample coverage mask for draw primitive. Samples whose bit is clear +# in the mask are never written, regardless of the coverage the rasterizer +# computes. Only has an effect when rendering to a multisampled target. +def bgfx_set_sample_mask(_mask: int, /) -> None: ... + # Set scissor for draw primitive. # # @remark @@ -3100,6 +3137,13 @@ def bgfx_set_scissor(_x: int, _y: int, _width: int, _height: int, /) -> int: ... # def bgfx_set_scissor_cached(_cache: int, /) -> None: ... +# Set depth control (depth bias and depth clip) for draw primitive. Overrides the +# view depth bias for this draw. +def bgfx_set_depth_control(_constant: int, _slopeScale: float, _clamp: float, _depthClamp: bool, /) -> int: ... + +# Set depth control from depth-control cache for draw primitive. +def bgfx_set_depth_control_cached(_cache: int, /) -> None: ... + # Set model matrix for draw primitive. If it is not called, # the model will be rendered with an identity model matrix. def bgfx_set_transform(_mtx: Any, _num: int, /) -> int: ... diff --git a/bindings/zig/bgfx.zig b/bindings/zig/bgfx.zig index 4060cd9ae..fb910ed13 100644 --- a/bindings/zig/bgfx.zig +++ b/bindings/zig/bgfx.zig @@ -581,9 +581,6 @@ pub const ResetFlags_Hdr10: ResetFlags = 0x00010000; /// Enable HiDPI rendering. pub const ResetFlags_Hidpi: ResetFlags = 0x00020000; -/// Enable depth clamp. -pub const ResetFlags_DepthClamp: ResetFlags = 0x00040000; - /// Suspend rendering. pub const ResetFlags_Suspend: ResetFlags = 0x00080000; @@ -810,12 +807,19 @@ pub const VideoDecodeFrameFlags_Final: VideoDecodeFrameFlags = /// the last displayable picture. pub const VideoDecodeFrameFlags_Loop: VideoDecodeFrameFlags = 0x00000008; -pub const ResolveFlags = u32; -/// No resolve flags. -pub const ResolveFlags_None: ResolveFlags = 0x00000000; +pub const AttachmentFlags = u32; +/// No attachment flags. +pub const AttachmentFlags_None: AttachmentFlags = 0x00000000; /// Auto-generate mip maps on resolve. -pub const ResolveFlags_AutoGenMips: ResolveFlags = 0x00000001; +pub const AttachmentFlags_AutoGenMips: AttachmentFlags = 0x00000001; + +/// Bind the depth aspect read-only (read-only depth-stencil view) so the +/// attachment can be sampled as a texture in the same pass. +pub const AttachmentFlags_ReadOnlyDepth: AttachmentFlags = 0x00000002; + +/// Bind the stencil aspect read-only. +pub const AttachmentFlags_ReadOnlyStencil: AttachmentFlags = 0x00000004; pub const PciIdFlags = u16; /// Autoselect adapter. @@ -1794,16 +1798,16 @@ pub const Init = extern struct { mip: u16, layer: u16, numLayers: u16, - resolve: u8, + flags: u8, /// Init attachment. /// Render target texture handle. /// Access. See `Access::Enum`. /// Cubemap side or depth layer/slice to use. /// Number of texture layer/slice(s) in array to use. /// Mip level. - /// Resolve flags. See: `BGFX_RESOLVE_*` - pub inline fn init(self: *Attachment, _handle: TextureHandle, _access: Access, _layer: u16, _numLayers: u16, _mip: u16, _resolve: u8) void { - return bgfx_attachment_init(self, _handle, _access, _layer, _numLayers, _mip, _resolve); + /// Attachment flags. See: `BGFX_ATTACHMENT_*` + pub inline fn init(self: *Attachment, _handle: TextureHandle, _access: Access, _layer: u16, _numLayers: u16, _mip: u16, _flags: u8) void { + return bgfx_attachment_init(self, _handle, _access, _layer, _numLayers, _mip, _flags); } }; @@ -1952,6 +1956,13 @@ pub const Init = extern struct { pub inline fn setStencil(self: ?*Encoder, _fstencil: u32, _bstencil: u32) void { return bgfx_encoder_set_stencil(self, _fstencil, _bstencil); } + /// Set multisample coverage mask for draw primitive. Samples whose bit is clear + /// in the mask are never written, regardless of the coverage the rasterizer + /// computes. Only has an effect when rendering to a multisampled target. + /// Sample coverage mask. + pub inline fn setSampleMask(self: ?*Encoder, _mask: u32) void { + return bgfx_encoder_set_sample_mask(self, _mask); + } /// Set scissor for draw primitive. /// /// @remark @@ -1973,6 +1984,20 @@ pub const Init = extern struct { pub inline fn setScissorCached(self: ?*Encoder, _cache: u16) void { return bgfx_encoder_set_scissor_cached(self, _cache); } + /// Set depth control (depth bias and depth clip) for draw primitive. Overrides the + /// view depth bias for this draw. + /// Constant depth bias. + /// Slope-scaled depth bias. + /// Depth bias clamp. + /// Disable depth clipping and clamp NDC depth to the [0,1] range instead. + pub inline fn setDepthControl(self: ?*Encoder, _constant: i32, _slopeScale: f32, _clamp: f32, _depthClamp: bool) u16 { + return bgfx_encoder_set_depth_control(self, _constant, _slopeScale, _clamp, _depthClamp); + } + /// Set depth control from depth-control cache for draw primitive. + /// Index in depth control cache. + pub inline fn setDepthControlCached(self: ?*Encoder, _cache: u16) void { + return bgfx_encoder_set_depth_control_cached(self, _cache); + } /// Set model matrix for draw primitive. If it is not called, /// the model will be rendered with an identity model matrix. /// Pointer to first matrix in array. @@ -2442,8 +2467,8 @@ extern fn bgfx_buffer_region_init_buffer(self: [*c]BufferRegion, _handle: Buffer /// Cubemap side or depth layer/slice to use. /// Number of texture layer/slice(s) in array to use. /// Mip level. -/// Resolve flags. See: `BGFX_RESOLVE_*` -extern fn bgfx_attachment_init(self: [*c]Attachment, _handle: TextureHandle, _access: Access, _layer: u16, _numLayers: u16, _mip: u16, _resolve: u8) void; +/// Attachment flags. See: `BGFX_ATTACHMENT_*` +extern fn bgfx_attachment_init(self: [*c]Attachment, _handle: TextureHandle, _access: Access, _layer: u16, _numLayers: u16, _mip: u16, _flags: u8) void; /// Start VertexLayout. /// Renderer backend type. See: `bgfx::RendererType` @@ -3498,10 +3523,12 @@ extern fn bgfx_set_view_name(_id: ViewId, _name: [*c]const u8, _len: i32) void; /// Position y from the top corner of the window. Can be negative to place view origin outside of the window. /// Width of view port region. /// Height of view port region. -pub inline fn setViewRect(_id: ViewId, _x: i16, _y: i16, _width: u16, _height: u16) void { - return bgfx_set_view_rect(_id, _x, _y, _width, _height); +/// Viewport minimum depth (maps clip-space z=0). +/// Viewport maximum depth (maps clip-space z=1). +pub inline fn setViewRect(_id: ViewId, _x: i16, _y: i16, _width: u16, _height: u16, _minDepth: f32, _maxDepth: f32) void { + return bgfx_set_view_rect(_id, _x, _y, _width, _height, _minDepth, _maxDepth); } -extern fn bgfx_set_view_rect(_id: ViewId, _x: i16, _y: i16, _width: u16, _height: u16) void; +extern fn bgfx_set_view_rect(_id: ViewId, _x: i16, _y: i16, _width: u16, _height: u16, _minDepth: f32, _maxDepth: f32) void; /// Set view rectangle. Draw primitive outside view will be clipped. /// View id. @@ -3525,6 +3552,26 @@ pub inline fn setViewScissor(_id: ViewId, _x: u16, _y: u16, _width: u16, _height } extern fn bgfx_set_view_scissor(_id: ViewId, _x: u16, _y: u16, _width: u16, _height: u16) void; +/// Set view depth bias. Applies to all draws in the view unless overridden per-draw +/// with `bgfx::setDepthControl`. +/// View id. +/// Constant depth bias. +/// Slope-scaled depth bias. +/// Depth bias clamp. +pub inline fn setViewDepthBias(_id: ViewId, _constant: i32, _slopeScale: f32, _clamp: f32) void { + return bgfx_set_view_depth_bias(_id, _constant, _slopeScale, _clamp); +} +extern fn bgfx_set_view_depth_bias(_id: ViewId, _constant: i32, _slopeScale: f32, _clamp: f32) void; + +/// Set view multisample coverage mask. Combined with the per-draw mask set by +/// `bgfx::setSampleMask`, so a draw can narrow the view's mask but not widen it. +/// View id. +/// Sample coverage mask. +pub inline fn setViewSampleMask(_id: ViewId, _mask: u32) void { + return bgfx_set_view_sample_mask(_id, _mask); +} +extern fn bgfx_set_view_sample_mask(_id: ViewId, _mask: u32) void; + /// Set view clear flags. /// View id. /// Clear flags. Use `BGFX_CLEAR_NONE` to remove any clear operation. See: `BGFX_CLEAR_*`. @@ -3701,6 +3748,12 @@ extern fn bgfx_encoder_set_condition(self: ?*Encoder, _handle: OcclusionQueryHan /// Back stencil state. If back is set to `BGFX_STENCIL_NONE` _fstencil is applied to both front and back facing primitives. extern fn bgfx_encoder_set_stencil(self: ?*Encoder, _fstencil: u32, _bstencil: u32) void; +/// Set multisample coverage mask for draw primitive. Samples whose bit is clear +/// in the mask are never written, regardless of the coverage the rasterizer +/// computes. Only has an effect when rendering to a multisampled target. +/// Sample coverage mask. +extern fn bgfx_encoder_set_sample_mask(self: ?*Encoder, _mask: u32) void; + /// Set scissor for draw primitive. /// /// @remark @@ -3720,6 +3773,18 @@ extern fn bgfx_encoder_set_scissor(self: ?*Encoder, _x: u16, _y: u16, _width: u1 /// Index in scissor cache. extern fn bgfx_encoder_set_scissor_cached(self: ?*Encoder, _cache: u16) void; +/// Set depth control (depth bias and depth clip) for draw primitive. Overrides the +/// view depth bias for this draw. +/// Constant depth bias. +/// Slope-scaled depth bias. +/// Depth bias clamp. +/// Disable depth clipping and clamp NDC depth to the [0,1] range instead. +extern fn bgfx_encoder_set_depth_control(self: ?*Encoder, _constant: i32, _slopeScale: f32, _clamp: f32, _depthClamp: bool) u16; + +/// Set depth control from depth-control cache for draw primitive. +/// Index in depth control cache. +extern fn bgfx_encoder_set_depth_control_cached(self: ?*Encoder, _cache: u16) void; + /// Set model matrix for draw primitive. If it is not called, /// the model will be rendered with an identity model matrix. /// Pointer to first matrix in array. @@ -4203,6 +4268,15 @@ pub inline fn setStencil(_fstencil: u32, _bstencil: u32) void { } extern fn bgfx_set_stencil(_fstencil: u32, _bstencil: u32) void; +/// Set multisample coverage mask for draw primitive. Samples whose bit is clear +/// in the mask are never written, regardless of the coverage the rasterizer +/// computes. Only has an effect when rendering to a multisampled target. +/// Sample coverage mask. +pub inline fn setSampleMask(_mask: u32) void { + return bgfx_set_sample_mask(_mask); +} +extern fn bgfx_set_sample_mask(_mask: u32) void; + /// Set scissor for draw primitive. /// /// @remark @@ -4228,6 +4302,24 @@ pub inline fn setScissorCached(_cache: u16) void { } extern fn bgfx_set_scissor_cached(_cache: u16) void; +/// Set depth control (depth bias and depth clip) for draw primitive. Overrides the +/// view depth bias for this draw. +/// Constant depth bias. +/// Slope-scaled depth bias. +/// Depth bias clamp. +/// Disable depth clipping and clamp NDC depth to the [0,1] range instead. +pub inline fn setDepthControl(_constant: i32, _slopeScale: f32, _clamp: f32, _depthClamp: bool) u16 { + return bgfx_set_depth_control(_constant, _slopeScale, _clamp, _depthClamp); +} +extern fn bgfx_set_depth_control(_constant: i32, _slopeScale: f32, _clamp: f32, _depthClamp: bool) u16; + +/// Set depth control from depth-control cache for draw primitive. +/// Index in depth control cache. +pub inline fn setDepthControlCached(_cache: u16) void { + return bgfx_set_depth_control_cached(_cache); +} +extern fn bgfx_set_depth_control_cached(_cache: u16) void; + /// Set model matrix for draw primitive. If it is not called, /// the model will be rendered with an identity model matrix. /// Pointer to first matrix in array. diff --git a/docs/bgfx.rst b/docs/bgfx.rst index e75144f71..199e96bce 100644 --- a/docs/bgfx.rst +++ b/docs/bgfx.rst @@ -54,7 +54,6 @@ Reset flags control back-buffer resolution, MSAA, vsync, and other global render .. doxygendefine:: BGFX_RESET_SRGB_BACKBUFFER .. doxygendefine:: BGFX_RESET_HDR10 .. doxygendefine:: BGFX_RESET_HIDPI -.. doxygendefine:: BGFX_RESET_DEPTH_CLAMP .. doxygendefine:: BGFX_RESET_SUSPEND .. doxygendefine:: BGFX_RESET_TRANSPARENT_BACKBUFFER @@ -251,9 +250,11 @@ A View's state is preserved between frames. :members: .. doxygenfunction:: bgfx::setViewName -.. doxygenfunction:: bgfx::setViewRect(ViewId _id, int16_t _x, int16_t _y, uint16_t _width, uint16_t _height) +.. doxygenfunction:: bgfx::setViewRect(ViewId _id, int16_t _x, int16_t _y, uint16_t _width, uint16_t _height, float _minDepth = 0.0f, float _maxDepth = 1.0f) .. doxygenfunction:: bgfx::setViewRect(ViewId _id, int16_t _x, int16_t _y, BackbufferRatio::Enum _ratio) .. doxygenfunction:: bgfx::setViewScissor +.. doxygenfunction:: bgfx::setViewDepthBias +.. doxygenfunction:: bgfx::setViewSampleMask .. doxygenfunction:: bgfx::setViewClear(ViewId _id, uint16_t _flags, uint32_t _rgba = 0x000000ff, float _depth = 1.0f, uint8_t _stencil = 0) .. doxygenfunction:: bgfx::setViewClear(ViewId _id, uint16_t _flags, float _depth, uint8_t _stencil, uint8_t _c0 = UINT8_MAX, uint8_t _c1 = UINT8_MAX, uint8_t _c2 = UINT8_MAX, uint8_t _c3 = UINT8_MAX, uint8_t _c4 = UINT8_MAX, uint8_t _c5 = UINT8_MAX, uint8_t _c6 = UINT8_MAX, uint8_t _c7 = UINT8_MAX) .. doxygenfunction:: bgfx::setViewMode @@ -298,6 +299,9 @@ State Configure render state for draw calls. .. doxygenfunction:: bgfx::setState +.. doxygenfunction:: bgfx::setSampleMask +.. doxygenfunction:: bgfx::setDepthControl(int32_t _constant, float _slopeScale, float _clamp = 0.0f, bool _depthClamp) +.. doxygenfunction:: bgfx::setDepthControl(uint16_t _cache = UINT16_MAX) State Flags *********** diff --git a/examples/08-update/update.cpp b/examples/08-update/update.cpp index 2159e3601..616593ea3 100644 --- a/examples/08-update/update.cpp +++ b/examples/08-update/update.cpp @@ -449,7 +449,7 @@ public: { bgfx::Attachment at; - at.init(m_mipRt, bgfx::Access::Write, 0, 1, 0, BGFX_RESOLVE_AUTO_GEN_MIPS); + at.init(m_mipRt, bgfx::Access::Write, 0, 1, 0, BGFX_ATTACHMENT_AUTO_GEN_MIPS); m_mipFb = bgfx::createFrameBuffer(1, &at); } diff --git a/examples/21-deferred/deferred.cpp b/examples/21-deferred/deferred.cpp index 31a048c03..2e034ef56 100644 --- a/examples/21-deferred/deferred.cpp +++ b/examples/21-deferred/deferred.cpp @@ -543,7 +543,7 @@ public: ; m_gbufferTex[2] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, depthFormat, BGFX_TEXTURE_RT | tsFlags); - gbufferAt[2].init(m_gbufferTex[2], bgfx::Access::Write, 0, 1, 0, BGFX_RESOLVE_NONE); + gbufferAt[2].init(m_gbufferTex[2], bgfx::Access::Write, 0, 1, 0, BGFX_ATTACHMENT_NONE); m_gbuffer = bgfx::createFrameBuffer(BX_COUNTOF(gbufferAt), gbufferAt, true); diff --git a/examples/25-c99/helloworld.c b/examples/25-c99/helloworld.c index 72e2cf579..f326c3e72 100644 --- a/examples/25-c99/helloworld.c +++ b/examples/25-c99/helloworld.c @@ -51,7 +51,7 @@ int32_t _main_(int32_t _argc, char** _argv) while (!entry_process_events(&width, &height, &debug, &reset) ) { // Set view 0 default viewport. - bgfx_set_view_rect(0, 0, 0, (uint16_t)width, (uint16_t)height); + bgfx_set_view_rect(0, 0, 0, (uint16_t)width, (uint16_t)height, 0.0f, 1.0f); // This dummy draw call is here to make sure that view 0 is cleared // if no other draw calls are submitted to view 0. diff --git a/examples/37-gpudrivenrendering/gpudrivenrendering.cpp b/examples/37-gpudrivenrendering/gpudrivenrendering.cpp index 7573fb203..ee409e6e2 100644 --- a/examples/37-gpudrivenrendering/gpudrivenrendering.cpp +++ b/examples/37-gpudrivenrendering/gpudrivenrendering.cpp @@ -517,7 +517,7 @@ public: bgfx::TextureHandle buffer = bgfx::createTexture2D(uint16_t(m_hiZwidth), uint16_t(m_hiZheight), true, 1, bgfx::TextureFormat::R32F, BGFX_TEXTURE_COMPUTE_WRITE | tsFlags); bgfx::Attachment at; - at.init(buffer, bgfx::Access::Write, 0, 1, 0, BGFX_RESOLVE_NONE); + at.init(buffer, bgfx::Access::Write, 0, 1, 0, BGFX_ATTACHMENT_NONE); m_hiZBuffer = bgfx::createFrameBuffer(1, &at, true); //how many mip will the Hi Z buffer have? diff --git a/examples/52-layered/layered.cpp b/examples/52-layered/layered.cpp index 16af94ff0..e1fc62f67 100644 --- a/examples/52-layered/layered.cpp +++ b/examples/52-layered/layered.cpp @@ -249,16 +249,16 @@ public: // Layered framebuffer: color and depth attachments each span all layers. bgfx::Attachment layered[2]; - layered[0].init(m_texColor, bgfx::Access::Write, 0, kNumLayers, 0, BGFX_RESOLVE_NONE); - layered[1].init(m_texDepth, bgfx::Access::Write, 0, kNumLayers, 0, BGFX_RESOLVE_NONE); + layered[0].init(m_texColor, bgfx::Access::Write, 0, kNumLayers, 0, BGFX_ATTACHMENT_NONE); + layered[1].init(m_texDepth, bgfx::Access::Write, 0, kNumLayers, 0, BGFX_ATTACHMENT_NONE); m_fbLayered = bgfx::createFrameBuffer(BX_COUNTOF(layered), layered); // Non-layered framebuffers: one per eye, each bound to a single layer. for (uint16_t ii = 0; ii < kNumLayers; ++ii) { bgfx::Attachment eye[2]; - eye[0].init(m_texColor, bgfx::Access::Write, ii, 1, 0, BGFX_RESOLVE_NONE); - eye[1].init(m_texDepth, bgfx::Access::Write, ii, 1, 0, BGFX_RESOLVE_NONE); + eye[0].init(m_texColor, bgfx::Access::Write, ii, 1, 0, BGFX_ATTACHMENT_NONE); + eye[1].init(m_texDepth, bgfx::Access::Write, ii, 1, 0, BGFX_ATTACHMENT_NONE); m_fbEye[ii] = bgfx::createFrameBuffer(BX_COUNTOF(eye), eye); } } diff --git a/examples/common/entry/entry.cpp b/examples/common/entry/entry.cpp index bcf07c54b..a6dc8a42a 100644 --- a/examples/common/entry/entry.cpp +++ b/examples/common/entry/entry.cpp @@ -308,7 +308,6 @@ BX_PRAGMA_DIAGNOSTIC_POP(); || setOrToggle(s_reset, "flush", BGFX_RESET_FLUSH_AFTER_RENDER, 1, _argc, _argv) || setOrToggle(s_reset, "flip", BGFX_RESET_FLIP_AFTER_RENDER, 1, _argc, _argv) || setOrToggle(s_reset, "hidpi", BGFX_RESET_HIDPI, 1, _argc, _argv) - || setOrToggle(s_reset, "depthclamp", BGFX_RESET_DEPTH_CLAMP, 1, _argc, _argv) ) { return bx::kExitSuccess; diff --git a/include/bgfx/bgfx.h b/include/bgfx/bgfx.h index b7a306139..b1cb697d6 100644 --- a/include/bgfx/bgfx.h +++ b/include/bgfx/bgfx.h @@ -1061,7 +1061,7 @@ namespace bgfx /// @param[in] _layer Cubemap side or depth layer/slice to use. /// @param[in] _numLayers Number of texture layer/slice(s) in array to use. /// @param[in] _mip Mip level. - /// @param[in] _resolve Resolve flags. See: `BGFX_RESOLVE_*` + /// @param[in] _flags Attachment flags. See: `BGFX_ATTACHMENT_*` /// /// @attention C99's equivalent binding is `bgfx_attachment_init`. /// @@ -1071,7 +1071,7 @@ namespace bgfx , uint16_t _layer = 0 , uint16_t _numLayers = 1 , uint16_t _mip = 0 - , uint8_t _resolve = BGFX_RESOLVE_AUTO_GEN_MIPS + , uint8_t _flags = BGFX_ATTACHMENT_AUTO_GEN_MIPS ); Access::Enum access; //!< Attachment access. See `Access::Enum`. @@ -1079,7 +1079,7 @@ namespace bgfx uint16_t mip; //!< Mip level. uint16_t layer; //!< Cubemap side or depth layer/slice to use. uint16_t numLayers; //!< Number of texture layer/slice(s) in array to use. - uint8_t resolve; //!< Resolve flags. See: `BGFX_RESOLVE_*` + uint8_t flags; //!< Attachment flags. See: `BGFX_ATTACHMENT_*` }; /// Transform data. @@ -1367,6 +1367,16 @@ namespace bgfx , uint32_t _bstencil = BGFX_STENCIL_NONE ); + /// Set multisample coverage mask for draw primitive. Samples whose bit is clear + /// in the mask are never written, regardless of the coverage the rasterizer + /// computes. Only has an effect when rendering to a multisampled target. + /// + /// @param[in] _mask Sample coverage mask. + /// + /// @attention C99's equivalent binding is `bgfx_encoder_set_sample_mask`. + /// + void setSampleMask(uint32_t _mask = UINT32_MAX); + /// Set scissor for draw primitive. /// /// @param[in] _x Position x from the left corner of the window. @@ -1399,6 +1409,33 @@ namespace bgfx /// void setScissor(uint16_t _cache = UINT16_MAX); + /// Set depth control (depth bias and depth clip) for draw primitive. Overrides the + /// view depth bias for this draw. + /// + /// @param[in] _constant Constant depth bias. + /// @param[in] _slopeScale Slope-scaled depth bias. + /// @param[in] _clamp Depth bias clamp. + /// @param[in] _depthClamp Disable depth clipping and clamp NDC depth to the [0,1] range instead. + /// + /// @returns Depth control cache index. + /// + /// @attention C99's equivalent binding is `bgfx_encoder_set_depth_control`. + /// + uint16_t setDepthControl( + int32_t _constant + , float _slopeScale + , float _clamp = 0.0f + , bool _depthClamp = false + ); + + /// Set depth control from depth-control cache for draw primitive. + /// + /// @param[in] _cache Index in depth control cache. + /// + /// @attention C99's equivalent binding is `bgfx_encoder_set_depth_control_cached`. + /// + void setDepthControl(uint16_t _cache = UINT16_MAX); + /// Set model matrix for draw primitive. If it is not called, /// the model will be rendered with an identity model matrix. /// @@ -4008,6 +4045,8 @@ namespace bgfx /// negative to place view origin outside of the window. /// @param[in] _width Width of view port region. /// @param[in] _height Height of view port region. + /// @param[in] _minDepth Viewport minimum depth (maps clip-space z=0). + /// @param[in] _maxDepth Viewport maximum depth (maps clip-space z=1). /// /// @attention C99's equivalent binding is `bgfx_set_view_rect`. /// @@ -4017,6 +4056,8 @@ namespace bgfx , int16_t _y , uint16_t _width , uint16_t _height + , float _minDepth = 0.0f + , float _maxDepth = 1.0f ); /// Set view rectangle. Draw primitive outside view will be clipped. @@ -4057,6 +4098,36 @@ namespace bgfx , uint16_t _height = 0 ); + /// Set view depth bias. Applies to all draws in the view unless overridden per-draw + /// with `bgfx::setDepthControl`. + /// + /// @param[in] _id View id. + /// @param[in] _constant Constant depth bias. + /// @param[in] _slopeScale Slope-scaled depth bias. + /// @param[in] _clamp Depth bias clamp. + /// + /// @attention C99's equivalent binding is `bgfx_set_view_depth_bias`. + /// + void setViewDepthBias( + ViewId _id + , int32_t _constant = 0 + , float _slopeScale = 0.0f + , float _clamp = 0.0f + ); + + /// Set view multisample coverage mask. Combined with the per-draw mask set by + /// `bgfx::setSampleMask`, so a draw can narrow the view's mask but not widen it. + /// + /// @param[in] _id View id. + /// @param[in] _mask Sample coverage mask. + /// + /// @attention C99's equivalent binding is `bgfx_set_view_sample_mask`. + /// + void setViewSampleMask( + ViewId _id + , uint32_t _mask = UINT32_MAX + ); + /// Set view clear flags. /// /// @param[in] _id View id. @@ -4433,6 +4504,16 @@ namespace bgfx , uint32_t _bstencil = BGFX_STENCIL_NONE ); + /// Set multisample coverage mask for draw primitive. Samples whose bit is clear + /// in the mask are never written, regardless of the coverage the rasterizer + /// computes. Only has an effect when rendering to a multisampled target. + /// + /// @param[in] _mask Sample coverage mask. + /// + /// @attention C99's equivalent binding is `bgfx_set_sample_mask`. + /// + void setSampleMask(uint32_t _mask = UINT32_MAX); + /// Set scissor for draw primitive. /// /// @param[in] _x Position x from the left corner of the window. @@ -4465,6 +4546,33 @@ namespace bgfx /// void setScissor(uint16_t _cache = UINT16_MAX); + /// Set depth control (depth bias and depth clip) for draw primitive. Overrides the + /// view depth bias for this draw. + /// + /// @param[in] _constant Constant depth bias. + /// @param[in] _slopeScale Slope-scaled depth bias. + /// @param[in] _clamp Depth bias clamp. + /// @param[in] _depthClamp Disable depth clipping and clamp NDC depth to the [0,1] range instead. + /// + /// @returns Depth control cache index. + /// + /// @attention C99's equivalent binding is `bgfx_set_depth_control`. + /// + uint16_t setDepthControl( + int32_t _constant + , float _slopeScale + , float _clamp = 0.0f + , bool _depthClamp = false + ); + + /// Set depth control from depth-control cache for draw primitive. + /// + /// @param[in] _cache Index in depth control cache. + /// + /// @attention C99's equivalent binding is `bgfx_set_depth_control_cached`. + /// + void setDepthControl(uint16_t _cache = UINT16_MAX); + /// Set model matrix for draw primitive. If it is not called, /// the model will be rendered with an identity model matrix. /// diff --git a/include/bgfx/c99/bgfx.h b/include/bgfx/c99/bgfx.h index d112545ed..4e1ab6882 100644 --- a/include/bgfx/c99/bgfx.h +++ b/include/bgfx/c99/bgfx.h @@ -1187,7 +1187,7 @@ typedef struct bgfx_attachment_s uint16_t mip; /** Mip level. */ uint16_t layer; /** Cubemap side or depth layer/slice to use. */ uint16_t numLayers; /** Number of texture layer/slice(s) in array to use. */ - uint8_t resolve; /** Resolve flags. See: `BGFX_RESOLVE_*` */ + uint8_t flags; /** Attachment flags. See: `BGFX_ATTACHMENT_*` */ } bgfx_attachment_t; @@ -1362,10 +1362,10 @@ BGFX_C_API void bgfx_buffer_region_init_buffer(bgfx_buffer_region_t* _this, bgfx * @param[in] _layer Cubemap side or depth layer/slice to use. * @param[in] _numLayers Number of texture layer/slice(s) in array to use. * @param[in] _mip Mip level. - * @param[in] _resolve Resolve flags. See: `BGFX_RESOLVE_*` + * @param[in] _flags Attachment flags. See: `BGFX_ATTACHMENT_*` * */ -BGFX_C_API void bgfx_attachment_init(bgfx_attachment_t* _this, bgfx_texture_handle_t _handle, bgfx_access_t _access, uint16_t _layer, uint16_t _numLayers, uint16_t _mip, uint8_t _resolve); +BGFX_C_API void bgfx_attachment_init(bgfx_attachment_t* _this, bgfx_texture_handle_t _handle, bgfx_access_t _access, uint16_t _layer, uint16_t _numLayers, uint16_t _mip, uint8_t _flags); /** * Start VertexLayout. @@ -2849,9 +2849,11 @@ BGFX_C_API void bgfx_set_view_name(bgfx_view_id_t _id, const char* _name, int32_ * negative to place view origin outside of the window. * @param[in] _width Width of view port region. * @param[in] _height Height of view port region. + * @param[in] _minDepth Viewport minimum depth (maps clip-space z=0). + * @param[in] _maxDepth Viewport maximum depth (maps clip-space z=1). * */ -BGFX_C_API void bgfx_set_view_rect(bgfx_view_id_t _id, int16_t _x, int16_t _y, uint16_t _width, uint16_t _height); +BGFX_C_API void bgfx_set_view_rect(bgfx_view_id_t _id, int16_t _x, int16_t _y, uint16_t _width, uint16_t _height, float _minDepth, float _maxDepth); /** * Set view rectangle. Draw primitive outside view will be clipped. @@ -2880,6 +2882,28 @@ BGFX_C_API void bgfx_set_view_rect_ratio(bgfx_view_id_t _id, int16_t _x, int16_t */ BGFX_C_API void bgfx_set_view_scissor(bgfx_view_id_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height); +/** + * Set view depth bias. Applies to all draws in the view unless overridden per-draw + * with `bgfx::setDepthControl`. + * + * @param[in] _id View id. + * @param[in] _constant Constant depth bias. + * @param[in] _slopeScale Slope-scaled depth bias. + * @param[in] _clamp Depth bias clamp. + * + */ +BGFX_C_API void bgfx_set_view_depth_bias(bgfx_view_id_t _id, int32_t _constant, float _slopeScale, float _clamp); + +/** + * Set view multisample coverage mask. Combined with the per-draw mask set by + * `bgfx::setSampleMask`, so a draw can narrow the view's mask but not widen it. + * + * @param[in] _id View id. + * @param[in] _mask Sample coverage mask. + * + */ +BGFX_C_API void bgfx_set_view_sample_mask(bgfx_view_id_t _id, uint32_t _mask); + /** * Set view clear flags. * @@ -3095,6 +3119,16 @@ BGFX_C_API void bgfx_encoder_set_condition(bgfx_encoder_t* _this, bgfx_occlusion */ BGFX_C_API void bgfx_encoder_set_stencil(bgfx_encoder_t* _this, uint32_t _fstencil, uint32_t _bstencil); +/** + * Set multisample coverage mask for draw primitive. Samples whose bit is clear + * in the mask are never written, regardless of the coverage the rasterizer + * computes. Only has an effect when rendering to a multisampled target. + * + * @param[in] _mask Sample coverage mask. + * + */ +BGFX_C_API void bgfx_encoder_set_sample_mask(bgfx_encoder_t* _this, uint32_t _mask); + /** * Set scissor for draw primitive. * @@ -3122,6 +3156,28 @@ BGFX_C_API uint16_t bgfx_encoder_set_scissor(bgfx_encoder_t* _this, uint16_t _x, */ BGFX_C_API void bgfx_encoder_set_scissor_cached(bgfx_encoder_t* _this, uint16_t _cache); +/** + * Set depth control (depth bias and depth clip) for draw primitive. Overrides the + * view depth bias for this draw. + * + * @param[in] _constant Constant depth bias. + * @param[in] _slopeScale Slope-scaled depth bias. + * @param[in] _clamp Depth bias clamp. + * @param[in] _depthClamp Disable depth clipping and clamp NDC depth to the [0,1] range instead. + * + * @returns Depth control cache index. + * + */ +BGFX_C_API uint16_t bgfx_encoder_set_depth_control(bgfx_encoder_t* _this, int32_t _constant, float _slopeScale, float _clamp, bool _depthClamp); + +/** + * Set depth control from depth-control cache for draw primitive. + * + * @param[in] _cache Index in depth control cache. + * + */ +BGFX_C_API void bgfx_encoder_set_depth_control_cached(bgfx_encoder_t* _this, uint16_t _cache); + /** * Set model matrix for draw primitive. If it is not called, * the model will be rendered with an identity model matrix. @@ -3790,6 +3846,16 @@ BGFX_C_API void bgfx_set_condition(bgfx_occlusion_query_handle_t _handle, bool _ */ BGFX_C_API void bgfx_set_stencil(uint32_t _fstencil, uint32_t _bstencil); +/** + * Set multisample coverage mask for draw primitive. Samples whose bit is clear + * in the mask are never written, regardless of the coverage the rasterizer + * computes. Only has an effect when rendering to a multisampled target. + * + * @param[in] _mask Sample coverage mask. + * + */ +BGFX_C_API void bgfx_set_sample_mask(uint32_t _mask); + /** * Set scissor for draw primitive. * @@ -3817,6 +3883,28 @@ BGFX_C_API uint16_t bgfx_set_scissor(uint16_t _x, uint16_t _y, uint16_t _width, */ BGFX_C_API void bgfx_set_scissor_cached(uint16_t _cache); +/** + * Set depth control (depth bias and depth clip) for draw primitive. Overrides the + * view depth bias for this draw. + * + * @param[in] _constant Constant depth bias. + * @param[in] _slopeScale Slope-scaled depth bias. + * @param[in] _clamp Depth bias clamp. + * @param[in] _depthClamp Disable depth clipping and clamp NDC depth to the [0,1] range instead. + * + * @returns Depth control cache index. + * + */ +BGFX_C_API uint16_t bgfx_set_depth_control(int32_t _constant, float _slopeScale, float _clamp, bool _depthClamp); + +/** + * Set depth control from depth-control cache for draw primitive. + * + * @param[in] _cache Index in depth control cache. + * + */ +BGFX_C_API void bgfx_set_depth_control_cached(uint16_t _cache); + /** * Set model matrix for draw primitive. If it is not called, * the model will be rendered with an identity model matrix. @@ -4439,6 +4527,8 @@ typedef enum bgfx_function_id BGFX_FUNCTION_ID_SET_VIEW_RECT, BGFX_FUNCTION_ID_SET_VIEW_RECT_RATIO, BGFX_FUNCTION_ID_SET_VIEW_SCISSOR, + BGFX_FUNCTION_ID_SET_VIEW_DEPTH_BIAS, + BGFX_FUNCTION_ID_SET_VIEW_SAMPLE_MASK, BGFX_FUNCTION_ID_SET_VIEW_CLEAR, BGFX_FUNCTION_ID_SET_VIEW_CLEAR_MRT, BGFX_FUNCTION_ID_SET_VIEW_MODE, @@ -4453,8 +4543,11 @@ typedef enum bgfx_function_id BGFX_FUNCTION_ID_ENCODER_SET_STATE, BGFX_FUNCTION_ID_ENCODER_SET_CONDITION, BGFX_FUNCTION_ID_ENCODER_SET_STENCIL, + BGFX_FUNCTION_ID_ENCODER_SET_SAMPLE_MASK, BGFX_FUNCTION_ID_ENCODER_SET_SCISSOR, BGFX_FUNCTION_ID_ENCODER_SET_SCISSOR_CACHED, + BGFX_FUNCTION_ID_ENCODER_SET_DEPTH_CONTROL, + BGFX_FUNCTION_ID_ENCODER_SET_DEPTH_CONTROL_CACHED, BGFX_FUNCTION_ID_ENCODER_SET_TRANSFORM, BGFX_FUNCTION_ID_ENCODER_SET_TRANSFORM_CACHED, BGFX_FUNCTION_ID_ENCODER_ALLOC_TRANSFORM, @@ -4503,8 +4596,11 @@ typedef enum bgfx_function_id BGFX_FUNCTION_ID_SET_STATE, BGFX_FUNCTION_ID_SET_CONDITION, BGFX_FUNCTION_ID_SET_STENCIL, + BGFX_FUNCTION_ID_SET_SAMPLE_MASK, BGFX_FUNCTION_ID_SET_SCISSOR, BGFX_FUNCTION_ID_SET_SCISSOR_CACHED, + BGFX_FUNCTION_ID_SET_DEPTH_CONTROL, + BGFX_FUNCTION_ID_SET_DEPTH_CONTROL_CACHED, BGFX_FUNCTION_ID_SET_TRANSFORM, BGFX_FUNCTION_ID_SET_TRANSFORM_CACHED, BGFX_FUNCTION_ID_ALLOC_TRANSFORM, @@ -4555,7 +4651,7 @@ struct bgfx_interface_vtbl void (*texture_region_init)(bgfx_texture_region_t* _this, bgfx_texture_handle_t _handle, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height); void (*buffer_region_init_texture)(bgfx_buffer_region_t* _this, const bgfx_texture_region_t * _texture); void (*buffer_region_init_buffer)(bgfx_buffer_region_t* _this, bgfx_buffer_handle_t _handle, uint32_t _offset, uint32_t _size); - void (*attachment_init)(bgfx_attachment_t* _this, bgfx_texture_handle_t _handle, bgfx_access_t _access, uint16_t _layer, uint16_t _numLayers, uint16_t _mip, uint8_t _resolve); + void (*attachment_init)(bgfx_attachment_t* _this, bgfx_texture_handle_t _handle, bgfx_access_t _access, uint16_t _layer, uint16_t _numLayers, uint16_t _mip, uint8_t _flags); bgfx_vertex_layout_t* (*vertex_layout_begin)(bgfx_vertex_layout_t* _this, bgfx_renderer_type_t _rendererType); bgfx_vertex_layout_t* (*vertex_layout_add)(bgfx_vertex_layout_t* _this, bgfx_attrib_t _attrib, uint8_t _num, bgfx_attrib_type_t _type, bool _normalized, bool _asInt); void (*vertex_layout_decode)(const bgfx_vertex_layout_t* _this, bgfx_attrib_t _attrib, uint8_t * _num, bgfx_attrib_type_t * _type, bool * _normalized, bool * _asInt); @@ -4659,9 +4755,11 @@ struct bgfx_interface_vtbl void (*set_palette_color_rgba32f)(uint8_t _index, float _r, float _g, float _b, float _a); void (*set_palette_color_rgba8)(uint8_t _index, uint32_t _rgba); void (*set_view_name)(bgfx_view_id_t _id, const char* _name, int32_t _len); - void (*set_view_rect)(bgfx_view_id_t _id, int16_t _x, int16_t _y, uint16_t _width, uint16_t _height); + void (*set_view_rect)(bgfx_view_id_t _id, int16_t _x, int16_t _y, uint16_t _width, uint16_t _height, float _minDepth, float _maxDepth); void (*set_view_rect_ratio)(bgfx_view_id_t _id, int16_t _x, int16_t _y, bgfx_backbuffer_ratio_t _ratio); void (*set_view_scissor)(bgfx_view_id_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height); + void (*set_view_depth_bias)(bgfx_view_id_t _id, int32_t _constant, float _slopeScale, float _clamp); + void (*set_view_sample_mask)(bgfx_view_id_t _id, uint32_t _mask); void (*set_view_clear)(bgfx_view_id_t _id, uint16_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil); void (*set_view_clear_mrt)(bgfx_view_id_t _id, uint16_t _flags, float _depth, uint8_t _stencil, uint8_t _c0, uint8_t _c1, uint8_t _c2, uint8_t _c3, uint8_t _c4, uint8_t _c5, uint8_t _c6, uint8_t _c7); void (*set_view_mode)(bgfx_view_id_t _id, bgfx_view_mode_t _mode); @@ -4676,8 +4774,11 @@ struct bgfx_interface_vtbl void (*encoder_set_state)(bgfx_encoder_t* _this, uint64_t _state, uint32_t _rgba); void (*encoder_set_condition)(bgfx_encoder_t* _this, bgfx_occlusion_query_handle_t _handle, bool _visible); void (*encoder_set_stencil)(bgfx_encoder_t* _this, uint32_t _fstencil, uint32_t _bstencil); + void (*encoder_set_sample_mask)(bgfx_encoder_t* _this, uint32_t _mask); uint16_t (*encoder_set_scissor)(bgfx_encoder_t* _this, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height); void (*encoder_set_scissor_cached)(bgfx_encoder_t* _this, uint16_t _cache); + uint16_t (*encoder_set_depth_control)(bgfx_encoder_t* _this, int32_t _constant, float _slopeScale, float _clamp, bool _depthClamp); + void (*encoder_set_depth_control_cached)(bgfx_encoder_t* _this, uint16_t _cache); uint32_t (*encoder_set_transform)(bgfx_encoder_t* _this, const void* _mtx, uint16_t _num); void (*encoder_set_transform_cached)(bgfx_encoder_t* _this, uint32_t _cache, uint16_t _num); uint32_t (*encoder_alloc_transform)(bgfx_encoder_t* _this, bgfx_transform_t* _transform, uint16_t _num); @@ -4726,8 +4827,11 @@ struct bgfx_interface_vtbl void (*set_state)(uint64_t _state, uint32_t _rgba); void (*set_condition)(bgfx_occlusion_query_handle_t _handle, bool _visible); void (*set_stencil)(uint32_t _fstencil, uint32_t _bstencil); + void (*set_sample_mask)(uint32_t _mask); uint16_t (*set_scissor)(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height); void (*set_scissor_cached)(uint16_t _cache); + uint16_t (*set_depth_control)(int32_t _constant, float _slopeScale, float _clamp, bool _depthClamp); + void (*set_depth_control_cached)(uint16_t _cache); uint32_t (*set_transform)(const void* _mtx, uint16_t _num); void (*set_transform_cached)(uint32_t _cache, uint16_t _num); uint32_t (*alloc_transform)(bgfx_transform_t* _transform, uint16_t _num); diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h index 10ac314ba..16d7331e9 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(159) +#define BGFX_API_VERSION UINT32_C(160) /** * Color RGB/alpha/depth write. When it's not specified write will be disabled. @@ -423,7 +423,6 @@ #define BGFX_RESET_SRGB_BACKBUFFER UINT32_C(0x00008000) //!< Enable sRGB backbuffer. #define BGFX_RESET_HDR10 UINT32_C(0x00010000) //!< Enable HDR10 rendering. #define BGFX_RESET_HIDPI UINT32_C(0x00020000) //!< Enable HiDPI rendering. -#define BGFX_RESET_DEPTH_CLAMP UINT32_C(0x00040000) //!< Enable depth clamp. #define BGFX_RESET_SUSPEND UINT32_C(0x00080000) //!< Suspend rendering. #define BGFX_RESET_TRANSPARENT_BACKBUFFER UINT32_C(0x00100000) //!< Transparent backbuffer. Availability depends on: `BGFX_CAPS_TRANSPARENT_BACKBUFFER`. @@ -539,8 +538,13 @@ /// the last displayable picture. #define BGFX_VIDEO_DECODE_FRAME_LOOP UINT8_C(0x08) -#define BGFX_RESOLVE_NONE UINT8_C(0x00) //!< No resolve flags. -#define BGFX_RESOLVE_AUTO_GEN_MIPS UINT8_C(0x01) //!< Auto-generate mip maps on resolve. +#define BGFX_ATTACHMENT_NONE UINT8_C(0x00) //!< No attachment flags. +#define BGFX_ATTACHMENT_AUTO_GEN_MIPS UINT8_C(0x01) //!< Auto-generate mip maps on resolve. + +/// Bind the depth aspect read-only (read-only depth-stencil view) so the +/// attachment can be sampled as a texture in the same pass. +#define BGFX_ATTACHMENT_READ_ONLY_DEPTH UINT8_C(0x02) +#define BGFX_ATTACHMENT_READ_ONLY_STENCIL UINT8_C(0x04) //!< Bind the stencil aspect read-only. #define BGFX_PCI_ID_NONE UINT16_C(0x0000) //!< Autoselect adapter. #define BGFX_PCI_ID_SOFTWARE_RASTERIZER UINT16_C(0x0001) //!< Software rasterizer. diff --git a/scripts/bgfx.idl b/scripts/bgfx.idl index ae41ce4d0..a825d8c4b 100644 --- a/scripts/bgfx.idl +++ b/scripts/bgfx.idl @@ -1,7 +1,7 @@ -- vim: syntax=lua -- bgfx interface -version(159) +version(160) typedef "bool" typedef "char" @@ -340,7 +340,6 @@ flag.Reset { bits = 32, section = "Reset" } .SrgbBackbuffer (16) --- Enable sRGB backbuffer. .Hdr10 (17) --- Enable HDR10 rendering. .Hidpi (18) --- Enable HiDPI rendering. - .DepthClamp (19) --- Enable depth clamp. .Suspend (20) --- Suspend rendering. .TransparentBackbuffer (21) --- Transparent backbuffer. Availability depends on: `BGFX_CAPS_TRANSPARENT_BACKBUFFER`. () @@ -452,9 +451,12 @@ flag.VideoDecodeFrame { bits = 8 } --- the last displayable picture. () -flag.Resolve { bits = 8 } - .None --- No resolve flags. - .AutoGenMips --- Auto-generate mip maps on resolve. +flag.Attachment { bits = 8 } + .None --- No attachment flags. + .AutoGenMips --- Auto-generate mip maps on resolve. + .ReadOnlyDepth --- Bind the depth aspect read-only (read-only depth-stencil view) so the + --- attachment can be sampled as a texture in the same pass. + .ReadOnlyStencil --- Bind the stencil aspect read-only. () flag.PciId { bits = 16, const, section = "Initialization and Shutdown" } @@ -1174,7 +1176,7 @@ struct.Attachment { shortname, section = "Frame Buffers" } .mip "uint16_t" --- Mip level. .layer "uint16_t" --- Cubemap side or depth layer/slice to use. .numLayers "uint16_t" --- Number of texture layer/slice(s) in array to use. - .resolve "uint8_t" --- Resolve flags. See: `BGFX_RESOLVE_*` + .flags "uint8_t" --- Attachment flags. See: `BGFX_ATTACHMENT_*` --- Init attachment. func.Attachment.init @@ -1188,8 +1190,8 @@ func.Attachment.init { default = 1 } .mip "uint16_t" --- Mip level. { default = 0 } - .resolve "uint8_t" --- Resolve flags. See: `BGFX_RESOLVE_*` - { default = "BGFX_RESOLVE_AUTO_GEN_MIPS" } + .flags "uint8_t" --- Attachment flags. See: `BGFX_ATTACHMENT_*` + { default = "BGFX_ATTACHMENT_AUTO_GEN_MIPS" } --- Transform data. struct.Transform @@ -2461,6 +2463,10 @@ func.setViewRect { section = "Views" } --- negative to place view origin outside of the window. .width "uint16_t" --- Width of view port region. .height "uint16_t" --- Height of view port region. + .minDepth "float" --- Viewport minimum depth (maps clip-space z=0). + { default = "0.0f" } + .maxDepth "float" --- Viewport maximum depth (maps clip-space z=1). + { default = "1.0f" } --- Set view rectangle. Draw primitive outside view will be clipped. func.setViewRect { cname = "set_view_rect_ratio", section = "Views" } @@ -2487,6 +2493,26 @@ func.setViewScissor { section = "Views" } .height "uint16_t" --- Height of view scissor region. { default = 0 } +--- Set view depth bias. Applies to all draws in the view unless overridden per-draw +--- with `bgfx::setDepthControl`. +func.setViewDepthBias { section = "Views" } + "void" + .id "ViewId" --- View id. + .constant "int32_t" --- Constant depth bias. + { default = 0 } + .slopeScale "float" --- Slope-scaled depth bias. + { default = "0.0f" } + .clamp "float" --- Depth bias clamp. + { default = "0.0f" } + +--- Set view multisample coverage mask. Combined with the per-draw mask set by +--- `bgfx::setSampleMask`, so a draw can narrow the view's mask but not widen it. +func.setViewSampleMask { section = "Views" } + "void" + .id "ViewId" --- View id. + .mask "uint32_t" --- Sample coverage mask. + { default = UINT32_MAX } + --- Set view clear flags. func.setViewClear { section = "Views" } "void" @@ -2683,6 +2709,14 @@ func.Encoder.setStencil { section = "Stencil" } --- _fstencil is applied to both front and back facing primitives. { default = "BGFX_STENCIL_NONE" } +--- Set multisample coverage mask for draw primitive. Samples whose bit is clear +--- in the mask are never written, regardless of the coverage the rasterizer +--- computes. Only has an effect when rendering to a multisampled target. +func.Encoder.setSampleMask { section = "State" } + "void" + .mask "uint32_t" --- Sample coverage mask. + { default = UINT32_MAX } + --- Set scissor for draw primitive. --- --- @remark @@ -2705,6 +2739,23 @@ func.Encoder.setScissor { cname = "set_scissor_cached", section = "Scissor" } .cache "uint16_t" --- Index in scissor cache. { default = UINT16_MAX } +--- Set depth control (depth bias and depth clip) for draw primitive. Overrides the +--- view depth bias for this draw. +func.Encoder.setDepthControl { section = "State" } + "uint16_t" --- Depth control cache index. + .constant "int32_t" --- Constant depth bias. + .slopeScale "float" --- Slope-scaled depth bias. + .clamp "float" --- Depth bias clamp. + { default = "0.0f" } + .depthClamp "bool" --- Disable depth clipping and clamp NDC depth to the [0,1] range instead. + { default = false } + +--- Set depth control from depth-control cache for draw primitive. +func.Encoder.setDepthControl { cname = "set_depth_control_cached", section = "State" } + "void" + .cache "uint16_t" --- Index in depth control cache. + { default = UINT16_MAX } + --- Set model matrix for draw primitive. If it is not called, --- the model will be rendered with an identity model matrix. func.Encoder.setTransform { section = "Transform" } @@ -3315,6 +3366,14 @@ func.setStencil { section = "Stencil" } --- _fstencil is applied to both front and back facing primitives. { default = "BGFX_STENCIL_NONE" } +--- Set multisample coverage mask for draw primitive. Samples whose bit is clear +--- in the mask are never written, regardless of the coverage the rasterizer +--- computes. Only has an effect when rendering to a multisampled target. +func.setSampleMask { section = "State" } + "void" + .mask "uint32_t" --- Sample coverage mask. + { default = UINT32_MAX } + --- Set scissor for draw primitive. --- --- @remark @@ -3337,6 +3396,23 @@ func.setScissor { cname = "set_scissor_cached", section = "Scissor" } .cache "uint16_t" --- Index in scissor cache. { default = UINT16_MAX } +--- Set depth control (depth bias and depth clip) for draw primitive. Overrides the +--- view depth bias for this draw. +func.setDepthControl { section = "State" } + "uint16_t" --- Depth control cache index. + .constant "int32_t" --- Constant depth bias. + .slopeScale "float" --- Slope-scaled depth bias. + .clamp "float" --- Depth bias clamp. + { default = "0.0f" } + .depthClamp "bool" --- Disable depth clipping and clamp NDC depth to the [0,1] range instead. + { default = false } + +--- Set depth control from depth-control cache for draw primitive. +func.setDepthControl { cname = "set_depth_control_cached", section = "State" } + "void" + .cache "uint16_t" --- Index in depth control cache. + { default = UINT16_MAX } + --- Set model matrix for draw primitive. If it is not called, --- the model will be rendered with an identity model matrix. func.setTransform { section = "Transform" } diff --git a/scripts/bindings-d.lua b/scripts/bindings-d.lua index 5fa800684..fa40336aa 100644 --- a/scripts/bindings-d.lua +++ b/scripts/bindings-d.lua @@ -330,7 +330,7 @@ local valSubs = { BGFX_RESET_NONE = "Reset.none", BGFX_SAMPLER_U_CLAMP = "SamplerU.clamp", BGFX_SAMPLER_V_CLAMP = "SamplerV.clamp", - BGFX_RESOLVE_AUTO_GEN_MIPS = "Resolve.autoGenMIPs", + BGFX_ATTACHMENT_AUTO_GEN_MIPS = "Attachment.autoGenMIPs", ["ViewMode::Default"] = "ViewMode.default_", } local function convVal(arg, type) diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 1f24ffa03..060e206ef 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -2195,7 +2195,6 @@ namespace bgfx BX_TRACE("\t[%c] Capture", 0 != (reset & BGFX_RESET_CAPTURE) ? 'x' : ' '); BX_TRACE("\t[%c] Flush After Render", 0 != (reset & BGFX_RESET_FLUSH_AFTER_RENDER) ? 'x' : ' '); BX_TRACE("\t[%c] Flip After Render", 0 != (reset & BGFX_RESET_FLIP_AFTER_RENDER) ? 'x' : ' '); - BX_TRACE("\t[%c] Depth Clamp", 0 != (reset & BGFX_RESET_DEPTH_CLAMP) ? 'x' : ' '); BX_TRACE("\t[%c] Suspend", 0 != (reset & BGFX_RESET_SUSPEND) ? 'x' : ' '); } @@ -3917,10 +3916,10 @@ namespace bgfx FrameBufferHandle handle; _cmdbuf.read(handle); - bool window; - _cmdbuf.read(window); + uint8_t type; + _cmdbuf.read(type); - if (window) + if (1 == type) // window (nwh) swap chain { m_renderCtx->createFrameBuffer(handle, readSwapChain(_cmdbuf) ); } @@ -4146,14 +4145,14 @@ namespace bgfx swapChain.numBackBuffers = 2; } - void Attachment::init(TextureHandle _handle, Access::Enum _access, uint16_t _layer, uint16_t _numLayers, uint16_t _mip, uint8_t _resolve) + void Attachment::init(TextureHandle _handle, Access::Enum _access, uint16_t _layer, uint16_t _numLayers, uint16_t _mip, uint8_t _flags) { access = _access; handle = _handle; mip = _mip; layer = _layer; numLayers = _numLayers; - resolve = _resolve; + flags = _flags; } bool init(const Init& _userInit) @@ -4360,6 +4359,11 @@ namespace bgfx BGFX_ENCODER(setStencil(_fstencil, _bstencil) ); } + void Encoder::setSampleMask(uint32_t _mask) + { + BGFX_ENCODER(setSampleMask(_mask) ); + } + uint16_t Encoder::setScissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height) { return BGFX_ENCODER(setScissor(_x, _y, _width, _height) ); @@ -4370,6 +4374,16 @@ namespace bgfx BGFX_ENCODER(setScissor(_cache) ); } + uint16_t Encoder::setDepthControl(int32_t _constant, float _slopeScale, float _clamp, bool _depthClamp) + { + return BGFX_ENCODER(setDepthControl(_constant, _slopeScale, _clamp, _depthClamp) ); + } + + void Encoder::setDepthControl(uint16_t _cache) + { + BGFX_ENCODER(setDepthControl(_cache) ); + } + uint32_t Encoder::setTransform(const void* _mtx, uint16_t _num) { return BGFX_ENCODER(setTransform(_mtx, _num) ); @@ -5661,13 +5675,13 @@ namespace bgfx ); BGFX_ERROR_CHECK( - 0 == (at.resolve & BGFX_RESOLVE_AUTO_GEN_MIPS) + 0 == (at.flags & BGFX_ATTACHMENT_AUTO_GEN_MIPS) , _err , BGFX_ERROR_FRAME_BUFFER_VALIDATION - , "Frame buffer depth attachment cannot use `BGFX_RESOLVE_AUTO_GEN_MIPS`. Depth textures do not support MSAA resolve." + , "Frame buffer depth attachment cannot use `BGFX_ATTACHMENT_AUTO_GEN_MIPS`. Depth textures do not support MSAA resolve." , "Attachment %d, resolve flags 0x%02x." , ii - , at.resolve + , at.flags ); } else @@ -5696,12 +5710,12 @@ namespace bgfx ); BGFX_ERROR_CHECK(true - && (0 == (at.resolve & BGFX_RESOLVE_AUTO_GEN_MIPS) + && (0 == (at.flags & BGFX_ATTACHMENT_AUTO_GEN_MIPS) || 1 == tr.m_numMips || 0 != (g_caps.formats[tr.m_format] & BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN) ) , _err , BGFX_ERROR_FRAME_BUFFER_VALIDATION - , "Frame buffer attachment with `BGFX_RESOLVE_AUTO_GEN_MIPS` requires a format supporting `BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN`." + , "Frame buffer attachment with `BGFX_ATTACHMENT_AUTO_GEN_MIPS` requires a format supporting `BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN`." , "Attachment %d, format %s, num mips %d, format caps 0x%08x." , ii , getName(TextureFormat::Enum(tr.m_format) ) @@ -6435,8 +6449,8 @@ namespace bgfx , 1 , 0 , !ref.hasMips() || ref.isDepth() - ? BGFX_RESOLVE_NONE - : BGFX_RESOLVE_AUTO_GEN_MIPS + ? BGFX_ATTACHMENT_NONE + : BGFX_ATTACHMENT_AUTO_GEN_MIPS ); } @@ -6588,10 +6602,10 @@ namespace bgfx s_ctx->setViewName(_id, bx::StringView(_name, _len) ); } - void setViewRect(ViewId _id, int16_t _x, int16_t _y, uint16_t _width, uint16_t _height) + void setViewRect(ViewId _id, int16_t _x, int16_t _y, uint16_t _width, uint16_t _height, float _minDepth, float _maxDepth) { BX_ASSERT(checkView(_id), "Invalid view id: %d", _id); - s_ctx->setViewRect(_id, _x, _y, _width, _height); + s_ctx->setViewRect(_id, _x, _y, _width, _height, _minDepth, _maxDepth); } void setViewRect(ViewId _id, int16_t _x, int16_t _y, BackbufferRatio::Enum _ratio) @@ -6610,6 +6624,18 @@ namespace bgfx s_ctx->setViewScissor(_id, _x, _y, _width, _height); } + void setViewDepthBias(ViewId _id, int32_t _constant, float _slopeScale, float _clamp) + { + BX_ASSERT(checkView(_id), "Invalid view id: %d", _id); + s_ctx->setViewDepthBias(_id, _constant, _slopeScale, _clamp); + } + + void setViewSampleMask(ViewId _id, uint32_t _mask) + { + BX_ASSERT(checkView(_id), "Invalid view id: %d", _id); + s_ctx->setViewSampleMask(_id, _mask); + } + void setViewClear(ViewId _id, uint16_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil) { BX_ASSERT(checkView(_id), "Invalid view id: %d", _id); @@ -6687,6 +6713,12 @@ namespace bgfx s_ctx->m_encoder0->setStencil(_fstencil, _bstencil); } + void setSampleMask(uint32_t _mask) + { + BGFX_CHECK_ENCODER0(); + s_ctx->m_encoder0->setSampleMask(_mask); + } + uint16_t setScissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height) { BGFX_CHECK_ENCODER0(); @@ -6699,6 +6731,18 @@ namespace bgfx s_ctx->m_encoder0->setScissor(_cache); } + uint16_t setDepthControl(int32_t _constant, float _slopeScale, float _clamp, bool _depthClamp) + { + BGFX_CHECK_ENCODER0(); + return s_ctx->m_encoder0->setDepthControl(_constant, _slopeScale, _clamp, _depthClamp); + } + + void setDepthControl(uint16_t _cache) + { + BGFX_CHECK_ENCODER0(); + s_ctx->m_encoder0->setDepthControl(_cache); + } + uint32_t setTransform(const void* _mtx, uint16_t _num) { BGFX_CHECK_ENCODER0(); @@ -7164,7 +7208,6 @@ static_assert(FLAGS_MASK_TEST(0 | BGFX_RESET_CAPTURE | BGFX_RESET_FLUSH_AFTER_RENDER | BGFX_RESET_FLIP_AFTER_RENDER - | BGFX_RESET_DEPTH_CLAMP | BGFX_RESET_SUSPEND | BGFX_RESET_RESERVED_MASK ) diff --git a/src/bgfx.idl.inl b/src/bgfx.idl.inl index 6f3fdf5d8..33ae0bc9e 100644 --- a/src/bgfx.idl.inl +++ b/src/bgfx.idl.inl @@ -73,11 +73,11 @@ BGFX_C_API void bgfx_buffer_region_init_buffer(bgfx_buffer_region_t* _this, bgfx This->init(handle.cpp, _offset, _size); } -BGFX_C_API void bgfx_attachment_init(bgfx_attachment_t* _this, bgfx_texture_handle_t _handle, bgfx_access_t _access, uint16_t _layer, uint16_t _numLayers, uint16_t _mip, uint8_t _resolve) +BGFX_C_API void bgfx_attachment_init(bgfx_attachment_t* _this, bgfx_texture_handle_t _handle, bgfx_access_t _access, uint16_t _layer, uint16_t _numLayers, uint16_t _mip, uint8_t _flags) { bgfx::Attachment* This = (bgfx::Attachment*)_this; union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle = { _handle }; - This->init(handle.cpp, (bgfx::Access::Enum)_access, _layer, _numLayers, _mip, _resolve); + This->init(handle.cpp, (bgfx::Access::Enum)_access, _layer, _numLayers, _mip, _flags); } BGFX_C_API bgfx_vertex_layout_t* bgfx_vertex_layout_begin(bgfx_vertex_layout_t* _this, bgfx_renderer_type_t _rendererType) @@ -703,9 +703,9 @@ BGFX_C_API void bgfx_set_view_name(bgfx_view_id_t _id, const char* _name, int32_ bgfx::setViewName((bgfx::ViewId)_id, _name, _len); } -BGFX_C_API void bgfx_set_view_rect(bgfx_view_id_t _id, int16_t _x, int16_t _y, uint16_t _width, uint16_t _height) +BGFX_C_API void bgfx_set_view_rect(bgfx_view_id_t _id, int16_t _x, int16_t _y, uint16_t _width, uint16_t _height, float _minDepth, float _maxDepth) { - bgfx::setViewRect((bgfx::ViewId)_id, _x, _y, _width, _height); + bgfx::setViewRect((bgfx::ViewId)_id, _x, _y, _width, _height, _minDepth, _maxDepth); } BGFX_C_API void bgfx_set_view_rect_ratio(bgfx_view_id_t _id, int16_t _x, int16_t _y, bgfx_backbuffer_ratio_t _ratio) @@ -718,6 +718,16 @@ BGFX_C_API void bgfx_set_view_scissor(bgfx_view_id_t _id, uint16_t _x, uint16_t bgfx::setViewScissor((bgfx::ViewId)_id, _x, _y, _width, _height); } +BGFX_C_API void bgfx_set_view_depth_bias(bgfx_view_id_t _id, int32_t _constant, float _slopeScale, float _clamp) +{ + bgfx::setViewDepthBias((bgfx::ViewId)_id, _constant, _slopeScale, _clamp); +} + +BGFX_C_API void bgfx_set_view_sample_mask(bgfx_view_id_t _id, uint32_t _mask) +{ + bgfx::setViewSampleMask((bgfx::ViewId)_id, _mask); +} + BGFX_C_API void bgfx_set_view_clear(bgfx_view_id_t _id, uint16_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil) { bgfx::setViewClear((bgfx::ViewId)_id, _flags, _rgba, _depth, _stencil); @@ -794,6 +804,12 @@ BGFX_C_API void bgfx_encoder_set_stencil(bgfx_encoder_t* _this, uint32_t _fstenc This->setStencil(_fstencil, _bstencil); } +BGFX_C_API void bgfx_encoder_set_sample_mask(bgfx_encoder_t* _this, uint32_t _mask) +{ + bgfx::Encoder* This = (bgfx::Encoder*)_this; + This->setSampleMask(_mask); +} + BGFX_C_API uint16_t bgfx_encoder_set_scissor(bgfx_encoder_t* _this, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height) { bgfx::Encoder* This = (bgfx::Encoder*)_this; @@ -806,6 +822,18 @@ BGFX_C_API void bgfx_encoder_set_scissor_cached(bgfx_encoder_t* _this, uint16_t This->setScissor(_cache); } +BGFX_C_API uint16_t bgfx_encoder_set_depth_control(bgfx_encoder_t* _this, int32_t _constant, float _slopeScale, float _clamp, bool _depthClamp) +{ + bgfx::Encoder* This = (bgfx::Encoder*)_this; + return This->setDepthControl(_constant, _slopeScale, _clamp, _depthClamp); +} + +BGFX_C_API void bgfx_encoder_set_depth_control_cached(bgfx_encoder_t* _this, uint16_t _cache) +{ + bgfx::Encoder* This = (bgfx::Encoder*)_this; + This->setDepthControl(_cache); +} + BGFX_C_API uint32_t bgfx_encoder_set_transform(bgfx_encoder_t* _this, const void* _mtx, uint16_t _num) { bgfx::Encoder* This = (bgfx::Encoder*)_this; @@ -1131,6 +1159,11 @@ BGFX_C_API void bgfx_set_stencil(uint32_t _fstencil, uint32_t _bstencil) bgfx::setStencil(_fstencil, _bstencil); } +BGFX_C_API void bgfx_set_sample_mask(uint32_t _mask) +{ + bgfx::setSampleMask(_mask); +} + BGFX_C_API uint16_t bgfx_set_scissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height) { return bgfx::setScissor(_x, _y, _width, _height); @@ -1141,6 +1174,16 @@ BGFX_C_API void bgfx_set_scissor_cached(uint16_t _cache) bgfx::setScissor(_cache); } +BGFX_C_API uint16_t bgfx_set_depth_control(int32_t _constant, float _slopeScale, float _clamp, bool _depthClamp) +{ + return bgfx::setDepthControl(_constant, _slopeScale, _clamp, _depthClamp); +} + +BGFX_C_API void bgfx_set_depth_control_cached(uint16_t _cache) +{ + bgfx::setDepthControl(_cache); +} + BGFX_C_API uint32_t bgfx_set_transform(const void* _mtx, uint16_t _num) { return bgfx::setTransform(_mtx, _num); @@ -1528,6 +1571,8 @@ BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version) bgfx_set_view_rect, bgfx_set_view_rect_ratio, bgfx_set_view_scissor, + bgfx_set_view_depth_bias, + bgfx_set_view_sample_mask, bgfx_set_view_clear, bgfx_set_view_clear_mrt, bgfx_set_view_mode, @@ -1542,8 +1587,11 @@ BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version) bgfx_encoder_set_state, bgfx_encoder_set_condition, bgfx_encoder_set_stencil, + bgfx_encoder_set_sample_mask, bgfx_encoder_set_scissor, bgfx_encoder_set_scissor_cached, + bgfx_encoder_set_depth_control, + bgfx_encoder_set_depth_control_cached, bgfx_encoder_set_transform, bgfx_encoder_set_transform_cached, bgfx_encoder_alloc_transform, @@ -1592,8 +1640,11 @@ BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version) bgfx_set_state, bgfx_set_condition, bgfx_set_stencil, + bgfx_set_sample_mask, bgfx_set_scissor, bgfx_set_scissor_cached, + bgfx_set_depth_control, + bgfx_set_depth_control_cached, bgfx_set_transform, bgfx_set_transform_cached, bgfx_alloc_transform, diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 68ad07635..2d6515872 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -295,6 +295,7 @@ namespace bgfx static constexpr uint32_t kDrawCallBlock = BGFX_CONFIG_DRAW_CALL_BLOCK; static constexpr uint32_t kBlitBlock = 64; static constexpr uint32_t kRectBlock = 64; + static constexpr uint32_t kDepthControlBlock = 64; static constexpr uint32_t kViewUsedWords = bx::alignUp(BGFX_CONFIG_MAX_VIEWS, 64); inline uint32_t alignDrawCalls(uint32_t _num) @@ -467,6 +468,48 @@ namespace bgfx return (_magic & BX_MAKEFOURCC(0, 0, 0, 0xff) ) < BX_MAKEFOURCC(0, 0, 0, _version); } + inline bool hasReadOnlyDepth(const Attachment* _attachment, uint8_t _num) + { + for (uint8_t ii = 0; ii < _num; ++ii) + { + if (0 != (_attachment[ii].flags & BGFX_ATTACHMENT_READ_ONLY_DEPTH) ) + { + return true; + } + } + + return false; + } + + inline bool hasReadOnlyStencil(const Attachment* _attachment, uint8_t _num) + { + for (uint8_t ii = 0; ii < _num; ++ii) + { + if (0 != (_attachment[ii].flags & BGFX_ATTACHMENT_READ_ONLY_STENCIL) ) + { + return true; + } + } + + return false; + } + + inline uint64_t getAttachmentStateMask(const Attachment* _attachment, uint8_t _num) + { + return hasReadOnlyDepth(_attachment, _num) + ? ~BGFX_STATE_WRITE_Z + : UINT64_MAX + ; + } + + inline uint64_t getAttachmentStencilMask(const Attachment* _attachment, uint8_t _num) + { + return hasReadOnlyStencil(_attachment, _num) + ? ~(uint64_t(BGFX_STENCIL_FUNC_RMASK_MASK)<<32) + : UINT64_MAX + ; + } + inline void readRawBindings(bx::ReaderI* _reader, uint32_t& _srvMask, uint32_t& _uavMask, bx::Error* _err) { bx::read(_reader, _srvMask, _err); @@ -2551,7 +2594,9 @@ namespace bgfx m_stateFlags = BGFX_STATE_DEFAULT; m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE); m_rgba = 0; + m_sampleMask = UINT32_MAX; m_scissor = UINT16_MAX; + m_depthBias = UINT16_MAX; } if (0 != (_flags & BGFX_DISCARD_TRANSFORM) ) @@ -2614,6 +2659,7 @@ namespace bgfx uint64_t m_stateFlags; uint64_t m_stencil; uint32_t m_rgba; + uint32_t m_sampleMask; uint32_t m_uniformBegin; uint32_t m_uniformEnd; uint32_t m_startMatrix; @@ -2638,6 +2684,7 @@ namespace bgfx IndirectBufferHandle m_indirectBuffer; IndexBufferHandle m_numIndirectBuffer; OcclusionQueryHandle m_occlusionQuery; + uint16_t m_depthBias; // depth-bias cache index (UINT16_MAX = use view) }; BX_ALIGN_DECL_CACHE_LINE(struct) RenderCompute @@ -2955,6 +3002,75 @@ namespace bgfx bool m_window; }; + struct DepthControl + { + int32_t m_constant; + float m_slopeScale; + float m_clamp; + bool m_depthClamp; + }; + + struct DepthControlCache + { + static_assert(BGFX_CONFIG_MAX_DEPTH_BIAS_CACHE <= UINT16_MAX + , "BGFX_CONFIG_MAX_DEPTH_BIAS_CACHE must leave UINT16_MAX free." + ); + + DepthControlCache() + : m_num(0) + , m_max(0) + { + } + + void create(uint32_t _numMax) + { + m_max = _numMax; + m_cache.create(0, _numMax); + } + + void destroy() + { + m_cache.destroy(); + } + + void reset() + { + m_num = 0; + } + + void shrink(uint32_t _numItems) + { + m_cache.shrink(bx::min(m_max, _numItems) ); + } + + uint32_t add(int32_t _constant, float _slopeScale, float _clamp, bool _depthClamp) + { + const uint32_t first = bx::atomicFetchAndAddsat(&m_num, 1, m_max); + + BX_WARN(first < m_max + , "Exceeded number of available depth control values per frame. BGFX_CONFIG_MAX_DEPTH_BIAS_CACHE is %d." + , BGFX_CONFIG_MAX_DEPTH_BIAS_CACHE + ); + + if (first >= m_max) + { + return UINT16_MAX; + } + + DepthControl& db = m_cache[first]; + db.m_constant = _constant; + db.m_slopeScale = _slopeScale; + db.m_clamp = _clamp; + db.m_depthClamp = _depthClamp; + + return first; + } + + FrameArenaT m_cache; + uint32_t m_num; + uint32_t m_max; + }; + BX_ALIGN_DECL_CACHE_LINE(struct) View { void reset() @@ -2966,18 +3082,32 @@ namespace bgfx setShadingRate(ShadingRate::Rate1x1); setFrameBuffer(BGFX_INVALID_HANDLE); setTransform(NULL, NULL); + setDepthBias(0, 0.0f, 0.0f); + setSampleMask(UINT32_MAX); } - void setRect(int16_t _x, int16_t _y, uint16_t _width, uint16_t _height) + void setRect(int16_t _x, int16_t _y, uint16_t _width, uint16_t _height, float _minDepth = 0.0f, float _maxDepth = 1.0f) { m_rect.m_x = _x; m_rect.m_y = _y; m_rect.m_width = bx::max(_width, 1); m_rect.m_height = bx::max(_height, 1); + m_minDepth = _minDepth; + m_maxDepth = _maxDepth; + m_clippedRect = m_rect; + } - // Frame::sort clips this against the render target. Default to - // unclipped, so it's never stale when sort didn't run. - m_clippedRect = m_rect; + void setSampleMask(uint32_t _mask) + { + m_sampleMask = _mask; + } + + void setDepthBias(int32_t _constant, float _slopeScale, float _clamp) + { + m_depthBias.m_constant = _constant; + m_depthBias.m_slopeScale = _slopeScale; + m_depthBias.m_clamp = _clamp; + m_depthBias.m_depthClamp = false; } void setScissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height) @@ -3048,6 +3178,10 @@ namespace bgfx FrameBufferHandle m_fbh; uint8_t m_mode; uint8_t m_shadingRate; + float m_minDepth = 0.0f; + float m_maxDepth = 1.0f; + DepthControl m_depthBias; + uint32_t m_sampleMask; }; struct UniformCacheKey @@ -3208,18 +3342,21 @@ namespace bgfx { m_matrixCache.create(_numReservedMatrices, _numMaxMatrices, _numHwmFrames); m_rectCache.create(BGFX_CONFIG_MAX_RECT_CACHE); + m_depthBiasCache.create(BGFX_CONFIG_MAX_DEPTH_BIAS_CACHE); } void destroy() { m_matrixCache.destroy(); m_rectCache.destroy(); + m_depthBiasCache.destroy(); } void reset() { m_matrixCache.reset(); m_rectCache.reset(); + m_depthBiasCache.reset(); } bool isZeroArea(const Rect& _rect, uint16_t _scissor) const @@ -3236,6 +3373,7 @@ namespace bgfx MatrixCache m_matrixCache; RectCache m_rectCache; + DepthControlCache m_depthBiasCache; }; struct ScreenShot @@ -3256,6 +3394,7 @@ namespace bgfx , m_peak(0) , m_peakBlit(0) , m_peakRect(0) + , m_peakDepthBias(0) , m_observe(0) , m_numPeakFrames(0) , m_waitSubmit(0) @@ -3346,9 +3485,10 @@ namespace bgfx return; } - m_peak = bx::max(m_peak, m_numRenderItemsRequested, m_numRenderBinds); - m_peakBlit = bx::max(m_peakBlit, m_numBlitItems); - m_peakRect = bx::max(m_peakRect, m_frameCache.m_rectCache.m_num); + m_peak = bx::max(m_peak, m_numRenderItemsRequested, m_numRenderBinds); + m_peakBlit = bx::max(m_peakBlit, m_numBlitItems); + m_peakRect = bx::max(m_peakRect, m_frameCache.m_rectCache.m_num); + m_peakDepthBias = bx::max(m_peakDepthBias, m_frameCache.m_depthBiasCache.m_num); if (++m_observe >= m_numPeakFrames) { @@ -3358,6 +3498,7 @@ namespace bgfx m_renderBind.shrink(keep); m_blitItem.shrink(m_peakBlit + 1 + kBlitBlock); m_frameCache.m_rectCache.shrink(m_peakRect + 1 + kRectBlock); + m_frameCache.m_depthBiasCache.shrink(m_peakDepthBias + 1 + kDepthControlBlock); m_cmdPre.shrink(); m_cmdPost.shrink(); @@ -3369,10 +3510,11 @@ namespace bgfx } } - m_peak = 0; - m_peakBlit = 0; - m_peakRect = 0; - m_observe = 0; + m_peak = 0; + m_peakBlit = 0; + m_peakRect = 0; + m_peakDepthBias = 0; + m_observe = 0; } } @@ -3598,6 +3740,7 @@ namespace bgfx uint32_t m_peak; uint32_t m_peakBlit; uint32_t m_peakRect; + uint32_t m_peakDepthBias; uint32_t m_observe; uint32_t m_numPeakFrames; @@ -3909,6 +4052,11 @@ namespace bgfx m_draw.m_stencil = packStencil(_fstencil, _bstencil); } + void setSampleMask(uint32_t _mask) + { + m_draw.m_sampleMask = _mask; + } + uint16_t setScissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height) { uint16_t scissor = bx::narrowCast(m_frame->m_frameCache.m_rectCache.add(_x, _y, _width, _height) ); @@ -3921,6 +4069,18 @@ namespace bgfx m_draw.m_scissor = _cache; } + uint16_t setDepthControl(int32_t _constant, float _slopeScale, float _clamp, bool _depthClamp) + { + uint16_t idx = bx::narrowCast(m_frame->m_frameCache.m_depthBiasCache.add(_constant, _slopeScale, _clamp, _depthClamp) ); + m_draw.m_depthBias = idx; + return idx; + } + + void setDepthControl(uint16_t _cache) + { + m_draw.m_depthBias = _cache; + } + uint32_t setTransform(const void* _mtx, uint16_t _num) { m_draw.m_startMatrix = m_frame->m_frameCache.m_matrixCache.add(_mtx, &_num); @@ -6868,7 +7028,7 @@ namespace bgfx { CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateFrameBuffer); cmdbuf.write(handle); - cmdbuf.write(false); + cmdbuf.write(uint8_t(0) ); // attachment-based cmdbuf.write(_num); const TextureRef& firstTexture = m_textureRef[_attachment[0].handle.idx]; @@ -7029,7 +7189,7 @@ namespace bgfx CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateFrameBuffer); cmdbuf.write(handle); - cmdbuf.write(true); + cmdbuf.write(uint8_t(1) ); // window swap chain writeSwapChain(cmdbuf, fbr); } @@ -7348,9 +7508,9 @@ namespace bgfx cmdbuf.write(_name); } - BGFX_API_FUNC(void setViewRect(ViewId _id, int16_t _x, int16_t _y, uint16_t _width, uint16_t _height) ) + BGFX_API_FUNC(void setViewRect(ViewId _id, int16_t _x, int16_t _y, uint16_t _width, uint16_t _height, float _minDepth = 0.0f, float _maxDepth = 1.0f) ) { - m_view[_id].setRect(_x, _y, _width, _height); + m_view[_id].setRect(_x, _y, _width, _height, _minDepth, _maxDepth); } BGFX_API_FUNC(void setViewScissor(ViewId _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height) ) @@ -7358,6 +7518,16 @@ namespace bgfx m_view[_id].setScissor(_x, _y, _width, _height); } + BGFX_API_FUNC(void setViewDepthBias(ViewId _id, int32_t _constant, float _slopeScale, float _clamp) ) + { + m_view[_id].setDepthBias(_constant, _slopeScale, _clamp); + } + + BGFX_API_FUNC(void setViewSampleMask(ViewId _id, uint32_t _mask) ) + { + m_view[_id].setSampleMask(_mask); + } + BGFX_API_FUNC(void setViewClear(ViewId _id, uint16_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil) ) { BX_ASSERT(bx::isEqual(_depth, bx::clamp(_depth, 0.0f, 1.0f), 0.0001f) diff --git a/src/config.h b/src/config.h index 1f65d7c1c..796afd414 100644 --- a/src/config.h +++ b/src/config.h @@ -359,6 +359,10 @@ # endif // BGFX_CONFIG_DYNAMIC_FRAME_STORAGE #endif // BGFX_CONFIG_MAX_RECT_CACHE +#ifndef BGFX_CONFIG_MAX_DEPTH_BIAS_CACHE +# define BGFX_CONFIG_MAX_DEPTH_BIAS_CACHE (4<<10) +#endif // BGFX_CONFIG_MAX_DEPTH_BIAS_CACHE + /// Number of bits used for depth in the sort key. Default is 32. /// Reducing this allows more bits for other sort key fields. #ifndef BGFX_CONFIG_SORT_KEY_NUM_BITS_DEPTH diff --git a/src/glimports.h b/src/glimports.h index 51254a7c2..0b9154bfc 100644 --- a/src/glimports.h +++ b/src/glimports.h @@ -174,6 +174,8 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC) (G typedef void (GL_APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); typedef void (GL_APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label); typedef void (GL_APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units); +typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETCLAMPPROC) (GLfloat factor, GLfloat units, GLfloat clamp); typedef void (GL_APIENTRYP PFNGLPOINTSIZEPROC) (GLfloat size); typedef void (GL_APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode); typedef void (GL_APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void); @@ -387,6 +389,8 @@ GL_IMPORT______(true, PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC, glMultiDrawEl GL_IMPORT______(true, PFNGLOBJECTLABELPROC, glObjectLabel); GL_IMPORT______(true, PFNGLOBJECTPTRLABELPROC, glObjectPtrLabel); GL_IMPORT______(false, PFNGLPIXELSTOREIPROC, glPixelStorei); +GL_IMPORT______(false, PFNGLPOLYGONOFFSETPROC, glPolygonOffset); +GL_IMPORT______(true, PFNGLPOLYGONOFFSETCLAMPPROC, glPolygonOffsetClamp); GL_IMPORT______(true, PFNGLPOPDEBUGGROUPPROC, glPopDebugGroup); GL_IMPORT______(true, PFNGLPROGRAMBINARYPROC, glProgramBinary); GL_IMPORT______(true, PFNGLPROGRAMPARAMETERIPROC, glProgramParameteri); @@ -513,10 +517,15 @@ GL_IMPORT______(true, PFNGLCLEARBUFFERUIVPROC, glClearBuffer GL_IMPORT______(true, PFNGLVERTEXATTRIBIPOINTERPROC, glVertexAttribIPointer); GL_IMPORT______(true, PFNGLGETINTERNALFORMATIVPROC, glGetInternalformativ); GL_IMPORT______(true, PFNGLGETINTERNALFORMATI64VPROC, glGetInternalformati64v); +GL_IMPORT______(true, PFNGLPOLYGONOFFSETCLAMPPROC, glPolygonOffsetClamp); +GL_IMPORT______(true, PFNGLSAMPLEMASKIPROC, glSampleMaski); #endif // BGFX_USE_GL_DYNAMIC_LIB GL_IMPORT______(true, PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC, glGetTranslatedShaderSourceANGLE); GL_IMPORT______(true, PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC, glFramebufferTexture2DMultisampleEXT); +GL_IMPORT______(true, PFNGLPOLYGONMODEPROC, glPolygonModeANGLE); +GL_IMPORT______(true, PFNGLPOLYGONMODEPROC, glPolygonModeNV); +GL_IMPORT______(true, PFNGLPOLYGONOFFSETCLAMPPROC, glPolygonOffsetClampEXT); #if !BGFX_CONFIG_RENDERER_OPENGL GL_IMPORT______(true, PFNGLPOINTSIZEPROC, glPointSize); diff --git a/src/renderer.h b/src/renderer.h index 020e282ad..d07e7700a 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -148,6 +148,10 @@ namespace bgfx float frect[4]; frect[0] = 1.0f/float(m_rect.m_width); frect[1] = 1.0f/float(m_rect.m_height); + // .zw = the view's viewport depth range [minDepth, maxDepth], for + // shaders that clamp a written depth (WebGPU @builtin(frag_depth)). + frect[2] = _frame->m_view[_view].m_minDepth; + frect[3] = _frame->m_view[_view].m_maxDepth; _renderer->setShaderUniform4f(flags , predefined.m_loc diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 300cf2676..eec2bfa8d 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -765,7 +765,6 @@ namespace bgfx { namespace d3d11 , m_swapEffect(DXGI_SWAP_EFFECT_DISCARD) , m_swapBufferCount(0) , m_maxAnisotropy(1) - , m_depthClamp(false) , m_wireframe(false) , m_currentProgram(NULL) , m_vsChanges(0) @@ -2505,14 +2504,6 @@ namespace bgfx { namespace d3d11 m_samplerStateCache.invalidate(); } - bool depthClamp = !!(_reset & BGFX_RESET_DEPTH_CLAMP); - - if (m_depthClamp != depthClamp) - { - m_depthClamp = depthClamp; - m_rasterizerStateCache.invalidate(); - } - if (_reset & BGFX_RESET_VSYNC) m_reset |= BGFX_RESET_VSYNC; else @@ -2520,7 +2511,6 @@ namespace bgfx { namespace d3d11 const uint32_t maskFlags = ~(0 | BGFX_RESET_MAXANISOTROPY - | BGFX_RESET_DEPTH_CLAMP | BGFX_RESET_SUSPEND | BGFX_RESET_VSYNC ); @@ -2835,7 +2825,7 @@ namespace bgfx { namespace d3d11 setInputLayout(BX_COUNTOF(layouts), layouts, _program, _numInstanceData); } - void setBlendState(uint64_t _state, uint32_t _rgba = 0) + void setBlendState(uint64_t _state, uint32_t _rgba = 0, uint32_t _sampleMask = UINT32_MAX) { _state &= BGFX_D3D11_BLEND_STATE_MASK; @@ -2948,7 +2938,7 @@ namespace bgfx { namespace d3d11 blendFactor[3] = ( (_rgba )&0xff)/255.0f; } - m_deviceCtx->OMSetBlendState(bs, blendFactor, 0xffffffff); + m_deviceCtx->OMSetBlendState(bs, blendFactor, _sampleMask); } void setDepthStencilState(uint64_t _state, uint64_t _stencil = 0) @@ -3012,7 +3002,7 @@ namespace bgfx { namespace d3d11 } } - void setRasterizerState(uint64_t _state, bool _wireframe = false, bool _scissor = false) + void setRasterizerState(uint64_t _state, bool _wireframe = false, bool _scissor = false, int32_t _depthBias = 0, float _slopeScale = 0.0f, float _clamp = 0.0f, bool _depthClamp = false) { _state &= 0 | BGFX_STATE_CULL_MASK @@ -3025,7 +3015,22 @@ namespace bgfx { namespace d3d11 _state |= _scissor ? BGFX_STATE_RESERVED_MASK : 0; _state &= ~(m_deviceInterfaceVersion >= 3 ? 0 : BGFX_STATE_CONSERVATIVE_RASTER); - ID3D11RasterizerState* rs = m_rasterizerStateCache.find(_state); + const bool depthClamp = _depthClamp && m_featureLevel > D3D_FEATURE_LEVEL_9_3; + + uint64_t key = _state; + if (0 != _depthBias || 0.0f != _slopeScale || 0.0f != _clamp || depthClamp) + { + bx::HashMurmur2A murmur; + murmur.begin(); + murmur.add(_state); + murmur.add(_depthBias); + murmur.add(_slopeScale); + murmur.add(_clamp); + murmur.add(depthClamp); + key = (uint64_t(murmur.end() )<<32) | UINT32_MAX; // low 32 bits set: never a raw _state value + } + + ID3D11RasterizerState* rs = m_rasterizerStateCache.find(key); if (NULL == rs) { uint32_t cull = (_state&BGFX_STATE_CULL_MASK)>>BGFX_STATE_CULL_SHIFT; @@ -3037,10 +3042,10 @@ namespace bgfx { namespace d3d11 desc.FillMode = _wireframe ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID; desc.CullMode = s_cullMode[cull]; desc.FrontCounterClockwise = !!(_state&BGFX_STATE_FRONT_CCW); - desc.DepthBias = 0; - desc.DepthBiasClamp = 0.0f; - desc.SlopeScaledDepthBias = 0.0f; - desc.DepthClipEnable = !m_depthClamp; + desc.DepthBias = _depthBias; + desc.DepthBiasClamp = _clamp; + desc.SlopeScaledDepthBias = _slopeScale; + desc.DepthClipEnable = !depthClamp; desc.ScissorEnable = _scissor; desc.MultisampleEnable = !!(_state&BGFX_STATE_MSAA); desc.AntialiasedLineEnable = !!(_state&BGFX_STATE_LINEAA); @@ -3060,10 +3065,10 @@ namespace bgfx { namespace d3d11 desc.FillMode = _wireframe ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID; desc.CullMode = s_cullMode[cull]; desc.FrontCounterClockwise = false; - desc.DepthBias = 0; - desc.DepthBiasClamp = 0.0f; - desc.SlopeScaledDepthBias = 0.0f; - desc.DepthClipEnable = !m_depthClamp; + desc.DepthBias = _depthBias; + desc.DepthBiasClamp = _clamp; + desc.SlopeScaledDepthBias = _slopeScale; + desc.DepthClipEnable = !depthClamp; desc.ScissorEnable = _scissor; desc.MultisampleEnable = !!(_state&BGFX_STATE_MSAA); desc.AntialiasedLineEnable = !!(_state&BGFX_STATE_LINEAA); @@ -3804,7 +3809,6 @@ namespace bgfx { namespace d3d11 DXGI_SWAP_EFFECT m_swapEffect; uint32_t m_swapBufferCount; uint32_t m_maxAnisotropy; - bool m_depthClamp; bool m_wireframe; IndexBufferD3D11 m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS]; @@ -5342,7 +5346,7 @@ namespace bgfx { namespace d3d11 } const bool renderTarget = 0 != (m_flags & BGFX_TEXTURE_RT_MASK); - const bool autoGenMips = 0 != (_resolve & BGFX_RESOLVE_AUTO_GEN_MIPS); + const bool autoGenMips = 0 != (_resolve & BGFX_ATTACHMENT_AUTO_GEN_MIPS); if (autoGenMips && renderTarget @@ -5708,7 +5712,10 @@ namespace bgfx { namespace d3d11 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; dsvDesc.Format = s_textureFormat[texture.m_textureFormat].m_fmtDsv; - dsvDesc.Flags = 0; + dsvDesc.Flags = 0 + | ( (at.flags & BGFX_ATTACHMENT_READ_ONLY_DEPTH) ? D3D11_DSV_READ_ONLY_DEPTH : 0) + | ( (at.flags & BGFX_ATTACHMENT_READ_ONLY_STENCIL) ? D3D11_DSV_READ_ONLY_STENCIL : 0) + ; switch (texture.m_type) { @@ -5886,7 +5893,7 @@ namespace bgfx { namespace d3d11 if (isValid(at.handle) ) { const TextureD3D11& texture = s_renderD3D11->m_textures[at.handle.idx]; - texture.resolve(at.resolve, at.layer, at.numLayers, at.mip); + texture.resolve(at.flags, at.layer, at.numLayers, at.mip); } } } @@ -6406,7 +6413,7 @@ namespace bgfx { namespace d3d11 && !srcReadsMsaaRt && 0 == blit.m_srcMip) { - src.resolve(BGFX_RESOLVE_NONE, blit.m_srcZ, 1, 0); + src.resolve(BGFX_ATTACHMENT_NONE, blit.m_srcZ, 1, 0); } if ( src.isMsaaSurface() @@ -6582,8 +6589,9 @@ namespace bgfx { namespace d3d11 PrimInfo prim = s_primInfo[primIndex]; deviceCtx->IASetPrimitiveTopology(prim.m_type); - bool wasCompute = false; + bool wasCompute = false; bool viewHasScissor = false; + uint64_t stateMask = UINT64_MAX; Rect viewScissorRect; viewScissorRect.clear(); @@ -6655,6 +6663,11 @@ namespace bgfx { namespace d3d11 { fbh = _render->m_view[view].m_fbh; setFrameBuffer(fbh); + + stateMask = isValid(fbh) + ? getAttachmentStateMask(m_frameBuffers[fbh.idx].m_attachment, m_frameBuffers[fbh.idx].m_numTh) + : UINT64_MAX + ; } viewState.m_rect = _render->m_view[view].m_rect; @@ -6669,8 +6682,8 @@ namespace bgfx { namespace d3d11 vp.TopLeftY = viewState.m_rect.m_y; vp.Width = viewState.m_rect.m_width; vp.Height = viewState.m_rect.m_height; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; + vp.MinDepth = _render->m_view[view].m_minDepth; + vp.MaxDepth = _render->m_view[view].m_maxDepth; deviceCtx->RSSetViewports(1, &vp); Clear& clr = _render->m_view[view].m_clear; @@ -6892,9 +6905,11 @@ namespace bgfx { namespace d3d11 } } - const uint64_t newFlags = draw.m_stateFlags; - uint64_t changedFlags = currentState.m_stateFlags ^ draw.m_stateFlags; + const uint64_t newFlags = draw.m_stateFlags & stateMask; + const uint32_t sampleMask = _render->m_view[view].m_sampleMask & draw.m_sampleMask; + uint64_t changedFlags = currentState.m_stateFlags ^ newFlags; changedFlags |= currentState.m_rgba != draw.m_rgba ? BGFX_D3D11_BLEND_STATE_MASK : 0; + changedFlags |= currentState.m_sampleMask != sampleMask ? BGFX_D3D11_BLEND_STATE_MASK : 0; currentState.m_stateFlags = newFlags; const uint64_t newStencil = draw.m_stencil; @@ -6915,7 +6930,7 @@ namespace bgfx { namespace d3d11 currentBind.clear(); - setBlendState(newFlags, draw.m_rgba); + setBlendState(newFlags, draw.m_rgba, sampleMask); setDepthStencilState(newFlags, packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE) ); const uint64_t pt = newFlags&BGFX_STATE_PT_MASK; @@ -6928,6 +6943,15 @@ namespace bgfx { namespace d3d11 deviceCtx->IASetPrimitiveTopology(prim.m_type); } + // Depth bias: per-draw override (cache index) or the view's default. + // Resolved after resetState so currentState.clear() doesn't stomp the + // tracked index. + const DepthControl& depthBias = (UINT16_MAX != draw.m_depthBias) + ? _render->m_frameCache.m_depthBiasCache.m_cache[draw.m_depthBias] + : _render->m_view[view].m_depthBias; + const bool depthBiasChanged = currentState.m_depthBias != draw.m_depthBias; + currentState.m_depthBias = draw.m_depthBias; + uint16_t scissor = draw.m_scissor; if (currentState.m_scissor != scissor) { @@ -6960,7 +6984,7 @@ namespace bgfx { namespace d3d11 deviceCtx->RSSetScissorRects(1, &rc); } - setRasterizerState(newFlags, wireframe, scissorEnabled); + setRasterizerState(newFlags, wireframe, scissorEnabled, depthBias.m_constant, depthBias.m_slopeScale, depthBias.m_clamp, depthBias.m_depthClamp); } if (BGFX_D3D11_DEPTH_STENCIL_MASK & changedFlags) @@ -6970,11 +6994,12 @@ namespace bgfx { namespace d3d11 if (BGFX_D3D11_BLEND_STATE_MASK & changedFlags) { - setBlendState(newFlags, draw.m_rgba); + setBlendState(newFlags, draw.m_rgba, sampleMask); currentState.m_rgba = draw.m_rgba; + currentState.m_sampleMask = sampleMask; } - if ( (0 + if ( ( (0 | BGFX_STATE_CULL_MASK | BGFX_STATE_FRONT_CCW | BGFX_STATE_ALPHA_REF_MASK @@ -6983,17 +7008,17 @@ namespace bgfx { namespace d3d11 | BGFX_STATE_MSAA | BGFX_STATE_LINEAA | BGFX_STATE_CONSERVATIVE_RASTER - ) & changedFlags) + ) & changedFlags) || depthBiasChanged) { - if ( (0 + if ( ( (0 | BGFX_STATE_CULL_MASK | BGFX_STATE_FRONT_CCW | BGFX_STATE_MSAA | BGFX_STATE_LINEAA | BGFX_STATE_CONSERVATIVE_RASTER - ) & changedFlags) + ) & changedFlags) || depthBiasChanged) { - setRasterizerState(newFlags, wireframe, scissorEnabled); + setRasterizerState(newFlags, wireframe, scissorEnabled, depthBias.m_constant, depthBias.m_slopeScale, depthBias.m_clamp, depthBias.m_depthClamp); } if (BGFX_STATE_ALPHA_REF_MASK & changedFlags) diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 0868301cf..764656d8f 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -830,7 +830,6 @@ namespace bgfx { namespace d3d12 , m_wireframe(false) , m_lost(false) , m_maxAnisotropy(1) - , m_depthClamp(false) , m_lastPso(NULL) , m_backBufferColorIdx(0) , m_rtMsaa(false) @@ -3172,15 +3171,6 @@ namespace bgfx { namespace d3d12 m_maxAnisotropy = 1; } - bool depthClamp = !!(_reset & BGFX_RESET_DEPTH_CLAMP); - - if (m_depthClamp != depthClamp) - { - m_depthClamp = depthClamp; - m_pipelineStateCache.invalidate(); - m_lastPso = NULL; - } - if (_reset & BGFX_RESET_VSYNC) m_reset |= BGFX_RESET_VSYNC; else @@ -3188,7 +3178,6 @@ namespace bgfx { namespace d3d12 const uint32_t maskFlags = ~(0 | BGFX_RESET_MAXANISOTROPY - | BGFX_RESET_DEPTH_CLAMP | BGFX_RESET_SUSPEND | BGFX_RESET_VSYNC ); @@ -3476,7 +3465,12 @@ namespace bgfx { namespace d3d12 if (isValid(frameBuffer.m_depth) ) { TextureD3D12& texture = m_textures[frameBuffer.m_depth.idx]; - texture.setState(m_commandList, D3D12_RESOURCE_STATE_DEPTH_WRITE); + + texture.setState(m_commandList + , hasReadOnlyDepth(frameBuffer.m_attachment, frameBuffer.m_numTh) + ? D3D12_RESOURCE_STATE_DEPTH_READ|D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE + : D3D12_RESOURCE_STATE_DEPTH_WRITE + ); } } @@ -3564,7 +3558,7 @@ namespace bgfx { namespace d3d12 } } - void setRasterizerState(D3D12_RASTERIZER_DESC& _desc, uint64_t _state, bool _wireframe = false) + void setRasterizerState(D3D12_RASTERIZER_DESC& _desc, uint64_t _state, bool _wireframe = false, bool _depthClamp = false, int32_t _depthBias = 0, float _slopeScale = 0.0f, float _clamp = 0.0f) { const uint32_t cull = (_state&BGFX_STATE_CULL_MASK) >> BGFX_STATE_CULL_SHIFT; @@ -3574,10 +3568,10 @@ namespace bgfx { namespace d3d12 ; _desc.CullMode = s_cullMode[cull]; _desc.FrontCounterClockwise = !!(_state&BGFX_STATE_FRONT_CCW);; - _desc.DepthBias = 0; - _desc.DepthBiasClamp = 0.0f; - _desc.SlopeScaledDepthBias = 0.0f; - _desc.DepthClipEnable = !m_depthClamp; + _desc.DepthBias = _depthBias; + _desc.DepthBiasClamp = _clamp; + _desc.SlopeScaledDepthBias = _slopeScale; + _desc.DepthClipEnable = !_depthClamp; _desc.MultisampleEnable = !!(_state&BGFX_STATE_MSAA); _desc.AntialiasedLineEnable = !!(_state&BGFX_STATE_LINEAA); _desc.ForcedSampleCount = 0; @@ -3783,6 +3777,11 @@ namespace bgfx { namespace d3d12 , ProgramHandle _program , uint8_t _numInstanceData , bool _index32 = false + , bool _depthClamp = false + , int32_t _depthBias = 0 + , float _slopeScale = 0.0f + , float _biasClamp = 0.0f + , uint32_t _sampleMask = UINT32_MAX ) { ProgramD3D12& program = m_program[_program.idx]; @@ -3815,10 +3814,15 @@ namespace bgfx { namespace d3d12 && m_lastPsoState.state == _state && m_lastPsoState.stencil == _stencil && m_lastPsoState.rgba == rgba + && m_lastPsoState.sampleMask == _sampleMask && m_lastPsoState.program == _program.idx && m_lastPsoState.numStreams == _numStreams && m_lastPsoState.numInstanceData == _numInstanceData && m_lastPsoState.fbh == m_fbh.idx + && m_lastPsoState.depthClamp == _depthClamp + && m_lastPsoState.depthBias == _depthBias + && m_lastPsoState.slopeScale == _slopeScale + && m_lastPsoState.biasClamp == _biasClamp ) { bool match = true; @@ -3836,10 +3840,15 @@ namespace bgfx { namespace d3d12 m_lastPsoState.state = _state; m_lastPsoState.stencil = _stencil; m_lastPsoState.rgba = rgba; + m_lastPsoState.sampleMask = _sampleMask; m_lastPsoState.program = _program.idx; m_lastPsoState.numStreams = _numStreams; m_lastPsoState.numInstanceData = _numInstanceData; m_lastPsoState.fbh = m_fbh.idx; + m_lastPsoState.depthClamp = _depthClamp; + m_lastPsoState.depthBias = _depthBias; + m_lastPsoState.slopeScale = _slopeScale; + m_lastPsoState.biasClamp = _biasClamp; for (uint32_t ii = 0; ii < _numStreams; ++ii) { @@ -3865,6 +3874,7 @@ namespace bgfx { namespace d3d12 murmur.add(_state); murmur.add(rgba); murmur.add(_index32); + murmur.add(_sampleMask); murmur.add(_stencil); murmur.add(program.m_vsh->m_hash); murmur.add(program.m_vsh->m_attrMask, sizeof(program.m_vsh->m_attrMask) ); @@ -3923,6 +3933,10 @@ namespace bgfx { namespace d3d12 } murmur.add(_numInstanceData); + murmur.add(_depthClamp); + murmur.add(_depthBias); + murmur.add(_slopeScale); + murmur.add(_biasClamp); const uint32_t hash = murmur.end(); ID3D12PipelineState* pso = m_pipelineStateCache.find(hash); @@ -3970,8 +3984,8 @@ namespace bgfx { namespace d3d12 desc.StreamOutput.RasterizedStream = 0; setBlendState(desc.BlendState, _state, _rgba); - desc.SampleMask = UINT32_MAX; - setRasterizerState(desc.RasterizerState, _state); + desc.SampleMask = _sampleMask; + setRasterizerState(desc.RasterizerState, _state, false, _depthClamp, _depthBias, _slopeScale, _biasClamp); setDepthStencilState(desc.DepthStencilState, _state, _stencil); D3D12_INPUT_ELEMENT_DESC vertexElements[Attrib::Count + 1 + BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT]; @@ -4435,7 +4449,6 @@ namespace bgfx { namespace d3d12 DxgiSwapChainDesc m_scd; uint32_t m_maxAnisotropy; - bool m_depthClamp; BufferD3D12 m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS]; VertexBufferD3D12 m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS]; @@ -4455,10 +4468,15 @@ namespace bgfx { namespace d3d12 uint64_t state; uint64_t stencil; uint32_t rgba; + uint32_t sampleMask; uint16_t program; uint16_t fbh; uint8_t numStreams; uint8_t numInstanceData; + bool depthClamp; + int32_t depthBias; + float slopeScale; + float biasClamp; const VertexLayout* layouts[BGFX_CONFIG_MAX_VERTEX_STREAMS]; }; @@ -7221,7 +7239,7 @@ namespace bgfx { namespace d3d12 } const bool renderTarget = 0 != (m_flags & BGFX_TEXTURE_RT_MASK); - const bool autoGenMips = 0 != (_resolve & BGFX_RESOLVE_AUTO_GEN_MIPS); + const bool autoGenMips = 0 != (_resolve & BGFX_ATTACHMENT_AUTO_GEN_MIPS); if (autoGenMips && renderTarget @@ -7926,14 +7944,13 @@ namespace bgfx { namespace d3d12 dsvDescriptor.ptr += fbhIdx * dsvDescriptorSize; const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(texture.m_textureFormat) ); - BX_UNUSED(blockInfo); D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc; bx::memSet(&dsvDesc, 0, sizeof(dsvDesc) ); dsvDesc.Format = s_textureFormat[texture.m_textureFormat].m_fmtDsv; dsvDesc.Flags = D3D12_DSV_FLAG_NONE -// | (blockInfo.depthBits > 0 ? D3D12_DSV_FLAG_READ_ONLY_DEPTH : D3D12_DSV_FLAG_NONE) -// | (blockInfo.stencilBits > 0 ? D3D12_DSV_FLAG_READ_ONLY_STENCIL : D3D12_DSV_FLAG_NONE) + | ( (at.flags & BGFX_ATTACHMENT_READ_ONLY_DEPTH) && blockInfo.depthBits > 0 ? D3D12_DSV_FLAG_READ_ONLY_DEPTH : D3D12_DSV_FLAG_NONE) + | ( (at.flags & BGFX_ATTACHMENT_READ_ONLY_STENCIL) && blockInfo.stencilBits > 0 ? D3D12_DSV_FLAG_READ_ONLY_STENCIL : D3D12_DSV_FLAG_NONE) ; switch (texture.m_type) @@ -8089,7 +8106,7 @@ namespace bgfx { namespace d3d12 if (isValid(at.handle) ) { TextureD3D12& texture = s_renderD3D12->m_textures[at.handle.idx]; - texture.resolve(s_renderD3D12->m_commandList, at.resolve, at.layer, at.numLayers, at.mip); + texture.resolve(s_renderD3D12->m_commandList, at.flags, at.layer, at.numLayers, at.mip); } } } @@ -8874,7 +8891,7 @@ namespace bgfx { namespace d3d12 && !dst.isMultisampled() && 0 == blit.m_srcMip) { - src.resolve(m_commandList, BGFX_RESOLVE_NONE, blit.m_srcZ, 1, 0); + src.resolve(m_commandList, BGFX_ATTACHMENT_NONE, blit.m_srcZ, 1, 0); } if (D3D12_RESOURCE_STATES(UINT32_MAX) != srcState) @@ -9165,9 +9182,10 @@ namespace bgfx { namespace d3d12 uint8_t primIndex = uint8_t(primType >> BGFX_STATE_PT_SHIFT); PrimInfo prim = s_primInfo[primIndex]; - bool wasCompute = false; + bool wasCompute = false; bool viewHasScissor = false; bool restoreScissor = false; + uint64_t stateMask = UINT64_MAX; Rect viewScissorRect; viewScissorRect.clear(); @@ -9306,6 +9324,11 @@ namespace bgfx { namespace d3d12 fbh = _render->m_view[view].m_fbh; setFrameBuffer(fbh); + stateMask = isValid(fbh) + ? getAttachmentStateMask(m_frameBuffers[fbh.idx].m_attachment, m_frameBuffers[fbh.idx].m_numTh) + : UINT64_MAX + ; + viewState.m_rect = renderView.m_rect; const Rect& rect = renderView.m_rect; const Rect& clippedRect = renderView.m_clippedRect; @@ -9318,8 +9341,8 @@ namespace bgfx { namespace d3d12 vp.TopLeftY = rect.m_y; vp.Width = rect.m_width; vp.Height = rect.m_height; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; + vp.MinDepth = renderView.m_minDepth; + vp.MaxDepth = renderView.m_maxDepth; m_commandList->RSSetViewports(1, &vp); D3D12_RECT rc; @@ -9680,8 +9703,9 @@ namespace bgfx { namespace d3d12 if (0 != draw.m_streamMask) { - const uint64_t newFlags = draw.m_stateFlags; - uint64_t changedFlags = currentState.m_stateFlags ^ draw.m_stateFlags; + const uint64_t newFlags = draw.m_stateFlags & stateMask; + const uint32_t sampleMask = _render->m_view[view].m_sampleMask & draw.m_sampleMask; + uint64_t changedFlags = currentState.m_stateFlags ^ newFlags; currentState.m_stateFlags = newFlags; if (0 != (BGFX_STATE_PT_MASK & changedFlags) ) @@ -9773,6 +9797,14 @@ namespace bgfx { namespace d3d12 } } + const DepthControl& depthControl = (UINT16_MAX != draw.m_depthBias) + ? _render->m_frameCache.m_depthBiasCache.m_cache[draw.m_depthBias] + : _render->m_view[view].m_depthBias + ; + const bool depthClamp = depthControl.m_depthClamp; + + + ID3D12PipelineState* pso = getPipelineState( state , draw.m_rgba @@ -9782,6 +9814,11 @@ namespace bgfx { namespace d3d12 , key.m_program , uint8_t(draw.m_instanceDataStride/16) , isValid(draw.m_indexBuffer) && !draw.isIndex16() + , depthClamp + , depthControl.m_constant + , depthControl.m_slopeScale + , depthControl.m_clamp + , sampleMask ); if (currentBindIdx != bindIdx diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 7607b1793..48d6aba9c 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -622,6 +622,7 @@ namespace bgfx { namespace gl ANGLE_framebuffer_blit, ANGLE_framebuffer_multisample, ANGLE_instanced_arrays, + ANGLE_polygon_mode, ANGLE_texture_compression_dxt1, ANGLE_texture_compression_dxt3, ANGLE_texture_compression_dxt5, @@ -658,6 +659,7 @@ namespace bgfx { namespace gl ARB_multisample, ARB_occlusion_query, ARB_occlusion_query2, + ARB_polygon_offset_clamp, ARB_program_interface_query, ARB_provoking_vertex, ARB_sampler_objects, @@ -717,6 +719,7 @@ namespace bgfx { namespace gl EXT_multi_draw_indirect, EXT_occlusion_query_boolean, EXT_packed_float, + EXT_polygon_offset_clamp, EXT_read_format_bgra, EXT_shader_image_load_store, EXT_shader_texture_lod, @@ -767,6 +770,7 @@ namespace bgfx { namespace gl NV_draw_instanced, NV_instanced_arrays, NV_occlusion_query, + NV_polygon_mode, NV_read_depth, NV_read_depth_stencil, NV_read_stencil, @@ -851,6 +855,7 @@ namespace bgfx { namespace gl { "ANGLE_framebuffer_blit", false, true }, { "ANGLE_framebuffer_multisample", false, false }, { "ANGLE_instanced_arrays", false, true }, + { "ANGLE_polygon_mode", false, true }, { "ANGLE_texture_compression_dxt1", false, true }, { "ANGLE_texture_compression_dxt3", false, true }, { "ANGLE_texture_compression_dxt5", false, true }, @@ -887,6 +892,7 @@ namespace bgfx { namespace gl { "ARB_multisample", BGFX_CONFIG_RENDERER_OPENGLES >= 20, true }, { "ARB_occlusion_query", BGFX_CONFIG_RENDERER_OPENGL >= 33, true }, { "ARB_occlusion_query2", BGFX_CONFIG_RENDERER_OPENGL >= 33, true }, + { "ARB_polygon_offset_clamp", BGFX_CONFIG_RENDERER_OPENGL >= 46, true }, { "ARB_program_interface_query", BGFX_CONFIG_RENDERER_OPENGL >= 43, true }, { "ARB_provoking_vertex", BGFX_CONFIG_RENDERER_OPENGL >= 32, true }, { "ARB_sampler_objects", BGFX_CONFIG_RENDERER_OPENGL >= 33, true }, @@ -946,6 +952,7 @@ namespace bgfx { namespace gl { "EXT_multi_draw_indirect", false, true }, // GLES3.1 extension. { "EXT_occlusion_query_boolean", false, true }, // GLES extension. { "EXT_packed_float", BGFX_CONFIG_RENDERER_OPENGL >= 33, true }, + { "EXT_polygon_offset_clamp", false, true }, { "EXT_read_format_bgra", false, true }, { "EXT_shader_image_load_store", false, true }, { "EXT_shader_texture_lod", false, true }, // GLES extension. @@ -996,6 +1003,7 @@ namespace bgfx { namespace gl { "NV_draw_instanced", false, true }, // GLES extension. { "NV_instanced_arrays", false, true }, // GLES extension. { "NV_occlusion_query", false, true }, + { "NV_polygon_mode", false, true }, // GLES extension. { "NV_read_depth", false, true }, // GLES extension. { "NV_read_depth_stencil", false, true }, // GLES extension. { "NV_read_stencil", false, true }, // GLES extension. @@ -2768,12 +2776,35 @@ namespace bgfx { namespace gl : 0 ; + if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES) ) + { + glPolygonMode = s_extension[Extension::NV_polygon_mode].m_supported + ? glPolygonModeNV + : s_extension[Extension::ANGLE_polygon_mode].m_supported + ? glPolygonModeANGLE + : NULL + ; + } + if (BX_ENABLED(BX_PLATFORM_EMSCRIPTEN) || NULL == glPolygonMode) { glPolygonMode = stubPolygonMode; } + glPolygonOffsetClamp = s_extension[Extension::ARB_polygon_offset_clamp].m_supported + ? glPolygonOffsetClamp + : s_extension[Extension::EXT_polygon_offset_clamp].m_supported + ? glPolygonOffsetClampEXT + : NULL + ; + + if (!BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES >= 31) + && !s_extension[Extension::ARB_texture_multisample].m_supported) + { + glSampleMaski = NULL; + } + if (s_extension[Extension::ARB_copy_image].m_supported || s_extension[Extension::EXT_copy_image].m_supported || s_extension[Extension:: NV_copy_image].m_supported @@ -3951,21 +3982,8 @@ namespace bgfx { namespace gl invalidateCache(); } - if (s_extension[Extension::ARB_depth_clamp].m_supported) - { - if (!!(_reset & BGFX_RESET_DEPTH_CLAMP) ) - { - GL_CHECK(glEnable(GL_DEPTH_CLAMP) ); - } - else - { - GL_CHECK(glDisable(GL_DEPTH_CLAMP) ); - } - } - const uint32_t maskFlags = ~(0 | BGFX_RESET_MAXANISOTROPY - | BGFX_RESET_DEPTH_CLAMP | BGFX_RESET_SUSPEND ); @@ -6816,7 +6834,7 @@ namespace bgfx { namespace gl const bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK); if (renderTarget && 1 < m_numMips - && 0 != (_resolve & BGFX_RESOLVE_AUTO_GEN_MIPS) ) + && 0 != (_resolve & BGFX_ATTACHMENT_AUTO_GEN_MIPS) ) { GL_CHECK(glBindTexture(m_target, m_id) ); GL_CHECK(glGenerateMipmap(m_target) ); @@ -7748,7 +7766,7 @@ namespace bgfx { namespace gl if (isValid(at.handle) ) { const TextureGL& texture = s_renderGL->m_textures[at.handle.idx]; - texture.resolve(at.resolve); + texture.resolve(at.flags); } } } @@ -8471,12 +8489,17 @@ namespace bgfx { namespace gl SortKey key; uint16_t view = UINT16_MAX; FrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS }; + bool currentDepthClamp = false; // GL default: depth clipping on (WebGPU unclippedDepth = false). + int32_t currentPolygonOffsetConstant = 0; + float currentPolygonOffsetSlope = 0.0f; + float currentPolygonOffsetClamp = 0.0f; UniformCacheState ucs(_render); BlitState bs(_render); int32_t resolutionHeight = _render->m_mainSwapChain.height; uint32_t blendFactor = 0; + uint32_t currentSampleMask = UINT32_MAX; uint8_t primIndex; { @@ -8497,13 +8520,15 @@ namespace bgfx { namespace gl : GL_FILL ) ); - bool wasCompute = false; + bool wasCompute = false; bool viewHasScissor = false; + bool ndcFlipRectY = true; Rect viewScissorRect; viewScissorRect.clear(); uint16_t discardFlags = BGFX_CLEAR_NONE; - uint64_t ndcFrontCcw = 0; - bool ndcFlipRectY = true; + uint64_t ndcFrontCcw = 0; + uint64_t stateMask = UINT64_MAX; + uint64_t stencilMask = UINT64_MAX; const bool blendIndependentSupported = 0 != (g_caps.supported & BGFX_CAPS_BLEND_INDEPENDENT); const bool computeSupported = false @@ -8574,6 +8599,16 @@ namespace bgfx { namespace gl fbh = _render->m_view[view].m_fbh; resolutionHeight = _render->m_mainSwapChain.height; resolutionHeight = setFrameBuffer(fbh, resolutionHeight, discardFlags); + + stateMask = isValid(fbh) + ? getAttachmentStateMask(m_frameBuffers[fbh.idx].m_attachment, m_frameBuffers[fbh.idx].m_numTh) + : UINT64_MAX + ; + + stencilMask = isValid(fbh) + ? getAttachmentStencilMask(m_frameBuffers[fbh.idx].m_attachment, m_frameBuffers[fbh.idx].m_numTh) + : UINT64_MAX + ; } setViewType(view, " "); @@ -8817,13 +8852,14 @@ namespace bgfx { namespace gl } } - const uint64_t newFlags = draw.m_stateFlags ^ ndcFrontCcw; - uint64_t changedFlags = currentState.m_stateFlags ^ newFlags; + const uint64_t newFlags = (draw.m_stateFlags & stateMask) ^ ndcFrontCcw; + const uint32_t sampleMask = _render->m_view[view].m_sampleMask & draw.m_sampleMask; + uint64_t changedFlags = currentState.m_stateFlags ^ newFlags; currentState.m_stateFlags = newFlags; - const uint64_t newStencil = draw.m_stencil; - uint64_t changedStencil = currentState.m_stencil ^ draw.m_stencil; - currentState.m_stencil = newStencil; + const uint64_t newStencil = draw.m_stencil & stencilMask; + uint64_t changedStencil = currentState.m_stencil ^ newStencil; + currentState.m_stencil = newStencil; if (resetState) { @@ -8920,6 +8956,77 @@ namespace bgfx { namespace gl } } + if (s_extension[Extension::ARB_depth_clamp].m_supported) + { + const bool depthClamp = (UINT16_MAX != draw.m_depthBias) + ? _render->m_frameCache.m_depthBiasCache.m_cache[draw.m_depthBias].m_depthClamp + : _render->m_view[view].m_depthBias.m_depthClamp + ; + if (currentDepthClamp != depthClamp) + { + currentDepthClamp = depthClamp; + if (depthClamp) + { + GL_CHECK(glEnable(GL_DEPTH_CLAMP) ); + } + else + { + GL_CHECK(glDisable(GL_DEPTH_CLAMP) ); + } + } + } + + { + const DepthControl& depthControl = (UINT16_MAX != draw.m_depthBias) + ? _render->m_frameCache.m_depthBiasCache.m_cache[draw.m_depthBias] + : _render->m_view[view].m_depthBias + ; + + if (currentPolygonOffsetConstant != depthControl.m_constant + || currentPolygonOffsetSlope != depthControl.m_slopeScale + || currentPolygonOffsetClamp != depthControl.m_clamp) + { + currentPolygonOffsetConstant = depthControl.m_constant; + currentPolygonOffsetSlope = depthControl.m_slopeScale; + currentPolygonOffsetClamp = depthControl.m_clamp; + + if (0 == currentPolygonOffsetConstant + && 0.0f == currentPolygonOffsetSlope) + { + GL_CHECK(glDisable(GL_POLYGON_OFFSET_FILL) ); + } + else + { + if (NULL != glPolygonOffsetClamp) + { + GL_CHECK(glPolygonOffsetClamp(currentPolygonOffsetSlope, float(currentPolygonOffsetConstant), currentPolygonOffsetClamp) ); + } + else + { + GL_CHECK(glPolygonOffset(currentPolygonOffsetSlope, float(currentPolygonOffsetConstant) ) ); + } + + GL_CHECK(glEnable(GL_POLYGON_OFFSET_FILL) ); + } + } + } + + if (currentSampleMask != sampleMask + && NULL != glSampleMaski) + { + currentSampleMask = sampleMask; + + if (UINT32_MAX == currentSampleMask) + { + GL_CHECK(glDisable(GL_SAMPLE_MASK) ); + } + else + { + GL_CHECK(glEnable(GL_SAMPLE_MASK) ); + GL_CHECK(glSampleMaski(0, currentSampleMask) ); + } + } + if ( ( (0 | BGFX_STATE_ALPHA_REF_MASK | BGFX_STATE_BLEND_ALPHA_TO_COVERAGE diff --git a/src/renderer_gl.h b/src/renderer_gl.h index 02380e4d5..4aafe7849 100644 --- a/src/renderer_gl.h +++ b/src/renderer_gl.h @@ -1042,6 +1042,10 @@ typedef double GLdouble; # define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E #endif // GL_SAMPLE_ALPHA_TO_COVERAGE +#ifndef GL_SAMPLE_MASK +# define GL_SAMPLE_MASK 0x8E51 +#endif // GL_SAMPLE_MASK + #ifndef GL_CONSERVATIVE_RASTERIZATION_NV # define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346 #endif // GL_CONSERVATIVE_RASTERIZATION_NV diff --git a/src/renderer_mtl.cpp b/src/renderer_mtl.cpp index 5e0724c87..7fedd1be3 100644 --- a/src/renderer_mtl.cpp +++ b/src/renderer_mtl.cpp @@ -877,7 +877,6 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames , m_supportsDepthClipMode(false) , m_borderColorSupport(false) , m_colorPalette(NULL) - , m_depthClamp(false) , m_screenshotBlitRenderPipelineState(NULL) , m_commandBuffer(NULL) , m_blitCommandEncoder(NULL) @@ -1985,11 +1984,6 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames m_renderCommandEncoderFbh = fbh; MTL_RELEASE(renderPassDescriptor, 0); - if (m_depthClamp) - { - rce->setDepthClipMode(MTL::DepthClipModeClamp); - } - { MTL::Viewport viewport = { 0.0f, 0.0f, (float)width, (float)height, 0.0f, 1.0f }; rce->setViewport(viewport); @@ -2119,12 +2113,8 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames ; } - m_depthClamp = m_supportsDepthClipMode - && !!(_reset & BGFX_RESET_DEPTH_CLAMP); - uint32_t maskFlags = ~(0 | BGFX_RESET_MAXANISOTROPY - | BGFX_RESET_DEPTH_CLAMP | BGFX_RESET_SUSPEND ); @@ -2296,11 +2286,6 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames setRenderCommandEncoder(m_commandBuffer->renderCommandEncoder(renderPassDescriptor) ); MTL_RELEASE(renderPassDescriptor, 0); - - if (m_depthClamp) - { - m_renderCommandEncoder->setDepthClipMode(MTL::DepthClipModeClamp); - } } } @@ -2998,6 +2983,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames , const VertexLayout** _layouts , ProgramHandle _program , uint8_t _numInstanceData + , uint32_t _sampleMask = UINT32_MAX ) { _state &= (0 @@ -3020,7 +3006,8 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames && m_lastPsoState.m_program == _program.idx && m_lastPsoState.m_fbh == _fbh.idx && m_lastPsoState.m_numStreams == _numStreams - && m_lastPsoState.m_numInstanceData == _numInstanceData) + && m_lastPsoState.m_numInstanceData == _numInstanceData + && m_lastPsoState.m_sampleMask == _sampleMask) { bool match = true; for (uint8_t ii = 0; ii < _numStreams && match; ++ii) @@ -3040,6 +3027,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames m_lastPsoState.m_fbh = _fbh.idx; m_lastPsoState.m_numStreams = _numStreams; m_lastPsoState.m_numInstanceData = _numInstanceData; + m_lastPsoState.m_sampleMask = _sampleMask; for (uint8_t ii = 0; ii < _numStreams; ++ii) { m_lastPsoState.m_layouts[ii] = _layouts[ii]; @@ -3052,6 +3040,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames murmur.add(_state); murmur.add(rgba); murmur.add(_numInstanceData); + murmur.add(_sampleMask); if (!isValid(_fbh) ) { @@ -3219,7 +3208,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames pd->setVertexFunction(program.m_vsh->m_function); pd->setFragmentFunction(program.m_fsh != NULL - ? program.m_fsh->m_function + ? program.m_fsh->getFunction(_sampleMask) : NULL ); @@ -3613,11 +3602,6 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames setRenderCommandEncoder(m_commandBuffer->renderCommandEncoder(renderPassDescriptor) ); MTL_RELEASE(renderPassDescriptor, 0); - - if (m_depthClamp) - { - m_renderCommandEncoder->setDepthClipMode(MTL::DepthClipModeClamp); - } } return m_renderCommandEncoder; @@ -3696,6 +3680,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames const VertexLayout* m_layouts[BGFX_CONFIG_MAX_VERTEX_STREAMS]; uint64_t m_state; uint32_t m_rgba; + uint32_t m_sampleMask; uint16_t m_program; uint16_t m_fbh; uint8_t m_numStreams; @@ -3724,7 +3709,6 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames bool m_borderColorSupport; const float (*m_colorPalette)[4]; - bool m_depthClamp; MTL::RenderPipelineDescriptor* m_renderPipelineDescriptor; MTL::DepthStencilDescriptor* m_depthStencilDescriptor; @@ -3907,12 +3891,11 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames const char* code = (const char*)reader.getDataPtr(); bx::skip(&reader, shaderSize+1); - MTL::Library* lib = newLibraryWithSource(s_renderMtl->m_device, code); + m_lib = newLibraryWithSource(s_renderMtl->m_device, code); - if (NULL != lib) + if (NULL != m_lib) { - m_function = lib->newFunction(nsstr(SHADER_FUNCTION_NAME) ); - MTL_RELEASE_W(lib, 0); + m_function = getFunction(UINT32_MAX); } BGFX_FATAL(NULL != m_function @@ -3929,6 +3912,41 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames m_hash = murmur.end(); } + MTL::Function* ShaderMtl::getFunction(uint32_t _sampleMask) const + { + if (NULL == m_lib) + { + return m_function; + } + + FunctionMap::const_iterator it = m_functions.find(_sampleMask); + + if (it != m_functions.end() ) + { + return it->second; + } + + MTL::FunctionConstantValues* constantValues = MTL::FunctionConstantValues::alloc()->init(); + + if (UINT32_MAX != _sampleMask) + { + constantValues->setConstantValue(&_sampleMask, MTL::DataTypeUInt, NS::UInteger(0) ); + } + + NS::Error* error = NULL; + MTL::Function* function = m_lib->newFunction(nsstr(SHADER_FUNCTION_NAME), constantValues, &error); + MTL_RELEASE_W(constantValues, 0); + + if (NULL == function) + { + return m_function; + } + + m_functions[_sampleMask] = function; + + return function; + } + void ProgramMtl::create(const ShaderMtl* _vsh, const ShaderMtl* _fsh) { BX_ASSERT(NULL != _vsh->m_function, "Vertex shader doesn't exist."); @@ -5254,7 +5272,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames { for (uint32_t ii = 0; ii < m_num; ++ii) { - if (0 != (m_colorAttachment[ii].resolve & BGFX_RESOLVE_AUTO_GEN_MIPS) ) + if (0 != (m_colorAttachment[ii].flags & BGFX_ATTACHMENT_AUTO_GEN_MIPS) ) { const TextureMtl& texture = s_renderMtl->m_textures[m_colorHandle[ii].idx]; const bool isRenderTarget = !!(texture.m_flags & BGFX_TEXTURE_RT_MASK); @@ -6049,6 +6067,9 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames Rect viewScissorRect; viewScissorRect.clear(); + uint64_t stateMask = UINT64_MAX; + uint64_t stencilMask = UINT64_MAX; + uint32_t statsNumPrimsSubmitted[BX_COUNTOF(s_primInfo)] = {}; uint32_t statsNumPrimsRendered[BX_COUNTOF(s_primInfo)] = {}; uint32_t statsNumInstances[BX_COUNTOF(s_primInfo)] = {}; @@ -6167,6 +6188,16 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames fbh = _render->m_view[view].m_fbh; + stateMask = isValid(fbh) + ? getAttachmentStateMask(&m_frameBuffers[fbh.idx].m_depthAttachment, 1) + : UINT64_MAX + ; + + stencilMask = isValid(fbh) + ? getAttachmentStencilMask(&m_frameBuffers[fbh.idx].m_depthAttachment, 1) + : UINT64_MAX + ; + clearWithRenderPass = true && 0 == viewRect.m_x && 0 == viewRect.m_y @@ -6301,11 +6332,6 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames m_renderCommandEncoderFbh = fbh; MTL_RELEASE(renderPassDescriptor, 0); - - if (m_depthClamp) - { - rce->setDepthClipMode(MTL::DepthClipModeClamp); - } } else if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) ) { @@ -6538,13 +6564,13 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames } } - const uint64_t newFlags = draw.m_stateFlags; - uint64_t changedFlags = currentState.m_stateFlags ^ draw.m_stateFlags; + const uint64_t newFlags = draw.m_stateFlags & stateMask; + uint64_t changedFlags = currentState.m_stateFlags ^ newFlags; currentState.m_stateFlags = newFlags; - const uint64_t newStencil = draw.m_stencil; - uint64_t changedStencil = currentState.m_stencil ^ draw.m_stencil; - currentState.m_stencil = newStencil; + const uint64_t newStencil = draw.m_stencil & stencilMask; + uint64_t changedStencil = currentState.m_stencil ^ newStencil; + currentState.m_stencil = newStencil; if (resetState) { @@ -6606,6 +6632,20 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames setDepthStencilState(newFlags, newStencil); } + { + const DepthControl& depthControl = (UINT16_MAX != draw.m_depthBias) + ? _render->m_frameCache.m_depthBiasCache.m_cache[draw.m_depthBias] + : _render->m_view[view].m_depthBias + ; + + if (m_supportsDepthClipMode) + { + rce->setDepthClipMode(depthControl.m_depthClamp ? MTL::DepthClipModeClamp : MTL::DepthClipModeClip); + } + + rce->setDepthBias(float(depthControl.m_constant), depthControl.m_slopeScale, depthControl.m_clamp); + } + if ( (0 | BGFX_STATE_CULL_MASK | BGFX_STATE_FRONT_CCW @@ -6660,8 +6700,11 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames bool vertexStreamChanged = hasVertexStreamChanged(currentState, draw); + const uint32_t sampleMask = _render->m_view[view].m_sampleMask & draw.m_sampleMask; + if (key.m_program.idx != currentProgram.idx || vertexStreamChanged + || currentState.m_sampleMask != sampleMask || (0 | BGFX_STATE_BLEND_MASK | BGFX_STATE_BLEND_EQUATION_MASK @@ -6676,6 +6719,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames { currentProgram = key.m_program; + currentState.m_sampleMask = sampleMask; currentState.m_streamMask = draw.m_streamMask; currentState.m_instanceDataBuffer.idx = draw.m_instanceDataBuffer.idx; currentState.m_instanceDataOffset = draw.m_instanceDataOffset; @@ -6737,6 +6781,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames , layouts , currentProgram , draw.m_instanceDataStride/16 + , sampleMask ); } @@ -7229,11 +7274,6 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames MTL_RELEASE(renderPassDescriptor, 0); - if (m_depthClamp) - { - rce->setDepthClipMode(MTL::DepthClipModeClamp); - } - rce->setCullMode( (MTL::CullMode)MTL::CullModeNone); rce->setRenderPipelineState(m_screenshotBlitRenderPipelineState); diff --git a/src/renderer_mtl.h b/src/renderer_mtl.h index cb2c7bd46..873e3735d 100644 --- a/src/renderer_mtl.h +++ b/src/renderer_mtl.h @@ -295,18 +295,33 @@ namespace bgfx { namespace mtl struct ShaderMtl { ShaderMtl() - : m_function(NULL) + : m_lib(NULL) + , m_function(NULL) { } void create(const Memory* _mem); + MTL::Function* getFunction(uint32_t _sampleMask) const; + void destroy() { - MTL_RELEASE_W(m_function, 0); + for (FunctionMap::iterator it = m_functions.begin(), itEnd = m_functions.end(); it != itEnd; ++it) + { + MTL_RELEASE_W(it->second, 0); + } + + m_functions.clear(); + m_function = NULL; + + MTL_RELEASE_W(m_lib, 0); } + typedef stl::unordered_map FunctionMap; + + MTL::Library* m_lib; MTL::Function* m_function; + mutable FunctionMap m_functions; uint32_t m_hash; uint16_t m_numThreads[3]; }; diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index 534c4e90a..20dd85f65 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -1124,6 +1124,12 @@ VK_IMPORT_DEVICE srcStageMask = depthStageMask | sampledStageMask; break; + case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: + srcStageMask = depthStageMask | sampledStageMask; + srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + break; + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: srcStageMask = sampledStageMask; break; @@ -1154,27 +1160,60 @@ VK_IMPORT_DEVICE { case VK_IMAGE_LAYOUT_GENERAL: dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; - dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT; + dstAccessMask = 0 + | VK_ACCESS_MEMORY_READ_BIT + | VK_ACCESS_MEMORY_WRITE_BIT + ; break; case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + dstAccessMask = 0 + | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT + | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT + ; break; case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: dstStageMask = depthStageMask; - dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + dstAccessMask = 0 + | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT + | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT + ; break; case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: - dstStageMask = depthStageMask | sampledStageMask; - dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; + dstStageMask = 0 + | depthStageMask + | sampledStageMask + ; + dstAccessMask = 0 + | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT + | VK_ACCESS_SHADER_READ_BIT + | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT + ; + break; + + case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: + dstStageMask = 0 + | depthStageMask + | sampledStageMask + ; + dstAccessMask = 0 + | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT + | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT + | VK_ACCESS_SHADER_READ_BIT + | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT + ; break; case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: dstStageMask = sampledStageMask; - dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; + dstAccessMask = 0 + | VK_ACCESS_SHADER_READ_BIT + | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT + ; break; case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: @@ -1237,7 +1276,6 @@ VK_IMPORT_DEVICE , m_renderDocDll(NULL) , m_vulkan1Dll(NULL) , m_maxAnisotropy(1.0f) - , m_depthClamp(false) , m_wireframe(false) , m_captureBuffer(VK_NULL_HANDLE) , m_captureMemory() @@ -1424,7 +1462,14 @@ VK_IMPORT } } - vulkanApiVersionSelector = bx::max(vulkanApiVersionSelector, VK_API_VERSION_1_0); + if (VK_API_VERSION_1_1 > vulkanApiVersionSelector) + { + BX_TRACE("Init error: Vulkan 1.1 or newer is required, instance reports %d.%d." + , VK_API_VERSION_MAJOR(vulkanApiVersionSelector) + , VK_API_VERSION_MINOR(vulkanApiVersionSelector) + ); + goto error; + } VkApplicationInfo appInfo; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; @@ -1590,7 +1635,11 @@ VK_IMPORT_INSTANCE g_caps.gpu[ii].deviceId = uint16_t(pdp.deviceID); ++g_caps.numGPUs; - if ( (BGFX_PCI_ID_NONE != g_caps.vendorId || 0 != g_caps.deviceId) + if (VK_API_VERSION_1_1 > pdp.apiVersion) + { + BX_TRACE("\tSkipped: Vulkan 1.1 or newer is required."); + } + else if ( (BGFX_PCI_ID_NONE != g_caps.vendorId || 0 != g_caps.deviceId) && (BGFX_PCI_ID_NONE == g_caps.vendorId || pdp.vendorID == g_caps.vendorId) && ( 0 == g_caps.deviceId || pdp.deviceID == g_caps.deviceId) ) { @@ -3193,14 +3242,6 @@ VK_IMPORT_DEVICE m_samplerBorderColorCache.invalidate(); } - bool depthClamp = m_deviceFeatures.depthClamp && !!(_reset & BGFX_RESET_DEPTH_CLAMP); - - if (m_depthClamp != depthClamp) - { - m_depthClamp = depthClamp; - m_pipelineStateCache.invalidate(); - } - if (!m_backBuffer.isSwapChain() ) { if (m_mainSwapChain.width != _swapChain.width @@ -3222,7 +3263,6 @@ VK_IMPORT_DEVICE uint32_t maskFlags = ~(0 | BGFX_RESET_SUSPEND | BGFX_RESET_MAXANISOTROPY - | BGFX_RESET_DEPTH_CLAMP ); if (m_swapchainMaintenance1Supported @@ -3507,14 +3547,14 @@ VK_IMPORT_DEVICE _desc.blendConstants[3] = 0.0f; } - void setRasterizerState(VkPipelineRasterizationStateCreateInfo& _desc, uint64_t _state, bool _wireframe = false) + void setRasterizerState(VkPipelineRasterizationStateCreateInfo& _desc, uint64_t _state, bool _wireframe = false, bool _depthClamp = false, int32_t _depthBias = 0, float _slopeScale = 0.0f, float _clamp = 0.0f) { const uint32_t cull = (_state&BGFX_STATE_CULL_MASK) >> BGFX_STATE_CULL_SHIFT; _desc.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; _desc.pNext = NULL; _desc.flags = 0; - _desc.depthClampEnable = m_deviceFeatures.depthClamp && m_depthClamp; + _desc.depthClampEnable = m_deviceFeatures.depthClamp && _depthClamp; _desc.rasterizerDiscardEnable = VK_FALSE; _desc.polygonMode = m_deviceFeatures.fillModeNonSolid && _wireframe ? VK_POLYGON_MODE_LINE @@ -3522,10 +3562,12 @@ VK_IMPORT_DEVICE ; _desc.cullMode = s_cullMode[cull]; _desc.frontFace = (_state&BGFX_STATE_FRONT_CCW) ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE; - _desc.depthBiasEnable = VK_FALSE; - _desc.depthBiasConstantFactor = 0.0f; - _desc.depthBiasClamp = 0.0f; - _desc.depthBiasSlopeFactor = 0.0f; + // WebGPU/D3D-style integer depth bias maps directly onto Vulkan's constant + // factor (both are scaled by the implementation's minimum resolvable depth). + _desc.depthBiasEnable = (0 != _depthBias || 0.0f != _slopeScale || 0.0f != _clamp) ? VK_TRUE : VK_FALSE; + _desc.depthBiasConstantFactor = float(_depthBias); + _desc.depthBiasClamp = _clamp; + _desc.depthBiasSlopeFactor = _slopeScale; _desc.lineWidth = 1.0f; } @@ -3645,7 +3687,7 @@ VK_IMPORT_DEVICE } } - VkResult getRenderPass(uint8_t _num, const VkFormat* _formats, const VkImageAspectFlags* _aspects, const bool* _resolve, VkSampleCountFlagBits _samples, uint16_t _clearFlags, ::VkRenderPass* _outRenderPass, uint32_t* _outHashKey) + VkResult getRenderPass(uint8_t _num, const VkFormat* _formats, const VkImageAspectFlags* _aspects, const bool* _resolve, VkSampleCountFlagBits _samples, uint16_t _clearFlags, uint8_t _depthFlags, ::VkRenderPass* _outRenderPass, uint32_t* _outHashKey) { VkResult result = VK_SUCCESS; @@ -3659,6 +3701,7 @@ VK_IMPORT_DEVICE hash.add(_samples); hash.add(_formats, sizeof(VkFormat) * _num); hash.add(_clearFlags); + hash.add(_depthFlags); if (NULL != _resolve) { hash.add(_resolve, sizeof(bool) * _num); @@ -3740,14 +3783,33 @@ VK_IMPORT_DEVICE } else if (_aspects[ii] & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) ) { + const bool hasDepthAspect = 0 != (_aspects[ii] & VK_IMAGE_ASPECT_DEPTH_BIT); + const bool hasStencilAspect = 0 != (_aspects[ii] & VK_IMAGE_ASPECT_STENCIL_BIT); + + const bool readOnlyDepth = hasDepthAspect && 0 != (_depthFlags & BGFX_ATTACHMENT_READ_ONLY_DEPTH); + const bool readOnlyStencil = hasStencilAspect && 0 != (_depthFlags & BGFX_ATTACHMENT_READ_ONLY_STENCIL); + + const bool allReadOnly = (!hasDepthAspect || readOnlyDepth) + && (!hasStencilAspect || readOnlyStencil) + ; + + const VkImageLayout layout = allReadOnly + ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL + : readOnlyDepth + ? VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL + : readOnlyStencil + ? VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL + : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL + ; + ad[ii].loadOp = 0 != (_clearFlags & BGFX_CLEAR_DEPTH) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD; ad[ii].storeOp = 0 != (_clearFlags & BGFX_CLEAR_DISCARD_DEPTH) ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE; ad[ii].stencilLoadOp = 0 != (_clearFlags & BGFX_CLEAR_STENCIL) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD; ad[ii].stencilStoreOp = 0 != (_clearFlags & BGFX_CLEAR_DISCARD_STENCIL) ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE; - ad[ii].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - ad[ii].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + ad[ii].initialLayout = layout; + ad[ii].finalLayout = layout; - depthAr.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + depthAr.layout = layout; depthAr.attachment = ii; } } @@ -3828,6 +3890,7 @@ VK_IMPORT_DEVICE VkFormat formats[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; VkImageAspectFlags aspects[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT; + uint8_t depthFlags = 0; for (uint8_t ii = 0; ii < _num; ++ii) { @@ -3835,9 +3898,14 @@ VK_IMPORT_DEVICE formats[ii] = texture.m_format; aspects[ii] = texture.m_aspectFlags; samples = texture.m_sampler.Sample; + + if (0 != (texture.m_aspectFlags & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) ) ) + { + depthFlags = _attachments[ii].flags; + } } - return getRenderPass(_num, formats, aspects, NULL, samples, _clearFlags, _outRenderPass, _outHashKey); + return getRenderPass(_num, formats, aspects, NULL, samples, _clearFlags, depthFlags, _outRenderPass, _outHashKey); } VkResult getRenderPass(const SwapChainVK& swapChain, uint16_t _clearFlags, ::VkRenderPass* _outRenderPass, uint32_t* _outHashKey = NULL) @@ -3867,7 +3935,7 @@ VK_IMPORT_DEVICE : 1 ; - return getRenderPass(num, formats, aspects, resolve, samples, _clearFlags, _outRenderPass, _outHashKey); + return getRenderPass(num, formats, aspects, resolve, samples, _clearFlags, 0, _outRenderPass, _outHashKey); } VkSampler getSampler(uint32_t _flags, VkFormat _format, const float _palette[][4]) @@ -4058,7 +4126,7 @@ VK_IMPORT_DEVICE return pipeline; } - VkPipeline getPipeline(uint64_t _state, uint32_t _rgba, uint64_t _stencil, uint8_t _numStreams, const VertexLayout** _layouts, ProgramHandle _program, uint8_t _numInstanceData) + VkPipeline getPipeline(uint64_t _state, uint32_t _rgba, uint64_t _stencil, uint8_t _numStreams, const VertexLayout** _layouts, ProgramHandle _program, uint8_t _numInstanceData, bool _depthClamp = false, int32_t _depthBias = 0, float _slopeScale = 0.0f, float _biasClamp = 0.0f, uint32_t _sampleMask = UINT32_MAX) { ProgramVK& program = m_program[_program.idx]; @@ -4099,6 +4167,7 @@ VK_IMPORT_DEVICE murmur.begin(); murmur.add(_state); murmur.add(!!(BGFX_STATE_BLEND_INDEPENDENT & _state) ? _rgba : 0); + murmur.add(_sampleMask); murmur.add(_stencil); murmur.add(program.m_vsh->m_hash); murmur.add(program.m_vsh->m_attrMask, sizeof(program.m_vsh->m_attrMask) ); @@ -4115,6 +4184,10 @@ VK_IMPORT_DEVICE murmur.add(layout.m_attributes, sizeof(layout.m_attributes) ); murmur.add(_numInstanceData); + murmur.add(_depthClamp); + murmur.add(_depthBias); + murmur.add(_slopeScale); + murmur.add(_biasClamp); murmur.add(frameBuffer.m_renderPassHashKey); const uint32_t hash = murmur.end(); @@ -4144,7 +4217,7 @@ VK_IMPORT_DEVICE ; VkPipelineRasterizationStateCreateInfo rasterizationState; - setRasterizerState(rasterizationState, _state, m_wireframe); + setRasterizerState(rasterizationState, _state, m_wireframe, _depthClamp, _depthBias, _slopeScale, _biasClamp); VkBaseInStructure* nextRasterizationState = (VkBaseInStructure*)&rasterizationState; @@ -4231,7 +4304,8 @@ VK_IMPORT_DEVICE multisampleState.rasterizationSamples = frameBuffer.m_sampler.Sample; multisampleState.sampleShadingEnable = VK_FALSE; multisampleState.minSampleShading = 0.0f; - multisampleState.pSampleMask = NULL; + const VkSampleMask sampleMask = _sampleMask; + multisampleState.pSampleMask = UINT32_MAX == _sampleMask ? NULL : &sampleMask; multisampleState.alphaToCoverageEnable = !!(BGFX_STATE_BLEND_ALPHA_TO_COVERAGE & _state); multisampleState.alphaToOneEnable = VK_FALSE; @@ -5148,7 +5222,6 @@ VK_IMPORT_DEVICE SwapChain m_mainSwapChain; uint32_t m_reset; float m_maxAnisotropy; - bool m_depthClamp; bool m_wireframe; VkBuffer m_captureBuffer; @@ -7441,7 +7514,7 @@ VK_DESTROY && 0 != (m_flags & BGFX_TEXTURE_RT_MASK) && 0 == (m_flags & BGFX_TEXTURE_RT_WRITE_ONLY) && (_mip + 1) < m_numMips - && 0 != (_resolve & BGFX_RESOLVE_AUTO_GEN_MIPS) + && 0 != (_resolve & BGFX_ATTACHMENT_AUTO_GEN_MIPS) ; const VkImageLayout oldLayout = m_currentImageLayout; @@ -7489,7 +7562,7 @@ VK_DESTROY ); const bool autoGenMips = true - && 0 != (_resolve & BGFX_RESOLVE_AUTO_GEN_MIPS) + && 0 != (_resolve & BGFX_ATTACHMENT_AUTO_GEN_MIPS) && 0 == (m_flags & BGFX_TEXTURE_RT_WRITE_ONLY) && (_mip + 1) < m_numMips ; @@ -9208,7 +9281,7 @@ VK_DESTROY if (isValid(at.handle) ) { TextureVK& texture = s_renderVK->m_textures[at.handle.idx]; - texture.resolve(s_renderVK->m_commandBuffer, at.resolve, at.layer, at.numLayers, at.mip); + texture.resolve(s_renderVK->m_commandBuffer, at.flags, at.layer, at.numLayers, at.mip); } } } @@ -9698,7 +9771,7 @@ VK_DESTROY if (blitReadsSingleMsaa(src, dst) && 0 == blit.m_srcMip) { - src.resolve(m_commandBuffer, BGFX_RESOLVE_NONE, blit.m_srcZ, 1, 0); + src.resolve(m_commandBuffer, BGFX_ATTACHMENT_NONE, blit.m_srcZ, 1, 0); } srcLayouts[item] = blitReadsSingleMsaa(src, dst) @@ -10061,6 +10134,8 @@ VK_DESTROY currentState.clear(); currentState.m_stateFlags = BGFX_STATE_NONE; currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE); + uint64_t stateMask = UINT64_MAX; + uint64_t stencilMask = UINT64_MAX; static ViewState viewState; viewState.reset(_render); @@ -10082,8 +10157,10 @@ VK_DESTROY uint64_t state; uint64_t stencil; uint32_t rgba; + uint32_t sampleMask; uint16_t program; uint16_t fbh; + DepthControl depthControl; uint8_t numStreams; uint8_t numInstanceData; bool valid; @@ -10199,6 +10276,16 @@ VK_DESTROY fbh = _render->m_view[view].m_fbh; setFrameBuffer(fbh); + + stateMask = isValid(fbh) + ? getAttachmentStateMask(m_frameBuffers[fbh.idx].m_attachment, m_frameBuffers[fbh.idx].m_numTh) + : UINT64_MAX + ; + + stencilMask = isValid(fbh) + ? getAttachmentStencilMask(m_frameBuffers[fbh.idx].m_attachment, m_frameBuffers[fbh.idx].m_numTh) + : UINT64_MAX + ; } } @@ -10279,8 +10366,8 @@ VK_DESTROY vp.y = float(rect.m_y + rect.m_height); vp.width = float(rect.m_width); vp.height = -float(rect.m_height); - vp.minDepth = 0.0f; - vp.maxDepth = 1.0f; + vp.minDepth = _render->m_view[view].m_minDepth; + vp.maxDepth = _render->m_view[view].m_maxDepth; vkCmdSetViewport(m_commandBuffer, 0, 1, &vp); VkRect2D rc; @@ -10586,8 +10673,11 @@ VK_DESTROY } } - const uint64_t changedFlags = currentState.m_stateFlags ^ draw.m_stateFlags; - currentState.m_stateFlags = draw.m_stateFlags; + const uint64_t state = draw.m_stateFlags & stateMask; + const uint32_t sampleMask = _render->m_view[view].m_sampleMask & draw.m_sampleMask; + const uint64_t stencil = draw.m_stencil & stencilMask; + const uint64_t changedFlags = currentState.m_stateFlags ^ state; + currentState.m_stateFlags = state; if (0 != draw.m_streamMask) { @@ -10662,38 +10752,54 @@ VK_DESTROY VkPipeline pipeline; + const DepthControl& depthControl = (UINT16_MAX != draw.m_depthBias) + ? _render->m_frameCache.m_depthBiasCache.m_cache[draw.m_depthBias] + : _render->m_view[view].m_depthBias + ; + if (pipelineState.valid - && pipelineState.state == draw.m_stateFlags + && pipelineState.state == state && pipelineState.rgba == draw.m_rgba - && pipelineState.stencil == draw.m_stencil + && pipelineState.sampleMask == sampleMask + && pipelineState.stencil == stencil && pipelineState.program == key.m_program.idx && pipelineState.fbh == m_fbh.idx && pipelineState.numStreams == numStreams && pipelineState.numInstanceData == numInstanceData + && 0 == bx::memCmp(&pipelineState.depthControl, &depthControl, sizeof(depthControl) ) && 0 == bx::memCmp(pipelineState.layouts, layouts, numStreams*sizeof(layouts[0]) ) ) { pipeline = pipelineState.pipeline; } else { - pipeline = getPipeline(draw.m_stateFlags + const bool depthClamp = depthControl.m_depthClamp; + + pipeline = getPipeline(state , draw.m_rgba - , draw.m_stencil + , stencil , numStreams , layouts , key.m_program , numInstanceData + , depthClamp + , depthControl.m_constant + , depthControl.m_slopeScale + , depthControl.m_clamp + , sampleMask ); bx::memCopy(pipelineState.layouts, layouts, numStreams*sizeof(layouts[0]) ); pipelineState.pipeline = pipeline; - pipelineState.state = draw.m_stateFlags; - pipelineState.stencil = draw.m_stencil; + pipelineState.state = state; + pipelineState.stencil = stencil; pipelineState.rgba = draw.m_rgba; + pipelineState.sampleMask = sampleMask; pipelineState.program = key.m_program.idx; pipelineState.fbh = m_fbh.idx; pipelineState.numStreams = numStreams; pipelineState.numInstanceData = numInstanceData; + pipelineState.depthControl = depthControl; pipelineState.valid = true; } @@ -10703,19 +10809,19 @@ VK_DESTROY vkCmdBindPipeline(m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); } - const bool hasStencil = stencilEnabled(draw.m_stencil); + const bool hasStencil = stencilEnabled(stencil); if (hasStencil - && currentState.m_stencil != draw.m_stencil) + && currentState.m_stencil != stencil) { - currentState.m_stencil = draw.m_stencil; + currentState.m_stencil = stencil; - const uint32_t fstencil = unpackStencil(0, draw.m_stencil); + const uint32_t fstencil = unpackStencil(0, stencil); const uint32_t ref = (fstencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT; const uint32_t rmask = (fstencil&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT; vkCmdSetStencilReference(m_commandBuffer, VK_STENCIL_FRONT_AND_BACK, ref); vkCmdSetStencilCompareMask(m_commandBuffer, VK_STENCIL_FRONT_AND_BACK, rmask); - vkCmdSetStencilWriteMask(m_commandBuffer, VK_STENCIL_FRONT_AND_BACK, unpackStencilWriteMask(draw.m_stencil) ); + vkCmdSetStencilWriteMask(m_commandBuffer, VK_STENCIL_FRONT_AND_BACK, unpackStencilWriteMask(stencil) ); } const bool hasFactor = 0 diff --git a/src/renderer_webgpu.cpp b/src/renderer_webgpu.cpp index 0e0c2bf72..0b4faeb32 100644 --- a/src/renderer_webgpu.cpp +++ b/src/renderer_webgpu.cpp @@ -879,7 +879,6 @@ WGPU_IMPORT , m_adapter(NULL) , m_device(NULL) , m_maxAnisotropy(1) - , m_depthClamp(false) , m_wireframe(false) , m_mipGen(NULL) { @@ -2702,14 +2701,6 @@ WGPU_IMPORT m_samplerStateCache.invalidate(); } - const bool depthClamp = !!(_reset & BGFX_RESET_DEPTH_CLAMP); - - if (m_depthClamp != depthClamp) - { - m_depthClamp = depthClamp; - m_renderPipelineCache.invalidate(); - } - if (!m_backBuffer.isSwapChain() ) { if (m_mainSwapChain.width != _swapChain.width @@ -2731,7 +2722,6 @@ WGPU_IMPORT uint32_t flags = _reset & ~(0 | BGFX_RESET_SUSPEND | BGFX_RESET_MAXANISOTROPY - | BGFX_RESET_DEPTH_CLAMP ); if (false @@ -3233,6 +3223,11 @@ WGPU_IMPORT , bool _isIndex16 , const RenderBind& _renderBind , bool _useDepthAttachment = true + , bool _depthClamp = false + , int32_t _depthBias = 0 + , float _slopeScale = 0.0f + , float _biasClamp = 0.0f + , uint32_t _sampleMask = UINT32_MAX ) { const ProgramWGPU& program = m_program[_program.idx]; @@ -3332,6 +3327,11 @@ WGPU_IMPORT murmur.add(_isIndex16); murmur.add(_useDepthAttachment); addAttachmentState(murmur, fb); + murmur.add(_depthClamp); + murmur.add(_depthBias); + murmur.add(_slopeScale); + murmur.add(_biasClamp); + murmur.add(_sampleMask); const uint32_t hash = murmur.end(); RenderPipeline* renderPipeline = m_renderPipelineCache.find(hash); @@ -3487,7 +3487,7 @@ WGPU_IMPORT if (NULL != depthStencilTextureView) { - setDepthStencilState(depthStencilState, formatDepthStencil, _state, _stencil); + setDepthStencilState(depthStencilState, formatDepthStencil, _state, _stencil, _depthBias, _slopeScale, _biasClamp); } else { @@ -3530,7 +3530,7 @@ WGPU_IMPORT .stripIndexFormat = primInfo.m_stripIndexFormat[!_isIndex16], .frontFace = !!(_state&BGFX_STATE_FRONT_CCW) ? WGPUFrontFace_CCW : WGPUFrontFace_CW, .cullMode = s_cullMode[cull], - .unclippedDepth = !m_depthClamp, + .unclippedDepth = _depthClamp, }, .depthStencil = WGPUTextureFormat_Undefined == depthStencilState.format ? NULL @@ -3540,7 +3540,7 @@ WGPU_IMPORT { .nextInChain = NULL, .count = _msaaCount, - .mask = 0xffffffff, + .mask = _sampleMask, .alphaToCoverageEnabled = 1 < _msaaCount && !!(BGFX_STATE_BLEND_ALPHA_TO_COVERAGE & _state), }, .fragment = hasFragmentShader ? &fragmentState : NULL, @@ -3861,7 +3861,7 @@ WGPU_IMPORT _murmur.add(_fb.m_formatDepthStencil); } - void setDepthStencilState(WGPUDepthStencilState& _outDepthStencilState, TextureFormat::Enum _format, uint64_t _state, uint64_t _stencil) + void setDepthStencilState(WGPUDepthStencilState& _outDepthStencilState, TextureFormat::Enum _format, uint64_t _state, uint64_t _stencil, int32_t _depthBias = 0, float _slopeScale = 0.0f, float _biasClamp = 0.0f) { if (!hasStencil(_format) ) { @@ -3901,9 +3901,9 @@ WGPU_IMPORT }, .stencilReadMask = (fstencil & BGFX_STENCIL_FUNC_RMASK_MASK) >> BGFX_STENCIL_FUNC_RMASK_SHIFT, .stencilWriteMask = writeMask, - .depthBias = 0, - .depthBiasSlopeScale = 0.0f, - .depthBiasClamp = 0.0f, + .depthBias = _depthBias, + .depthBiasSlopeScale = _slopeScale, + .depthBiasClamp = _biasClamp, }; } @@ -3927,7 +3927,6 @@ WGPU_IMPORT SwapChain m_mainSwapChain; uint32_t m_reset; uint16_t m_maxAnisotropy; - bool m_depthClamp; bool m_wireframe; const MipGen* m_mipGen; @@ -5753,6 +5752,8 @@ WGPU_IMPORT m_depthStencilView = attachmentView; m_formatDepthStencil = texture.m_textureFormat; m_depth = at.handle; + m_readOnlyDepth = 0 != (at.flags & BGFX_ATTACHMENT_READ_ONLY_DEPTH); + m_readOnlyStencil = 0 != (at.flags & BGFX_ATTACHMENT_READ_ONLY_STENCIL); } else { @@ -5796,7 +5797,7 @@ WGPU_IMPORT const Attachment& at = m_attachment[ii]; if (isValid(at.handle) - && 0 != (at.resolve & BGFX_RESOLVE_AUTO_GEN_MIPS) ) + && 0 != (at.flags & BGFX_ATTACHMENT_AUTO_GEN_MIPS) ) { TextureWGPU& texture = s_renderWGPU->m_textures[at.handle.idx]; @@ -6770,6 +6771,7 @@ WGPU_IMPORT currentState.clear(); currentState.m_stateFlags = BGFX_STATE_NONE; currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE); + uint64_t stateMask = UINT64_MAX; static ViewState viewState; viewState.reset(_render); @@ -6824,8 +6826,10 @@ WGPU_IMPORT uint32_t rgba; uint32_t streamMask; uint32_t bindIdx; + uint32_t sampleMask; uint16_t program; uint16_t fbh; + uint16_t depthBias; uint8_t numInstanceData; bool valid; bool isIndex16; @@ -6910,6 +6914,11 @@ WGPU_IMPORT } fbh = _render->m_view[view].m_fbh; + + stateMask = isValid(fbh) + ? getAttachmentStateMask(m_frameBuffers[fbh.idx].m_attachment, m_frameBuffers[fbh.idx].m_numAttachments) + : UINT64_MAX + ; } } @@ -7054,8 +7063,8 @@ WGPU_IMPORT } } - const bool stencilRw = hasStencil(TextureFormat::Enum(fb.m_formatDepthStencil) ); - const bool depthRw = hasDepth(TextureFormat::Enum(fb.m_formatDepthStencil) ); + const bool stencilRw = hasStencil(TextureFormat::Enum(fb.m_formatDepthStencil) ) && !fb.m_readOnlyStencil; + const bool depthRw = hasDepth(TextureFormat::Enum(fb.m_formatDepthStencil) ) && !fb.m_readOnlyDepth; WGPURenderPassDepthStencilAttachment depthStencilAttachement = { @@ -7266,7 +7275,8 @@ WGPU_IMPORT bool constantsChanged = draw.m_uniformBegin < draw.m_uniformEnd; rendererUpdateUniforms(this, _render->m_uniformBuffer[draw.m_uniformIdx], draw.m_uniformBegin, draw.m_uniformEnd); - const uint64_t state = draw.m_stateFlags; + const uint64_t state = draw.m_stateFlags & stateMask; + const uint32_t sampleMask = _render->m_view[view].m_sampleMask & draw.m_sampleMask; const uint8_t numInstanceData = uint8_t(draw.m_instanceDataStride/16); const bool drawIsIndex16 = draw.isIndex16(); @@ -7276,24 +7286,32 @@ WGPU_IMPORT && pipelineState.program == key.m_program.idx && pipelineState.fbh == fbh.idx && pipelineState.msaaCount == msaaCount - && pipelineState.state == draw.m_stateFlags + && pipelineState.state == state && pipelineState.rgba == draw.m_rgba && pipelineState.stencil == draw.m_stencil && pipelineState.streamMask == draw.m_streamMask && pipelineState.numInstanceData == numInstanceData && pipelineState.isIndex16 == drawIsIndex16 && pipelineState.bindIdx == bindIdx + && pipelineState.depthBias == draw.m_depthBias + && pipelineState.sampleMask == sampleMask && 0 == bx::memCmp(pipelineState.stream, draw.m_stream, sizeof(pipelineState.stream) ) ) { renderPipelinePtr = pipelineState.pipeline; } else { + const DepthControl& depthControl = (UINT16_MAX != draw.m_depthBias) + ? _render->m_frameCache.m_depthBiasCache.m_cache[draw.m_depthBias] + : _render->m_view[view].m_depthBias + ; + const bool depthClamp = depthControl.m_depthClamp; + renderPipelinePtr = getPipeline( key.m_program , fbh , msaaCount - , draw.m_stateFlags + , state , draw.m_rgba , draw.m_stencil , draw.m_streamMask @@ -7301,19 +7319,27 @@ WGPU_IMPORT , numInstanceData , drawIsIndex16 , renderBind + , true + , depthClamp + , depthControl.m_constant + , depthControl.m_slopeScale + , depthControl.m_clamp + , sampleMask ); pipelineState.valid = true; pipelineState.program = key.m_program.idx; pipelineState.fbh = fbh.idx; pipelineState.msaaCount = msaaCount; - pipelineState.state = draw.m_stateFlags; + pipelineState.state = state; pipelineState.rgba = draw.m_rgba; pipelineState.stencil = draw.m_stencil; pipelineState.streamMask = draw.m_streamMask; pipelineState.numInstanceData = numInstanceData; pipelineState.isIndex16 = drawIsIndex16; pipelineState.bindIdx = bindIdx; + pipelineState.depthBias = draw.m_depthBias; + pipelineState.sampleMask = sampleMask; bx::memCopy(pipelineState.stream, draw.m_stream, sizeof(pipelineState.stream) ); pipelineState.pipeline = renderPipelinePtr; } diff --git a/src/renderer_webgpu.h b/src/renderer_webgpu.h index f581c17a2..c433f18a1 100644 --- a/src/renderer_webgpu.h +++ b/src/renderer_webgpu.h @@ -711,6 +711,8 @@ namespace wgpu { FrameBufferWGPU() : m_depth({ kInvalidHandle }) , m_depthStencilView(NULL) + , m_readOnlyDepth(false) + , m_readOnlyStencil(false) , m_denseIdx(kInvalidHandle) , m_numColorAttachments(0) , m_numAttachments(0) @@ -746,6 +748,9 @@ namespace wgpu { WGPUTextureView m_depthStencilView; uint8_t m_formatDepthStencil; + bool m_readOnlyDepth; + bool m_readOnlyStencil; + uint16_t m_denseIdx; uint8_t m_numColorAttachments; uint8_t m_numAttachments; diff --git a/tools/shaderc/shaderc_metal.cpp b/tools/shaderc/shaderc_metal.cpp index 11ad949e5..632a95d42 100644 --- a/tools/shaderc/shaderc_metal.cpp +++ b/tools/shaderc/shaderc_metal.cpp @@ -784,6 +784,33 @@ namespace bgfx { namespace metal } } + if ('f' == _options.shaderType + && source.find("[[sample_mask]]") == std::string::npos) + { + const bx::StringView structOut("struct xlatMtlMain_out\n{"); + const bx::StringView localOut("xlatMtlMain_out out = {};"); + + const size_t structPos = source.find(structOut.getPtr() ); + const size_t localPos = std::string::npos == structPos + ? std::string::npos + : source.find(localOut.getPtr(), structPos) + ; + + if (std::string::npos != localPos) + { + source.insert(localPos + localOut.getLength() + , "\n\tif (bgfx_sampleMaskEnabled) { out.bgfx_metal_sampleMask = bgfx_sampleMask; }" + ); + source.insert(structPos + structOut.getLength() + , "\n\tuint bgfx_metal_sampleMask [[sample_mask, function_constant(bgfx_sampleMaskEnabled)]];" + ); + source.insert(structPos + , "constant uint bgfx_sampleMask [[function_constant(0)]];\n" + "constant bool bgfx_sampleMaskEnabled = is_function_constant_defined(bgfx_sampleMask);\n\n" + ); + } + } + if ('c' == _options.shaderType) { for (int i = 0; i < 3; ++i)