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

View File

@ -1151,6 +1151,11 @@ public static partial class bgfx
/// </summary> /// </summary>
ViewportLayerArray = 0x0000000010000000, ViewportLayerArray = 0x0000000010000000,
/// <summary>
/// Draw indirect with indirect count is supported.
/// </summary>
DrawIndirectCount = 0x0000000020000000,
/// <summary> /// <summary>
/// All texture compare modes are supported. /// All texture compare modes are supported.
/// </summary> /// </summary>
@ -3858,19 +3863,39 @@ public static partial class bgfx
/// <summary> /// <summary>
/// Submit primitive for rendering with index and instance data info from /// Submit primitive for rendering with index and instance data info from
/// indirect buffer. /// indirect buffer.
/// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
/// </summary> /// </summary>
/// ///
/// <param name="_id">View id.</param> /// <param name="_id">View id.</param>
/// <param name="_program">Program.</param> /// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param> /// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in 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="_depth">Depth for sorting.</param>
/// <param name="_flags">Discard or preserve states. See `BGFX_DISCARD_*`.</param> /// <param name="_flags">Discard or preserve states. See `BGFX_DISCARD_*`.</param>
/// ///
[DllImport(DllName, EntryPoint="bgfx_encoder_submit_indirect", CallingConvention = CallingConvention.Cdecl)] [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); 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> /// <summary>
/// Set compute index buffer. /// Set compute index buffer.
/// </summary> /// </summary>
@ -4414,19 +4439,39 @@ public static partial class bgfx
/// <summary> /// <summary>
/// Submit primitive for rendering with index and instance data info from /// Submit primitive for rendering with index and instance data info from
/// indirect buffer. /// indirect buffer.
/// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
/// </summary> /// </summary>
/// ///
/// <param name="_id">View id.</param> /// <param name="_id">View id.</param>
/// <param name="_program">Program.</param> /// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param> /// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in 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="_depth">Depth for sorting.</param>
/// <param name="_flags">Which states to discard for next draw. See `BGFX_DISCARD_*`.</param> /// <param name="_flags">Which states to discard for next draw. See `BGFX_DISCARD_*`.</param>
/// ///
[DllImport(DllName, EntryPoint="bgfx_submit_indirect", CallingConvention = CallingConvention.Cdecl)] [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); 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> /// <summary>
/// Set compute index buffer. /// Set compute index buffer.
/// </summary> /// </summary>

View File

@ -1526,17 +1526,36 @@ version(BindBgfx_Static)
/** /**
* Submit primitive for rendering with index and instance data info from * Submit primitive for rendering with index and instance data info from
* indirect buffer. * indirect buffer.
* Attention: Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
* Params: * Params:
* _id = View id. * _id = View id.
* _program = Program. * _program = Program.
* _indirectHandle = Indirect buffer. * _indirectHandle = Indirect buffer.
* _start = First element in indirect buffer. * _start = First element in indirect buffer.
* _num = Number of dispatches. * _num = Number of draws.
* _depth = Depth for sorting. * _depth = Depth for sorting.
* _flags = Discard or preserve states. See `BGFX_DISCARD_*`. * _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); 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. * Set compute index buffer.
* Params: * Params:
@ -2026,17 +2045,36 @@ version(BindBgfx_Static)
/** /**
* Submit primitive for rendering with index and instance data info from * Submit primitive for rendering with index and instance data info from
* indirect buffer. * indirect buffer.
* Attention: Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
* Params: * Params:
* _id = View id. * _id = View id.
* _program = Program. * _program = Program.
* _indirectHandle = Indirect buffer. * _indirectHandle = Indirect buffer.
* _start = First element in indirect buffer. * _start = First element in indirect buffer.
* _num = Number of dispatches. * _num = Number of draws.
* _depth = Depth for sorting. * _depth = Depth for sorting.
* _flags = Which states to discard for next draw. See `BGFX_DISCARD_*`. * _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); 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. * Set compute index buffer.
* Params: * Params:
@ -3806,18 +3844,38 @@ else
/** /**
* Submit primitive for rendering with index and instance data info from * Submit primitive for rendering with index and instance data info from
* indirect buffer. * indirect buffer.
* Attention: Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
* Params: * Params:
* _id = View id. * _id = View id.
* _program = Program. * _program = Program.
* _indirectHandle = Indirect buffer. * _indirectHandle = Indirect buffer.
* _start = First element in indirect buffer. * _start = First element in indirect buffer.
* _num = Number of dispatches. * _num = Number of draws.
* _depth = Depth for sorting. * _depth = Depth for sorting.
* _flags = Discard or preserve states. See `BGFX_DISCARD_*`. * _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); 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; 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. * Set compute index buffer.
* Params: * Params:
@ -4351,18 +4409,38 @@ else
/** /**
* Submit primitive for rendering with index and instance data info from * Submit primitive for rendering with index and instance data info from
* indirect buffer. * indirect buffer.
* Attention: Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
* Params: * Params:
* _id = View id. * _id = View id.
* _program = Program. * _program = Program.
* _indirectHandle = Indirect buffer. * _indirectHandle = Indirect buffer.
* _start = First element in indirect buffer. * _start = First element in indirect buffer.
* _num = Number of dispatches. * _num = Number of draws.
* _depth = Depth for sorting. * _depth = Depth for sorting.
* _flags = Which states to discard for next draw. See `BGFX_DISCARD_*`. * _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); 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; 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. * Set compute index buffer.
* Params: * 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_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_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_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 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. 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. /// Viewport layer is available in vertex shader.
pub const CapsFlags_ViewportLayerArray: CapsFlags = 0x0000000010000000; 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. /// All texture compare modes are supported.
pub const CapsFlags_TextureCompareAll: CapsFlags = 0x0000000000300000; 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 /// Submit primitive for rendering with index and instance data info from
/// indirect buffer. /// indirect buffer.
/// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
/// <param name="_id">View id.</param> /// <param name="_id">View id.</param>
/// <param name="_program">Program.</param> /// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param> /// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in 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="_depth">Depth for sorting.</param>
/// <param name="_flags">Discard or preserve states. See `BGFX_DISCARD_*`.</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 { 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); 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. /// Set compute index buffer.
/// <param name="_stage">Compute stage.</param> /// <param name="_stage">Compute stage.</param>
/// <param name="_handle">Index buffer handle.</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 /// Submit primitive for rendering with index and instance data info from
/// indirect buffer. /// indirect buffer.
/// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
/// <param name="_id">View id.</param> /// <param name="_id">View id.</param>
/// <param name="_program">Program.</param> /// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param> /// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in 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="_depth">Depth for sorting.</param>
/// <param name="_flags">Discard or preserve states. See `BGFX_DISCARD_*`.</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; 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. /// Set compute index buffer.
/// <param name="_stage">Compute stage.</param> /// <param name="_stage">Compute stage.</param>
/// <param name="_handle">Index buffer handle.</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 /// Submit primitive for rendering with index and instance data info from
/// indirect buffer. /// indirect buffer.
/// @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
/// <param name="_id">View id.</param> /// <param name="_id">View id.</param>
/// <param name="_program">Program.</param> /// <param name="_program">Program.</param>
/// <param name="_indirectHandle">Indirect buffer.</param> /// <param name="_indirectHandle">Indirect buffer.</param>
/// <param name="_start">First element in 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="_depth">Depth for sorting.</param>
/// <param name="_flags">Which states to discard for next draw. See `BGFX_DISCARD_*`.</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 { 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; 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. /// Set compute index buffer.
/// <param name="_stage">Compute stage.</param> /// <param name="_stage">Compute stage.</param>
/// <param name="_handle">Index buffer handle.</param> /// <param name="_handle">Index buffer handle.</param>

View File

@ -121,6 +121,7 @@ Available Caps
.. doxygendefine:: BGFX_CAPS_COMPUTE .. doxygendefine:: BGFX_CAPS_COMPUTE
.. doxygendefine:: BGFX_CAPS_CONSERVATIVE_RASTER .. doxygendefine:: BGFX_CAPS_CONSERVATIVE_RASTER
.. doxygendefine:: BGFX_CAPS_DRAW_INDIRECT .. doxygendefine:: BGFX_CAPS_DRAW_INDIRECT
.. doxygendefine:: BGFX_CAPS_DRAW_INDIRECT_COUNT
.. doxygendefine:: BGFX_CAPS_FRAGMENT_DEPTH .. doxygendefine:: BGFX_CAPS_FRAGMENT_DEPTH
.. doxygendefine:: BGFX_CAPS_FRAGMENT_ORDERING .. doxygendefine:: BGFX_CAPS_FRAGMENT_ORDERING
.. doxygendefine:: BGFX_CAPS_GRAPHICS_DEBUGGER .. doxygendefine:: BGFX_CAPS_GRAPHICS_DEBUGGER

View File

@ -11,6 +11,9 @@ BUFFER_RO(instanceDataIn, vec4, 0);
// Output // Output
BUFFER_WR(indirectBuffer, uvec4, 1); BUFFER_WR(indirectBuffer, uvec4, 1);
BUFFER_WR(instanceBufferOut, vec4, 2); BUFFER_WR(instanceBufferOut, vec4, 2);
#ifdef INDIRECT_COUNT
BUFFER_WR(indirectCountBuffer, int, 3);
#endif
uniform vec4 u_drawParams; uniform vec4 u_drawParams;
@ -23,15 +26,15 @@ void main()
int numDrawItems = int(u_drawParams.x); int numDrawItems = int(u_drawParams.x);
int sideSize = int(u_drawParams.y); int sideSize = int(u_drawParams.y);
float time = u_drawParams.z; float time = u_drawParams.z;
// Work out the amount of work we're going to do here // Work out the amount of work we're going to do here
int maxToDraw = min(sideSize*sideSize, numDrawItems); int maxToDraw = min(sideSize*sideSize, numDrawItems);
int numToDrawPerThread = maxToDraw/64 + 1; int numToDrawPerThread = maxToDraw/64 + 1;
int idxStart = tId*numToDrawPerThread; int idxStart = tId*numToDrawPerThread;
int idxMax = min(maxToDraw, (tId+1)*numToDrawPerThread); int idxMax = min(maxToDraw, (tId+1)*numToDrawPerThread);
// Prepare draw mtx // Prepare draw mtx
for (int k = idxStart; k < idxMax; k++) { for (int k = idxStart; k < idxMax; k++) {
int yy = k / sideSize; int yy = k / sideSize;
@ -47,24 +50,24 @@ void main()
vec4 a = vec4( cy, 0, sy, 0); vec4 a = vec4( cy, 0, sy, 0);
vec4 b = vec4( sx*sy, cx, -sx*cy, 0); vec4 b = vec4( sx*sy, cx, -sx*cy, 0);
vec4 c = vec4(-cx*sy, sx, cx*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 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; vec4 color;
color.x = sin(time + float(xx) / 11.0f) * 0.5f + 0.5f; 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.y = cos(time + float(yy) / 11.0f) * 0.5f + 0.5f;
color.z = sin(time * 3.0f) * 0.5f + 0.5f; color.z = sin(time * 3.0f) * 0.5f + 0.5f;
color.w = 1.0f; color.w = 1.0f;
instanceBufferOut[k*5+0] = a; instanceBufferOut[k*5+0] = a;
instanceBufferOut[k*5+1] = b; instanceBufferOut[k*5+1] = b;
instanceBufferOut[k*5+2] = c; instanceBufferOut[k*5+2] = c;
instanceBufferOut[k*5+3] = d; instanceBufferOut[k*5+3] = d;
instanceBufferOut[k*5+4] = color; instanceBufferOut[k*5+4] = color;
} }
// Fill indirect buffer // Fill indirect buffer
for (int k = idxStart; k < idxMax; k++) { for (int k = idxStart; k < idxMax; k++) {
drawIndexedIndirect( drawIndexedIndirect(
// Target location params: // 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 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 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

@ -42,7 +42,7 @@ struct ObjectInstance {
float m_vertexCount; float m_vertexCount;
float m_indexOffset; float m_indexOffset;
float m_indexCount; float m_indexCount;
static void init() static void init()
{ {
ms_layout ms_layout
@ -50,7 +50,7 @@ struct ObjectInstance {
.add(bgfx::Attrib::TexCoord0, 4, bgfx::AttribType::Float) .add(bgfx::Attrib::TexCoord0, 4, bgfx::AttribType::Float)
.end(); .end();
}; };
static bgfx::VertexLayout ms_layout; static bgfx::VertexLayout ms_layout;
}; };
@ -59,7 +59,7 @@ bgfx::VertexLayout ObjectInstance::ms_layout;
struct RenderInstance { struct RenderInstance {
float m_mtx[16]; float m_mtx[16];
float m_color[4]; float m_color[4];
static void init() static void init()
{ {
ms_layout ms_layout
@ -71,10 +71,10 @@ struct RenderInstance {
.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Float) .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Float)
.end(); .end();
}; };
static bgfx::VertexLayout ms_layout; static bgfx::VertexLayout ms_layout;
}; };
bgfx::VertexLayout RenderInstance::ms_layout; bgfx::VertexLayout RenderInstance::ms_layout;
static PosColorVertex s_multiMeshVertices[12] = 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, 0xffff00ff },
{-1.0f, -1.0f, -1.0f, 0xffffff00 }, {-1.0f, -1.0f, -1.0f, 0xffffff00 },
{ 1.0f, -1.0f, -1.0f, 0xffffffff }, { 1.0f, -1.0f, -1.0f, 0xffffffff },
// Tetrahedron Model (offset = 8) // Tetrahedron Model (offset = 8)
{ 1.0f, 1.0f, 1.0f, 0xff0000ff }, { 1.0f, 1.0f, 1.0f, 0xff0000ff },
{ 1.0f, -1.0f, -1.0f, 0xff000000 }, { 1.0f, -1.0f, -1.0f, 0xff000000 },
@ -111,7 +111,7 @@ static const uint16_t s_multiMeshIndices[48] =
4, 5, 1, 4, 5, 1,
2, 3, 6, // 10 2, 3, 6, // 10
6, 3, 7, 6, 3, 7,
// Tetrahedron Indices (offset = 36) // Tetrahedron Indices (offset = 36)
0, 2, 1, 0, 2, 1,
1, 2, 3, 1, 2, 3,
@ -137,8 +137,9 @@ public:
m_height = _height; m_height = _height;
m_debug = BGFX_DEBUG_TEXT; m_debug = BGFX_DEBUG_TEXT;
m_reset = BGFX_RESET_VSYNC; m_reset = BGFX_RESET_VSYNC;
m_sideSize = 11; m_sideSize = 11;
m_nDrawElements = s_maxSideSize*s_maxSideSize; m_nDrawElements = s_maxSideSize*s_maxSideSize;
m_useIndirectCount = false;
bgfx::Init init; bgfx::Init init;
init.type = args.m_type; init.type = args.m_type;
@ -179,26 +180,40 @@ public:
// Create program from shaders. // Create program from shaders.
m_program = loadProgram("vs_instancing", "fs_instancing"); // These are reused from 05-instancing m_program = loadProgram("vs_instancing", "fs_instancing"); // These are reused from 05-instancing
m_indirect_program = BGFX_INVALID_HANDLE; m_indirect_program = BGFX_INVALID_HANDLE;
m_indirect_count_program = BGFX_INVALID_HANDLE;
m_indirect_buffer_handle = 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; m_object_list_buffer = BGFX_INVALID_HANDLE;
u_drawParams = bgfx::createUniform("u_drawParams", bgfx::UniformType::Vec4); 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); const bool instancingSupported = !!(BGFX_CAPS_INSTANCING & bgfx::getCaps()->supported);
if (computeSupported && instancingSupported) if (computeSupported && indirectSupported && instancingSupported)
{ {
// Set up indirect program // Set up indirect program
// This is a barebones program that populates the indirect buffer handle with draw requests // 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_program = bgfx::createProgram(loadShader("cs_drawindirect"), true);
m_indirect_buffer_handle = bgfx::createIndirectBuffer(m_nDrawElements); 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); const bgfx::Memory * mem = bgfx::alloc(sizeof(ObjectInstance) * m_nDrawElements);
ObjectInstance* objs = (ObjectInstance*) mem->data; ObjectInstance* objs = (ObjectInstance*) mem->data;
for (uint32_t ii = 0; ii < m_nDrawElements; ++ii) for (uint32_t ii = 0; ii < m_nDrawElements; ++ii)
{ {
if (ii % 2) if (ii % 2)
@ -218,15 +233,15 @@ public:
objs[ii].m_indexCount = 36; objs[ii].m_indexCount = 36;
} }
} }
// This is a list of objects to be rendered via the indirect program // 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); 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) // 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_instance_buffer = bgfx::createDynamicVertexBuffer(m_nDrawElements, RenderInstance::ms_layout, BGFX_BUFFER_COMPUTE_WRITE);
} }
m_timeOffset = bx::getHPCounter(); m_timeOffset = bx::getHPCounter();
imguiCreate(); imguiCreate();
@ -245,10 +260,18 @@ public:
{ {
bgfx::destroy(m_indirect_program); 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)) if (bgfx::isValid(m_indirect_buffer_handle))
{ {
bgfx::destroy(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)) if (bgfx::isValid(m_object_list_buffer))
{ {
bgfx::destroy(m_object_list_buffer); bgfx::destroy(m_object_list_buffer);
@ -258,7 +281,7 @@ public:
bgfx::destroy(m_instance_buffer); bgfx::destroy(m_instance_buffer);
} }
bgfx::destroy(u_drawParams); bgfx::destroy(u_drawParams);
// Shutdown bgfx. // Shutdown bgfx.
bgfx::shutdown(); bgfx::shutdown();
@ -269,6 +292,12 @@ public:
{ {
if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) ) 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 imguiBeginFrame(m_mouseState.m_mx
, m_mouseState.m_my , m_mouseState.m_my
, (m_mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) , (m_mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0)
@ -300,10 +329,18 @@ public:
ImGui::Text("Grid Side Size:"); ImGui::Text("Grid Side Size:");
ImGui::SliderInt("##size", (int*)&m_sideSize, 1, s_maxSideSize); 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(); ImGui::End();
imguiEndFrame(); imguiEndFrame();
// Set view 0 default viewport. // Set view 0 default viewport.
bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) ); bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
@ -327,55 +364,66 @@ public:
// Set view 0 default viewport. // Set view 0 default viewport.
bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) ); bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
} }
float time = (float)( (bx::getHPCounter() - m_timeOffset)/double(bx::getHPFrequency() ) ); float time = (float)( (bx::getHPCounter() - m_timeOffset)/double(bx::getHPFrequency() ) );
// Get renderer capabilities info. if (computeSupported && indirectSupported && instancingSupported)
const bool computeSupported = !!(BGFX_CAPS_DRAW_INDIRECT & bgfx::getCaps()->supported);
const bool instancingSupported = !!(BGFX_CAPS_INSTANCING & bgfx::getCaps()->supported);
if (computeSupported && instancingSupported)
{ {
// Build indirect buffer & prepare instance buffer // Build indirect buffer & prepare instance buffer
// NOTE: IF you are rendering static data then // NOTE: IF you are rendering static data then
// this could be done once on startup and results stored // this could be done once on startup and results stored
// This is done here for demonstration purposes // This is done here for demonstration purposes
// The model matrix for each instance is also set on compute // 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 }; float ud[4] = { float(m_nDrawElements), float(m_sideSize), float(time), 0 };
uint32_t numToDraw = (m_sideSize*m_sideSize); uint32_t numToDraw = (m_sideSize*m_sideSize);
bgfx::setUniform(u_drawParams, ud); bgfx::setUniform(u_drawParams, ud);
bgfx::setBuffer(0, m_object_list_buffer, bgfx::Access::Read); bgfx::setBuffer(0, m_object_list_buffer, bgfx::Access::Read);
bgfx::setBuffer(1, m_indirect_buffer_handle, bgfx::Access::Write); bgfx::setBuffer(1, m_indirect_buffer_handle, bgfx::Access::Write);
bgfx::setBuffer(2, m_instance_buffer, 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 // 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 // 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 // Submit our 1 draw call
// Set vertex and index buffer. // Set vertex and index buffer.
bgfx::setIndexBuffer(m_ibh); bgfx::setIndexBuffer(m_ibh);
bgfx::setVertexBuffer(0, m_vbh); bgfx::setVertexBuffer(0, m_vbh);
bgfx::setInstanceDataBuffer(m_instance_buffer, 0, numToDraw); bgfx::setInstanceDataBuffer(m_instance_buffer, 0, numToDraw);
// Set render states. // Set render states.
bgfx::setState(BGFX_STATE_DEFAULT); bgfx::setState(BGFX_STATE_DEFAULT);
// Submit primitive for rendering to view 0. // Submit primitive for rendering to view 0.
// note that this submission requires the draw count if (m_useIndirectCount)
bgfx::submit(0, m_program, m_indirect_buffer_handle, 0, uint16_t(numToDraw)); {
// 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 else
{ {
// Compute/Instancing is not supported // Compute/Indirect/Instancing is not supported
bool blink = uint32_t(time*3.0f)&1; 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 // Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives. // process submitted rendering primitives.
bgfx::frame(); bgfx::frame();
@ -394,12 +442,15 @@ public:
uint32_t m_reset; uint32_t m_reset;
uint32_t m_sideSize; uint32_t m_sideSize;
uint32_t m_nDrawElements; uint32_t m_nDrawElements;
bool m_useIndirectCount;
bgfx::VertexBufferHandle m_vbh; bgfx::VertexBufferHandle m_vbh;
bgfx::IndexBufferHandle m_ibh; bgfx::IndexBufferHandle m_ibh;
bgfx::ProgramHandle m_program; 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_program;
bgfx::ProgramHandle m_indirect_count_program;
bgfx::VertexBufferHandle m_object_list_buffer; bgfx::VertexBufferHandle m_object_list_buffer;
bgfx::DynamicVertexBufferHandle m_instance_buffer; bgfx::DynamicVertexBufferHandle m_instance_buffer;
bgfx::UniformHandle u_drawParams; bgfx::UniformHandle u_drawParams;

View File

@ -1480,10 +1480,11 @@ namespace bgfx
/// @param[in] _program Program. /// @param[in] _program Program.
/// @param[in] _indirectHandle Indirect buffer. /// @param[in] _indirectHandle Indirect buffer.
/// @param[in] _start First element in 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] _depth Depth for sorting.
/// @param[in] _flags Discard or preserve states. See `BGFX_DISCARD_*`. /// @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`. /// @attention C99's equivalent binding is `bgfx_encoder_submit_indirect`.
/// ///
void submit( void submit(
@ -1496,6 +1497,35 @@ namespace bgfx
, uint8_t _flags = BGFX_DISCARD_ALL , 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. /// Set compute index buffer.
/// ///
/// @param[in] _stage Compute stage. /// @param[in] _stage Compute stage.
@ -3924,10 +3954,11 @@ namespace bgfx
/// @param[in] _program Program. /// @param[in] _program Program.
/// @param[in] _indirectHandle Indirect buffer. /// @param[in] _indirectHandle Indirect buffer.
/// @param[in] _start First element in 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] _depth Depth for sorting.
/// @param[in] _flags Discard or preserve states. See `BGFX_DISCARD_*`. /// @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`. /// @attention C99's equivalent binding is `bgfx_submit_indirect`.
/// ///
void submit( void submit(
@ -3940,6 +3971,35 @@ namespace bgfx
, uint8_t _flags = BGFX_DISCARD_ALL , 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. /// Set compute index buffer.
/// ///
/// @param[in] _stage Compute stage. /// @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 * Submit primitive for rendering with index and instance data info from
* indirect buffer. * indirect buffer.
* @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
* *
* @param[in] _id View id. * @param[in] _id View id.
* @param[in] _program Program. * @param[in] _program Program.
* @param[in] _indirectHandle Indirect buffer. * @param[in] _indirectHandle Indirect buffer.
* @param[in] _start First element in 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] _depth Depth for sorting.
* @param[in] _flags Discard or preserve states. See `BGFX_DISCARD_*`. * @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); 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. * 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 * Submit primitive for rendering with index and instance data info from
* indirect buffer. * indirect buffer.
* @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
* *
* @param[in] _id View id. * @param[in] _id View id.
* @param[in] _program Program. * @param[in] _program Program.
* @param[in] _indirectHandle Indirect buffer. * @param[in] _indirectHandle Indirect buffer.
* @param[in] _start First element in 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] _depth Depth for sorting.
* @param[in] _flags Which states to discard for next draw. See `BGFX_DISCARD_*`. * @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); 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. * Set compute index buffer.
* *
@ -3503,6 +3543,7 @@ typedef enum bgfx_function_id
BGFX_FUNCTION_ID_ENCODER_SUBMIT, BGFX_FUNCTION_ID_ENCODER_SUBMIT,
BGFX_FUNCTION_ID_ENCODER_SUBMIT_OCCLUSION_QUERY, BGFX_FUNCTION_ID_ENCODER_SUBMIT_OCCLUSION_QUERY,
BGFX_FUNCTION_ID_ENCODER_SUBMIT_INDIRECT, 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_INDEX_BUFFER,
BGFX_FUNCTION_ID_ENCODER_SET_COMPUTE_VERTEX_BUFFER, BGFX_FUNCTION_ID_ENCODER_SET_COMPUTE_VERTEX_BUFFER,
BGFX_FUNCTION_ID_ENCODER_SET_COMPUTE_DYNAMIC_INDEX_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,
BGFX_FUNCTION_ID_SUBMIT_OCCLUSION_QUERY, BGFX_FUNCTION_ID_SUBMIT_OCCLUSION_QUERY,
BGFX_FUNCTION_ID_SUBMIT_INDIRECT, BGFX_FUNCTION_ID_SUBMIT_INDIRECT,
BGFX_FUNCTION_ID_SUBMIT_INDIRECT_COUNT,
BGFX_FUNCTION_ID_SET_COMPUTE_INDEX_BUFFER, BGFX_FUNCTION_ID_SET_COMPUTE_INDEX_BUFFER,
BGFX_FUNCTION_ID_SET_COMPUTE_VERTEX_BUFFER, BGFX_FUNCTION_ID_SET_COMPUTE_VERTEX_BUFFER,
BGFX_FUNCTION_ID_SET_COMPUTE_DYNAMIC_INDEX_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)(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_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)(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_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_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); 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)(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_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)(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_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_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); 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_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_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_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. /// All texture compare modes are supported.
#define BGFX_CAPS_TEXTURE_COMPARE_ALL (0 \ #define BGFX_CAPS_TEXTURE_COMPARE_ALL (0 \
| BGFX_CAPS_TEXTURE_COMPARE_RESERVED \ | 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. .VertexAttribUint10 --- Vertex attribute 10_10_10_2 is supported.
.VertexId --- Rendering with VertexID only is supported. .VertexId --- Rendering with VertexID only is supported.
.ViewportLayerArray --- Viewport layer is available in vertex shader. .ViewportLayerArray --- Viewport layer is available in vertex shader.
.DrawIndirectCount --- Draw indirect with indirect count is supported.
.TextureCompareAll --- All texture compare modes are supported. .TextureCompareAll --- All texture compare modes are supported.
{ "TextureCompareReserved", "TextureCompareLequal" } { "TextureCompareReserved", "TextureCompareLequal" }
() ()
@ -2444,6 +2445,9 @@ func.Encoder.submit { cname = "submit_occlusion_query" }
--- Submit primitive for rendering with index and instance data info from --- Submit primitive for rendering with index and instance data info from
--- indirect buffer. --- indirect buffer.
---
--- @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
---
func.Encoder.submit { cname = "submit_indirect" } func.Encoder.submit { cname = "submit_indirect" }
"void" "void"
.id "ViewId" --- View id. .id "ViewId" --- View id.
@ -2451,13 +2455,35 @@ func.Encoder.submit { cname = "submit_indirect" }
.indirectHandle "IndirectBufferHandle" --- Indirect buffer. .indirectHandle "IndirectBufferHandle" --- Indirect buffer.
.start "uint16_t" --- First element in indirect buffer. .start "uint16_t" --- First element in indirect buffer.
{ default = 0 } { default = 0 }
.num "uint16_t" --- Number of dispatches. .num "uint16_t" --- Number of draws.
{ default = 1 } { default = 1 }
.depth "uint32_t" --- Depth for sorting. .depth "uint32_t" --- Depth for sorting.
{ default = 0 } { default = 0 }
.flags "uint8_t" --- Discard or preserve states. See `BGFX_DISCARD_*`. .flags "uint8_t" --- Discard or preserve states. See `BGFX_DISCARD_*`.
{ default = "BGFX_DISCARD_ALL" } { 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. --- Set compute index buffer.
func.Encoder.setBuffer { cname = "set_compute_index_buffer" } func.Encoder.setBuffer { cname = "set_compute_index_buffer" }
"void" "void"
@ -2997,6 +3023,9 @@ func.submit { cname = "submit_occlusion_query" }
--- Submit primitive for rendering with index and instance data info from --- Submit primitive for rendering with index and instance data info from
--- indirect buffer. --- indirect buffer.
---
--- @attention Availability depends on: `BGFX_CAPS_DRAW_INDIRECT`.
---
func.submit { cname = "submit_indirect" } func.submit { cname = "submit_indirect" }
"void" "void"
.id "ViewId" --- View id. .id "ViewId" --- View id.
@ -3004,11 +3033,33 @@ func.submit { cname = "submit_indirect" }
.indirectHandle "IndirectBufferHandle" --- Indirect buffer. .indirectHandle "IndirectBufferHandle" --- Indirect buffer.
.start "uint16_t" --- First element in indirect buffer. .start "uint16_t" --- First element in indirect buffer.
{ default = 0 } { default = 0 }
.num "uint16_t" --- Number of dispatches. .num "uint16_t" --- Number of draws.
{ default = 1 } { default = 1 }
.depth "uint32_t" --- Depth for sorting. .depth "uint32_t" --- Depth for sorting.
{ default = 0 } { 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" } { default = "BGFX_DISCARD_ALL" }
--- Set compute index buffer. --- Set compute index buffer.

View File

@ -3860,6 +3860,16 @@ namespace bgfx
BGFX_ENCODER(submit(_id, _program, _indirectHandle, _start, _num, _depth, _flags) ); 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) 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); 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); 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) void setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access)
{ {
BGFX_CHECK_ENCODER0(); BGFX_CHECK_ENCODER0();
@ -5732,6 +5748,8 @@ BX_STATIC_ASSERT( (0
| BGFX_CAPS_VERTEX_ATTRIB_HALF | BGFX_CAPS_VERTEX_ATTRIB_HALF
| BGFX_CAPS_VERTEX_ATTRIB_UINT10 | BGFX_CAPS_VERTEX_ATTRIB_UINT10
| BGFX_CAPS_VERTEX_ID | BGFX_CAPS_VERTEX_ID
| BGFX_CAPS_VIEWPORT_LAYER_ARRAY
| BGFX_CAPS_DRAW_INDIRECT_COUNT
) == (0 ) == (0
^ BGFX_CAPS_ALPHA_TO_COVERAGE ^ BGFX_CAPS_ALPHA_TO_COVERAGE
^ BGFX_CAPS_BLEND_INDEPENDENT ^ BGFX_CAPS_BLEND_INDEPENDENT
@ -5757,6 +5775,8 @@ BX_STATIC_ASSERT( (0
^ BGFX_CAPS_VERTEX_ATTRIB_HALF ^ BGFX_CAPS_VERTEX_ATTRIB_HALF
^ BGFX_CAPS_VERTEX_ATTRIB_UINT10 ^ BGFX_CAPS_VERTEX_ATTRIB_UINT10
^ BGFX_CAPS_VERTEX_ID ^ BGFX_CAPS_VERTEX_ID
^ BGFX_CAPS_VIEWPORT_LAYER_ARRAY
^ BGFX_CAPS_DRAW_INDIRECT_COUNT
) ); ) );
#undef FLAGS_MASK_TEST #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); 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_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; 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::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) 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 }; 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,
bgfx_encoder_submit_occlusion_query, bgfx_encoder_submit_occlusion_query,
bgfx_encoder_submit_indirect, bgfx_encoder_submit_indirect,
bgfx_encoder_submit_indirect_count,
bgfx_encoder_set_compute_index_buffer, bgfx_encoder_set_compute_index_buffer,
bgfx_encoder_set_compute_vertex_buffer, bgfx_encoder_set_compute_vertex_buffer,
bgfx_encoder_set_compute_dynamic_index_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,
bgfx_submit_occlusion_query, bgfx_submit_occlusion_query,
bgfx_submit_indirect, bgfx_submit_indirect,
bgfx_submit_indirect_count,
bgfx_set_compute_index_buffer, bgfx_set_compute_index_buffer,
bgfx_set_compute_vertex_buffer, bgfx_set_compute_vertex_buffer,
bgfx_set_compute_dynamic_index_buffer, bgfx_set_compute_dynamic_index_buffer,

View File

@ -1676,8 +1676,10 @@ namespace bgfx
} }
m_startIndirect = 0; m_startIndirect = 0;
m_numIndirect = UINT16_MAX; m_numIndirect = UINT16_MAX;
m_numIndirectIndex = 0;
m_indirectBuffer.idx = kInvalidHandle; m_indirectBuffer.idx = kInvalidHandle;
m_numIndirectBuffer.idx = kInvalidHandle;
m_occlusionQuery.idx = kInvalidHandle; m_occlusionQuery.idx = kInvalidHandle;
} }
@ -1710,6 +1712,7 @@ namespace bgfx
uint16_t m_instanceDataStride; uint16_t m_instanceDataStride;
uint16_t m_startIndirect; uint16_t m_startIndirect;
uint16_t m_numIndirect; uint16_t m_numIndirect;
uint32_t m_numIndirectIndex;
uint16_t m_numMatrices; uint16_t m_numMatrices;
uint16_t m_scissor; uint16_t m_scissor;
uint8_t m_submitFlags; uint8_t m_submitFlags;
@ -1719,6 +1722,7 @@ namespace bgfx
IndexBufferHandle m_indexBuffer; IndexBufferHandle m_indexBuffer;
VertexBufferHandle m_instanceDataBuffer; VertexBufferHandle m_instanceDataBuffer;
IndirectBufferHandle m_indirectBuffer; IndirectBufferHandle m_indirectBuffer;
IndexBufferHandle m_numIndirectBuffer;
OcclusionQueryHandle m_occlusionQuery; OcclusionQueryHandle m_occlusionQuery;
}; };
@ -2698,6 +2702,13 @@ namespace bgfx
submit(_id, _program, handle, _depth, _flags); 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, 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) 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, PFNGLMEMORYBARRIERPROC, glMemoryBarrier);
GL_IMPORT______(true, PFNGLMULTIDRAWARRAYSINDIRECTPROC, glMultiDrawArraysIndirect); GL_IMPORT______(true, PFNGLMULTIDRAWARRAYSINDIRECTPROC, glMultiDrawArraysIndirect);
GL_IMPORT______(true, PFNGLMULTIDRAWELEMENTSINDIRECTPROC, glMultiDrawElementsIndirect); GL_IMPORT______(true, PFNGLMULTIDRAWELEMENTSINDIRECTPROC, glMultiDrawElementsIndirect);
GL_IMPORT______(true, PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC, glMultiDrawArraysIndirectCount);
GL_IMPORT______(true, PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC, glMultiDrawElementsIndirectCount);
GL_IMPORT______(true, PFNGLOBJECTLABELPROC, glObjectLabel); GL_IMPORT______(true, PFNGLOBJECTLABELPROC, glObjectLabel);
GL_IMPORT______(true, PFNGLOBJECTPTRLABELPROC, glObjectPtrLabel); GL_IMPORT______(true, PFNGLOBJECTPTRLABELPROC, glObjectPtrLabel);
GL_IMPORT______(false, PFNGLPIXELSTOREIPROC, glPixelStorei); 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, PFNGLMULTIDRAWARRAYSINDIRECTPROC, glMultiDrawArraysIndirect);
GL_IMPORT_ARB__(true, PFNGLMULTIDRAWELEMENTSINDIRECTPROC, glMultiDrawElementsIndirect); 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, PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer);
GL_IMPORT_EXT__(true, PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers); GL_IMPORT_EXT__(true, PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers);
GL_IMPORT_EXT__(true, PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers); GL_IMPORT_EXT__(true, PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers);

View File

@ -1205,6 +1205,7 @@ namespace bgfx { namespace d3d12
| BGFX_CAPS_TEXTURE_CUBE_ARRAY | BGFX_CAPS_TEXTURE_CUBE_ARRAY
| BGFX_CAPS_IMAGE_RW | BGFX_CAPS_IMAGE_RW
| BGFX_CAPS_VIEWPORT_LAYER_ARRAY | BGFX_CAPS_VIEWPORT_LAYER_ARRAY
| BGFX_CAPS_DRAW_INDIRECT_COUNT
); );
g_caps.limits.maxTextureSize = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; g_caps.limits.maxTextureSize = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION;
g_caps.limits.maxTextureLayers = D3D12_REQ_TEXTURE2D_ARRAY_AXIS_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 ? indirect.m_size/BGFX_CONFIG_DRAW_INDIRECT_STRIDE
: _draw.m_numIndirect : _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; uint32_t numIndices = 0;
@ -4165,8 +4173,8 @@ namespace bgfx { namespace d3d12
, numDrawIndirect , numDrawIndirect
, indirect.m_ptr , indirect.m_ptr
, _draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE , _draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE
, NULL , numIndirect
, 0 , numOffsetIndirect
); );
} }
else else
@ -4176,8 +4184,8 @@ namespace bgfx { namespace d3d12
, numDrawIndirect , numDrawIndirect
, indirect.m_ptr , indirect.m_ptr
, _draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE , _draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE
, NULL , numIndirect
, 0 , numOffsetIndirect
); );
} }
@ -4441,8 +4449,8 @@ namespace bgfx { namespace d3d12
#if BX_PLATFORM_XBOXONE #if BX_PLATFORM_XBOXONE
flags |= D3D12XBOX_RESOURCE_FLAG_ALLOW_INDIRECT_BUFFER; flags |= D3D12XBOX_RESOURCE_FLAG_ALLOW_INDIRECT_BUFFER;
#endif // BX_PLATFORM_XBOXONE #endif // BX_PLATFORM_XBOXONE
format = DXGI_FORMAT_R32G32B32A32_UINT; format = _vertex ? DXGI_FORMAT_R32G32B32A32_UINT : DXGI_FORMAT_R32_UINT;
stride = 16; stride = _vertex ? 16 : 4;
} }
else else
{ {

View File

@ -539,6 +539,7 @@ namespace bgfx { namespace gl
ARB_get_program_binary, ARB_get_program_binary,
ARB_half_float_pixel, ARB_half_float_pixel,
ARB_half_float_vertex, ARB_half_float_vertex,
ARB_indirect_parameters,
ARB_instanced_arrays, ARB_instanced_arrays,
ARB_internalformat_query, ARB_internalformat_query,
ARB_internalformat_query2, ARB_internalformat_query2,
@ -756,6 +757,7 @@ namespace bgfx { namespace gl
{ "ARB_get_program_binary", BGFX_CONFIG_RENDERER_OPENGL >= 41, true }, { "ARB_get_program_binary", BGFX_CONFIG_RENDERER_OPENGL >= 41, true },
{ "ARB_half_float_pixel", BGFX_CONFIG_RENDERER_OPENGL >= 30, true }, { "ARB_half_float_pixel", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
{ "ARB_half_float_vertex", 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_instanced_arrays", BGFX_CONFIG_RENDERER_OPENGL >= 33, true },
{ "ARB_internalformat_query", BGFX_CONFIG_RENDERER_OPENGL >= 42, true }, { "ARB_internalformat_query", BGFX_CONFIG_RENDERER_OPENGL >= 42, true },
{ "ARB_internalformat_query2", BGFX_CONFIG_RENDERER_OPENGL >= 43, true }, { "ARB_internalformat_query2", BGFX_CONFIG_RENDERER_OPENGL >= 43, true },
@ -2829,6 +2831,11 @@ namespace bgfx { namespace gl
: 0 : 0
; ;
g_caps.supported |= s_extension[Extension::ARB_indirect_parameters].m_supported
? BGFX_CAPS_DRAW_INDIRECT_COUNT
: 0
;
if (BX_ENABLED(BX_PLATFORM_EMSCRIPTEN) if (BX_ENABLED(BX_PLATFORM_EMSCRIPTEN)
|| NULL == glPolygonMode) || NULL == glPolygonMode)
{ {
@ -8412,6 +8419,19 @@ namespace bgfx { namespace gl
GL_CHECK(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, vb.m_id) ); 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) ) if (isValid(draw.m_indexBuffer) )
{ {
const IndexBufferGL& ib = m_indexBuffers[draw.m_indexBuffer.idx]; 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; uintptr_t args = draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
GL_CHECK(glMultiDrawElementsIndirect(prim.m_type, indexFormat
, (void*)args if (isValid(draw.m_numIndirectBuffer) )
, numDrawIndirect {
, BGFX_CONFIG_DRAW_INDIRECT_STRIDE 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 else
{ {
@ -8441,11 +8474,24 @@ namespace bgfx { namespace gl
; ;
uintptr_t args = draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE; uintptr_t args = draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
GL_CHECK(glMultiDrawArraysIndirect(prim.m_type
, (void*)args if (isValid(draw.m_numIndirectBuffer) )
, numDrawIndirect {
, BGFX_CONFIG_DRAW_INDIRECT_STRIDE 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 else
@ -8454,6 +8500,12 @@ namespace bgfx { namespace gl
{ {
currentState.m_indirectBuffer.idx = kInvalidHandle; currentState.m_indirectBuffer.idx = kInvalidHandle;
GL_CHECK(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0) ); 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) ) if (isValid(draw.m_indexBuffer) )

View File

@ -329,6 +329,7 @@ VK_IMPORT_DEVICE
EXT_line_rasterization, EXT_line_rasterization,
EXT_shader_viewport_index_layer, EXT_shader_viewport_index_layer,
EXT_custom_border_color, EXT_custom_border_color,
KHR_draw_indirect_count,
Count Count
}; };
@ -353,6 +354,7 @@ VK_IMPORT_DEVICE
{ "VK_EXT_line_rasterization", 1, false, false, true , Layer::Count }, { "VK_EXT_line_rasterization", 1, false, false, true , Layer::Count },
{ "VK_EXT_shader_viewport_index_layer", 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_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) ); 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_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::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); dumpExtensions(VK_NULL_HANDLE, s_extension);
@ -1570,6 +1573,7 @@ VK_IMPORT_INSTANCE
g_caps.supported |= 0 g_caps.supported |= 0
| (s_extension[Extension::EXT_conservative_rasterization ].m_supported ? BGFX_CAPS_CONSERVATIVE_RASTER : 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::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); 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 bufferIndirect = VK_NULL_HANDLE;
VkBuffer bufferNumIndirect = VK_NULL_HANDLE;
uint32_t numDrawIndirect = 0; uint32_t numDrawIndirect = 0;
uint32_t bufferOffsetIndirect = 0; uint32_t bufferOffsetIndirect = 0;
uint32_t bufferNumOffsetIndirect = 0;
if (isValid(draw.m_indirectBuffer) ) if (isValid(draw.m_indirectBuffer) )
{ {
const VertexBufferVK& vb = m_vertexBuffers[draw.m_indirectBuffer.idx]; const VertexBufferVK& vb = m_vertexBuffers[draw.m_indirectBuffer.idx];
@ -8694,6 +8700,12 @@ VK_DESTROY
: draw.m_numIndirect : draw.m_numIndirect
; ;
bufferOffsetIndirect = draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE; 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) if (hasOcclusionQuery)
@ -8713,13 +8725,28 @@ VK_DESTROY
if (isValid(draw.m_indirectBuffer) ) if (isValid(draw.m_indirectBuffer) )
{ {
vkCmdDrawIndirect( if (isValid(draw.m_numIndirectBuffer) )
m_commandBuffer {
, bufferIndirect vkCmdDrawIndirectCountKHR(
, bufferOffsetIndirect m_commandBuffer
, numDrawIndirect , bufferIndirect
, BGFX_CONFIG_DRAW_INDIRECT_STRIDE , bufferOffsetIndirect
); , bufferNumIndirect
, bufferNumOffsetIndirect
, numDrawIndirect
, BGFX_CONFIG_DRAW_INDIRECT_STRIDE
);
}
else
{
vkCmdDrawIndirect(
m_commandBuffer
, bufferIndirect
, bufferOffsetIndirect
, numDrawIndirect
, BGFX_CONFIG_DRAW_INDIRECT_STRIDE
);
}
} }
else else
{ {
@ -8762,13 +8789,28 @@ VK_DESTROY
if (isValid(draw.m_indirectBuffer) ) if (isValid(draw.m_indirectBuffer) )
{ {
vkCmdDrawIndexedIndirect( if (isValid(draw.m_numIndirectBuffer) )
m_commandBuffer {
, bufferIndirect vkCmdDrawIndexedIndirectCountKHR(
, bufferOffsetIndirect m_commandBuffer
, numDrawIndirect , bufferIndirect
, BGFX_CONFIG_DRAW_INDIRECT_STRIDE , bufferOffsetIndirect
); , bufferNumIndirect
, bufferNumOffsetIndirect
, numDrawIndirect
, BGFX_CONFIG_DRAW_INDIRECT_STRIDE
);
}
else
{
vkCmdDrawIndexedIndirect(
m_commandBuffer
, bufferIndirect
, bufferOffsetIndirect
, numDrawIndirect
, BGFX_CONFIG_DRAW_INDIRECT_STRIDE
);
}
} }
else else
{ {

View File

@ -96,110 +96,113 @@
VK_IMPORT_INSTANCE_FUNC(true, vkDestroyDebugReportCallbackEXT); \ VK_IMPORT_INSTANCE_FUNC(true, vkDestroyDebugReportCallbackEXT); \
VK_IMPORT_INSTANCE_PLATFORM VK_IMPORT_INSTANCE_PLATFORM
#define VK_IMPORT_DEVICE \ #define VK_IMPORT_DEVICE \
VK_IMPORT_DEVICE_FUNC(false, vkGetDeviceQueue); \ VK_IMPORT_DEVICE_FUNC(false, vkGetDeviceQueue); \
VK_IMPORT_DEVICE_FUNC(false, vkCreateFence); \ VK_IMPORT_DEVICE_FUNC(false, vkCreateFence); \
VK_IMPORT_DEVICE_FUNC(false, vkDestroyFence); \ VK_IMPORT_DEVICE_FUNC(false, vkDestroyFence); \
VK_IMPORT_DEVICE_FUNC(false, vkCreateSemaphore); \ VK_IMPORT_DEVICE_FUNC(false, vkCreateSemaphore); \
VK_IMPORT_DEVICE_FUNC(false, vkDestroySemaphore); \ VK_IMPORT_DEVICE_FUNC(false, vkDestroySemaphore); \
VK_IMPORT_DEVICE_FUNC(false, vkResetFences); \ VK_IMPORT_DEVICE_FUNC(false, vkResetFences); \
VK_IMPORT_DEVICE_FUNC(false, vkCreateCommandPool); \ VK_IMPORT_DEVICE_FUNC(false, vkCreateCommandPool); \
VK_IMPORT_DEVICE_FUNC(false, vkDestroyCommandPool); \ VK_IMPORT_DEVICE_FUNC(false, vkDestroyCommandPool); \
VK_IMPORT_DEVICE_FUNC(false, vkResetCommandPool); \ VK_IMPORT_DEVICE_FUNC(false, vkResetCommandPool); \
VK_IMPORT_DEVICE_FUNC(false, vkAllocateCommandBuffers); \ VK_IMPORT_DEVICE_FUNC(false, vkAllocateCommandBuffers); \
VK_IMPORT_DEVICE_FUNC(false, vkFreeCommandBuffers); \ VK_IMPORT_DEVICE_FUNC(false, vkFreeCommandBuffers); \
VK_IMPORT_DEVICE_FUNC(false, vkGetBufferMemoryRequirements); \ VK_IMPORT_DEVICE_FUNC(false, vkGetBufferMemoryRequirements); \
VK_IMPORT_DEVICE_FUNC(false, vkGetImageMemoryRequirements); \ VK_IMPORT_DEVICE_FUNC(false, vkGetImageMemoryRequirements); \
VK_IMPORT_DEVICE_FUNC(false, vkGetImageSubresourceLayout); \ VK_IMPORT_DEVICE_FUNC(false, vkGetImageSubresourceLayout); \
VK_IMPORT_DEVICE_FUNC(false, vkAllocateMemory); \ VK_IMPORT_DEVICE_FUNC(false, vkAllocateMemory); \
VK_IMPORT_DEVICE_FUNC(false, vkFreeMemory); \ VK_IMPORT_DEVICE_FUNC(false, vkFreeMemory); \
VK_IMPORT_DEVICE_FUNC(false, vkCreateImage); \ VK_IMPORT_DEVICE_FUNC(false, vkCreateImage); \
VK_IMPORT_DEVICE_FUNC(false, vkDestroyImage); \ VK_IMPORT_DEVICE_FUNC(false, vkDestroyImage); \
VK_IMPORT_DEVICE_FUNC(false, vkCreateImageView); \ VK_IMPORT_DEVICE_FUNC(false, vkCreateImageView); \
VK_IMPORT_DEVICE_FUNC(false, vkDestroyImageView); \ VK_IMPORT_DEVICE_FUNC(false, vkDestroyImageView); \
VK_IMPORT_DEVICE_FUNC(false, vkCreateBuffer); \ VK_IMPORT_DEVICE_FUNC(false, vkCreateBuffer); \
VK_IMPORT_DEVICE_FUNC(false, vkDestroyBuffer); \ VK_IMPORT_DEVICE_FUNC(false, vkDestroyBuffer); \
VK_IMPORT_DEVICE_FUNC(false, vkCreateFramebuffer); \ VK_IMPORT_DEVICE_FUNC(false, vkCreateFramebuffer); \
VK_IMPORT_DEVICE_FUNC(false, vkDestroyFramebuffer); \ VK_IMPORT_DEVICE_FUNC(false, vkDestroyFramebuffer); \
VK_IMPORT_DEVICE_FUNC(false, vkCreateRenderPass); \ VK_IMPORT_DEVICE_FUNC(false, vkCreateRenderPass); \
VK_IMPORT_DEVICE_FUNC(false, vkDestroyRenderPass); \ VK_IMPORT_DEVICE_FUNC(false, vkDestroyRenderPass); \
VK_IMPORT_DEVICE_FUNC(false, vkCreateShaderModule); \ VK_IMPORT_DEVICE_FUNC(false, vkCreateShaderModule); \
VK_IMPORT_DEVICE_FUNC(false, vkDestroyShaderModule); \ VK_IMPORT_DEVICE_FUNC(false, vkDestroyShaderModule); \
VK_IMPORT_DEVICE_FUNC(false, vkCreatePipelineCache); \ VK_IMPORT_DEVICE_FUNC(false, vkCreatePipelineCache); \
VK_IMPORT_DEVICE_FUNC(false, vkDestroyPipelineCache); \ VK_IMPORT_DEVICE_FUNC(false, vkDestroyPipelineCache); \
VK_IMPORT_DEVICE_FUNC(false, vkGetPipelineCacheData); \ VK_IMPORT_DEVICE_FUNC(false, vkGetPipelineCacheData); \
VK_IMPORT_DEVICE_FUNC(false, vkMergePipelineCaches); \ VK_IMPORT_DEVICE_FUNC(false, vkMergePipelineCaches); \
VK_IMPORT_DEVICE_FUNC(false, vkCreateGraphicsPipelines); \ VK_IMPORT_DEVICE_FUNC(false, vkCreateGraphicsPipelines); \
VK_IMPORT_DEVICE_FUNC(false, vkCreateComputePipelines); \ VK_IMPORT_DEVICE_FUNC(false, vkCreateComputePipelines); \
VK_IMPORT_DEVICE_FUNC(false, vkDestroyPipeline); \ VK_IMPORT_DEVICE_FUNC(false, vkDestroyPipeline); \
VK_IMPORT_DEVICE_FUNC(false, vkCreatePipelineLayout); \ VK_IMPORT_DEVICE_FUNC(false, vkCreatePipelineLayout); \
VK_IMPORT_DEVICE_FUNC(false, vkDestroyPipelineLayout); \ VK_IMPORT_DEVICE_FUNC(false, vkDestroyPipelineLayout); \
VK_IMPORT_DEVICE_FUNC(false, vkCreateSampler); \ VK_IMPORT_DEVICE_FUNC(false, vkCreateSampler); \
VK_IMPORT_DEVICE_FUNC(false, vkDestroySampler); \ VK_IMPORT_DEVICE_FUNC(false, vkDestroySampler); \
VK_IMPORT_DEVICE_FUNC(false, vkCreateDescriptorSetLayout); \ VK_IMPORT_DEVICE_FUNC(false, vkCreateDescriptorSetLayout); \
VK_IMPORT_DEVICE_FUNC(false, vkDestroyDescriptorSetLayout); \ VK_IMPORT_DEVICE_FUNC(false, vkDestroyDescriptorSetLayout); \
VK_IMPORT_DEVICE_FUNC(false, vkCreateDescriptorPool); \ VK_IMPORT_DEVICE_FUNC(false, vkCreateDescriptorPool); \
VK_IMPORT_DEVICE_FUNC(false, vkDestroyDescriptorPool); \ VK_IMPORT_DEVICE_FUNC(false, vkDestroyDescriptorPool); \
VK_IMPORT_DEVICE_FUNC(false, vkResetDescriptorPool); \ VK_IMPORT_DEVICE_FUNC(false, vkResetDescriptorPool); \
VK_IMPORT_DEVICE_FUNC(false, vkAllocateDescriptorSets); \ VK_IMPORT_DEVICE_FUNC(false, vkAllocateDescriptorSets); \
VK_IMPORT_DEVICE_FUNC(false, vkFreeDescriptorSets); \ VK_IMPORT_DEVICE_FUNC(false, vkFreeDescriptorSets); \
VK_IMPORT_DEVICE_FUNC(false, vkUpdateDescriptorSets); \ VK_IMPORT_DEVICE_FUNC(false, vkUpdateDescriptorSets); \
VK_IMPORT_DEVICE_FUNC(false, vkCreateQueryPool); \ VK_IMPORT_DEVICE_FUNC(false, vkCreateQueryPool); \
VK_IMPORT_DEVICE_FUNC(false, vkDestroyQueryPool); \ VK_IMPORT_DEVICE_FUNC(false, vkDestroyQueryPool); \
VK_IMPORT_DEVICE_FUNC(false, vkQueueSubmit); \ VK_IMPORT_DEVICE_FUNC(false, vkQueueSubmit); \
VK_IMPORT_DEVICE_FUNC(false, vkQueueWaitIdle); \ VK_IMPORT_DEVICE_FUNC(false, vkQueueWaitIdle); \
VK_IMPORT_DEVICE_FUNC(false, vkDeviceWaitIdle); \ VK_IMPORT_DEVICE_FUNC(false, vkDeviceWaitIdle); \
VK_IMPORT_DEVICE_FUNC(false, vkWaitForFences); \ VK_IMPORT_DEVICE_FUNC(false, vkWaitForFences); \
VK_IMPORT_DEVICE_FUNC(false, vkBeginCommandBuffer); \ VK_IMPORT_DEVICE_FUNC(false, vkBeginCommandBuffer); \
VK_IMPORT_DEVICE_FUNC(false, vkEndCommandBuffer); \ VK_IMPORT_DEVICE_FUNC(false, vkEndCommandBuffer); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdPipelineBarrier); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdPipelineBarrier); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdBeginRenderPass); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdBeginRenderPass); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdEndRenderPass); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdEndRenderPass); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdSetViewport); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdSetViewport); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdDraw); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdDraw); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdDrawIndexed); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdDrawIndexed); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdDrawIndirect); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdDrawIndirect); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdDrawIndexedIndirect); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdDrawIndexedIndirect); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdDispatch); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdDispatch); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdDispatchIndirect); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdDispatchIndirect); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdBindPipeline); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdBindPipeline); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdSetStencilReference); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdSetStencilReference); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdSetBlendConstants); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdSetBlendConstants); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdSetScissor); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdSetScissor); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdBindDescriptorSets); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdBindDescriptorSets); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdBindIndexBuffer); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdBindIndexBuffer); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdBindVertexBuffers); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdBindVertexBuffers); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdClearColorImage); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdClearColorImage); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdClearDepthStencilImage); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdClearDepthStencilImage); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdClearAttachments); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdClearAttachments); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdResolveImage); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdResolveImage); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyBuffer); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyBuffer); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyBufferToImage); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyBufferToImage); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyImage); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyImage); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyImageToBuffer); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyImageToBuffer); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdBlitImage); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdBlitImage); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdResetQueryPool); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdResetQueryPool); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdWriteTimestamp); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdWriteTimestamp); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdBeginQuery); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdBeginQuery); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdEndQuery); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdEndQuery); \
VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyQueryPoolResults); \ VK_IMPORT_DEVICE_FUNC(false, vkCmdCopyQueryPoolResults); \
VK_IMPORT_DEVICE_FUNC(false, vkMapMemory); \ VK_IMPORT_DEVICE_FUNC(false, vkMapMemory); \
VK_IMPORT_DEVICE_FUNC(false, vkUnmapMemory); \ VK_IMPORT_DEVICE_FUNC(false, vkUnmapMemory); \
VK_IMPORT_DEVICE_FUNC(false, vkFlushMappedMemoryRanges); \ VK_IMPORT_DEVICE_FUNC(false, vkFlushMappedMemoryRanges); \
VK_IMPORT_DEVICE_FUNC(false, vkInvalidateMappedMemoryRanges); \ VK_IMPORT_DEVICE_FUNC(false, vkInvalidateMappedMemoryRanges); \
VK_IMPORT_DEVICE_FUNC(false, vkBindBufferMemory); \ VK_IMPORT_DEVICE_FUNC(false, vkBindBufferMemory); \
VK_IMPORT_DEVICE_FUNC(false, vkBindImageMemory); \ VK_IMPORT_DEVICE_FUNC(false, vkBindImageMemory); \
/* VK_KHR_swapchain */ \ /* VK_KHR_swapchain */ \
VK_IMPORT_DEVICE_FUNC(true, vkCreateSwapchainKHR); \ VK_IMPORT_DEVICE_FUNC(true, vkCreateSwapchainKHR); \
VK_IMPORT_DEVICE_FUNC(true, vkDestroySwapchainKHR); \ VK_IMPORT_DEVICE_FUNC(true, vkDestroySwapchainKHR); \
VK_IMPORT_DEVICE_FUNC(true, vkGetSwapchainImagesKHR); \ VK_IMPORT_DEVICE_FUNC(true, vkGetSwapchainImagesKHR); \
VK_IMPORT_DEVICE_FUNC(true, vkAcquireNextImageKHR); \ VK_IMPORT_DEVICE_FUNC(true, vkAcquireNextImageKHR); \
VK_IMPORT_DEVICE_FUNC(true, vkQueuePresentKHR); \ VK_IMPORT_DEVICE_FUNC(true, vkQueuePresentKHR); \
/* VK_EXT_debug_utils */ \ /* VK_EXT_debug_utils */ \
VK_IMPORT_DEVICE_FUNC(true, vkSetDebugUtilsObjectNameEXT); \ VK_IMPORT_DEVICE_FUNC(true, vkSetDebugUtilsObjectNameEXT); \
VK_IMPORT_DEVICE_FUNC(true, vkCmdBeginDebugUtilsLabelEXT); \ VK_IMPORT_DEVICE_FUNC(true, vkCmdBeginDebugUtilsLabelEXT); \
VK_IMPORT_DEVICE_FUNC(true, vkCmdEndDebugUtilsLabelEXT); \ VK_IMPORT_DEVICE_FUNC(true, vkCmdEndDebugUtilsLabelEXT); \
VK_IMPORT_DEVICE_FUNC(true, vkCmdInsertDebugUtilsLabelEXT); \ 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 \ #define VK_DESTROY \
VK_DESTROY_FUNC(Buffer); \ VK_DESTROY_FUNC(Buffer); \