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); \