diff --git a/bindings/bf/bgfx.bf b/bindings/bf/bgfx.bf index dbca7cd91..5b41ad759 100644 --- a/bindings/bf/bgfx.bf +++ b/bindings/bf/bgfx.bf @@ -4879,6 +4879,22 @@ public static class bgfx [LinkName("bgfx_encoder_set_image")] public static extern void encoder_set_image(Encoder* _this, uint8 _stage, TextureHandle _handle, uint8 _mip, Access _access, TextureFormat _format); + /// + /// Set compute image stage for draw primitive, selecting a sub-range of the + /// texture's array layers and mip levels. + /// + /// + /// Compute stage. + /// Texture handle. + /// First array layer. + /// Number of array layers. + /// Mip level. + /// Image access. See `Access::Enum`. + /// Texture format. See: `TextureFormat::Enum`. + /// + [LinkName("bgfx_encoder_set_image_view")] + public static extern void encoder_set_image_view(Encoder* _this, uint8 _stage, TextureHandle _handle, uint16 _firstLayer, uint16 _numLayers, uint8 _mip, Access _access, TextureFormat _format); + /// /// Dispatch compute. /// @@ -5540,6 +5556,22 @@ public static class bgfx [LinkName("bgfx_set_image")] public static extern void set_image(uint8 _stage, TextureHandle _handle, uint8 _mip, Access _access, TextureFormat _format); + /// + /// Set compute image stage for draw primitive, selecting a sub-range of the + /// texture's array layers and mip levels. + /// + /// + /// Compute stage. + /// Texture handle. + /// First array layer. + /// Number of array layers. + /// Mip level. + /// Image access. See `Access::Enum`. + /// Texture format. See: `TextureFormat::Enum`. + /// + [LinkName("bgfx_set_image_view")] + public static extern void set_image_view(uint8 _stage, TextureHandle _handle, uint16 _firstLayer, uint16 _numLayers, uint8 _mip, Access _access, TextureFormat _format); + /// /// Dispatch compute. /// diff --git a/bindings/c3/bgfx.c3 b/bindings/c3/bgfx.c3 index 1a3721814..78280c7df 100644 --- a/bindings/c3/bgfx.c3 +++ b/bindings/c3/bgfx.c3 @@ -3440,6 +3440,17 @@ extern fn void encoder_set_compute_indirect_buffer(Encoder* _this, char _stage, // _format : `Texture format. See: `TextureFormat::Enum`.` extern fn void encoder_set_image(Encoder* _this, char _stage, TextureHandle _handle, char _mip, Access _access, TextureFormat _format) @cname("bgfx_encoder_set_image"); +// Set compute image stage for draw primitive, selecting a sub-range of the +// texture's array layers and mip levels. +// _stage : `Compute stage.` +// _handle : `Texture handle.` +// _firstLayer : `First array layer.` +// _numLayers : `Number of array layers.` +// _mip : `Mip level.` +// _access : `Image access. See `Access::Enum`.` +// _format : `Texture format. See: `TextureFormat::Enum`.` +extern fn void encoder_set_image_view(Encoder* _this, char _stage, TextureHandle _handle, ushort _firstLayer, ushort _numLayers, char _mip, Access _access, TextureFormat _format) @cname("bgfx_encoder_set_image_view"); + // Dispatch compute. // _id : `View id.` // _program : `Compute program.` @@ -3867,6 +3878,17 @@ extern fn void set_compute_indirect_buffer(char _stage, IndirectBufferHandle _ha // _format : `Texture format. See: `TextureFormat::Enum`.` extern fn void set_image(char _stage, TextureHandle _handle, char _mip, Access _access, TextureFormat _format) @cname("bgfx_set_image"); +// Set compute image stage for draw primitive, selecting a sub-range of the +// texture's array layers and mip levels. +// _stage : `Compute stage.` +// _handle : `Texture handle.` +// _firstLayer : `First array layer.` +// _numLayers : `Number of array layers.` +// _mip : `Mip level.` +// _access : `Image access. See `Access::Enum`.` +// _format : `Texture format. See: `TextureFormat::Enum`.` +extern fn void set_image_view(char _stage, TextureHandle _handle, ushort _firstLayer, ushort _numLayers, char _mip, Access _access, TextureFormat _format) @cname("bgfx_set_image_view"); + // Dispatch compute. // _id : `View id.` // _program : `Compute program.` diff --git a/bindings/cs/bgfx.cs b/bindings/cs/bgfx.cs index 139aea8d4..f1d3657bc 100644 --- a/bindings/cs/bgfx.cs +++ b/bindings/cs/bgfx.cs @@ -4829,6 +4829,22 @@ public static partial class bgfx [DllImport(DllName, EntryPoint="bgfx_encoder_set_image", CallingConvention = CallingConvention.Cdecl)] public static extern unsafe void encoder_set_image(Encoder* _this, byte _stage, TextureHandle _handle, byte _mip, Access _access, TextureFormat _format); + /// + /// Set compute image stage for draw primitive, selecting a sub-range of the + /// texture's array layers and mip levels. + /// + /// + /// Compute stage. + /// Texture handle. + /// First array layer. + /// Number of array layers. + /// Mip level. + /// Image access. See `Access::Enum`. + /// Texture format. See: `TextureFormat::Enum`. + /// + [DllImport(DllName, EntryPoint="bgfx_encoder_set_image_view", CallingConvention = CallingConvention.Cdecl)] + public static extern unsafe void encoder_set_image_view(Encoder* _this, byte _stage, TextureHandle _handle, ushort _firstLayer, ushort _numLayers, byte _mip, Access _access, TextureFormat _format); + /// /// Dispatch compute. /// @@ -5490,6 +5506,22 @@ public static partial class bgfx [DllImport(DllName, EntryPoint="bgfx_set_image", CallingConvention = CallingConvention.Cdecl)] public static extern unsafe void set_image(byte _stage, TextureHandle _handle, byte _mip, Access _access, TextureFormat _format); + /// + /// Set compute image stage for draw primitive, selecting a sub-range of the + /// texture's array layers and mip levels. + /// + /// + /// Compute stage. + /// Texture handle. + /// First array layer. + /// Number of array layers. + /// Mip level. + /// Image access. See `Access::Enum`. + /// Texture format. See: `TextureFormat::Enum`. + /// + [DllImport(DllName, EntryPoint="bgfx_set_image_view", CallingConvention = CallingConvention.Cdecl)] + public static extern unsafe void set_image_view(byte _stage, TextureHandle _handle, ushort _firstLayer, ushort _numLayers, byte _mip, Access _access, TextureFormat _format); + /// /// Dispatch compute. /// diff --git a/bindings/d/package.d b/bindings/d/package.d index f1727ec88..ee9d9d253 100644 --- a/bindings/d/package.d +++ b/bindings/d/package.d @@ -9,7 +9,7 @@ import bindbc.common.types: c_int64, c_uint64, va_list; import bindbc.bgfx.config; static import bgfx.impl; -enum uint apiVersion = 148; +enum uint apiVersion = 149; alias ViewID = ushort; @@ -2095,6 +2095,20 @@ extern(C++, "bgfx") struct Encoder{ */ {q{void}, q{setImage}, q{ubyte stage, TextureHandle handle, ubyte mip, bgfx.impl.Access.Enum access, bgfx.impl.TextureFormat.Enum format=TextureFormat.count}, ext: `C++`}, + /** + Set compute image stage for draw primitive, selecting a sub-range of the + texture's array layers and mip levels. + Params: + stage = Compute stage. + handle = Texture handle. + firstLayer = First array layer. + numLayers = Number of array layers. + mip = Mip level. + access = Image access. See `Access::Enum`. + format = Texture format. See: `TextureFormat::Enum`. + */ + {q{void}, q{setImage}, q{ubyte stage, TextureHandle handle, ushort firstLayer, ushort numLayers, ubyte mip, bgfx.impl.Access.Enum access, bgfx.impl.TextureFormat.Enum format=TextureFormat.count}, ext: `C++`}, + /** Dispatch compute. Params: @@ -4084,6 +4098,20 @@ mixin(joinFnBinds((){ */ {q{void}, q{setImage}, q{ubyte stage, TextureHandle handle, ubyte mip, bgfx.impl.Access.Enum access, bgfx.impl.TextureFormat.Enum format=TextureFormat.count}, ext: `C++, "bgfx"`}, + /** + * Set compute image stage for draw primitive, selecting a sub-range of the + * texture's array layers and mip levels. + Params: + stage = Compute stage. + handle = Texture handle. + firstLayer = First array layer. + numLayers = Number of array layers. + mip = Mip level. + access = Image access. See `Access::Enum`. + format = Texture format. See: `TextureFormat::Enum`. + */ + {q{void}, q{setImage}, q{ubyte stage, TextureHandle handle, ushort firstLayer, ushort numLayers, ubyte mip, bgfx.impl.Access.Enum access, bgfx.impl.TextureFormat.Enum format=TextureFormat.count}, ext: `C++, "bgfx"`}, + /** * Dispatch compute. Params: diff --git a/bindings/zig/bgfx.zig b/bindings/zig/bgfx.zig index e0c621435..45ff27db9 100644 --- a/bindings/zig/bgfx.zig +++ b/bindings/zig/bgfx.zig @@ -2188,6 +2188,18 @@ pub const Init = extern struct { pub inline fn setImage(self: ?*Encoder, _stage: u8, _handle: TextureHandle, _mip: u8, _access: Access, _format: TextureFormat) void { return bgfx_encoder_set_image(self, _stage, _handle, _mip, _access, _format); } + /// Set compute image stage for draw primitive, selecting a sub-range of the + /// texture's array layers and mip levels. + /// Compute stage. + /// Texture handle. + /// First array layer. + /// Number of array layers. + /// Mip level. + /// Image access. See `Access::Enum`. + /// Texture format. See: `TextureFormat::Enum`. + pub inline fn setImageView(self: ?*Encoder, _stage: u8, _handle: TextureHandle, _firstLayer: u16, _numLayers: u16, _mip: u8, _access: Access, _format: TextureFormat) void { + return bgfx_encoder_set_image_view(self, _stage, _handle, _firstLayer, _numLayers, _mip, _access, _format); + } /// Dispatch compute. /// View id. /// Compute program. @@ -3781,6 +3793,17 @@ extern fn bgfx_encoder_set_compute_indirect_buffer(self: ?*Encoder, _stage: u8, /// Texture format. See: `TextureFormat::Enum`. extern fn bgfx_encoder_set_image(self: ?*Encoder, _stage: u8, _handle: TextureHandle, _mip: u8, _access: Access, _format: TextureFormat) void; +/// Set compute image stage for draw primitive, selecting a sub-range of the +/// texture's array layers and mip levels. +/// Compute stage. +/// Texture handle. +/// First array layer. +/// Number of array layers. +/// Mip level. +/// Image access. See `Access::Enum`. +/// Texture format. See: `TextureFormat::Enum`. +extern fn bgfx_encoder_set_image_view(self: ?*Encoder, _stage: u8, _handle: TextureHandle, _firstLayer: u16, _numLayers: u16, _mip: u8, _access: Access, _format: TextureFormat) void; + /// Dispatch compute. /// View id. /// Compute program. @@ -4337,6 +4360,20 @@ pub inline fn setImage(_stage: u8, _handle: TextureHandle, _mip: u8, _access: Ac } extern fn bgfx_set_image(_stage: u8, _handle: TextureHandle, _mip: u8, _access: Access, _format: TextureFormat) void; +/// Set compute image stage for draw primitive, selecting a sub-range of the +/// texture's array layers and mip levels. +/// Compute stage. +/// Texture handle. +/// First array layer. +/// Number of array layers. +/// Mip level. +/// Image access. See `Access::Enum`. +/// Texture format. See: `TextureFormat::Enum`. +pub inline fn setImageView(_stage: u8, _handle: TextureHandle, _firstLayer: u16, _numLayers: u16, _mip: u8, _access: Access, _format: TextureFormat) void { + return bgfx_set_image_view(_stage, _handle, _firstLayer, _numLayers, _mip, _access, _format); +} +extern fn bgfx_set_image_view(_stage: u8, _handle: TextureHandle, _firstLayer: u16, _numLayers: u16, _mip: u8, _access: Access, _format: TextureFormat) void; + /// Dispatch compute. /// View id. /// Compute program. diff --git a/docs/bgfx.rst b/docs/bgfx.rst index 5f141b4f6..d80402b4f 100644 --- a/docs/bgfx.rst +++ b/docs/bgfx.rst @@ -501,7 +501,8 @@ Images Bind texture images to compute stages. -.. doxygenfunction:: bgfx::setImage +.. doxygenfunction:: bgfx::setImage(uint8_t _stage, TextureHandle _handle, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format = TextureFormat::Count) +.. doxygenfunction:: bgfx::setImage(uint8_t _stage, TextureHandle _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format = TextureFormat::Count) Dispatch ******** diff --git a/include/bgfx/bgfx.h b/include/bgfx/bgfx.h index 82e719123..9357f176c 100644 --- a/include/bgfx/bgfx.h +++ b/include/bgfx/bgfx.h @@ -1724,6 +1724,29 @@ namespace bgfx , TextureFormat::Enum _format = TextureFormat::Count ); + /// Set compute image stage for draw primitive, selecting a sub-range of the + /// texture's array layers and mip levels. + /// + /// @param[in] _stage Compute stage. + /// @param[in] _handle Texture handle. + /// @param[in] _firstLayer First array layer. + /// @param[in] _numLayers Number of array layers. + /// @param[in] _mip Mip level. + /// @param[in] _access Image access. See `Access::Enum`. + /// @param[in] _format Texture format. See: `TextureFormat::Enum`. + /// + /// @attention C99's equivalent binding is `bgfx_encoder_set_image_view`. + /// + void setImage( + uint8_t _stage + , TextureHandle _handle + , uint16_t _firstLayer + , uint16_t _numLayers + , uint8_t _mip + , Access::Enum _access + , TextureFormat::Enum _format = TextureFormat::Count + ); + /// Dispatch compute. /// /// @param[in] _id View id. @@ -4738,6 +4761,29 @@ namespace bgfx , TextureFormat::Enum _format = TextureFormat::Count ); + /// Set compute image stage for draw primitive, selecting a sub-range of the + /// texture's array layers and mip levels. + /// + /// @param[in] _stage Compute stage. + /// @param[in] _handle Texture handle. + /// @param[in] _firstLayer First array layer. + /// @param[in] _numLayers Number of array layers. + /// @param[in] _mip Mip level. + /// @param[in] _access Image access. See `Access::Enum`. + /// @param[in] _format Texture format. See: `TextureFormat::Enum`. + /// + /// @attention C99's equivalent binding is `bgfx_set_image_view`. + /// + void setImage( + uint8_t _stage + , TextureHandle _handle + , uint16_t _firstLayer + , uint16_t _numLayers + , uint8_t _mip + , Access::Enum _access + , TextureFormat::Enum _format = TextureFormat::Count + ); + /// Dispatch compute. /// /// @param[in] _id View id. diff --git a/include/bgfx/c99/bgfx.h b/include/bgfx/c99/bgfx.h index 574b6129a..17eca6c81 100644 --- a/include/bgfx/c99/bgfx.h +++ b/include/bgfx/c99/bgfx.h @@ -3224,6 +3224,21 @@ BGFX_C_API void bgfx_encoder_set_compute_indirect_buffer(bgfx_encoder_t* _this, */ BGFX_C_API void bgfx_encoder_set_image(bgfx_encoder_t* _this, uint8_t _stage, bgfx_texture_handle_t _handle, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format); +/** + * Set compute image stage for draw primitive, selecting a sub-range of the + * texture's array layers and mip levels. + * + * @param[in] _stage Compute stage. + * @param[in] _handle Texture handle. + * @param[in] _firstLayer First array layer. + * @param[in] _numLayers Number of array layers. + * @param[in] _mip Mip level. + * @param[in] _access Image access. See `Access::Enum`. + * @param[in] _format Texture format. See: `TextureFormat::Enum`. + * + */ +BGFX_C_API void bgfx_encoder_set_image_view(bgfx_encoder_t* _this, uint8_t _stage, bgfx_texture_handle_t _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format); + /** * Dispatch compute. * @@ -3877,6 +3892,21 @@ BGFX_C_API void bgfx_set_compute_indirect_buffer(uint8_t _stage, bgfx_indirect_b */ BGFX_C_API void bgfx_set_image(uint8_t _stage, bgfx_texture_handle_t _handle, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format); +/** + * Set compute image stage for draw primitive, selecting a sub-range of the + * texture's array layers and mip levels. + * + * @param[in] _stage Compute stage. + * @param[in] _handle Texture handle. + * @param[in] _firstLayer First array layer. + * @param[in] _numLayers Number of array layers. + * @param[in] _mip Mip level. + * @param[in] _access Image access. See `Access::Enum`. + * @param[in] _format Texture format. See: `TextureFormat::Enum`. + * + */ +BGFX_C_API void bgfx_set_image_view(uint8_t _stage, bgfx_texture_handle_t _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format); + /** * Dispatch compute. * @@ -4096,6 +4126,7 @@ typedef enum bgfx_function_id BGFX_FUNCTION_ID_ENCODER_SET_COMPUTE_DYNAMIC_VERTEX_BUFFER, BGFX_FUNCTION_ID_ENCODER_SET_COMPUTE_INDIRECT_BUFFER, BGFX_FUNCTION_ID_ENCODER_SET_IMAGE, + BGFX_FUNCTION_ID_ENCODER_SET_IMAGE_VIEW, BGFX_FUNCTION_ID_ENCODER_DISPATCH, BGFX_FUNCTION_ID_ENCODER_DISPATCH_INDIRECT, BGFX_FUNCTION_ID_ENCODER_DISCARD, @@ -4143,6 +4174,7 @@ typedef enum bgfx_function_id BGFX_FUNCTION_ID_SET_COMPUTE_DYNAMIC_VERTEX_BUFFER, BGFX_FUNCTION_ID_SET_COMPUTE_INDIRECT_BUFFER, BGFX_FUNCTION_ID_SET_IMAGE, + BGFX_FUNCTION_ID_SET_IMAGE_VIEW, BGFX_FUNCTION_ID_DISPATCH, BGFX_FUNCTION_ID_DISPATCH_INDIRECT, BGFX_FUNCTION_ID_DISCARD, @@ -4308,6 +4340,7 @@ struct bgfx_interface_vtbl void (*encoder_set_compute_dynamic_vertex_buffer)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_dynamic_vertex_buffer_handle_t _handle, bgfx_access_t _access); void (*encoder_set_compute_indirect_buffer)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_indirect_buffer_handle_t _handle, bgfx_access_t _access); void (*encoder_set_image)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_texture_handle_t _handle, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format); + void (*encoder_set_image_view)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_texture_handle_t _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format); void (*encoder_dispatch)(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags); void (*encoder_dispatch_indirect)(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, uint32_t _start, uint32_t _num, uint8_t _flags); void (*encoder_discard)(bgfx_encoder_t* _this, uint8_t _flags); @@ -4355,6 +4388,7 @@ struct bgfx_interface_vtbl void (*set_compute_dynamic_vertex_buffer)(uint8_t _stage, bgfx_dynamic_vertex_buffer_handle_t _handle, bgfx_access_t _access); void (*set_compute_indirect_buffer)(uint8_t _stage, bgfx_indirect_buffer_handle_t _handle, bgfx_access_t _access); void (*set_image)(uint8_t _stage, bgfx_texture_handle_t _handle, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format); + void (*set_image_view)(uint8_t _stage, bgfx_texture_handle_t _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format); void (*dispatch)(bgfx_view_id_t _id, bgfx_program_handle_t _program, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags); void (*dispatch_indirect)(bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, uint32_t _start, uint32_t _num, uint8_t _flags); void (*discard)(uint8_t _flags); diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h index 636b06976..9f9065b7b 100644 --- a/include/bgfx/defines.h +++ b/include/bgfx/defines.h @@ -15,7 +15,7 @@ #ifndef BGFX_DEFINES_H_HEADER_GUARD #define BGFX_DEFINES_H_HEADER_GUARD -#define BGFX_API_VERSION UINT32_C(148) +#define BGFX_API_VERSION UINT32_C(149) /** * Color RGB/alpha/depth write. When it's not specified write will be disabled. diff --git a/scripts/bgfx.idl b/scripts/bgfx.idl index 43ee8d4f6..f8e5bb39e 100644 --- a/scripts/bgfx.idl +++ b/scripts/bgfx.idl @@ -1,7 +1,7 @@ -- vim: syntax=lua -- bgfx interface -version(148) +version(149) typedef "bool" typedef "char" @@ -2890,6 +2890,19 @@ func.Encoder.setImage { section = "Images" } .format "TextureFormat::Enum" --- Texture format. See: `TextureFormat::Enum`. { default = "TextureFormat::Count" } +--- Set compute image stage for draw primitive, selecting a sub-range of the +--- texture's array layers and mip levels. +func.Encoder.setImage { cname = "set_image_view", section = "Images" } + "void" + .stage "uint8_t" --- Compute stage. + .handle "TextureHandle" --- Texture handle. + .firstLayer "uint16_t" --- First array layer. + .numLayers "uint16_t" --- Number of array layers. + .mip "uint8_t" --- Mip level. + .access "Access::Enum" --- Image access. See `Access::Enum`. + .format "TextureFormat::Enum" --- Texture format. See: `TextureFormat::Enum`. + { default = "TextureFormat::Count" } + --- Dispatch compute. func.Encoder.dispatch { section = "Dispatch" } "void" @@ -3509,6 +3522,19 @@ func.setImage { section = "Images" } .format "TextureFormat::Enum" --- Texture format. See: `TextureFormat::Enum`. { default = "TextureFormat::Count" } +--- Set compute image stage for draw primitive, selecting a sub-range of the +--- texture's array layers and mip levels. +func.setImage { cname = "set_image_view", section = "Images" } + "void" + .stage "uint8_t" --- Compute stage. + .handle "TextureHandle" --- Texture handle. + .firstLayer "uint16_t" --- First array layer. + .numLayers "uint16_t" --- Number of array layers. + .mip "uint8_t" --- Mip level. + .access "Access::Enum" --- Image access. See `Access::Enum`. + .format "TextureFormat::Enum" --- Texture format. See: `TextureFormat::Enum`. + { default = "TextureFormat::Count" } + --- Dispatch compute. func.dispatch { section = "Dispatch" } "void" diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 8ca47a4b4..4d940584b 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -4514,6 +4514,11 @@ namespace bgfx } void Encoder::setImage(uint8_t _stage, TextureHandle _handle, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format) + { + setImage(_stage, _handle, 0, UINT16_MAX, _mip, _access, _format); + } + + void Encoder::setImage(uint8_t _stage, TextureHandle _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format) { BX_ASSERT(_stage < g_caps.limits.maxComputeBindings, "Invalid stage %d (max %d).", _stage, g_caps.limits.maxComputeBindings); BGFX_CHECK_HANDLE_INVALID_OK("setImage/TextureHandle", s_ctx->m_textureHandle, _handle); @@ -4536,7 +4541,7 @@ namespace bgfx BX_UNUSED(ref); } - BGFX_ENCODER(setImage(_stage, _handle, _mip, _access, _format) ); + BGFX_ENCODER(setImage(_stage, _handle, _firstLayer, _numLayers, _mip, _access, _format) ); } void Encoder::dispatch(ViewId _id, ProgramHandle _program, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags) @@ -6364,6 +6369,12 @@ namespace bgfx s_ctx->m_encoder0->setImage(_stage, _handle, _mip, _access, _format); } + void setImage(uint8_t _stage, TextureHandle _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format) + { + BGFX_CHECK_ENCODER0(); + s_ctx->m_encoder0->setImage(_stage, _handle, _firstLayer, _numLayers, _mip, _access, _format); + } + void dispatch(ViewId _id, ProgramHandle _handle, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags) { BGFX_CHECK_ENCODER0(); diff --git a/src/bgfx.idl.inl b/src/bgfx.idl.inl index a77509909..6bb0b1db0 100644 --- a/src/bgfx.idl.inl +++ b/src/bgfx.idl.inl @@ -992,6 +992,13 @@ BGFX_C_API void bgfx_encoder_set_image(bgfx_encoder_t* _this, uint8_t _stage, bg This->setImage(_stage, handle.cpp, _mip, (bgfx::Access::Enum)_access, (bgfx::TextureFormat::Enum)_format); } +BGFX_C_API void bgfx_encoder_set_image_view(bgfx_encoder_t* _this, uint8_t _stage, bgfx_texture_handle_t _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format) +{ + bgfx::Encoder* This = (bgfx::Encoder*)_this; + union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle = { _handle }; + This->setImage(_stage, handle.cpp, _firstLayer, _numLayers, _mip, (bgfx::Access::Enum)_access, (bgfx::TextureFormat::Enum)_format); +} + BGFX_C_API void bgfx_encoder_dispatch(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags) { bgfx::Encoder* This = (bgfx::Encoder*)_this; @@ -1271,6 +1278,12 @@ BGFX_C_API void bgfx_set_image(uint8_t _stage, bgfx_texture_handle_t _handle, ui bgfx::setImage(_stage, handle.cpp, _mip, (bgfx::Access::Enum)_access, (bgfx::TextureFormat::Enum)_format); } +BGFX_C_API void bgfx_set_image_view(uint8_t _stage, bgfx_texture_handle_t _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format) +{ + union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle = { _handle }; + bgfx::setImage(_stage, handle.cpp, _firstLayer, _numLayers, _mip, (bgfx::Access::Enum)_access, (bgfx::TextureFormat::Enum)_format); +} + BGFX_C_API void bgfx_dispatch(bgfx_view_id_t _id, bgfx_program_handle_t _program, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags) { union { bgfx_program_handle_t c; bgfx::ProgramHandle cpp; } program = { _program }; @@ -1489,6 +1502,7 @@ BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version) bgfx_encoder_set_compute_dynamic_vertex_buffer, bgfx_encoder_set_compute_indirect_buffer, bgfx_encoder_set_image, + bgfx_encoder_set_image_view, bgfx_encoder_dispatch, bgfx_encoder_dispatch_indirect, bgfx_encoder_discard, @@ -1536,6 +1550,7 @@ BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version) bgfx_set_compute_dynamic_vertex_buffer, bgfx_set_compute_indirect_buffer, bgfx_set_image, + bgfx_set_image_view, bgfx_dispatch, bgfx_dispatch_indirect, bgfx_discard, diff --git a/src/bgfx_p.h b/src/bgfx_p.h index b192d9cf1..f7f82bfb3 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -1999,16 +1999,21 @@ namespace bgfx } void setImage(TextureHandle _handle, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format) + { + setImage(_handle, 0, UINT16_MAX, _mip, _access, _format); + } + + void setImage(TextureHandle _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format) { m_samplerFlags = BGFX_SAMPLER_NONE; - m_firstLayer = 0; - m_numLayers = UINT16_MAX; - m_idx = _handle.idx; - m_type = uint8_t(Binding::Image); - m_format = uint8_t(_format); - m_access = uint8_t(_access); - m_firstMip = _mip; - m_numMips = 1; + m_firstLayer = _firstLayer; + m_numLayers = _numLayers; + m_idx = _handle.idx; + m_type = uint8_t(Binding::Image); + m_format = uint8_t(_format); + m_access = uint8_t(_access); + m_firstMip = _mip; + m_numMips = 1; } uint32_t m_samplerFlags; @@ -3493,6 +3498,13 @@ namespace bgfx bind.setImage(_handle, _mip, _access, _format); } + void setImage(uint8_t _stage, TextureHandle _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format) + { + m_bindDirty = true; + Binding& bind = m_bind.m_bind[_stage]; + bind.setImage(_handle, _firstLayer, _numLayers, _mip, _access, _format); + } + void discard(uint8_t _flags) { if (BX_ENABLED(BGFX_CONFIG_DEBUG_UNIFORM) ) diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 9065bc9eb..7b2421b5f 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -3276,13 +3276,16 @@ namespace bgfx { namespace d3d11 commitTextureStage(); } - ID3D11UnorderedAccessView* getCachedUav(TextureHandle _handle, uint8_t _mip) + ID3D11UnorderedAccessView* getCachedUav(TextureHandle _handle, uint8_t _mip, uint16_t _firstLayer = 0, uint16_t _numLayers = UINT16_MAX) { + const bool arrayed = UINT16_MAX != _numLayers; + bx::HashMurmur2A murmur; murmur.begin(); murmur.add(_handle); murmur.add(_mip); - murmur.add(1); + murmur.add(_firstLayer); + murmur.add(arrayed ? _numLayers : 0); uint32_t hash = murmur.end(); IUnknown** ptr = m_srvUavLru.find(hash); @@ -3296,12 +3299,16 @@ namespace bgfx { namespace d3d11 switch (texture.m_type) { case TextureD3D11::Texture2D: - if (1 < texture.m_numLayers) + if (1 < texture.m_numLayers || arrayed) { + const uint16_t numLayers = arrayed + ? _numLayers + : uint16_t(texture.m_numLayers) + ; desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; desc.Texture2DArray.MipSlice = _mip; - desc.Texture2DArray.FirstArraySlice = 0; - desc.Texture2DArray.ArraySize = texture.m_numLayers; + desc.Texture2DArray.FirstArraySlice = _firstLayer; + desc.Texture2DArray.ArraySize = bx::max(numLayers, 1); } else { @@ -6012,9 +6019,10 @@ namespace bgfx { namespace d3d11 TextureD3D11& texture = m_textures[bind.m_idx]; if (Access::Read != bind.m_access) { - uav[stage] = 0 == bind.m_firstMip + const bool arrayed = (UINT16_MAX != bind.m_numLayers); + uav[stage] = (0 == bind.m_firstMip && !arrayed) ? texture.m_uav - : s_renderD3D11->getCachedUav(texture.getHandle(), bind.m_firstMip) + : s_renderD3D11->getCachedUav(texture.getHandle(), bind.m_firstMip, bind.m_firstLayer, bind.m_numLayers) ; m_textureStage.m_srv[stage] = NULL; m_textureStage.m_sampler[stage] = NULL; @@ -6350,9 +6358,10 @@ namespace bgfx { namespace d3d11 TextureD3D11& texture = m_textures[bind.m_idx]; if (Access::Read != bind.m_access) { - m_textureStage.m_uav[stage] = 0 == bind.m_firstMip + const bool arrayed = (UINT16_MAX != bind.m_numLayers); + m_textureStage.m_uav[stage] = (0 == bind.m_firstMip && !arrayed) ? texture.m_uav - : s_renderD3D11->getCachedUav(texture.getHandle(), bind.m_firstMip) + : s_renderD3D11->getCachedUav(texture.getHandle(), bind.m_firstMip, bind.m_firstLayer, bind.m_numLayers) ; } else diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index e24073f2f..1ee9e1ab3 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -4296,33 +4296,47 @@ namespace bgfx { namespace d3d12 } } - void ScratchBufferD3D12::allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, TextureD3D12& _texture, uint8_t _mip) + void ScratchBufferD3D12::allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, TextureD3D12& _texture, uint8_t _mip, uint16_t _firstLayer, uint16_t _numLayers) { ID3D12Device* device = s_renderD3D12->m_device; D3D12_UNORDERED_ACCESS_VIEW_DESC tmpUavd; D3D12_UNORDERED_ACCESS_VIEW_DESC* uavd = &_texture.m_uavd; - if (0 != _mip) + const bool arrayed = UINT16_MAX != _numLayers; + const bool forceArray = arrayed && D3D12_UAV_DIMENSION_TEXTURE2D == uavd->ViewDimension; + + if (0 != _mip || forceArray) { bx::memCopy(&tmpUavd, uavd, sizeof(tmpUavd) ); uavd = &tmpUavd; - switch (_texture.m_uavd.ViewDimension) + if (forceArray) { - default: - case D3D12_UAV_DIMENSION_TEXTURE2D: - uavd->Texture2D.MipSlice = _mip; - uavd->Texture2D.PlaneSlice = 0; - break; - case D3D12_UAV_DIMENSION_TEXTURE2DARRAY: - uavd->Texture2DArray.MipSlice = _mip; - uavd->Texture2DArray.PlaneSlice = 0; - break; + uavd->ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY; + uavd->Texture2DArray.MipSlice = _mip; + uavd->Texture2DArray.FirstArraySlice = _firstLayer; + uavd->Texture2DArray.ArraySize = bx::max(_numLayers, 1); + uavd->Texture2DArray.PlaneSlice = 0; + } + else + { + switch (uavd->ViewDimension) + { + default: + case D3D12_UAV_DIMENSION_TEXTURE2D: + uavd->Texture2D.MipSlice = _mip; + uavd->Texture2D.PlaneSlice = 0; + break; + case D3D12_UAV_DIMENSION_TEXTURE2DARRAY: + uavd->Texture2DArray.MipSlice = _mip; + uavd->Texture2DArray.PlaneSlice = 0; + break; - case D3D12_UAV_DIMENSION_TEXTURE3D: - uavd->Texture3D.MipSlice = _mip; - break; + case D3D12_UAV_DIMENSION_TEXTURE3D: + uavd->Texture3D.MipSlice = _mip; + break; + } } } @@ -7782,7 +7796,7 @@ namespace bgfx { namespace d3d12 if (Access::Read != bind.m_access) { texture.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - scratchBuffer.allocUav(srvHandle[stage], texture, bind.m_firstMip); + scratchBuffer.allocUav(srvHandle[stage], texture, bind.m_firstMip, bind.m_firstLayer, bind.m_numLayers); } else { @@ -8101,7 +8115,7 @@ namespace bgfx { namespace d3d12 if (Access::Read != bind.m_access) { texture.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - scratchBuffer.allocUav(srvHandle[stage], texture, bind.m_firstMip); + scratchBuffer.allocUav(srvHandle[stage], texture, bind.m_firstMip, bind.m_firstLayer, bind.m_numLayers); } else { diff --git a/src/renderer_d3d12.h b/src/renderer_d3d12.h index 2d1a5876e..d29da6e61 100644 --- a/src/renderer_d3d12.h +++ b/src/renderer_d3d12.h @@ -131,7 +131,7 @@ namespace bgfx { namespace d3d12 void allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct TextureD3D12& _texture, uint16_t _firstLayer = 0, uint16_t _numLayers = UINT16_MAX, uint8_t _firstMip = 0, uint8_t _numMips = UINT8_MAX); void allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct BufferD3D12& _buffer); - void allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct TextureD3D12& _texture, uint8_t _mip = 0); + void allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct TextureD3D12& _texture, uint8_t _mip = 0, uint16_t _firstLayer = 0, uint16_t _numLayers = UINT16_MAX); void allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, ID3D12Resource* _resource, const D3D12_SHADER_RESOURCE_VIEW_DESC& _desc); void allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct BufferD3D12& _buffer); diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index d6b572e57..58544a601 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -7912,8 +7912,8 @@ namespace bgfx { namespace gl GL_CHECK(glBindImageTexture(ii , texture.m_id , bind.m_firstMip - , texture.isCubeMap() || texture.m_target == GL_TEXTURE_2D_ARRAY ? GL_TRUE : GL_FALSE - , 0 + , texture.isCubeMap() || texture.m_target == GL_TEXTURE_2D_ARRAY || UINT16_MAX != bind.m_numLayers ? GL_TRUE : GL_FALSE + , bind.m_firstLayer , s_access[bind.m_access] , s_imageFormat[bind.m_format]) ); @@ -8426,8 +8426,8 @@ namespace bgfx { namespace gl GL_CHECK(glBindImageTexture(stage , texture.m_id , bind.m_firstMip - , texture.isCubeMap() || texture.m_target == GL_TEXTURE_2D_ARRAY ? GL_TRUE : GL_FALSE - , 0 + , texture.isCubeMap() || texture.m_target == GL_TEXTURE_2D_ARRAY || UINT16_MAX != bind.m_numLayers ? GL_TRUE : GL_FALSE + , bind.m_firstLayer , s_access[bind.m_access] , s_imageFormat[bind.m_format]) ); diff --git a/src/renderer_mtl.cpp b/src/renderer_mtl.cpp index 7e2290968..7cf70ca75 100644 --- a/src/renderer_mtl.cpp +++ b/src/renderer_mtl.cpp @@ -4105,12 +4105,29 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames return view; } - MTL::Texture* TextureMtl::getTextureMipLevel(uint8_t _mip) + MTL::Texture* TextureMtl::getTextureMipLevel(uint8_t _mip, bool _array) { _mip = bx::clamp(_mip, 0, m_numMips); if (NULL != m_ptr) { + if (_array + && TextureCube != m_type + && MTL::TextureType2DArray != m_ptr->textureType() ) + { + if (NULL == m_ptrMipsArray[_mip]) + { + m_ptrMipsArray[_mip] = m_ptr->newTextureView( + m_ptr->pixelFormat() + , (MTL::TextureType)MTL::TextureType2DArray + , NS::Range::Make(_mip, 1) + , NS::Range::Make(0, m_ptr->arrayLength() ) + ); + } + + return m_ptrMipsArray[_mip]; + } + if (NULL == m_ptrMips[_mip]) { if (TextureCube == m_type) @@ -5445,7 +5462,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames case Binding::Image: { TextureMtl& texture = m_textures[bind.m_idx]; - m_computeCommandEncoder->setTexture(texture.getTextureMipLevel(bind.m_firstMip), stage); + m_computeCommandEncoder->setTexture(texture.getTextureMipLevel(bind.m_firstMip, UINT16_MAX != bind.m_numLayers), stage); } break; diff --git a/src/renderer_mtl.h b/src/renderer_mtl.h index a8a3010ac..f7bf806e8 100644 --- a/src/renderer_mtl.h +++ b/src/renderer_mtl.h @@ -430,7 +430,8 @@ namespace bgfx { namespace mtl { for (uint32_t ii = 0; ii < BX_COUNTOF(m_ptrMips); ++ii) { - m_ptrMips[ii] = NULL; + m_ptrMips[ii] = NULL; + m_ptrMipsArray[ii] = NULL; } } @@ -460,13 +461,14 @@ namespace bgfx { namespace mtl , uint8_t _numMips = UINT8_MAX ); - MTL::Texture* getTextureMipLevel(uint8_t _mip); + MTL::Texture* getTextureMipLevel(uint8_t _mip, bool _array = false); MTL::Texture* getTextureView(uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips); MTL::Texture* m_ptr; MTL::Texture* m_ptrMsaa; MTL::Texture* m_ptrStencil; // for emulating packed depth/stencil formats - only for iOS8... MTL::Texture* m_ptrMips[14]; + MTL::Texture* m_ptrMipsArray[14]; stl::unordered_map m_ptrViews; MTL::SamplerState* m_sampler; VideoDecoderMtl* m_videoDecoder; diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index a8e5647ac..6c3a09ac9 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -4284,6 +4284,12 @@ VK_IMPORT_DEVICE type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; } + if (UINT16_MAX != bind.m_numLayers + && VK_IMAGE_VIEW_TYPE_2D == type) + { + type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + } + texture.setState(m_commandBuffer, texture.m_sampledLayout); imageInfo[imageCount].imageLayout = texture.m_sampledLayout; diff --git a/src/renderer_webgpu.cpp b/src/renderer_webgpu.cpp index acc98f7a1..016ae3ce9 100644 --- a/src/renderer_webgpu.cpp +++ b/src/renderer_webgpu.cpp @@ -3124,7 +3124,7 @@ WGPU_IMPORT .size = 0, .sampler = NULL, .textureView = _isCompute - ? texture.getTextureView(bind.m_firstMip, bind.m_numMips, Binding::Image == bind.m_type) + ? texture.getTextureView(bind.m_firstMip, bind.m_numMips, Binding::Image == bind.m_type, 0, UINT16_MAX, Binding::Image == bind.m_type && UINT16_MAX != bind.m_numLayers) : texture.getTextureView(bind.m_firstMip, bind.m_numMips, false, bind.m_firstLayer, bind.m_numLayers) , };