diff --git a/bindings/bf/bgfx.bf b/bindings/bf/bgfx.bf index eabf8a0fe..c3c9e17a3 100644 --- a/bindings/bf/bgfx.bf +++ b/bindings/bf/bgfx.bf @@ -1152,6 +1152,11 @@ public static class bgfx /// ViewportLayerArray = 0x0000000010000000, + /// + /// Draw indirect with indirect count is supported. + /// + DrawIndirectCount = 0x0000000020000000, + /// /// All texture compare modes are supported. /// @@ -3901,19 +3906,39 @@ public static class bgfx /// /// Submit primitive for rendering with index and instance data info from /// indirect buffer. + /// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. /// /// /// View id. /// Program. /// Indirect buffer. /// First element in indirect buffer. - /// Number of dispatches. + /// Number of draws. /// Depth for sorting. /// Discard or preserve states. See `BGFX_DISCARD_*`. /// [LinkName("bgfx_encoder_submit_indirect")] public static extern void encoder_submit_indirect(Encoder* _this, ViewId _id, ProgramHandle _program, IndirectBufferHandle _indirectHandle, uint16 _start, uint16 _num, uint32 _depth, uint8 _flags); + /// + /// Submit primitive for rendering with index and instance data info and + /// draw count from indirect buffers. + /// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT_COUNT`. + /// + /// + /// View id. + /// Program. + /// Indirect buffer. + /// First element in indirect buffer. + /// Buffer for number of draws. Must be created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. + /// Element in number buffer. + /// Max number of draws. + /// Depth for sorting. + /// Discard or preserve states. See `BGFX_DISCARD_*`. + /// + [LinkName("bgfx_encoder_submit_indirect_count")] + public static extern void encoder_submit_indirect_count(Encoder* _this, ViewId _id, ProgramHandle _program, IndirectBufferHandle _indirectHandle, uint16 _start, IndexBufferHandle _numHandle, uint32 _numIndex, uint16 _numMax, uint32 _depth, uint8 _flags); + /// /// Set compute index buffer. /// @@ -4457,19 +4482,39 @@ public static class bgfx /// /// Submit primitive for rendering with index and instance data info from /// indirect buffer. + /// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. /// /// /// View id. /// Program. /// Indirect buffer. /// First element in indirect buffer. - /// Number of dispatches. + /// Number of draws. /// Depth for sorting. /// Which states to discard for next draw. See `BGFX_DISCARD_*`. /// [LinkName("bgfx_submit_indirect")] public static extern void submit_indirect(ViewId _id, ProgramHandle _program, IndirectBufferHandle _indirectHandle, uint16 _start, uint16 _num, uint32 _depth, uint8 _flags); + /// + /// Submit primitive for rendering with index and instance data info and + /// draw count from indirect buffers. + /// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT_COUNT`. + /// + /// + /// View id. + /// Program. + /// Indirect buffer. + /// First element in indirect buffer. + /// Buffer for number of draws. Must be created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. + /// Element in number buffer. + /// Max number of draws. + /// Depth for sorting. + /// Which states to discard for next draw. See `BGFX_DISCARD_*`. + /// + [LinkName("bgfx_submit_indirect_count")] + public static extern void submit_indirect_count(ViewId _id, ProgramHandle _program, IndirectBufferHandle _indirectHandle, uint16 _start, IndexBufferHandle _numHandle, uint32 _numIndex, uint16 _numMax, uint32 _depth, uint8 _flags); + /// /// Set compute index buffer. /// diff --git a/bindings/cs/bgfx.cs b/bindings/cs/bgfx.cs index 5ef717462..a3787082d 100644 --- a/bindings/cs/bgfx.cs +++ b/bindings/cs/bgfx.cs @@ -1151,6 +1151,11 @@ public static partial class bgfx /// ViewportLayerArray = 0x0000000010000000, + /// + /// Draw indirect with indirect count is supported. + /// + DrawIndirectCount = 0x0000000020000000, + /// /// All texture compare modes are supported. /// @@ -3858,19 +3863,39 @@ public static partial class bgfx /// /// Submit primitive for rendering with index and instance data info from /// indirect buffer. + /// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. /// /// /// View id. /// Program. /// Indirect buffer. /// First element in indirect buffer. - /// Number of dispatches. + /// Number of draws. /// Depth for sorting. /// Discard or preserve states. See `BGFX_DISCARD_*`. /// [DllImport(DllName, EntryPoint="bgfx_encoder_submit_indirect", CallingConvention = CallingConvention.Cdecl)] public static extern unsafe void encoder_submit_indirect(Encoder* _this, ushort _id, ProgramHandle _program, IndirectBufferHandle _indirectHandle, ushort _start, ushort _num, uint _depth, byte _flags); + /// + /// Submit primitive for rendering with index and instance data info and + /// draw count from indirect buffers. + /// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT_COUNT`. + /// + /// + /// View id. + /// Program. + /// Indirect buffer. + /// First element in indirect buffer. + /// Buffer for number of draws. Must be created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. + /// Element in number buffer. + /// Max number of draws. + /// Depth for sorting. + /// Discard or preserve states. See `BGFX_DISCARD_*`. + /// + [DllImport(DllName, EntryPoint="bgfx_encoder_submit_indirect_count", CallingConvention = CallingConvention.Cdecl)] + public static extern unsafe void encoder_submit_indirect_count(Encoder* _this, ushort _id, ProgramHandle _program, IndirectBufferHandle _indirectHandle, ushort _start, IndexBufferHandle _numHandle, uint _numIndex, ushort _numMax, uint _depth, byte _flags); + /// /// Set compute index buffer. /// @@ -4414,19 +4439,39 @@ public static partial class bgfx /// /// Submit primitive for rendering with index and instance data info from /// indirect buffer. + /// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. /// /// /// View id. /// Program. /// Indirect buffer. /// First element in indirect buffer. - /// Number of dispatches. + /// Number of draws. /// Depth for sorting. /// Which states to discard for next draw. See `BGFX_DISCARD_*`. /// [DllImport(DllName, EntryPoint="bgfx_submit_indirect", CallingConvention = CallingConvention.Cdecl)] public static extern unsafe void submit_indirect(ushort _id, ProgramHandle _program, IndirectBufferHandle _indirectHandle, ushort _start, ushort _num, uint _depth, byte _flags); + /// + /// Submit primitive for rendering with index and instance data info and + /// draw count from indirect buffers. + /// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT_COUNT`. + /// + /// + /// View id. + /// Program. + /// Indirect buffer. + /// First element in indirect buffer. + /// Buffer for number of draws. Must be created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. + /// Element in number buffer. + /// Max number of draws. + /// Depth for sorting. + /// Which states to discard for next draw. See `BGFX_DISCARD_*`. + /// + [DllImport(DllName, EntryPoint="bgfx_submit_indirect_count", CallingConvention = CallingConvention.Cdecl)] + public static extern unsafe void submit_indirect_count(ushort _id, ProgramHandle _program, IndirectBufferHandle _indirectHandle, ushort _start, IndexBufferHandle _numHandle, uint _numIndex, ushort _numMax, uint _depth, byte _flags); + /// /// Set compute index buffer. /// diff --git a/bindings/d/funcs.d b/bindings/d/funcs.d index 2bb7d738e..561556ba5 100644 --- a/bindings/d/funcs.d +++ b/bindings/d/funcs.d @@ -1526,17 +1526,36 @@ version(BindBgfx_Static) /** * Submit primitive for rendering with index and instance data info from * indirect buffer. + * Attention: Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. * Params: * _id = View id. * _program = Program. * _indirectHandle = Indirect buffer. * _start = First element in indirect buffer. - * _num = Number of dispatches. + * _num = Number of draws. * _depth = Depth for sorting. * _flags = Discard or preserve states. See `BGFX_DISCARD_*`. */ void bgfx_encoder_submit_indirect(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, ushort _start, ushort _num, uint _depth, ubyte _flags); + /** + * Submit primitive for rendering with index and instance data info and + * draw count from indirect buffers. + * Attention: Availability depends on: `BGFX_CAPS_DRAW_INDIRECT_COUNT`. + * Params: + * _id = View id. + * _program = Program. + * _indirectHandle = Indirect buffer. + * _start = First element in indirect buffer. + * _numHandle = Buffer for number of draws. Must be + * created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. + * _numIndex = Element in number buffer. + * _numMax = Max number of draws. + * _depth = Depth for sorting. + * _flags = Discard or preserve states. See `BGFX_DISCARD_*`. + */ + void bgfx_encoder_submit_indirect_count(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, ushort _start, bgfx_index_buffer_handle_t _numHandle, uint _numIndex, ushort _numMax, uint _depth, ubyte _flags); + /** * Set compute index buffer. * Params: @@ -2026,17 +2045,36 @@ version(BindBgfx_Static) /** * Submit primitive for rendering with index and instance data info from * indirect buffer. + * Attention: Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. * Params: * _id = View id. * _program = Program. * _indirectHandle = Indirect buffer. * _start = First element in indirect buffer. - * _num = Number of dispatches. + * _num = Number of draws. * _depth = Depth for sorting. * _flags = Which states to discard for next draw. See `BGFX_DISCARD_*`. */ void bgfx_submit_indirect(bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, ushort _start, ushort _num, uint _depth, ubyte _flags); + /** + * Submit primitive for rendering with index and instance data info and + * draw count from indirect buffers. + * Attention: Availability depends on: `BGFX_CAPS_DRAW_INDIRECT_COUNT`. + * Params: + * _id = View id. + * _program = Program. + * _indirectHandle = Indirect buffer. + * _start = First element in indirect buffer. + * _numHandle = Buffer for number of draws. Must be + * created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. + * _numIndex = Element in number buffer. + * _numMax = Max number of draws. + * _depth = Depth for sorting. + * _flags = Which states to discard for next draw. See `BGFX_DISCARD_*`. + */ + void bgfx_submit_indirect_count(bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, ushort _start, bgfx_index_buffer_handle_t _numHandle, uint _numIndex, ushort _numMax, uint _depth, ubyte _flags); + /** * Set compute index buffer. * Params: @@ -3806,18 +3844,38 @@ else /** * Submit primitive for rendering with index and instance data info from * indirect buffer. + * Attention: Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. * Params: * _id = View id. * _program = Program. * _indirectHandle = Indirect buffer. * _start = First element in indirect buffer. - * _num = Number of dispatches. + * _num = Number of draws. * _depth = Depth for sorting. * _flags = Discard or preserve states. See `BGFX_DISCARD_*`. */ alias da_bgfx_encoder_submit_indirect = void function(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, ushort _start, ushort _num, uint _depth, ubyte _flags); da_bgfx_encoder_submit_indirect bgfx_encoder_submit_indirect; + /** + * Submit primitive for rendering with index and instance data info and + * draw count from indirect buffers. + * Attention: Availability depends on: `BGFX_CAPS_DRAW_INDIRECT_COUNT`. + * Params: + * _id = View id. + * _program = Program. + * _indirectHandle = Indirect buffer. + * _start = First element in indirect buffer. + * _numHandle = Buffer for number of draws. Must be + * created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. + * _numIndex = Element in number buffer. + * _numMax = Max number of draws. + * _depth = Depth for sorting. + * _flags = Discard or preserve states. See `BGFX_DISCARD_*`. + */ + alias da_bgfx_encoder_submit_indirect_count = void function(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, ushort _start, bgfx_index_buffer_handle_t _numHandle, uint _numIndex, ushort _numMax, uint _depth, ubyte _flags); + da_bgfx_encoder_submit_indirect_count bgfx_encoder_submit_indirect_count; + /** * Set compute index buffer. * Params: @@ -4351,18 +4409,38 @@ else /** * Submit primitive for rendering with index and instance data info from * indirect buffer. + * Attention: Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. * Params: * _id = View id. * _program = Program. * _indirectHandle = Indirect buffer. * _start = First element in indirect buffer. - * _num = Number of dispatches. + * _num = Number of draws. * _depth = Depth for sorting. * _flags = Which states to discard for next draw. See `BGFX_DISCARD_*`. */ alias da_bgfx_submit_indirect = void function(bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, ushort _start, ushort _num, uint _depth, ubyte _flags); da_bgfx_submit_indirect bgfx_submit_indirect; + /** + * Submit primitive for rendering with index and instance data info and + * draw count from indirect buffers. + * Attention: Availability depends on: `BGFX_CAPS_DRAW_INDIRECT_COUNT`. + * Params: + * _id = View id. + * _program = Program. + * _indirectHandle = Indirect buffer. + * _start = First element in indirect buffer. + * _numHandle = Buffer for number of draws. Must be + * created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. + * _numIndex = Element in number buffer. + * _numMax = Max number of draws. + * _depth = Depth for sorting. + * _flags = Which states to discard for next draw. See `BGFX_DISCARD_*`. + */ + alias da_bgfx_submit_indirect_count = void function(bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, ushort _start, bgfx_index_buffer_handle_t _numHandle, uint _numIndex, ushort _numMax, uint _depth, ubyte _flags); + da_bgfx_submit_indirect_count bgfx_submit_indirect_count; + /** * Set compute index buffer. * Params: diff --git a/bindings/d/types.d b/bindings/d/types.d index afa52cff6..c51993680 100644 --- a/bindings/d/types.d +++ b/bindings/d/types.d @@ -410,6 +410,7 @@ enum ulong BGFX_CAPS_VERTEX_ATTRIB_HALF = 0x0000000002000000; /// Vertex attribu enum ulong BGFX_CAPS_VERTEX_ATTRIB_UINT10 = 0x0000000004000000; /// Vertex attribute 10_10_10_2 is supported. enum ulong BGFX_CAPS_VERTEX_ID = 0x0000000008000000; /// Rendering with VertexID only is supported. enum ulong BGFX_CAPS_VIEWPORT_LAYER_ARRAY = 0x0000000010000000; /// Viewport layer is available in vertex shader. +enum ulong BGFX_CAPS_DRAW_INDIRECT_COUNT = 0x0000000020000000; /// Draw indirect with indirect count is supported. enum ulong BGFX_CAPS_TEXTURE_COMPARE_ALL = 0x0000000000300000; /// All texture compare modes are supported. enum uint BGFX_CAPS_FORMAT_TEXTURE_NONE = 0x00000000; /// Texture format is not supported. diff --git a/bindings/zig/bgfx.zig b/bindings/zig/bgfx.zig index 6e3ce16dd..abfec7eba 100644 --- a/bindings/zig/bgfx.zig +++ b/bindings/zig/bgfx.zig @@ -711,6 +711,9 @@ pub const CapsFlags_VertexId: CapsFlags = 0x0000000008000000; /// Viewport layer is available in vertex shader. pub const CapsFlags_ViewportLayerArray: CapsFlags = 0x0000000010000000; +/// Draw indirect with indirect count is supported. +pub const CapsFlags_DrawIndirectCount: CapsFlags = 0x0000000020000000; + /// All texture compare modes are supported. pub const CapsFlags_TextureCompareAll: CapsFlags = 0x0000000000300000; @@ -1724,16 +1727,32 @@ pub const Init = extern struct { } /// Submit primitive for rendering with index and instance data info from /// indirect buffer. + /// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. /// View id. /// Program. /// Indirect buffer. /// First element in indirect buffer. - /// Number of dispatches. + /// Number of draws. /// Depth for sorting. /// Discard or preserve states. See `BGFX_DISCARD_*`. pub inline fn submitIndirect(self: ?*Encoder, _id: ViewId, _program: ProgramHandle, _indirectHandle: IndirectBufferHandle, _start: u16, _num: u16, _depth: u32, _flags: u8) void { return bgfx_encoder_submit_indirect(self, _id, _program, _indirectHandle, _start, _num, _depth, _flags); } + /// Submit primitive for rendering with index and instance data info and + /// draw count from indirect buffers. + /// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT_COUNT`. + /// View id. + /// Program. + /// Indirect buffer. + /// First element in indirect buffer. + /// Buffer for number of draws. Must be created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. + /// Element in number buffer. + /// Max number of draws. + /// Depth for sorting. + /// Discard or preserve states. See `BGFX_DISCARD_*`. + pub inline fn submitIndirectCount(self: ?*Encoder, _id: ViewId, _program: ProgramHandle, _indirectHandle: IndirectBufferHandle, _start: u16, _numHandle: IndexBufferHandle, _numIndex: u32, _numMax: u16, _depth: u32, _flags: u8) void { + return bgfx_encoder_submit_indirect_count(self, _id, _program, _indirectHandle, _start, _numHandle, _numIndex, _numMax, _depth, _flags); + } /// Set compute index buffer. /// Compute stage. /// Index buffer handle. @@ -3068,15 +3087,30 @@ extern fn bgfx_encoder_submit_occlusion_query(self: ?*Encoder, _id: ViewId, _pro /// Submit primitive for rendering with index and instance data info from /// indirect buffer. +/// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. /// View id. /// Program. /// Indirect buffer. /// First element in indirect buffer. -/// Number of dispatches. +/// Number of draws. /// Depth for sorting. /// Discard or preserve states. See `BGFX_DISCARD_*`. extern fn bgfx_encoder_submit_indirect(self: ?*Encoder, _id: ViewId, _program: ProgramHandle, _indirectHandle: IndirectBufferHandle, _start: u16, _num: u16, _depth: u32, _flags: u8) void; +/// Submit primitive for rendering with index and instance data info and +/// draw count from indirect buffers. +/// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT_COUNT`. +/// View id. +/// Program. +/// Indirect buffer. +/// First element in indirect buffer. +/// Buffer for number of draws. Must be created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. +/// Element in number buffer. +/// Max number of draws. +/// Depth for sorting. +/// Discard or preserve states. See `BGFX_DISCARD_*`. +extern fn bgfx_encoder_submit_indirect_count(self: ?*Encoder, _id: ViewId, _program: ProgramHandle, _indirectHandle: IndirectBufferHandle, _start: u16, _numHandle: IndexBufferHandle, _numIndex: u32, _numMax: u16, _depth: u32, _flags: u8) void; + /// Set compute index buffer. /// Compute stage. /// Index buffer handle. @@ -3503,11 +3537,12 @@ extern fn bgfx_submit_occlusion_query(_id: ViewId, _program: ProgramHandle, _occ /// Submit primitive for rendering with index and instance data info from /// indirect buffer. +/// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. /// View id. /// Program. /// Indirect buffer. /// First element in indirect buffer. -/// Number of dispatches. +/// Number of draws. /// Depth for sorting. /// Which states to discard for next draw. See `BGFX_DISCARD_*`. pub inline fn submitIndirect(_id: ViewId, _program: ProgramHandle, _indirectHandle: IndirectBufferHandle, _start: u16, _num: u16, _depth: u32, _flags: u8) void { @@ -3515,6 +3550,23 @@ pub inline fn submitIndirect(_id: ViewId, _program: ProgramHandle, _indirectHand } extern fn bgfx_submit_indirect(_id: ViewId, _program: ProgramHandle, _indirectHandle: IndirectBufferHandle, _start: u16, _num: u16, _depth: u32, _flags: u8) void; +/// Submit primitive for rendering with index and instance data info and +/// draw count from indirect buffers. +/// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT_COUNT`. +/// View id. +/// Program. +/// Indirect buffer. +/// First element in indirect buffer. +/// Buffer for number of draws. Must be created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. +/// Element in number buffer. +/// Max number of draws. +/// Depth for sorting. +/// Which states to discard for next draw. See `BGFX_DISCARD_*`. +pub inline fn submitIndirectCount(_id: ViewId, _program: ProgramHandle, _indirectHandle: IndirectBufferHandle, _start: u16, _numHandle: IndexBufferHandle, _numIndex: u32, _numMax: u16, _depth: u32, _flags: u8) void { + return bgfx_submit_indirect_count(_id, _program, _indirectHandle, _start, _numHandle, _numIndex, _numMax, _depth, _flags); +} +extern fn bgfx_submit_indirect_count(_id: ViewId, _program: ProgramHandle, _indirectHandle: IndirectBufferHandle, _start: u16, _numHandle: IndexBufferHandle, _numIndex: u32, _numMax: u16, _depth: u32, _flags: u8) void; + /// Set compute index buffer. /// Compute stage. /// Index buffer handle. diff --git a/docs/bgfx.rst b/docs/bgfx.rst index 9235c701f..87cd4c45e 100644 --- a/docs/bgfx.rst +++ b/docs/bgfx.rst @@ -121,6 +121,7 @@ Available Caps .. doxygendefine:: BGFX_CAPS_COMPUTE .. doxygendefine:: BGFX_CAPS_CONSERVATIVE_RASTER .. doxygendefine:: BGFX_CAPS_DRAW_INDIRECT +.. doxygendefine:: BGFX_CAPS_DRAW_INDIRECT_COUNT .. doxygendefine:: BGFX_CAPS_FRAGMENT_DEPTH .. doxygendefine:: BGFX_CAPS_FRAGMENT_ORDERING .. doxygendefine:: BGFX_CAPS_GRAPHICS_DEBUGGER diff --git a/examples/48-drawindirect/cs_drawindirect.sc b/examples/48-drawindirect/cs_drawindirect.sc index 989bb3005..0e37a38ec 100644 --- a/examples/48-drawindirect/cs_drawindirect.sc +++ b/examples/48-drawindirect/cs_drawindirect.sc @@ -11,6 +11,9 @@ BUFFER_RO(instanceDataIn, vec4, 0); // Output BUFFER_WR(indirectBuffer, uvec4, 1); BUFFER_WR(instanceBufferOut, vec4, 2); +#ifdef INDIRECT_COUNT +BUFFER_WR(indirectCountBuffer, int, 3); +#endif uniform vec4 u_drawParams; @@ -23,15 +26,15 @@ void main() int numDrawItems = int(u_drawParams.x); int sideSize = int(u_drawParams.y); float time = u_drawParams.z; - + // Work out the amount of work we're going to do here int maxToDraw = min(sideSize*sideSize, numDrawItems); - + int numToDrawPerThread = maxToDraw/64 + 1; - + int idxStart = tId*numToDrawPerThread; int idxMax = min(maxToDraw, (tId+1)*numToDrawPerThread); - + // Prepare draw mtx for (int k = idxStart; k < idxMax; k++) { int yy = k / sideSize; @@ -47,24 +50,24 @@ void main() vec4 a = vec4( cy, 0, sy, 0); vec4 b = vec4( sx*sy, cx, -sx*cy, 0); vec4 c = vec4(-cx*sy, sx, cx*cy, 0); - + vec4 d = vec4(-15.0f - (sideSize-11)*1.2f + float(xx) * 3.0f, -15.0f - (sideSize-11)*1.4f + float(yy) * 3.0f, max(0.0f, (sideSize-11.0f)*3.0f), 1.0f); - + vec4 color; color.x = sin(time + float(xx) / 11.0f) * 0.5f + 0.5f; color.y = cos(time + float(yy) / 11.0f) * 0.5f + 0.5f; color.z = sin(time * 3.0f) * 0.5f + 0.5f; color.w = 1.0f; - + instanceBufferOut[k*5+0] = a; instanceBufferOut[k*5+1] = b; instanceBufferOut[k*5+2] = c; instanceBufferOut[k*5+3] = d; instanceBufferOut[k*5+4] = color; } - + // Fill indirect buffer - + for (int k = idxStart; k < idxMax; k++) { drawIndexedIndirect( // Target location params: @@ -77,9 +80,14 @@ void main() instanceDataIn[k].x, // offset in the vertex buffer. Note that you can use this to "reindex" submeshses - all indicies in this draw will be decremented by this amount k // offset in the instance buffer. If you are drawing more than 1 instance per call see gpudrivenrendering for how to handle ); - } + } + #ifdef INDIRECT_COUNT + if (tId == 0) + { + // If BGFX_CAPS_DRAW_INDIRECT_COUNT is supported, you can limit the + // number of draw calls dynamically without a CPU round trip + indirectCountBuffer[0] = maxToDraw; + } + #endif } - - - diff --git a/examples/48-drawindirect/cs_drawindirect_count.sc b/examples/48-drawindirect/cs_drawindirect_count.sc new file mode 100644 index 000000000..9a1f95415 --- /dev/null +++ b/examples/48-drawindirect/cs_drawindirect_count.sc @@ -0,0 +1,2 @@ +#define INDIRECT_COUNT +#include "cs_drawindirect.sc" diff --git a/examples/48-drawindirect/drawindirect.cpp b/examples/48-drawindirect/drawindirect.cpp index eefd5e172..d8b4d6d58 100644 --- a/examples/48-drawindirect/drawindirect.cpp +++ b/examples/48-drawindirect/drawindirect.cpp @@ -42,7 +42,7 @@ struct ObjectInstance { float m_vertexCount; float m_indexOffset; float m_indexCount; - + static void init() { ms_layout @@ -50,7 +50,7 @@ struct ObjectInstance { .add(bgfx::Attrib::TexCoord0, 4, bgfx::AttribType::Float) .end(); }; - + static bgfx::VertexLayout ms_layout; }; @@ -59,7 +59,7 @@ bgfx::VertexLayout ObjectInstance::ms_layout; struct RenderInstance { float m_mtx[16]; float m_color[4]; - + static void init() { ms_layout @@ -71,10 +71,10 @@ struct RenderInstance { .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Float) .end(); }; - + static bgfx::VertexLayout ms_layout; }; - + bgfx::VertexLayout RenderInstance::ms_layout; static PosColorVertex s_multiMeshVertices[12] = @@ -88,7 +88,7 @@ static PosColorVertex s_multiMeshVertices[12] = { 1.0f, 1.0f, -1.0f, 0xffff00ff }, {-1.0f, -1.0f, -1.0f, 0xffffff00 }, { 1.0f, -1.0f, -1.0f, 0xffffffff }, - + // Tetrahedron Model (offset = 8) { 1.0f, 1.0f, 1.0f, 0xff0000ff }, { 1.0f, -1.0f, -1.0f, 0xff000000 }, @@ -111,7 +111,7 @@ static const uint16_t s_multiMeshIndices[48] = 4, 5, 1, 2, 3, 6, // 10 6, 3, 7, - + // Tetrahedron Indices (offset = 36) 0, 2, 1, 1, 2, 3, @@ -137,8 +137,9 @@ public: m_height = _height; m_debug = BGFX_DEBUG_TEXT; m_reset = BGFX_RESET_VSYNC; - m_sideSize = 11; + m_sideSize = 11; m_nDrawElements = s_maxSideSize*s_maxSideSize; + m_useIndirectCount = false; bgfx::Init init; init.type = args.m_type; @@ -179,26 +180,40 @@ public: // Create program from shaders. m_program = loadProgram("vs_instancing", "fs_instancing"); // These are reused from 05-instancing - + m_indirect_program = BGFX_INVALID_HANDLE; + m_indirect_count_program = BGFX_INVALID_HANDLE; m_indirect_buffer_handle = BGFX_INVALID_HANDLE; + m_indirect_count_buffer_handle = BGFX_INVALID_HANDLE; m_object_list_buffer = BGFX_INVALID_HANDLE; - + u_drawParams = bgfx::createUniform("u_drawParams", bgfx::UniformType::Vec4); - - const bool computeSupported = !!(BGFX_CAPS_DRAW_INDIRECT & bgfx::getCaps()->supported); + + const bool computeSupported = !!(BGFX_CAPS_COMPUTE & bgfx::getCaps()->supported); + const bool indirectSupported = !!(BGFX_CAPS_DRAW_INDIRECT & bgfx::getCaps()->supported); const bool instancingSupported = !!(BGFX_CAPS_INSTANCING & bgfx::getCaps()->supported); - - if (computeSupported && instancingSupported) + + if (computeSupported && indirectSupported && instancingSupported) { // Set up indirect program // This is a barebones program that populates the indirect buffer handle with draw requests m_indirect_program = bgfx::createProgram(loadShader("cs_drawindirect"), true); m_indirect_buffer_handle = bgfx::createIndirectBuffer(m_nDrawElements); - + + const bool indirectCountSupported = !!(BGFX_CAPS_DRAW_INDIRECT_COUNT & bgfx::getCaps()->supported); + if (indirectCountSupported) + { + m_useIndirectCount = true; + m_indirect_count_program = bgfx::createProgram(loadShader("cs_drawindirect_count"), true); + + const bgfx::Memory * mem = bgfx::alloc(sizeof(uint32_t)); + *(uint32_t *)mem->data = 0; + m_indirect_count_buffer_handle = bgfx::createIndexBuffer(mem, BGFX_BUFFER_INDEX32 | BGFX_BUFFER_COMPUTE_WRITE | BGFX_BUFFER_DRAW_INDIRECT); + } + const bgfx::Memory * mem = bgfx::alloc(sizeof(ObjectInstance) * m_nDrawElements); ObjectInstance* objs = (ObjectInstance*) mem->data; - + for (uint32_t ii = 0; ii < m_nDrawElements; ++ii) { if (ii % 2) @@ -218,15 +233,15 @@ public: objs[ii].m_indexCount = 36; } } - + // This is a list of objects to be rendered via the indirect program m_object_list_buffer = bgfx::createVertexBuffer(mem, ObjectInstance::ms_layout, BGFX_BUFFER_COMPUTE_READ); - - // This is the instance buffer used for rendering. + + // This is the instance buffer used for rendering. // You could instead use a dynamic instance buffer when rendering (use bgfx::allocInstanceDataBuffer in draw loop) m_instance_buffer = bgfx::createDynamicVertexBuffer(m_nDrawElements, RenderInstance::ms_layout, BGFX_BUFFER_COMPUTE_WRITE); } - + m_timeOffset = bx::getHPCounter(); imguiCreate(); @@ -245,10 +260,18 @@ public: { bgfx::destroy(m_indirect_program); } + if (bgfx::isValid(m_indirect_count_program)) + { + bgfx::destroy(m_indirect_count_program); + } if (bgfx::isValid(m_indirect_buffer_handle)) { bgfx::destroy(m_indirect_buffer_handle); } + if (bgfx::isValid(m_indirect_count_buffer_handle)) + { + bgfx::destroy(m_indirect_count_buffer_handle); + } if (bgfx::isValid(m_object_list_buffer)) { bgfx::destroy(m_object_list_buffer); @@ -258,7 +281,7 @@ public: bgfx::destroy(m_instance_buffer); } bgfx::destroy(u_drawParams); - + // Shutdown bgfx. bgfx::shutdown(); @@ -269,6 +292,12 @@ public: { if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) ) { + // Get renderer capabilities info. + const bool computeSupported = !!(BGFX_CAPS_COMPUTE & bgfx::getCaps()->supported); + const bool indirectSupported = !!(BGFX_CAPS_DRAW_INDIRECT & bgfx::getCaps()->supported); + const bool indirectCountSupported = !!(BGFX_CAPS_DRAW_INDIRECT_COUNT & bgfx::getCaps()->supported); + const bool instancingSupported = !!(BGFX_CAPS_INSTANCING & bgfx::getCaps()->supported); + imguiBeginFrame(m_mouseState.m_mx , m_mouseState.m_my , (m_mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) @@ -300,10 +329,18 @@ public: ImGui::Text("Grid Side Size:"); ImGui::SliderInt("##size", (int*)&m_sideSize, 1, s_maxSideSize); + ImGui::BeginDisabled(!indirectCountSupported); + ImGui::Checkbox("Indirect Count", &m_useIndirectCount); + ImGui::EndDisabled(); + if (!indirectCountSupported && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) ) + { + ImGui::SetTooltip("Indirect Count is not supported by GPU."); + } + ImGui::End(); - + imguiEndFrame(); - + // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) ); @@ -327,55 +364,66 @@ public: // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) ); } - + float time = (float)( (bx::getHPCounter() - m_timeOffset)/double(bx::getHPFrequency() ) ); - // Get renderer capabilities info. - const bool computeSupported = !!(BGFX_CAPS_DRAW_INDIRECT & bgfx::getCaps()->supported); - const bool instancingSupported = !!(BGFX_CAPS_INSTANCING & bgfx::getCaps()->supported); - - if (computeSupported && instancingSupported) + if (computeSupported && indirectSupported && instancingSupported) { // Build indirect buffer & prepare instance buffer // NOTE: IF you are rendering static data then // this could be done once on startup and results stored // This is done here for demonstration purposes - + // The model matrix for each instance is also set on compute - // you could modify this to, eg, do frustrum culling on the GPU + // you could modify this to, eg, do frustrum culling on the GPU float ud[4] = { float(m_nDrawElements), float(m_sideSize), float(time), 0 }; uint32_t numToDraw = (m_sideSize*m_sideSize); - + bgfx::setUniform(u_drawParams, ud); - + bgfx::setBuffer(0, m_object_list_buffer, bgfx::Access::Read); bgfx::setBuffer(1, m_indirect_buffer_handle, bgfx::Access::Write); bgfx::setBuffer(2, m_instance_buffer, bgfx::Access::Write); - + // Dispatch the call. We are using 64 local threads on the GPU to process the object list // So lets dispatch ceil(numToDraw/64) workgroups of 64 local threads - bgfx::dispatch(0, m_indirect_program, uint32_t(numToDraw/64 + 1), 1, 1); - + if (m_useIndirectCount) + { + bgfx::setBuffer(3, m_indirect_count_buffer_handle, bgfx::Access::Write); + bgfx::dispatch(0, m_indirect_count_program, uint32_t(numToDraw/64 + 1), 1, 1); + } + else + { + bgfx::dispatch(0, m_indirect_program, uint32_t(numToDraw/64 + 1), 1, 1); + } + // Submit our 1 draw call // Set vertex and index buffer. bgfx::setIndexBuffer(m_ibh); bgfx::setVertexBuffer(0, m_vbh); bgfx::setInstanceDataBuffer(m_instance_buffer, 0, numToDraw); - + // Set render states. bgfx::setState(BGFX_STATE_DEFAULT); // Submit primitive for rendering to view 0. - // note that this submission requires the draw count - bgfx::submit(0, m_program, m_indirect_buffer_handle, 0, uint16_t(numToDraw)); + if (m_useIndirectCount) + { + // With indirect count, the number of draws is read from a buffer + bgfx::submit(0, m_program, m_indirect_buffer_handle, 0, m_indirect_count_buffer_handle); + } + else + { + bgfx::submit(0, m_program, m_indirect_buffer_handle, 0, uint16_t(numToDraw)); + } } else { - // Compute/Instancing is not supported + // Compute/Indirect/Instancing is not supported bool blink = uint32_t(time*3.0f)&1; - bgfx::dbgTextPrintf(0, 0, blink ? 0x4f : 0x04, " Compute/Instancing is not supported by GPU. "); + bgfx::dbgTextPrintf(0, 0, blink ? 0x4f : 0x04, " Compute/Indirect/Instancing is not supported by GPU. "); } - + // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); @@ -394,12 +442,15 @@ public: uint32_t m_reset; uint32_t m_sideSize; uint32_t m_nDrawElements; + bool m_useIndirectCount; bgfx::VertexBufferHandle m_vbh; bgfx::IndexBufferHandle m_ibh; bgfx::ProgramHandle m_program; - bgfx::IndirectBufferHandle m_indirect_buffer_handle; + bgfx::IndirectBufferHandle m_indirect_buffer_handle; + bgfx::IndexBufferHandle m_indirect_count_buffer_handle; bgfx::ProgramHandle m_indirect_program; + bgfx::ProgramHandle m_indirect_count_program; bgfx::VertexBufferHandle m_object_list_buffer; bgfx::DynamicVertexBufferHandle m_instance_buffer; bgfx::UniformHandle u_drawParams; diff --git a/examples/runtime/shaders/dx11/cs_drawindirect_count.bin b/examples/runtime/shaders/dx11/cs_drawindirect_count.bin new file mode 100644 index 000000000..33deac008 Binary files /dev/null and b/examples/runtime/shaders/dx11/cs_drawindirect_count.bin differ diff --git a/examples/runtime/shaders/glsl/cs_drawindirect_count.bin b/examples/runtime/shaders/glsl/cs_drawindirect_count.bin new file mode 100644 index 000000000..fcf2a6f47 Binary files /dev/null and b/examples/runtime/shaders/glsl/cs_drawindirect_count.bin differ diff --git a/examples/runtime/shaders/spirv/cs_drawindirect.bin b/examples/runtime/shaders/spirv/cs_drawindirect.bin index e72fcda3b..f9ea06d53 100755 Binary files a/examples/runtime/shaders/spirv/cs_drawindirect.bin and b/examples/runtime/shaders/spirv/cs_drawindirect.bin differ diff --git a/examples/runtime/shaders/spirv/cs_drawindirect_count.bin b/examples/runtime/shaders/spirv/cs_drawindirect_count.bin new file mode 100644 index 000000000..e7edaec37 Binary files /dev/null and b/examples/runtime/shaders/spirv/cs_drawindirect_count.bin differ diff --git a/include/bgfx/bgfx.h b/include/bgfx/bgfx.h index a3c212ba6..013d04ea5 100644 --- a/include/bgfx/bgfx.h +++ b/include/bgfx/bgfx.h @@ -1480,10 +1480,11 @@ namespace bgfx /// @param[in] _program Program. /// @param[in] _indirectHandle Indirect buffer. /// @param[in] _start First element in indirect buffer. - /// @param[in] _num Number of dispatches. + /// @param[in] _num Number of draws. /// @param[in] _depth Depth for sorting. /// @param[in] _flags Discard or preserve states. See `BGFX_DISCARD_*`. /// + /// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. /// @attention C99's equivalent binding is `bgfx_encoder_submit_indirect`. /// void submit( @@ -1496,6 +1497,35 @@ namespace bgfx , uint8_t _flags = BGFX_DISCARD_ALL ); + /// Submit primitive for rendering with index and instance data info and + /// draw count from indirect buffers. + /// + /// @param[in] _id View id. + /// @param[in] _program Program. + /// @param[in] _indirectHandle Indirect buffer. + /// @param[in] _start First element in indirect buffer. + /// @param[in] _numHandle Buffer for number of draws. Must be created + /// with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. + /// @param[in] _numIndex Element in number buffer. + /// @param[in] _numMax Max number of draws. + /// @param[in] _depth Depth for sorting. + /// @param[in] _flags Discard or preserve states. See `BGFX_DISCARD_*`. + /// + /// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT_COUNT`. + /// @attention C99's equivalent binding is `bgfx_encoder_submit_indirect_count`. + /// + void submit( + ViewId _id + , ProgramHandle _program + , IndirectBufferHandle _indirectHandle + , uint16_t _start + , IndexBufferHandle _numHandle + , uint32_t _numIndex = 0 + , uint16_t _numMax = UINT16_MAX + , uint32_t _depth = 0 + , uint8_t _flags = BGFX_DISCARD_ALL + ); + /// Set compute index buffer. /// /// @param[in] _stage Compute stage. @@ -3924,10 +3954,11 @@ namespace bgfx /// @param[in] _program Program. /// @param[in] _indirectHandle Indirect buffer. /// @param[in] _start First element in indirect buffer. - /// @param[in] _num Number of dispatches. + /// @param[in] _num Number of draws. /// @param[in] _depth Depth for sorting. /// @param[in] _flags Discard or preserve states. See `BGFX_DISCARD_*`. /// + /// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. /// @attention C99's equivalent binding is `bgfx_submit_indirect`. /// void submit( @@ -3940,6 +3971,35 @@ namespace bgfx , uint8_t _flags = BGFX_DISCARD_ALL ); + /// Submit primitive for rendering with index and instance data info and + /// draw count from indirect buffers. + /// + /// @param[in] _id View id. + /// @param[in] _program Program. + /// @param[in] _indirectHandle Indirect buffer. + /// @param[in] _start First element in indirect buffer. + /// @param[in] _numHandle Buffer for number of draws. Must be created + /// with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. + /// @param[in] _numIndex Element in number buffer. + /// @param[in] _numMax Max number of draws. + /// @param[in] _depth Depth for sorting. + /// @param[in] _flags Discard or preserve states. See `BGFX_DISCARD_*`. + /// + /// @attention Availability depends on:`BGFX_CAPS_DRAW_INDIRECT_COUNT`. + /// @attention C99's equivalent binding is `bgfx_submit_indirect_count`. + /// + void submit( + ViewId _id + , ProgramHandle _program + , IndirectBufferHandle _indirectHandle + , uint16_t _start + , IndexBufferHandle _numHandle + , uint32_t _numIndex = 0 + , uint16_t _numMax = UINT16_MAX + , uint32_t _depth = 0 + , uint8_t _flags = BGFX_DISCARD_ALL + ); + /// Set compute index buffer. /// /// @param[in] _stage Compute stage. diff --git a/include/bgfx/c99/bgfx.h b/include/bgfx/c99/bgfx.h index d096e7c92..d0ef34029 100644 --- a/include/bgfx/c99/bgfx.h +++ b/include/bgfx/c99/bgfx.h @@ -2665,18 +2665,38 @@ BGFX_C_API void bgfx_encoder_submit_occlusion_query(bgfx_encoder_t* _this, bgfx_ /** * Submit primitive for rendering with index and instance data info from * indirect buffer. + * @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. * * @param[in] _id View id. * @param[in] _program Program. * @param[in] _indirectHandle Indirect buffer. * @param[in] _start First element in indirect buffer. - * @param[in] _num Number of dispatches. + * @param[in] _num Number of draws. * @param[in] _depth Depth for sorting. * @param[in] _flags Discard or preserve states. See `BGFX_DISCARD_*`. * */ BGFX_C_API void bgfx_encoder_submit_indirect(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, uint16_t _num, uint32_t _depth, uint8_t _flags); +/** + * Submit primitive for rendering with index and instance data info and + * draw count from indirect buffers. + * @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT_COUNT`. + * + * @param[in] _id View id. + * @param[in] _program Program. + * @param[in] _indirectHandle Indirect buffer. + * @param[in] _start First element in indirect buffer. + * @param[in] _numHandle Buffer for number of draws. Must be + * created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. + * @param[in] _numIndex Element in number buffer. + * @param[in] _numMax Max number of draws. + * @param[in] _depth Depth for sorting. + * @param[in] _flags Discard or preserve states. See `BGFX_DISCARD_*`. + * + */ +BGFX_C_API void bgfx_encoder_submit_indirect_count(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, bgfx_index_buffer_handle_t _numHandle, uint32_t _numIndex, uint16_t _numMax, uint32_t _depth, uint8_t _flags); + /** * Set compute index buffer. * @@ -3227,18 +3247,38 @@ BGFX_C_API void bgfx_submit_occlusion_query(bgfx_view_id_t _id, bgfx_program_han /** * Submit primitive for rendering with index and instance data info from * indirect buffer. + * @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. * * @param[in] _id View id. * @param[in] _program Program. * @param[in] _indirectHandle Indirect buffer. * @param[in] _start First element in indirect buffer. - * @param[in] _num Number of dispatches. + * @param[in] _num Number of draws. * @param[in] _depth Depth for sorting. * @param[in] _flags Which states to discard for next draw. See `BGFX_DISCARD_*`. * */ BGFX_C_API void bgfx_submit_indirect(bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, uint16_t _num, uint32_t _depth, uint8_t _flags); +/** + * Submit primitive for rendering with index and instance data info and + * draw count from indirect buffers. + * @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT_COUNT`. + * + * @param[in] _id View id. + * @param[in] _program Program. + * @param[in] _indirectHandle Indirect buffer. + * @param[in] _start First element in indirect buffer. + * @param[in] _numHandle Buffer for number of draws. Must be + * created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. + * @param[in] _numIndex Element in number buffer. + * @param[in] _numMax Max number of draws. + * @param[in] _depth Depth for sorting. + * @param[in] _flags Which states to discard for next draw. See `BGFX_DISCARD_*`. + * + */ +BGFX_C_API void bgfx_submit_indirect_count(bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, bgfx_index_buffer_handle_t _numHandle, uint32_t _numIndex, uint16_t _numMax, uint32_t _depth, uint8_t _flags); + /** * Set compute index buffer. * @@ -3503,6 +3543,7 @@ typedef enum bgfx_function_id BGFX_FUNCTION_ID_ENCODER_SUBMIT, BGFX_FUNCTION_ID_ENCODER_SUBMIT_OCCLUSION_QUERY, BGFX_FUNCTION_ID_ENCODER_SUBMIT_INDIRECT, + BGFX_FUNCTION_ID_ENCODER_SUBMIT_INDIRECT_COUNT, BGFX_FUNCTION_ID_ENCODER_SET_COMPUTE_INDEX_BUFFER, BGFX_FUNCTION_ID_ENCODER_SET_COMPUTE_VERTEX_BUFFER, BGFX_FUNCTION_ID_ENCODER_SET_COMPUTE_DYNAMIC_INDEX_BUFFER, @@ -3548,6 +3589,7 @@ typedef enum bgfx_function_id BGFX_FUNCTION_ID_SUBMIT, BGFX_FUNCTION_ID_SUBMIT_OCCLUSION_QUERY, BGFX_FUNCTION_ID_SUBMIT_INDIRECT, + BGFX_FUNCTION_ID_SUBMIT_INDIRECT_COUNT, BGFX_FUNCTION_ID_SET_COMPUTE_INDEX_BUFFER, BGFX_FUNCTION_ID_SET_COMPUTE_VERTEX_BUFFER, BGFX_FUNCTION_ID_SET_COMPUTE_DYNAMIC_INDEX_BUFFER, @@ -3703,6 +3745,7 @@ struct bgfx_interface_vtbl void (*encoder_submit)(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, uint32_t _depth, uint8_t _flags); void (*encoder_submit_occlusion_query)(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_occlusion_query_handle_t _occlusionQuery, uint32_t _depth, uint8_t _flags); void (*encoder_submit_indirect)(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, uint16_t _num, uint32_t _depth, uint8_t _flags); + void (*encoder_submit_indirect_count)(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, bgfx_index_buffer_handle_t _numHandle, uint32_t _numIndex, uint16_t _numMax, uint32_t _depth, uint8_t _flags); void (*encoder_set_compute_index_buffer)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access); void (*encoder_set_compute_vertex_buffer)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_vertex_buffer_handle_t _handle, bgfx_access_t _access); void (*encoder_set_compute_dynamic_index_buffer)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_dynamic_index_buffer_handle_t _handle, bgfx_access_t _access); @@ -3748,6 +3791,7 @@ struct bgfx_interface_vtbl void (*submit)(bgfx_view_id_t _id, bgfx_program_handle_t _program, uint32_t _depth, uint8_t _flags); void (*submit_occlusion_query)(bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_occlusion_query_handle_t _occlusionQuery, uint32_t _depth, uint8_t _flags); void (*submit_indirect)(bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, uint16_t _num, uint32_t _depth, uint8_t _flags); + void (*submit_indirect_count)(bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, bgfx_index_buffer_handle_t _numHandle, uint32_t _numIndex, uint16_t _numMax, uint32_t _depth, uint8_t _flags); void (*set_compute_index_buffer)(uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access); void (*set_compute_vertex_buffer)(uint8_t _stage, bgfx_vertex_buffer_handle_t _handle, bgfx_access_t _access); void (*set_compute_dynamic_index_buffer)(uint8_t _stage, bgfx_dynamic_index_buffer_handle_t _handle, bgfx_access_t _access); diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h index c586ac631..fcae3c1bd 100644 --- a/include/bgfx/defines.h +++ b/include/bgfx/defines.h @@ -491,6 +491,7 @@ #define BGFX_CAPS_VERTEX_ATTRIB_UINT10 UINT64_C(0x0000000004000000) //!< Vertex attribute 10_10_10_2 is supported. #define BGFX_CAPS_VERTEX_ID UINT64_C(0x0000000008000000) //!< Rendering with VertexID only is supported. #define BGFX_CAPS_VIEWPORT_LAYER_ARRAY UINT64_C(0x0000000010000000) //!< Viewport layer is available in vertex shader. +#define BGFX_CAPS_DRAW_INDIRECT_COUNT UINT64_C(0x0000000020000000) //!< Draw indirect with indirect count is supported. /// All texture compare modes are supported. #define BGFX_CAPS_TEXTURE_COMPARE_ALL (0 \ | BGFX_CAPS_TEXTURE_COMPARE_RESERVED \ diff --git a/scripts/bgfx.idl b/scripts/bgfx.idl index e311b5428..8f4e226f8 100644 --- a/scripts/bgfx.idl +++ b/scripts/bgfx.idl @@ -394,6 +394,7 @@ flag.Caps { bits = 64, base = 1, name = "Caps" } .VertexAttribUint10 --- Vertex attribute 10_10_10_2 is supported. .VertexId --- Rendering with VertexID only is supported. .ViewportLayerArray --- Viewport layer is available in vertex shader. + .DrawIndirectCount --- Draw indirect with indirect count is supported. .TextureCompareAll --- All texture compare modes are supported. { "TextureCompareReserved", "TextureCompareLequal" } () @@ -2444,6 +2445,9 @@ func.Encoder.submit { cname = "submit_occlusion_query" } --- Submit primitive for rendering with index and instance data info from --- indirect buffer. +--- +--- @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. +--- func.Encoder.submit { cname = "submit_indirect" } "void" .id "ViewId" --- View id. @@ -2451,13 +2455,35 @@ func.Encoder.submit { cname = "submit_indirect" } .indirectHandle "IndirectBufferHandle" --- Indirect buffer. .start "uint16_t" --- First element in indirect buffer. { default = 0 } - .num "uint16_t" --- Number of dispatches. + .num "uint16_t" --- Number of draws. { default = 1 } .depth "uint32_t" --- Depth for sorting. { default = 0 } .flags "uint8_t" --- Discard or preserve states. See `BGFX_DISCARD_*`. { default = "BGFX_DISCARD_ALL" } +--- Submit primitive for rendering with index and instance data info and +--- draw count from indirect buffers. +--- +--- @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT_COUNT`. +--- +func.Encoder.submit { cname = "submit_indirect_count" } + "void" + .id "ViewId" --- View id. + .program "ProgramHandle" --- Program. + .indirectHandle "IndirectBufferHandle" --- Indirect buffer. + .start "uint16_t" --- First element in indirect buffer. + .numHandle "IndexBufferHandle" --- Buffer for number of draws. Must be + --- created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. + .numIndex "uint32_t" --- Element in number buffer. + { default = 0 } + .numMax "uint16_t" --- Max number of draws. + { default = UINT16_MAX } + .depth "uint32_t" --- Depth for sorting. + { default = 0 } + .flags "uint8_t" --- Discard or preserve states. See `BGFX_DISCARD_*`. + { default = "BGFX_DISCARD_ALL" } + --- Set compute index buffer. func.Encoder.setBuffer { cname = "set_compute_index_buffer" } "void" @@ -2997,6 +3023,9 @@ func.submit { cname = "submit_occlusion_query" } --- Submit primitive for rendering with index and instance data info from --- indirect buffer. +--- +--- @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`. +--- func.submit { cname = "submit_indirect" } "void" .id "ViewId" --- View id. @@ -3004,11 +3033,33 @@ func.submit { cname = "submit_indirect" } .indirectHandle "IndirectBufferHandle" --- Indirect buffer. .start "uint16_t" --- First element in indirect buffer. { default = 0 } - .num "uint16_t" --- Number of dispatches. + .num "uint16_t" --- Number of draws. { default = 1 } .depth "uint32_t" --- Depth for sorting. { default = 0 } - .flags "uint8_t" --- Which states to discard for next draw. See `BGFX_DISCARD_*`. + .flags "uint8_t" --- Which states to discard for next draw. See `BGFX_DISCARD_*`. + { default = "BGFX_DISCARD_ALL" } + +--- Submit primitive for rendering with index and instance data info and +--- draw count from indirect buffers. +--- +--- @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT_COUNT`. +--- +func.submit { cname = "submit_indirect_count" } + "void" + .id "ViewId" --- View id. + .program "ProgramHandle" --- Program. + .indirectHandle "IndirectBufferHandle" --- Indirect buffer. + .start "uint16_t" --- First element in indirect buffer. + .numHandle "IndexBufferHandle" --- Buffer for number of draws. Must be + --- created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`. + .numIndex "uint32_t" --- Element in number buffer. + { default = 0 } + .numMax "uint16_t" --- Max number of draws. + { default = UINT16_MAX } + .depth "uint32_t" --- Depth for sorting. + { default = 0 } + .flags "uint8_t" --- Which states to discard for next draw. See `BGFX_DISCARD_*`. { default = "BGFX_DISCARD_ALL" } --- Set compute index buffer. diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 1353bb131..b21c8a450 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -3860,6 +3860,16 @@ namespace bgfx BGFX_ENCODER(submit(_id, _program, _indirectHandle, _start, _num, _depth, _flags) ); } + void Encoder::submit(ViewId _id, ProgramHandle _program, IndirectBufferHandle _indirectHandle, uint16_t _start, IndexBufferHandle _numHandle, uint32_t _numIndex, uint16_t _numMax, uint32_t _depth, uint8_t _flags) + { + BGFX_CHECK_HANDLE_INVALID_OK("submit", s_ctx->m_programHandle, _program); + BGFX_CHECK_HANDLE("submit", s_ctx->m_vertexBufferHandle, _indirectHandle); + BGFX_CHECK_HANDLE("submit", s_ctx->m_indexBufferHandle, _numHandle); + BGFX_CHECK_CAPS(BGFX_CAPS_DRAW_INDIRECT, "Draw indirect is not supported!"); + BGFX_CHECK_CAPS(BGFX_CAPS_DRAW_INDIRECT_COUNT, "Draw indirect count is not supported!"); + BGFX_ENCODER(submit(_id, _program, _indirectHandle, _start, _numHandle, _numIndex, _numMax, _depth, _flags) ); + } + void Encoder::setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access) { BX_ASSERT(_stage < g_caps.limits.maxComputeBindings, "Invalid stage %d (max %d).", _stage, g_caps.limits.maxComputeBindings); @@ -5456,6 +5466,12 @@ namespace bgfx s_ctx->m_encoder0->submit(_id, _program, _indirectHandle, _start, _num, _depth, _flags); } + void submit(ViewId _id, ProgramHandle _program, IndirectBufferHandle _indirectHandle, uint16_t _start, IndexBufferHandle _numHandle, uint32_t _numIndex, uint16_t _numMax, uint32_t _depth, uint8_t _flags) + { + BGFX_CHECK_ENCODER0(); + s_ctx->m_encoder0->submit(_id, _program, _indirectHandle, _start, _numHandle, _numIndex, _numMax, _depth, _flags); + } + void setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access) { BGFX_CHECK_ENCODER0(); @@ -5732,6 +5748,8 @@ BX_STATIC_ASSERT( (0 | BGFX_CAPS_VERTEX_ATTRIB_HALF | BGFX_CAPS_VERTEX_ATTRIB_UINT10 | BGFX_CAPS_VERTEX_ID + | BGFX_CAPS_VIEWPORT_LAYER_ARRAY + | BGFX_CAPS_DRAW_INDIRECT_COUNT ) == (0 ^ BGFX_CAPS_ALPHA_TO_COVERAGE ^ BGFX_CAPS_BLEND_INDEPENDENT @@ -5757,6 +5775,8 @@ BX_STATIC_ASSERT( (0 ^ BGFX_CAPS_VERTEX_ATTRIB_HALF ^ BGFX_CAPS_VERTEX_ATTRIB_UINT10 ^ BGFX_CAPS_VERTEX_ID + ^ BGFX_CAPS_VIEWPORT_LAYER_ARRAY + ^ BGFX_CAPS_DRAW_INDIRECT_COUNT ) ); #undef FLAGS_MASK_TEST diff --git a/src/bgfx.idl.inl b/src/bgfx.idl.inl index b539a8846..2c3b16fe4 100644 --- a/src/bgfx.idl.inl +++ b/src/bgfx.idl.inl @@ -885,6 +885,15 @@ BGFX_C_API void bgfx_encoder_submit_indirect(bgfx_encoder_t* _this, bgfx_view_id This->submit((bgfx::ViewId)_id, program.cpp, indirectHandle.cpp, _start, _num, _depth, _flags); } +BGFX_C_API void bgfx_encoder_submit_indirect_count(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, bgfx_index_buffer_handle_t _numHandle, uint32_t _numIndex, uint16_t _numMax, uint32_t _depth, uint8_t _flags) +{ + bgfx::Encoder* This = (bgfx::Encoder*)_this; + union { bgfx_program_handle_t c; bgfx::ProgramHandle cpp; } program = { _program }; + union { bgfx_indirect_buffer_handle_t c; bgfx::IndirectBufferHandle cpp; } indirectHandle = { _indirectHandle }; + union { bgfx_index_buffer_handle_t c; bgfx::IndexBufferHandle cpp; } numHandle = { _numHandle }; + This->submit((bgfx::ViewId)_id, program.cpp, indirectHandle.cpp, _start, numHandle.cpp, _numIndex, _numMax, _depth, _flags); +} + BGFX_C_API void bgfx_encoder_set_compute_index_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access) { bgfx::Encoder* This = (bgfx::Encoder*)_this; @@ -1155,6 +1164,14 @@ BGFX_C_API void bgfx_submit_indirect(bgfx_view_id_t _id, bgfx_program_handle_t _ bgfx::submit((bgfx::ViewId)_id, program.cpp, indirectHandle.cpp, _start, _num, _depth, _flags); } +BGFX_C_API void bgfx_submit_indirect_count(bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, bgfx_index_buffer_handle_t _numHandle, uint32_t _numIndex, uint16_t _numMax, uint32_t _depth, uint8_t _flags) +{ + union { bgfx_program_handle_t c; bgfx::ProgramHandle cpp; } program = { _program }; + union { bgfx_indirect_buffer_handle_t c; bgfx::IndirectBufferHandle cpp; } indirectHandle = { _indirectHandle }; + union { bgfx_index_buffer_handle_t c; bgfx::IndexBufferHandle cpp; } numHandle = { _numHandle }; + bgfx::submit((bgfx::ViewId)_id, program.cpp, indirectHandle.cpp, _start, numHandle.cpp, _numIndex, _numMax, _depth, _flags); +} + BGFX_C_API void bgfx_set_compute_index_buffer(uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access) { union { bgfx_index_buffer_handle_t c; bgfx::IndexBufferHandle cpp; } handle = { _handle }; @@ -1393,6 +1410,7 @@ BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version) bgfx_encoder_submit, bgfx_encoder_submit_occlusion_query, bgfx_encoder_submit_indirect, + bgfx_encoder_submit_indirect_count, bgfx_encoder_set_compute_index_buffer, bgfx_encoder_set_compute_vertex_buffer, bgfx_encoder_set_compute_dynamic_index_buffer, @@ -1438,6 +1456,7 @@ BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version) bgfx_submit, bgfx_submit_occlusion_query, bgfx_submit_indirect, + bgfx_submit_indirect_count, bgfx_set_compute_index_buffer, bgfx_set_compute_vertex_buffer, bgfx_set_compute_dynamic_index_buffer, diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 879729a34..bdaab761a 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -1676,8 +1676,10 @@ namespace bgfx } m_startIndirect = 0; - m_numIndirect = UINT16_MAX; + m_numIndirect = UINT16_MAX; + m_numIndirectIndex = 0; m_indirectBuffer.idx = kInvalidHandle; + m_numIndirectBuffer.idx = kInvalidHandle; m_occlusionQuery.idx = kInvalidHandle; } @@ -1710,6 +1712,7 @@ namespace bgfx uint16_t m_instanceDataStride; uint16_t m_startIndirect; uint16_t m_numIndirect; + uint32_t m_numIndirectIndex; uint16_t m_numMatrices; uint16_t m_scissor; uint8_t m_submitFlags; @@ -1719,6 +1722,7 @@ namespace bgfx IndexBufferHandle m_indexBuffer; VertexBufferHandle m_instanceDataBuffer; IndirectBufferHandle m_indirectBuffer; + IndexBufferHandle m_numIndirectBuffer; OcclusionQueryHandle m_occlusionQuery; }; @@ -2698,6 +2702,13 @@ namespace bgfx submit(_id, _program, handle, _depth, _flags); } + void submit(ViewId _id, ProgramHandle _program, IndirectBufferHandle _indirectHandle, uint16_t _start, IndexBufferHandle _numHandle, uint32_t _numIndex, uint16_t _numMax, uint32_t _depth, uint8_t _flags) + { + m_draw.m_numIndirectIndex = _numIndex; + m_draw.m_numIndirectBuffer = _numHandle; + submit(_id, _program, _indirectHandle, _start, _numMax, _depth, _flags); + } + void dispatch(ViewId _id, ProgramHandle _handle, uint32_t _ngx, uint32_t _ngy, uint32_t _ngz, uint8_t _flags); void dispatch(ViewId _id, ProgramHandle _handle, IndirectBufferHandle _indirectHandle, uint16_t _start, uint16_t _num, uint8_t _flags) diff --git a/src/glimports.h b/src/glimports.h index b36d7f62c..796cda023 100644 --- a/src/glimports.h +++ b/src/glimports.h @@ -368,6 +368,8 @@ GL_IMPORT______(false, PFNGLLINKPROGRAMPROC, glLinkProgram GL_IMPORT______(true, PFNGLMEMORYBARRIERPROC, glMemoryBarrier); GL_IMPORT______(true, PFNGLMULTIDRAWARRAYSINDIRECTPROC, glMultiDrawArraysIndirect); GL_IMPORT______(true, PFNGLMULTIDRAWELEMENTSINDIRECTPROC, glMultiDrawElementsIndirect); +GL_IMPORT______(true, PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC, glMultiDrawArraysIndirectCount); +GL_IMPORT______(true, PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC, glMultiDrawElementsIndirectCount); GL_IMPORT______(true, PFNGLOBJECTLABELPROC, glObjectLabel); GL_IMPORT______(true, PFNGLOBJECTPTRLABELPROC, glObjectPtrLabel); GL_IMPORT______(false, PFNGLPIXELSTOREIPROC, glPixelStorei); @@ -458,6 +460,9 @@ GL_IMPORT_ARB__(true, PFNGLINVALIDATEFRAMEBUFFERPROC, glInvalidateF GL_IMPORT_ARB__(true, PFNGLMULTIDRAWARRAYSINDIRECTPROC, glMultiDrawArraysIndirect); GL_IMPORT_ARB__(true, PFNGLMULTIDRAWELEMENTSINDIRECTPROC, glMultiDrawElementsIndirect); +GL_IMPORT_ARB__(true, PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC, glMultiDrawArraysIndirectCount); +GL_IMPORT_ARB__(true, PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC, glMultiDrawElementsIndirectCount); + GL_IMPORT_EXT__(true, PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer); GL_IMPORT_EXT__(true, PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers); GL_IMPORT_EXT__(true, PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers); diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 4242541be..55495d17f 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -1205,6 +1205,7 @@ namespace bgfx { namespace d3d12 | BGFX_CAPS_TEXTURE_CUBE_ARRAY | BGFX_CAPS_IMAGE_RW | BGFX_CAPS_VIEWPORT_LAYER_ARRAY + | BGFX_CAPS_DRAW_INDIRECT_COUNT ); g_caps.limits.maxTextureSize = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; g_caps.limits.maxTextureLayers = D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; @@ -4134,6 +4135,13 @@ namespace bgfx { namespace d3d12 ? indirect.m_size/BGFX_CONFIG_DRAW_INDIRECT_STRIDE : _draw.m_numIndirect ; + ID3D12Resource* numIndirect = NULL; + uint32_t numOffsetIndirect = 0; + if (isValid(_draw.m_numIndirectBuffer) ) + { + numIndirect = s_renderD3D12->m_indexBuffers[_draw.m_numIndirectBuffer.idx].m_ptr; + numOffsetIndirect = _draw.m_numIndirectIndex * sizeof(uint32_t); + } uint32_t numIndices = 0; @@ -4165,8 +4173,8 @@ namespace bgfx { namespace d3d12 , numDrawIndirect , indirect.m_ptr , _draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE - , NULL - , 0 + , numIndirect + , numOffsetIndirect ); } else @@ -4176,8 +4184,8 @@ namespace bgfx { namespace d3d12 , numDrawIndirect , indirect.m_ptr , _draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE - , NULL - , 0 + , numIndirect + , numOffsetIndirect ); } @@ -4441,8 +4449,8 @@ namespace bgfx { namespace d3d12 #if BX_PLATFORM_XBOXONE flags |= D3D12XBOX_RESOURCE_FLAG_ALLOW_INDIRECT_BUFFER; #endif // BX_PLATFORM_XBOXONE - format = DXGI_FORMAT_R32G32B32A32_UINT; - stride = 16; + format = _vertex ? DXGI_FORMAT_R32G32B32A32_UINT : DXGI_FORMAT_R32_UINT; + stride = _vertex ? 16 : 4; } else { diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 2b98fc81e..c99da325c 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -539,6 +539,7 @@ namespace bgfx { namespace gl ARB_get_program_binary, ARB_half_float_pixel, ARB_half_float_vertex, + ARB_indirect_parameters, ARB_instanced_arrays, ARB_internalformat_query, ARB_internalformat_query2, @@ -756,6 +757,7 @@ namespace bgfx { namespace gl { "ARB_get_program_binary", BGFX_CONFIG_RENDERER_OPENGL >= 41, true }, { "ARB_half_float_pixel", BGFX_CONFIG_RENDERER_OPENGL >= 30, true }, { "ARB_half_float_vertex", BGFX_CONFIG_RENDERER_OPENGL >= 30, true }, + { "ARB_indirect_parameters", BGFX_CONFIG_RENDERER_OPENGL >= 46, true }, { "ARB_instanced_arrays", BGFX_CONFIG_RENDERER_OPENGL >= 33, true }, { "ARB_internalformat_query", BGFX_CONFIG_RENDERER_OPENGL >= 42, true }, { "ARB_internalformat_query2", BGFX_CONFIG_RENDERER_OPENGL >= 43, true }, @@ -2829,6 +2831,11 @@ namespace bgfx { namespace gl : 0 ; + g_caps.supported |= s_extension[Extension::ARB_indirect_parameters].m_supported + ? BGFX_CAPS_DRAW_INDIRECT_COUNT + : 0 + ; + if (BX_ENABLED(BX_PLATFORM_EMSCRIPTEN) || NULL == glPolygonMode) { @@ -8412,6 +8419,19 @@ namespace bgfx { namespace gl GL_CHECK(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, vb.m_id) ); } + uint32_t numOffsetIndirect = 0; + if (isValid(draw.m_numIndirectBuffer) ) + { + if (currentState.m_numIndirectBuffer.idx != draw.m_numIndirectBuffer.idx) + { + const IndexBufferGL& nb = m_indexBuffers[draw.m_numIndirectBuffer.idx]; + currentState.m_numIndirectBuffer = draw.m_numIndirectBuffer; + GL_CHECK(glBindBuffer(GL_PARAMETER_BUFFER_ARB, nb.m_id) ); + } + + numOffsetIndirect = draw.m_numIndirectIndex * sizeof(uint32_t); + } + if (isValid(draw.m_indexBuffer) ) { const IndexBufferGL& ib = m_indexBuffers[draw.m_indexBuffer.idx]; @@ -8427,11 +8447,24 @@ namespace bgfx { namespace gl ; uintptr_t args = draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE; - GL_CHECK(glMultiDrawElementsIndirect(prim.m_type, indexFormat - , (void*)args - , numDrawIndirect - , BGFX_CONFIG_DRAW_INDIRECT_STRIDE - ) ); + + if (isValid(draw.m_numIndirectBuffer) ) + { + GL_CHECK(glMultiDrawElementsIndirectCount(prim.m_type, indexFormat + , (void*)args + , numOffsetIndirect + , numDrawIndirect + , BGFX_CONFIG_DRAW_INDIRECT_STRIDE + ) ); + } + else + { + GL_CHECK(glMultiDrawElementsIndirect(prim.m_type, indexFormat + , (void*)args + , numDrawIndirect + , BGFX_CONFIG_DRAW_INDIRECT_STRIDE + ) ); + } } else { @@ -8441,11 +8474,24 @@ namespace bgfx { namespace gl ; uintptr_t args = draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE; - GL_CHECK(glMultiDrawArraysIndirect(prim.m_type - , (void*)args - , numDrawIndirect - , BGFX_CONFIG_DRAW_INDIRECT_STRIDE - ) ); + + if (isValid(draw.m_numIndirectBuffer) ) + { + GL_CHECK(glMultiDrawArraysIndirectCount(prim.m_type + , (void*)args + , numOffsetIndirect + , numDrawIndirect + , BGFX_CONFIG_DRAW_INDIRECT_STRIDE + ) ); + } + else + { + GL_CHECK(glMultiDrawArraysIndirect(prim.m_type + , (void*)args + , numDrawIndirect + , BGFX_CONFIG_DRAW_INDIRECT_STRIDE + ) ); + } } } else @@ -8454,6 +8500,12 @@ namespace bgfx { namespace gl { currentState.m_indirectBuffer.idx = kInvalidHandle; GL_CHECK(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0) ); + + if (isValid(currentState.m_numIndirectBuffer) ) + { + currentState.m_numIndirectBuffer.idx = kInvalidHandle; + GL_CHECK(glBindBuffer(GL_PARAMETER_BUFFER_ARB, 0) ); + } } if (isValid(draw.m_indexBuffer) ) diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index 20f0f658e..e921b504c 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -329,6 +329,7 @@ VK_IMPORT_DEVICE EXT_line_rasterization, EXT_shader_viewport_index_layer, EXT_custom_border_color, + KHR_draw_indirect_count, Count }; @@ -353,6 +354,7 @@ VK_IMPORT_DEVICE { "VK_EXT_line_rasterization", 1, false, false, true , Layer::Count }, { "VK_EXT_shader_viewport_index_layer", 1, false, false, true , Layer::Count }, { "VK_EXT_custom_border_color", 1, false, false, true , Layer::Count }, + { "VK_KHR_draw_indirect_count", 1, false, false, true , Layer::Count }, }; BX_STATIC_ASSERT(Extension::Count == BX_COUNTOF(s_extension) ); @@ -1178,6 +1180,7 @@ VK_IMPORT s_extension[Extension::EXT_shader_viewport_index_layer].m_initialize = !!(_init.capabilities & BGFX_CAPS_VIEWPORT_LAYER_ARRAY); s_extension[Extension::EXT_conservative_rasterization ].m_initialize = !!(_init.capabilities & BGFX_CAPS_CONSERVATIVE_RASTER ); + s_extension[Extension::KHR_draw_indirect_count ].m_initialize = !!(_init.capabilities & BGFX_CAPS_DRAW_INDIRECT_COUNT ); dumpExtensions(VK_NULL_HANDLE, s_extension); @@ -1570,6 +1573,7 @@ VK_IMPORT_INSTANCE g_caps.supported |= 0 | (s_extension[Extension::EXT_conservative_rasterization ].m_supported ? BGFX_CAPS_CONSERVATIVE_RASTER : 0) | (s_extension[Extension::EXT_shader_viewport_index_layer].m_supported ? BGFX_CAPS_VIEWPORT_LAYER_ARRAY : 0) + | (s_extension[Extension::KHR_draw_indirect_count ].m_supported && indirectDrawSupport ? BGFX_CAPS_DRAW_INDIRECT_COUNT : 0) ; const uint32_t maxAttachments = bx::min(m_deviceProperties.limits.maxFragmentOutputAttachments, m_deviceProperties.limits.maxColorAttachments); @@ -8683,8 +8687,10 @@ VK_DESTROY } VkBuffer bufferIndirect = VK_NULL_HANDLE; + VkBuffer bufferNumIndirect = VK_NULL_HANDLE; uint32_t numDrawIndirect = 0; uint32_t bufferOffsetIndirect = 0; + uint32_t bufferNumOffsetIndirect = 0; if (isValid(draw.m_indirectBuffer) ) { const VertexBufferVK& vb = m_vertexBuffers[draw.m_indirectBuffer.idx]; @@ -8694,6 +8700,12 @@ VK_DESTROY : draw.m_numIndirect ; bufferOffsetIndirect = draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE; + + if (isValid(draw.m_numIndirectBuffer) ) + { + bufferNumIndirect = m_indexBuffers[draw.m_numIndirectBuffer.idx].m_buffer; + bufferNumOffsetIndirect = draw.m_numIndirectIndex * sizeof(uint32_t); + } } if (hasOcclusionQuery) @@ -8713,13 +8725,28 @@ VK_DESTROY if (isValid(draw.m_indirectBuffer) ) { - vkCmdDrawIndirect( - m_commandBuffer - , bufferIndirect - , bufferOffsetIndirect - , numDrawIndirect - , BGFX_CONFIG_DRAW_INDIRECT_STRIDE - ); + if (isValid(draw.m_numIndirectBuffer) ) + { + vkCmdDrawIndirectCountKHR( + m_commandBuffer + , bufferIndirect + , bufferOffsetIndirect + , bufferNumIndirect + , bufferNumOffsetIndirect + , numDrawIndirect + , BGFX_CONFIG_DRAW_INDIRECT_STRIDE + ); + } + else + { + vkCmdDrawIndirect( + m_commandBuffer + , bufferIndirect + , bufferOffsetIndirect + , numDrawIndirect + , BGFX_CONFIG_DRAW_INDIRECT_STRIDE + ); + } } else { @@ -8762,13 +8789,28 @@ VK_DESTROY if (isValid(draw.m_indirectBuffer) ) { - vkCmdDrawIndexedIndirect( - m_commandBuffer - , bufferIndirect - , bufferOffsetIndirect - , numDrawIndirect - , BGFX_CONFIG_DRAW_INDIRECT_STRIDE - ); + if (isValid(draw.m_numIndirectBuffer) ) + { + vkCmdDrawIndexedIndirectCountKHR( + m_commandBuffer + , bufferIndirect + , bufferOffsetIndirect + , bufferNumIndirect + , bufferNumOffsetIndirect + , numDrawIndirect + , BGFX_CONFIG_DRAW_INDIRECT_STRIDE + ); + } + else + { + vkCmdDrawIndexedIndirect( + m_commandBuffer + , bufferIndirect + , bufferOffsetIndirect + , numDrawIndirect + , BGFX_CONFIG_DRAW_INDIRECT_STRIDE + ); + } } else { diff --git a/src/renderer_vk.h b/src/renderer_vk.h index a65da97eb..e8d11917e 100644 --- a/src/renderer_vk.h +++ b/src/renderer_vk.h @@ -96,110 +96,113 @@ VK_IMPORT_INSTANCE_FUNC(true, vkDestroyDebugReportCallbackEXT); \ VK_IMPORT_INSTANCE_PLATFORM -#define VK_IMPORT_DEVICE \ - VK_IMPORT_DEVICE_FUNC(false, vkGetDeviceQueue); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreateFence); \ - VK_IMPORT_DEVICE_FUNC(false, vkDestroyFence); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreateSemaphore); \ - VK_IMPORT_DEVICE_FUNC(false, vkDestroySemaphore); \ - VK_IMPORT_DEVICE_FUNC(false, vkResetFences); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreateCommandPool); \ - VK_IMPORT_DEVICE_FUNC(false, vkDestroyCommandPool); \ - VK_IMPORT_DEVICE_FUNC(false, vkResetCommandPool); \ - VK_IMPORT_DEVICE_FUNC(false, vkAllocateCommandBuffers); \ - VK_IMPORT_DEVICE_FUNC(false, vkFreeCommandBuffers); \ - VK_IMPORT_DEVICE_FUNC(false, vkGetBufferMemoryRequirements); \ - VK_IMPORT_DEVICE_FUNC(false, vkGetImageMemoryRequirements); \ - VK_IMPORT_DEVICE_FUNC(false, vkGetImageSubresourceLayout); \ - VK_IMPORT_DEVICE_FUNC(false, vkAllocateMemory); \ - VK_IMPORT_DEVICE_FUNC(false, vkFreeMemory); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreateImage); \ - VK_IMPORT_DEVICE_FUNC(false, vkDestroyImage); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreateImageView); \ - VK_IMPORT_DEVICE_FUNC(false, vkDestroyImageView); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreateBuffer); \ - VK_IMPORT_DEVICE_FUNC(false, vkDestroyBuffer); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreateFramebuffer); \ - VK_IMPORT_DEVICE_FUNC(false, vkDestroyFramebuffer); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreateRenderPass); \ - VK_IMPORT_DEVICE_FUNC(false, vkDestroyRenderPass); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreateShaderModule); \ - VK_IMPORT_DEVICE_FUNC(false, vkDestroyShaderModule); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreatePipelineCache); \ - VK_IMPORT_DEVICE_FUNC(false, vkDestroyPipelineCache); \ - VK_IMPORT_DEVICE_FUNC(false, vkGetPipelineCacheData); \ - VK_IMPORT_DEVICE_FUNC(false, vkMergePipelineCaches); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreateGraphicsPipelines); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreateComputePipelines); \ - VK_IMPORT_DEVICE_FUNC(false, vkDestroyPipeline); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreatePipelineLayout); \ - VK_IMPORT_DEVICE_FUNC(false, vkDestroyPipelineLayout); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreateSampler); \ - VK_IMPORT_DEVICE_FUNC(false, vkDestroySampler); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreateDescriptorSetLayout); \ - VK_IMPORT_DEVICE_FUNC(false, vkDestroyDescriptorSetLayout); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreateDescriptorPool); \ - VK_IMPORT_DEVICE_FUNC(false, vkDestroyDescriptorPool); \ - VK_IMPORT_DEVICE_FUNC(false, vkResetDescriptorPool); \ - VK_IMPORT_DEVICE_FUNC(false, vkAllocateDescriptorSets); \ - VK_IMPORT_DEVICE_FUNC(false, vkFreeDescriptorSets); \ - VK_IMPORT_DEVICE_FUNC(false, vkUpdateDescriptorSets); \ - VK_IMPORT_DEVICE_FUNC(false, vkCreateQueryPool); \ - VK_IMPORT_DEVICE_FUNC(false, vkDestroyQueryPool); \ - VK_IMPORT_DEVICE_FUNC(false, vkQueueSubmit); \ - VK_IMPORT_DEVICE_FUNC(false, vkQueueWaitIdle); \ - VK_IMPORT_DEVICE_FUNC(false, vkDeviceWaitIdle); \ - VK_IMPORT_DEVICE_FUNC(false, vkWaitForFences); \ - VK_IMPORT_DEVICE_FUNC(false, vkBeginCommandBuffer); \ - VK_IMPORT_DEVICE_FUNC(false, vkEndCommandBuffer); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdPipelineBarrier); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdBeginRenderPass); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdEndRenderPass); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdSetViewport); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdDraw); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdDrawIndexed); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdDrawIndirect); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdDrawIndexedIndirect); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdDispatch); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdDispatchIndirect); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdBindPipeline); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdSetStencilReference); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdSetBlendConstants); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdSetScissor); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdBindDescriptorSets); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdBindIndexBuffer); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdBindVertexBuffers); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdClearColorImage); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdClearDepthStencilImage); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdClearAttachments); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdResolveImage); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyBuffer); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyBufferToImage); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyImage); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyImageToBuffer); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdBlitImage); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdResetQueryPool); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdWriteTimestamp); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdBeginQuery); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdEndQuery); \ - VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyQueryPoolResults); \ - VK_IMPORT_DEVICE_FUNC(false, vkMapMemory); \ - VK_IMPORT_DEVICE_FUNC(false, vkUnmapMemory); \ - VK_IMPORT_DEVICE_FUNC(false, vkFlushMappedMemoryRanges); \ - VK_IMPORT_DEVICE_FUNC(false, vkInvalidateMappedMemoryRanges); \ - VK_IMPORT_DEVICE_FUNC(false, vkBindBufferMemory); \ - VK_IMPORT_DEVICE_FUNC(false, vkBindImageMemory); \ - /* VK_KHR_swapchain */ \ - VK_IMPORT_DEVICE_FUNC(true, vkCreateSwapchainKHR); \ - VK_IMPORT_DEVICE_FUNC(true, vkDestroySwapchainKHR); \ - VK_IMPORT_DEVICE_FUNC(true, vkGetSwapchainImagesKHR); \ - VK_IMPORT_DEVICE_FUNC(true, vkAcquireNextImageKHR); \ - VK_IMPORT_DEVICE_FUNC(true, vkQueuePresentKHR); \ - /* VK_EXT_debug_utils */ \ - VK_IMPORT_DEVICE_FUNC(true, vkSetDebugUtilsObjectNameEXT); \ - VK_IMPORT_DEVICE_FUNC(true, vkCmdBeginDebugUtilsLabelEXT); \ - VK_IMPORT_DEVICE_FUNC(true, vkCmdEndDebugUtilsLabelEXT); \ - VK_IMPORT_DEVICE_FUNC(true, vkCmdInsertDebugUtilsLabelEXT); \ +#define VK_IMPORT_DEVICE \ + VK_IMPORT_DEVICE_FUNC(false, vkGetDeviceQueue); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreateFence); \ + VK_IMPORT_DEVICE_FUNC(false, vkDestroyFence); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreateSemaphore); \ + VK_IMPORT_DEVICE_FUNC(false, vkDestroySemaphore); \ + VK_IMPORT_DEVICE_FUNC(false, vkResetFences); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreateCommandPool); \ + VK_IMPORT_DEVICE_FUNC(false, vkDestroyCommandPool); \ + VK_IMPORT_DEVICE_FUNC(false, vkResetCommandPool); \ + VK_IMPORT_DEVICE_FUNC(false, vkAllocateCommandBuffers); \ + VK_IMPORT_DEVICE_FUNC(false, vkFreeCommandBuffers); \ + VK_IMPORT_DEVICE_FUNC(false, vkGetBufferMemoryRequirements); \ + VK_IMPORT_DEVICE_FUNC(false, vkGetImageMemoryRequirements); \ + VK_IMPORT_DEVICE_FUNC(false, vkGetImageSubresourceLayout); \ + VK_IMPORT_DEVICE_FUNC(false, vkAllocateMemory); \ + VK_IMPORT_DEVICE_FUNC(false, vkFreeMemory); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreateImage); \ + VK_IMPORT_DEVICE_FUNC(false, vkDestroyImage); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreateImageView); \ + VK_IMPORT_DEVICE_FUNC(false, vkDestroyImageView); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreateBuffer); \ + VK_IMPORT_DEVICE_FUNC(false, vkDestroyBuffer); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreateFramebuffer); \ + VK_IMPORT_DEVICE_FUNC(false, vkDestroyFramebuffer); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreateRenderPass); \ + VK_IMPORT_DEVICE_FUNC(false, vkDestroyRenderPass); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreateShaderModule); \ + VK_IMPORT_DEVICE_FUNC(false, vkDestroyShaderModule); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreatePipelineCache); \ + VK_IMPORT_DEVICE_FUNC(false, vkDestroyPipelineCache); \ + VK_IMPORT_DEVICE_FUNC(false, vkGetPipelineCacheData); \ + VK_IMPORT_DEVICE_FUNC(false, vkMergePipelineCaches); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreateGraphicsPipelines); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreateComputePipelines); \ + VK_IMPORT_DEVICE_FUNC(false, vkDestroyPipeline); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreatePipelineLayout); \ + VK_IMPORT_DEVICE_FUNC(false, vkDestroyPipelineLayout); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreateSampler); \ + VK_IMPORT_DEVICE_FUNC(false, vkDestroySampler); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreateDescriptorSetLayout); \ + VK_IMPORT_DEVICE_FUNC(false, vkDestroyDescriptorSetLayout); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreateDescriptorPool); \ + VK_IMPORT_DEVICE_FUNC(false, vkDestroyDescriptorPool); \ + VK_IMPORT_DEVICE_FUNC(false, vkResetDescriptorPool); \ + VK_IMPORT_DEVICE_FUNC(false, vkAllocateDescriptorSets); \ + VK_IMPORT_DEVICE_FUNC(false, vkFreeDescriptorSets); \ + VK_IMPORT_DEVICE_FUNC(false, vkUpdateDescriptorSets); \ + VK_IMPORT_DEVICE_FUNC(false, vkCreateQueryPool); \ + VK_IMPORT_DEVICE_FUNC(false, vkDestroyQueryPool); \ + VK_IMPORT_DEVICE_FUNC(false, vkQueueSubmit); \ + VK_IMPORT_DEVICE_FUNC(false, vkQueueWaitIdle); \ + VK_IMPORT_DEVICE_FUNC(false, vkDeviceWaitIdle); \ + VK_IMPORT_DEVICE_FUNC(false, vkWaitForFences); \ + VK_IMPORT_DEVICE_FUNC(false, vkBeginCommandBuffer); \ + VK_IMPORT_DEVICE_FUNC(false, vkEndCommandBuffer); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdPipelineBarrier); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdBeginRenderPass); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdEndRenderPass); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdSetViewport); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdDraw); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdDrawIndexed); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdDrawIndirect); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdDrawIndexedIndirect); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdDispatch); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdDispatchIndirect); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdBindPipeline); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdSetStencilReference); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdSetBlendConstants); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdSetScissor); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdBindDescriptorSets); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdBindIndexBuffer); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdBindVertexBuffers); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdClearColorImage); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdClearDepthStencilImage); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdClearAttachments); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdResolveImage); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyBuffer); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyBufferToImage); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyImage); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyImageToBuffer); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdBlitImage); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdResetQueryPool); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdWriteTimestamp); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdBeginQuery); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdEndQuery); \ + VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyQueryPoolResults); \ + VK_IMPORT_DEVICE_FUNC(false, vkMapMemory); \ + VK_IMPORT_DEVICE_FUNC(false, vkUnmapMemory); \ + VK_IMPORT_DEVICE_FUNC(false, vkFlushMappedMemoryRanges); \ + VK_IMPORT_DEVICE_FUNC(false, vkInvalidateMappedMemoryRanges); \ + VK_IMPORT_DEVICE_FUNC(false, vkBindBufferMemory); \ + VK_IMPORT_DEVICE_FUNC(false, vkBindImageMemory); \ + /* VK_KHR_swapchain */ \ + VK_IMPORT_DEVICE_FUNC(true, vkCreateSwapchainKHR); \ + VK_IMPORT_DEVICE_FUNC(true, vkDestroySwapchainKHR); \ + VK_IMPORT_DEVICE_FUNC(true, vkGetSwapchainImagesKHR); \ + VK_IMPORT_DEVICE_FUNC(true, vkAcquireNextImageKHR); \ + VK_IMPORT_DEVICE_FUNC(true, vkQueuePresentKHR); \ + /* VK_EXT_debug_utils */ \ + VK_IMPORT_DEVICE_FUNC(true, vkSetDebugUtilsObjectNameEXT); \ + VK_IMPORT_DEVICE_FUNC(true, vkCmdBeginDebugUtilsLabelEXT); \ + VK_IMPORT_DEVICE_FUNC(true, vkCmdEndDebugUtilsLabelEXT); \ + VK_IMPORT_DEVICE_FUNC(true, vkCmdInsertDebugUtilsLabelEXT); \ + /* VK_KHR_draw_indirect_count */ \ + VK_IMPORT_DEVICE_FUNC(true, vkCmdDrawIndirectCountKHR); \ + VK_IMPORT_DEVICE_FUNC(true, vkCmdDrawIndexedIndirectCountKHR); \ #define VK_DESTROY \ VK_DESTROY_FUNC(Buffer); \