Add support for indirect draw with indirect count (#2925)

* Add indirect draw with indirect count (BGFX_CAPS_DRAW_INDIRECT_COUNT)

* Update bindings

* VK: Add support for BGFX_CAPS_DRAW_INDIRECT_COUNT

* D3D12: Add support for BGFX_CAPS_DRAW_INDIRECT_COUNT

* GL: Add support for BGFX_CAPS_DRAW_INDIRECT_COUNT

* 48-drawindirect: Use BGFX_CAPS_DRAW_INDIRECT_COUNT if available

* 48-drawindirect: Update shaders
This commit is contained in:
pezcode 2022-09-18 03:16:19 +02:00 committed by GitHub
parent 408988946d
commit ba467be036
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 808 additions and 209 deletions

View File

@ -1152,6 +1152,11 @@ public static class bgfx
/// </summary>
ViewportLayerArray = 0x0000000010000000,
/// <summary>
/// Draw indirect with indirect count is supported.
/// </summary>
DrawIndirectCount = 0x0000000020000000,
/// <summary>
/// All texture compare modes are supported.
/// </summary>
@ -3901,19 +3906,39 @@ public static class bgfx
/// <summary>
/// Submit primitive for rendering with index and instance data info from
/// indirect buffer.
/// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
/// </summary>
///
/// <param name="_id">View id.</param>
/// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in indirect buffer.</param>
/// <param name="_num">Number of dispatches.</param>
/// <param name="_num">Number of draws.</param>
/// <param name="_depth">Depth for sorting.</param>
/// <param name="_flags">Discard or preserve states. See `BGFX_DISCARD_*`.</param>
///
[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);
/// <summary>
/// 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`.
/// </summary>
///
/// <param name="_id">View id.</param>
/// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in indirect buffer.</param>
/// <param name="_numHandle">Buffer for number of draws. Must be created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`.</param>
/// <param name="_numIndex">Element in number buffer.</param>
/// <param name="_numMax">Max number of draws.</param>
/// <param name="_depth">Depth for sorting.</param>
/// <param name="_flags">Discard or preserve states. See `BGFX_DISCARD_*`.</param>
///
[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);
/// <summary>
/// Set compute index buffer.
/// </summary>
@ -4457,19 +4482,39 @@ public static class bgfx
/// <summary>
/// Submit primitive for rendering with index and instance data info from
/// indirect buffer.
/// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
/// </summary>
///
/// <param name="_id">View id.</param>
/// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in indirect buffer.</param>
/// <param name="_num">Number of dispatches.</param>
/// <param name="_num">Number of draws.</param>
/// <param name="_depth">Depth for sorting.</param>
/// <param name="_flags">Which states to discard for next draw. See `BGFX_DISCARD_*`.</param>
///
[LinkName("bgfx_submit_indirect")]
public static extern void submit_indirect(ViewId _id, ProgramHandle _program, IndirectBufferHandle _indirectHandle, uint16 _start, uint16 _num, uint32 _depth, uint8 _flags);
/// <summary>
/// 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`.
/// </summary>
///
/// <param name="_id">View id.</param>
/// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in indirect buffer.</param>
/// <param name="_numHandle">Buffer for number of draws. Must be created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`.</param>
/// <param name="_numIndex">Element in number buffer.</param>
/// <param name="_numMax">Max number of draws.</param>
/// <param name="_depth">Depth for sorting.</param>
/// <param name="_flags">Which states to discard for next draw. See `BGFX_DISCARD_*`.</param>
///
[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);
/// <summary>
/// Set compute index buffer.
/// </summary>

View File

@ -1151,6 +1151,11 @@ public static partial class bgfx
/// </summary>
ViewportLayerArray = 0x0000000010000000,
/// <summary>
/// Draw indirect with indirect count is supported.
/// </summary>
DrawIndirectCount = 0x0000000020000000,
/// <summary>
/// All texture compare modes are supported.
/// </summary>
@ -3858,19 +3863,39 @@ public static partial class bgfx
/// <summary>
/// Submit primitive for rendering with index and instance data info from
/// indirect buffer.
/// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
/// </summary>
///
/// <param name="_id">View id.</param>
/// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in indirect buffer.</param>
/// <param name="_num">Number of dispatches.</param>
/// <param name="_num">Number of draws.</param>
/// <param name="_depth">Depth for sorting.</param>
/// <param name="_flags">Discard or preserve states. See `BGFX_DISCARD_*`.</param>
///
[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);
/// <summary>
/// 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`.
/// </summary>
///
/// <param name="_id">View id.</param>
/// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in indirect buffer.</param>
/// <param name="_numHandle">Buffer for number of draws. Must be created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`.</param>
/// <param name="_numIndex">Element in number buffer.</param>
/// <param name="_numMax">Max number of draws.</param>
/// <param name="_depth">Depth for sorting.</param>
/// <param name="_flags">Discard or preserve states. See `BGFX_DISCARD_*`.</param>
///
[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);
/// <summary>
/// Set compute index buffer.
/// </summary>
@ -4414,19 +4439,39 @@ public static partial class bgfx
/// <summary>
/// Submit primitive for rendering with index and instance data info from
/// indirect buffer.
/// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
/// </summary>
///
/// <param name="_id">View id.</param>
/// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in indirect buffer.</param>
/// <param name="_num">Number of dispatches.</param>
/// <param name="_num">Number of draws.</param>
/// <param name="_depth">Depth for sorting.</param>
/// <param name="_flags">Which states to discard for next draw. See `BGFX_DISCARD_*`.</param>
///
[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);
/// <summary>
/// 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`.
/// </summary>
///
/// <param name="_id">View id.</param>
/// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in indirect buffer.</param>
/// <param name="_numHandle">Buffer for number of draws. Must be created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`.</param>
/// <param name="_numIndex">Element in number buffer.</param>
/// <param name="_numMax">Max number of draws.</param>
/// <param name="_depth">Depth for sorting.</param>
/// <param name="_flags">Which states to discard for next draw. See `BGFX_DISCARD_*`.</param>
///
[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);
/// <summary>
/// Set compute index buffer.
/// </summary>

View File

@ -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:

View File

@ -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.

View File

@ -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`.
/// <param name="_id">View id.</param>
/// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in indirect buffer.</param>
/// <param name="_num">Number of dispatches.</param>
/// <param name="_num">Number of draws.</param>
/// <param name="_depth">Depth for sorting.</param>
/// <param name="_flags">Discard or preserve states. See `BGFX_DISCARD_*`.</param>
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`.
/// <param name="_id">View id.</param>
/// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in indirect buffer.</param>
/// <param name="_numHandle">Buffer for number of draws. Must be created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`.</param>
/// <param name="_numIndex">Element in number buffer.</param>
/// <param name="_numMax">Max number of draws.</param>
/// <param name="_depth">Depth for sorting.</param>
/// <param name="_flags">Discard or preserve states. See `BGFX_DISCARD_*`.</param>
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.
/// <param name="_stage">Compute stage.</param>
/// <param name="_handle">Index buffer handle.</param>
@ -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`.
/// <param name="_id">View id.</param>
/// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in indirect buffer.</param>
/// <param name="_num">Number of dispatches.</param>
/// <param name="_num">Number of draws.</param>
/// <param name="_depth">Depth for sorting.</param>
/// <param name="_flags">Discard or preserve states. See `BGFX_DISCARD_*`.</param>
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`.
/// <param name="_id">View id.</param>
/// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in indirect buffer.</param>
/// <param name="_numHandle">Buffer for number of draws. Must be created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`.</param>
/// <param name="_numIndex">Element in number buffer.</param>
/// <param name="_numMax">Max number of draws.</param>
/// <param name="_depth">Depth for sorting.</param>
/// <param name="_flags">Discard or preserve states. See `BGFX_DISCARD_*`.</param>
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.
/// <param name="_stage">Compute stage.</param>
/// <param name="_handle">Index buffer handle.</param>
@ -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`.
/// <param name="_id">View id.</param>
/// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in indirect buffer.</param>
/// <param name="_num">Number of dispatches.</param>
/// <param name="_num">Number of draws.</param>
/// <param name="_depth">Depth for sorting.</param>
/// <param name="_flags">Which states to discard for next draw. See `BGFX_DISCARD_*`.</param>
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`.
/// <param name="_id">View id.</param>
/// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in indirect buffer.</param>
/// <param name="_numHandle">Buffer for number of draws. Must be created with `BGFX_BUFFER_INDEX32` and `BGFX_BUFFER_DRAW_INDIRECT`.</param>
/// <param name="_numIndex">Element in number buffer.</param>
/// <param name="_numMax">Max number of draws.</param>
/// <param name="_depth">Depth for sorting.</param>
/// <param name="_flags">Which states to discard for next draw. See `BGFX_DISCARD_*`.</param>
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.
/// <param name="_stage">Compute stage.</param>
/// <param name="_handle">Index buffer handle.</param>

View File

@ -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

View File

@ -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;
@ -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
}

View File

@ -0,0 +1,2 @@
#define INDIRECT_COUNT
#include "cs_drawindirect.sc"

View File

@ -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;
@ -181,21 +182,35 @@ public:
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;
@ -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);
@ -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,6 +329,14 @@ 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();
@ -330,11 +367,7 @@ public:
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
@ -354,7 +387,15 @@ public:
// 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.
@ -366,14 +407,21 @@ public:
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
@ -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;

View File

@ -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.

View File

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

View File

@ -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 \

View File

@ -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.

View File

@ -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

View File

@ -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,

View File

@ -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)

View File

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

View File

@ -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
{

View File

@ -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) )

View File

@ -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<uint32_t>(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
{

View File

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