From 40e614c45d22b5ce7554be2e7a7736ecd775490a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Wed, 18 Feb 2026 12:12:37 -0800 Subject: [PATCH] Added external texture parameter. (#3596) * Added external texture parameter. * Use uint64_t instead of uintptr_t for external texture because VkImage is always 64-bit. --- bindings/bf/bgfx.bf | 45 ++++-- bindings/c3/bgfx.c3 | 40 ++++-- bindings/cs/bgfx.cs | 45 ++++-- bindings/d/package.d | 48 ++++--- bindings/zig/bgfx.zig | 51 ++++--- include/bgfx/bgfx.h | 7 + include/bgfx/c99/bgfx.h | 17 ++- include/bgfx/defines.h | 23 +-- scripts/bgfx.idl | 28 ++-- src/bgfx.cpp | 65 +++++++-- src/bgfx.idl.inl | 12 +- src/bgfx_p.h | 5 +- src/renderer_d3d11.cpp | 303 ++++++++++++++++++++++------------------ src/renderer_d3d11.h | 5 +- src/renderer_d3d12.cpp | 172 +++++++++++++++++------ src/renderer_d3d12.h | 13 +- src/renderer_gl.cpp | 3 +- src/renderer_mtl.h | 27 +--- src/renderer_mtl.mm | 42 +++++- src/renderer_noop.cpp | 2 +- src/renderer_vk.cpp | 209 ++++++++++++++++----------- src/renderer_vk.h | 19 ++- src/renderer_webgpu.cpp | 3 +- src/version.h | 4 +- 24 files changed, 762 insertions(+), 426 deletions(-) diff --git a/bindings/bf/bgfx.bf b/bindings/bf/bgfx.bf index eaf019552..f0d7be1d4 100644 --- a/bindings/bf/bgfx.bf +++ b/bindings/bf/bgfx.bf @@ -739,6 +739,11 @@ public static class bgfx /// ReadBack = 0x0000800000000000, + /// + /// Texture is shared with other device or other process. + /// + ExternalShared = 0x0001000000000000, + /// /// Render target MSAAx2 mode. /// @@ -1122,50 +1127,60 @@ public static class bgfx /// TextureDirectAccess = 0x0000000000400000, + /// + /// External texture is supported. + /// + TextureExternal = 0x0000000000800000, + + /// + /// External shared texture is supported. + /// + TextureExternalShared = 0x0000000001000000, + /// /// Read-back texture is supported. /// - TextureReadBack = 0x0000000000800000, + TextureReadBack = 0x0000000002000000, /// /// 2D texture array is supported. /// - Texture2dArray = 0x0000000001000000, + Texture2dArray = 0x0000000004000000, /// /// 3D textures are supported. /// - Texture3d = 0x0000000002000000, + Texture3d = 0x0000000008000000, /// /// Transparent back buffer supported. /// - TransparentBackbuffer = 0x0000000004000000, + TransparentBackbuffer = 0x0000000010000000, /// /// Variable Rate Shading /// - VariableRateShading = 0x0000000008000000, + VariableRateShading = 0x0000000020000000, /// /// Vertex attribute half-float is supported. /// - VertexAttribHalf = 0x0000000010000000, + VertexAttribHalf = 0x0000000040000000, /// /// Vertex attribute 10_10_10_2 is supported. /// - VertexAttribUint10 = 0x0000000020000000, + VertexAttribUint10 = 0x0000000080000000, /// /// Rendering with VertexID only is supported. /// - VertexId = 0x0000000040000000, + VertexId = 0x0000000100000000, /// /// Viewport layer is available in vertex shader. /// - ViewportLayerArray = 0x0000000080000000, + ViewportLayerArray = 0x0000000200000000, /// /// All texture compare modes are supported. @@ -2205,6 +2220,7 @@ public static class bgfx public void* ndt; public void* nwh; public void* context; + public void* queue; public void* backBuffer; public void* backBufferDS; public NativeWindowHandleType type; @@ -3234,9 +3250,10 @@ public static class bgfx /// Texture format. See: `TextureFormat::Enum`. /// Texture creation (see `BGFX_TEXTURE_*`.), and sampler (see `BGFX_SAMPLER_*`) flags. Default texture sampling mode is linear, and wrap mode is repeat. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling. /// Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than 1, expected memory layout is texture and all mips together for each array element. + /// Native API pointer to texture. /// [LinkName("bgfx_create_texture_2d")] - public static extern TextureHandle create_texture_2d(uint16 _width, uint16 _height, bool _hasMips, uint16 _numLayers, TextureFormat _format, uint64 _flags, Memory* _mem); + public static extern TextureHandle create_texture_2d(uint16 _width, uint16 _height, bool _hasMips, uint16 _numLayers, TextureFormat _format, uint64 _flags, Memory* _mem, uint64 _external); /// /// Create texture with size based on back-buffer ratio. Texture will maintain ratio @@ -3263,9 +3280,10 @@ public static class bgfx /// Texture format. See: `TextureFormat::Enum`. /// Texture creation (see `BGFX_TEXTURE_*`.), and sampler (see `BGFX_SAMPLER_*`) flags. Default texture sampling mode is linear, and wrap mode is repeat. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling. /// Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than 1, expected memory layout is texture and all mips together for each array element. + /// Native API pointer to texture. /// [LinkName("bgfx_create_texture_3d")] - public static extern TextureHandle create_texture_3d(uint16 _width, uint16 _height, uint16 _depth, bool _hasMips, TextureFormat _format, uint64 _flags, Memory* _mem); + public static extern TextureHandle create_texture_3d(uint16 _width, uint16 _height, uint16 _depth, bool _hasMips, TextureFormat _format, uint64 _flags, Memory* _mem, uint64 _external); /// /// Create Cube texture. @@ -3276,10 +3294,11 @@ public static class bgfx /// Number of layers in texture array. Must be 1 if caps `BGFX_CAPS_TEXTURE_2D_ARRAY` flag is not set. /// Texture format. See: `TextureFormat::Enum`. /// Texture creation (see `BGFX_TEXTURE_*`.), and sampler (see `BGFX_SAMPLER_*`) flags. Default texture sampling mode is linear, and wrap mode is repeat. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling. - /// Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than 1, expected memory layout is texture and all mips together for each array element. + /// Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than + /// Native API pointer to texture. /// [LinkName("bgfx_create_texture_cube")] - public static extern TextureHandle create_texture_cube(uint16 _size, bool _hasMips, uint16 _numLayers, TextureFormat _format, uint64 _flags, Memory* _mem); + public static extern TextureHandle create_texture_cube(uint16 _size, bool _hasMips, uint16 _numLayers, TextureFormat _format, uint64 _flags, Memory* _mem, uint64 _external); /// /// Update 2D texture. diff --git a/bindings/c3/bgfx.c3 b/bindings/c3/bgfx.c3 index a7b33135f..d04463788 100644 --- a/bindings/c3/bgfx.c3 +++ b/bindings/c3/bgfx.c3 @@ -465,6 +465,9 @@ enum TextureFlags : const ulong // Texture will be used for read back from GPU. READBACK = 0x0000800000000000, + // Texture is shared with other device or other process. + EXTERNALSHARED = 0x0001000000000000, + // Render target MSAAx2 mode. RTMSAAX2 = 0x0000002000000000, @@ -711,32 +714,38 @@ enum CapsFlags : const ulong // CPU direct access to GPU texture memory. TEXTUREDIRECTACCESS = 0x0000000000400000, + // External texture is supported. + TEXTUREEXTERNAL = 0x0000000000800000, + + // External shared texture is supported. + TEXTUREEXTERNALSHARED = 0x0000000001000000, + // Read-back texture is supported. - TEXTUREREADBACK = 0x0000000000800000, + TEXTUREREADBACK = 0x0000000002000000, // 2D texture array is supported. - TEXTURE_2DARRAY = 0x0000000001000000, + TEXTURE_2DARRAY = 0x0000000004000000, // 3D textures are supported. - TEXTURE_3D = 0x0000000002000000, + TEXTURE_3D = 0x0000000008000000, // Transparent back buffer supported. - TRANSPARENTBACKBUFFER = 0x0000000004000000, + TRANSPARENTBACKBUFFER = 0x0000000010000000, // Variable Rate Shading - VARIABLERATESHADING = 0x0000000008000000, + VARIABLERATESHADING = 0x0000000020000000, // Vertex attribute half-float is supported. - VERTEXATTRIBHALF = 0x0000000010000000, + VERTEXATTRIBHALF = 0x0000000040000000, // Vertex attribute 10_10_10_2 is supported. - VERTEXATTRIBUINT10 = 0x0000000020000000, + VERTEXATTRIBUINT10 = 0x0000000080000000, // Rendering with VertexID only is supported. - VERTEXID = 0x0000000040000000, + VERTEXID = 0x0000000100000000, // Viewport layer is available in vertex shader. - VIEWPORTLAYERARRAY = 0x0000000080000000, + VIEWPORTLAYERARRAY = 0x0000000200000000, // All texture compare modes are supported. TEXTURECOMPAREALL = 0x0000000000180000, @@ -1512,6 +1521,8 @@ struct PlatformData // GL context, D3D device, or Vulkan device. If `NULL`, bgfx // will create context/device. void* context; + // D3D12 Queue. If `NULL` bgfx will create queue. + void* queue; // GL back-buffer, or D3D render target view. If `NULL` bgfx will // create back-buffer color surface. void* backBuffer; @@ -2321,7 +2332,8 @@ extern fn TextureHandle create_texture(Memory* _mem, ulong _flags, char _skip, T // _format : `Texture format. See: `TextureFormat::Enum`.` // _flags : `Texture creation (see `BGFX_TEXTURE_*`.), and sampler (see `BGFX_SAMPLER_*`) flags. Default texture sampling mode is linear, and wrap mode is repeat. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling.` // _mem : `Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than 1, expected memory layout is texture and all mips together for each array element.` -extern fn TextureHandle create_texture_2d(ushort _width, ushort _height, bool _hasMips, ushort _numLayers, TextureFormat _format, ulong _flags, Memory* _mem) @extern("bgfx_create_texture_2d"); +// _external : `Native API pointer to texture.` +extern fn TextureHandle create_texture_2d(ushort _width, ushort _height, bool _hasMips, ushort _numLayers, TextureFormat _format, ulong _flags, Memory* _mem, ulong _external) @extern("bgfx_create_texture_2d"); // Create texture with size based on back-buffer ratio. Texture will maintain ratio // if back buffer resolution changes. @@ -2340,7 +2352,8 @@ extern fn TextureHandle create_texture_2d_scaled(BackbufferRatio _ratio, bool _h // _format : `Texture format. See: `TextureFormat::Enum`.` // _flags : `Texture creation (see `BGFX_TEXTURE_*`.), and sampler (see `BGFX_SAMPLER_*`) flags. Default texture sampling mode is linear, and wrap mode is repeat. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling.` // _mem : `Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than 1, expected memory layout is texture and all mips together for each array element.` -extern fn TextureHandle create_texture_3d(ushort _width, ushort _height, ushort _depth, bool _hasMips, TextureFormat _format, ulong _flags, Memory* _mem) @extern("bgfx_create_texture_3d"); +// _external : `Native API pointer to texture.` +extern fn TextureHandle create_texture_3d(ushort _width, ushort _height, ushort _depth, bool _hasMips, TextureFormat _format, ulong _flags, Memory* _mem, ulong _external) @extern("bgfx_create_texture_3d"); // Create Cube texture. // _size : `Cube side size.` @@ -2348,8 +2361,9 @@ extern fn TextureHandle create_texture_3d(ushort _width, ushort _height, ushort // _numLayers : `Number of layers in texture array. Must be 1 if caps `BGFX_CAPS_TEXTURE_2D_ARRAY` flag is not set.` // _format : `Texture format. See: `TextureFormat::Enum`.` // _flags : `Texture creation (see `BGFX_TEXTURE_*`.), and sampler (see `BGFX_SAMPLER_*`) flags. Default texture sampling mode is linear, and wrap mode is repeat. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling.` -// _mem : `Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than 1, expected memory layout is texture and all mips together for each array element.` -extern fn TextureHandle create_texture_cube(ushort _size, bool _hasMips, ushort _numLayers, TextureFormat _format, ulong _flags, Memory* _mem) @extern("bgfx_create_texture_cube"); +// _mem : `Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than` +// _external : `Native API pointer to texture.` +extern fn TextureHandle create_texture_cube(ushort _size, bool _hasMips, ushort _numLayers, TextureFormat _format, ulong _flags, Memory* _mem, ulong _external) @extern("bgfx_create_texture_cube"); // Update 2D texture. // @attention It's valid to update only mutable texture. See `bgfx::createTexture2D` for more info. diff --git a/bindings/cs/bgfx.cs b/bindings/cs/bgfx.cs index 30974844b..7100d6ce7 100644 --- a/bindings/cs/bgfx.cs +++ b/bindings/cs/bgfx.cs @@ -738,6 +738,11 @@ public static partial class bgfx /// ReadBack = 0x0000800000000000, + /// + /// Texture is shared with other device or other process. + /// + ExternalShared = 0x0001000000000000, + /// /// Render target MSAAx2 mode. /// @@ -1121,50 +1126,60 @@ public static partial class bgfx /// TextureDirectAccess = 0x0000000000400000, + /// + /// External texture is supported. + /// + TextureExternal = 0x0000000000800000, + + /// + /// External shared texture is supported. + /// + TextureExternalShared = 0x0000000001000000, + /// /// Read-back texture is supported. /// - TextureReadBack = 0x0000000000800000, + TextureReadBack = 0x0000000002000000, /// /// 2D texture array is supported. /// - Texture2dArray = 0x0000000001000000, + Texture2dArray = 0x0000000004000000, /// /// 3D textures are supported. /// - Texture3d = 0x0000000002000000, + Texture3d = 0x0000000008000000, /// /// Transparent back buffer supported. /// - TransparentBackbuffer = 0x0000000004000000, + TransparentBackbuffer = 0x0000000010000000, /// /// Variable Rate Shading /// - VariableRateShading = 0x0000000008000000, + VariableRateShading = 0x0000000020000000, /// /// Vertex attribute half-float is supported. /// - VertexAttribHalf = 0x0000000010000000, + VertexAttribHalf = 0x0000000040000000, /// /// Vertex attribute 10_10_10_2 is supported. /// - VertexAttribUint10 = 0x0000000020000000, + VertexAttribUint10 = 0x0000000080000000, /// /// Rendering with VertexID only is supported. /// - VertexId = 0x0000000040000000, + VertexId = 0x0000000100000000, /// /// Viewport layer is available in vertex shader. /// - ViewportLayerArray = 0x0000000080000000, + ViewportLayerArray = 0x0000000200000000, /// /// All texture compare modes are supported. @@ -2182,6 +2197,7 @@ public static partial class bgfx public void* ndt; public void* nwh; public void* context; + public void* queue; public void* backBuffer; public void* backBufferDS; public NativeWindowHandleType type; @@ -3187,9 +3203,10 @@ public static partial class bgfx /// Texture format. See: `TextureFormat::Enum`. /// Texture creation (see `BGFX_TEXTURE_*`.), and sampler (see `BGFX_SAMPLER_*`) flags. Default texture sampling mode is linear, and wrap mode is repeat. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling. /// Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than 1, expected memory layout is texture and all mips together for each array element. + /// Native API pointer to texture. /// [DllImport(DllName, EntryPoint="bgfx_create_texture_2d", CallingConvention = CallingConvention.Cdecl)] - public static extern unsafe TextureHandle create_texture_2d(ushort _width, ushort _height, bool _hasMips, ushort _numLayers, TextureFormat _format, ulong _flags, Memory* _mem); + public static extern unsafe TextureHandle create_texture_2d(ushort _width, ushort _height, bool _hasMips, ushort _numLayers, TextureFormat _format, ulong _flags, Memory* _mem, ulong _external); /// /// Create texture with size based on back-buffer ratio. Texture will maintain ratio @@ -3216,9 +3233,10 @@ public static partial class bgfx /// Texture format. See: `TextureFormat::Enum`. /// Texture creation (see `BGFX_TEXTURE_*`.), and sampler (see `BGFX_SAMPLER_*`) flags. Default texture sampling mode is linear, and wrap mode is repeat. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling. /// Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than 1, expected memory layout is texture and all mips together for each array element. + /// Native API pointer to texture. /// [DllImport(DllName, EntryPoint="bgfx_create_texture_3d", CallingConvention = CallingConvention.Cdecl)] - public static extern unsafe TextureHandle create_texture_3d(ushort _width, ushort _height, ushort _depth, bool _hasMips, TextureFormat _format, ulong _flags, Memory* _mem); + public static extern unsafe TextureHandle create_texture_3d(ushort _width, ushort _height, ushort _depth, bool _hasMips, TextureFormat _format, ulong _flags, Memory* _mem, ulong _external); /// /// Create Cube texture. @@ -3229,10 +3247,11 @@ public static partial class bgfx /// Number of layers in texture array. Must be 1 if caps `BGFX_CAPS_TEXTURE_2D_ARRAY` flag is not set. /// Texture format. See: `TextureFormat::Enum`. /// Texture creation (see `BGFX_TEXTURE_*`.), and sampler (see `BGFX_SAMPLER_*`) flags. Default texture sampling mode is linear, and wrap mode is repeat. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling. - /// Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than 1, expected memory layout is texture and all mips together for each array element. + /// Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than + /// Native API pointer to texture. /// [DllImport(DllName, EntryPoint="bgfx_create_texture_cube", CallingConvention = CallingConvention.Cdecl)] - public static extern unsafe TextureHandle create_texture_cube(ushort _size, bool _hasMips, ushort _numLayers, TextureFormat _format, ulong _flags, Memory* _mem); + public static extern unsafe TextureHandle create_texture_cube(ushort _size, bool _hasMips, ushort _numLayers, TextureFormat _format, ulong _flags, Memory* _mem, ulong _external); /// /// Update 2D texture. diff --git a/bindings/d/package.d b/bindings/d/package.d index 32b9b08cd..a8319648a 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 = 136; +enum uint apiVersion = 137; alias ViewID = ushort; @@ -329,13 +329,14 @@ enum Buffer: Buffer_{ alias Texture_ = ulong; enum Texture: Texture_{ - none = 0x0000_0000_0000_0000, - msaaSample = 0x0000_0008_0000_0000, ///Texture will be used for MSAA sampling. - rt = 0x0000_0010_0000_0000, ///Render target no MSAA. - computeWrite = 0x0000_1000_0000_0000, ///Texture will be used for compute write. - srgb = 0x0000_2000_0000_0000, ///Sample texture as sRGB. - blitDst = 0x0000_4000_0000_0000, ///Texture will be used as blit destination. - readBack = 0x0000_8000_0000_0000, ///Texture will be used for read back from GPU. + none = 0x0000_0000_0000_0000, + msaaSample = 0x0000_0008_0000_0000, ///Texture will be used for MSAA sampling. + rt = 0x0000_0010_0000_0000, ///Render target no MSAA. + computeWrite = 0x0000_1000_0000_0000, ///Texture will be used for compute write. + srgb = 0x0000_2000_0000_0000, ///Sample texture as sRGB. + blitDst = 0x0000_4000_0000_0000, ///Texture will be used as blit destination. + readBack = 0x0000_8000_0000_0000, ///Texture will be used for read back from GPU. + externalShared = 0x0001_0000_0000_0000, ///Texture is shared with other device or other process. } alias TextureRTMSAA_ = ulong; @@ -514,15 +515,17 @@ enum CapFlags: CapFlags_{ textureCompareReserved = 0x0000_0000_0010_0000, textureCubeArray = 0x0000_0000_0020_0000, ///Cubemap texture array is supported. textureDirectAccess = 0x0000_0000_0040_0000, ///CPU direct access to GPU texture memory. - textureReadBack = 0x0000_0000_0080_0000, ///Read-back texture is supported. - texture2DArray = 0x0000_0000_0100_0000, ///2D texture array is supported. - texture3D = 0x0000_0000_0200_0000, ///3D textures are supported. - transparentBackbuffer = 0x0000_0000_0400_0000, ///Transparent back buffer supported. - variableRateShading = 0x0000_0000_0800_0000, ///Variable Rate Shading - vertexAttribHalf = 0x0000_0000_1000_0000, ///Vertex attribute half-float is supported. - vertexAttribUint10 = 0x0000_0000_2000_0000, ///Vertex attribute 10_10_10_2 is supported. - vertexID = 0x0000_0000_4000_0000, ///Rendering with VertexID only is supported. - viewportLayerArray = 0x0000_0000_8000_0000, ///Viewport layer is available in vertex shader. + textureExternal = 0x0000_0000_0080_0000, ///External texture is supported. + textureExternalShared = 0x0000_0000_0100_0000, ///External shared texture is supported. + textureReadBack = 0x0000_0000_0200_0000, ///Read-back texture is supported. + texture2DArray = 0x0000_0000_0400_0000, ///2D texture array is supported. + texture3D = 0x0000_0000_0800_0000, ///3D textures are supported. + transparentBackbuffer = 0x0000_0000_1000_0000, ///Transparent back buffer supported. + variableRateShading = 0x0000_0000_2000_0000, ///Variable Rate Shading + vertexAttribHalf = 0x0000_0000_4000_0000, ///Vertex attribute half-float is supported. + vertexAttribUint10 = 0x0000_0000_8000_0000, ///Vertex attribute 10_10_10_2 is supported. + vertexID = 0x0000_0001_0000_0000, ///Rendering with VertexID only is supported. + viewportLayerArray = 0x0000_0002_0000_0000, ///Viewport layer is available in vertex shader. textureCompareAll = 0x0000_0000_0018_0000, ///All texture compare modes are supported. } @@ -1122,6 +1125,7 @@ extern(C++, "bgfx") struct PlatformData{ will create context/device. */ void* context; + void* queue; ///D3D12 Queue. If `NULL` bgfx will create queue. /** GL back-buffer, or D3D render target view. If `NULL` bgfx will @@ -2576,8 +2580,9 @@ mixin(joinFnBinds((){ mem = Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than 1, expected memory layout is texture and all mips together for each array element. + external = Native API pointer to texture. */ - {q{TextureHandle}, q{createTexture2D}, q{ushort width, ushort height, bool hasMIPs, ushort numLayers, bgfx.impl.TextureFormat.Enum format, c_uint64 flags=Texture.none|Sampler.none, const(Memory)* mem=null}, ext: `C++, "bgfx"`}, + {q{TextureHandle}, q{createTexture2D}, q{ushort width, ushort height, bool hasMIPs, ushort numLayers, bgfx.impl.TextureFormat.Enum format, c_uint64 flags=Texture.none|Sampler.none, const(Memory)* mem=null, c_uint64 external=0}, ext: `C++, "bgfx"`}, /** * Create texture with size based on back-buffer ratio. Texture will maintain ratio @@ -2614,8 +2619,9 @@ mixin(joinFnBinds((){ mem = Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than 1, expected memory layout is texture and all mips together for each array element. + external = Native API pointer to texture. */ - {q{TextureHandle}, q{createTexture3D}, q{ushort width, ushort height, ushort depth, bool hasMIPs, bgfx.impl.TextureFormat.Enum format, c_uint64 flags=Texture.none|Sampler.none, const(Memory)* mem=null}, ext: `C++, "bgfx"`}, + {q{TextureHandle}, q{createTexture3D}, q{ushort width, ushort height, ushort depth, bool hasMIPs, bgfx.impl.TextureFormat.Enum format, c_uint64 flags=Texture.none|Sampler.none, const(Memory)* mem=null, c_uint64 external=0}, ext: `C++, "bgfx"`}, /** * Create Cube texture. @@ -2633,9 +2639,9 @@ mixin(joinFnBinds((){ sampling. mem = Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than - 1, expected memory layout is texture and all mips together for each array element. + external = Native API pointer to texture. */ - {q{TextureHandle}, q{createTextureCube}, q{ushort size, bool hasMIPs, ushort numLayers, bgfx.impl.TextureFormat.Enum format, c_uint64 flags=Texture.none|Sampler.none, const(Memory)* mem=null}, ext: `C++, "bgfx"`}, + {q{TextureHandle}, q{createTextureCube}, q{ushort size, bool hasMIPs, ushort numLayers, bgfx.impl.TextureFormat.Enum format, c_uint64 flags=Texture.none|Sampler.none, const(Memory)* mem=null, c_uint64 external=0}, ext: `C++, "bgfx"`}, /** * Update 2D texture. diff --git a/bindings/zig/bgfx.zig b/bindings/zig/bgfx.zig index 175713545..0c1a16113 100644 --- a/bindings/zig/bgfx.zig +++ b/bindings/zig/bgfx.zig @@ -453,6 +453,9 @@ pub const TextureFlags_BlitDst: TextureFlags = 0x0000400000000000 /// Texture will be used for read back from GPU. pub const TextureFlags_ReadBack: TextureFlags = 0x0000800000000000; +/// Texture is shared with other device or other process. +pub const TextureFlags_ExternalShared: TextureFlags = 0x0001000000000000; + /// Render target MSAAx2 mode. pub const TextureFlags_RtMsaaX2: TextureFlags = 0x0000002000000000; @@ -693,32 +696,38 @@ pub const CapsFlags_TextureCubeArray: CapsFlags = 0x0000000000200000; /// CPU direct access to GPU texture memory. pub const CapsFlags_TextureDirectAccess: CapsFlags = 0x0000000000400000; +/// External texture is supported. +pub const CapsFlags_TextureExternal: CapsFlags = 0x0000000000800000; + +/// External shared texture is supported. +pub const CapsFlags_TextureExternalShared: CapsFlags = 0x0000000001000000; + /// Read-back texture is supported. -pub const CapsFlags_TextureReadBack: CapsFlags = 0x0000000000800000; +pub const CapsFlags_TextureReadBack: CapsFlags = 0x0000000002000000; /// 2D texture array is supported. -pub const CapsFlags_Texture2DArray: CapsFlags = 0x0000000001000000; +pub const CapsFlags_Texture2DArray: CapsFlags = 0x0000000004000000; /// 3D textures are supported. -pub const CapsFlags_Texture3D: CapsFlags = 0x0000000002000000; +pub const CapsFlags_Texture3D: CapsFlags = 0x0000000008000000; /// Transparent back buffer supported. -pub const CapsFlags_TransparentBackbuffer: CapsFlags = 0x0000000004000000; +pub const CapsFlags_TransparentBackbuffer: CapsFlags = 0x0000000010000000; /// Variable Rate Shading -pub const CapsFlags_VariableRateShading: CapsFlags = 0x0000000008000000; +pub const CapsFlags_VariableRateShading: CapsFlags = 0x0000000020000000; /// Vertex attribute half-float is supported. -pub const CapsFlags_VertexAttribHalf: CapsFlags = 0x0000000010000000; +pub const CapsFlags_VertexAttribHalf: CapsFlags = 0x0000000040000000; /// Vertex attribute 10_10_10_2 is supported. -pub const CapsFlags_VertexAttribUint10: CapsFlags = 0x0000000020000000; +pub const CapsFlags_VertexAttribUint10: CapsFlags = 0x0000000080000000; /// Rendering with VertexID only is supported. -pub const CapsFlags_VertexId: CapsFlags = 0x0000000040000000; +pub const CapsFlags_VertexId: CapsFlags = 0x0000000100000000; /// Viewport layer is available in vertex shader. -pub const CapsFlags_ViewportLayerArray: CapsFlags = 0x0000000080000000; +pub const CapsFlags_ViewportLayerArray: CapsFlags = 0x0000000200000000; /// All texture compare modes are supported. pub const CapsFlags_TextureCompareAll: CapsFlags = 0x0000000000180000; @@ -1391,6 +1400,7 @@ pub const Caps = extern struct { ndt: ?*anyopaque, nwh: ?*anyopaque, context: ?*anyopaque, + queue: ?*anyopaque, backBuffer: ?*anyopaque, backBufferDS: ?*anyopaque, type: NativeWindowHandleType, @@ -2568,10 +2578,11 @@ extern fn bgfx_create_texture(_mem: [*c]const Memory, _flags: u64, _skip: u8, _i /// Texture format. See: `TextureFormat::Enum`. /// Texture creation (see `BGFX_TEXTURE_*`.), and sampler (see `BGFX_SAMPLER_*`) flags. Default texture sampling mode is linear, and wrap mode is repeat. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling. /// Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than 1, expected memory layout is texture and all mips together for each array element. -pub inline fn createTexture2D(_width: u16, _height: u16, _hasMips: bool, _numLayers: u16, _format: TextureFormat, _flags: u64, _mem: [*c]const Memory) TextureHandle { - return bgfx_create_texture_2d(_width, _height, _hasMips, _numLayers, _format, _flags, _mem); +/// Native API pointer to texture. +pub inline fn createTexture2D(_width: u16, _height: u16, _hasMips: bool, _numLayers: u16, _format: TextureFormat, _flags: u64, _mem: [*c]const Memory, _external: u64) TextureHandle { + return bgfx_create_texture_2d(_width, _height, _hasMips, _numLayers, _format, _flags, _mem, _external); } -extern fn bgfx_create_texture_2d(_width: u16, _height: u16, _hasMips: bool, _numLayers: u16, _format: TextureFormat, _flags: u64, _mem: [*c]const Memory) TextureHandle; +extern fn bgfx_create_texture_2d(_width: u16, _height: u16, _hasMips: bool, _numLayers: u16, _format: TextureFormat, _flags: u64, _mem: [*c]const Memory, _external: u64) TextureHandle; /// Create texture with size based on back-buffer ratio. Texture will maintain ratio /// if back buffer resolution changes. @@ -2593,10 +2604,11 @@ extern fn bgfx_create_texture_2d_scaled(_ratio: BackbufferRatio, _hasMips: bool, /// Texture format. See: `TextureFormat::Enum`. /// Texture creation (see `BGFX_TEXTURE_*`.), and sampler (see `BGFX_SAMPLER_*`) flags. Default texture sampling mode is linear, and wrap mode is repeat. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling. /// Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than 1, expected memory layout is texture and all mips together for each array element. -pub inline fn createTexture3D(_width: u16, _height: u16, _depth: u16, _hasMips: bool, _format: TextureFormat, _flags: u64, _mem: [*c]const Memory) TextureHandle { - return bgfx_create_texture_3d(_width, _height, _depth, _hasMips, _format, _flags, _mem); +/// Native API pointer to texture. +pub inline fn createTexture3D(_width: u16, _height: u16, _depth: u16, _hasMips: bool, _format: TextureFormat, _flags: u64, _mem: [*c]const Memory, _external: u64) TextureHandle { + return bgfx_create_texture_3d(_width, _height, _depth, _hasMips, _format, _flags, _mem, _external); } -extern fn bgfx_create_texture_3d(_width: u16, _height: u16, _depth: u16, _hasMips: bool, _format: TextureFormat, _flags: u64, _mem: [*c]const Memory) TextureHandle; +extern fn bgfx_create_texture_3d(_width: u16, _height: u16, _depth: u16, _hasMips: bool, _format: TextureFormat, _flags: u64, _mem: [*c]const Memory, _external: u64) TextureHandle; /// Create Cube texture. /// Cube side size. @@ -2604,11 +2616,12 @@ extern fn bgfx_create_texture_3d(_width: u16, _height: u16, _depth: u16, _hasMip /// Number of layers in texture array. Must be 1 if caps `BGFX_CAPS_TEXTURE_2D_ARRAY` flag is not set. /// Texture format. See: `TextureFormat::Enum`. /// Texture creation (see `BGFX_TEXTURE_*`.), and sampler (see `BGFX_SAMPLER_*`) flags. Default texture sampling mode is linear, and wrap mode is repeat. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling. -/// Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than 1, expected memory layout is texture and all mips together for each array element. -pub inline fn createTextureCube(_size: u16, _hasMips: bool, _numLayers: u16, _format: TextureFormat, _flags: u64, _mem: [*c]const Memory) TextureHandle { - return bgfx_create_texture_cube(_size, _hasMips, _numLayers, _format, _flags, _mem); +/// Texture data. If `_mem` is non-NULL, created texture will be immutable. If `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than +/// Native API pointer to texture. +pub inline fn createTextureCube(_size: u16, _hasMips: bool, _numLayers: u16, _format: TextureFormat, _flags: u64, _mem: [*c]const Memory, _external: u64) TextureHandle { + return bgfx_create_texture_cube(_size, _hasMips, _numLayers, _format, _flags, _mem, _external); } -extern fn bgfx_create_texture_cube(_size: u16, _hasMips: bool, _numLayers: u16, _format: TextureFormat, _flags: u64, _mem: [*c]const Memory) TextureHandle; +extern fn bgfx_create_texture_cube(_size: u16, _hasMips: bool, _numLayers: u16, _format: TextureFormat, _flags: u64, _mem: [*c]const Memory, _external: u64) TextureHandle; /// Update 2D texture. /// @attention It's valid to update only mutable texture. See `bgfx::createTexture2D` for more info. diff --git a/include/bgfx/bgfx.h b/include/bgfx/bgfx.h index abb9d903f..f04f92bf0 100644 --- a/include/bgfx/bgfx.h +++ b/include/bgfx/bgfx.h @@ -685,6 +685,7 @@ namespace bgfx /// context/device, provided the rendering API supports it. void* context; //!< GL context, D3D device, or Vulkan device. If `NULL`, bgfx /// will create context/device. + void* queue; /// void* backBuffer; //!< GL back-buffer, or D3D render target view. If `NULL` bgfx will /// create back-buffer color surface. void* backBufferDS; //!< Backbuffer depth/stencil. If `NULL`, bgfx will create a back-buffer @@ -2856,6 +2857,7 @@ namespace bgfx /// @param[in] _mem Texture data. If `_mem` is non-NULL, created texture will be immutable. If /// `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than /// 1, expected memory layout is texture and all mips together for each array element. + /// @param[in] _external Native API pointer to texture. /// /// @attention C99's equivalent binding is `bgfx_create_texture_2d`. /// @@ -2867,6 +2869,7 @@ namespace bgfx , TextureFormat::Enum _format , uint64_t _flags = BGFX_TEXTURE_NONE|BGFX_SAMPLER_NONE , const Memory* _mem = NULL + , uint64_t _external = 0 ); /// Create texture with size based on back-buffer ratio. Texture will maintain ratio @@ -2911,6 +2914,7 @@ namespace bgfx /// /// @param[in] _mem Texture data. If `_mem` is non-NULL, created texture will be immutable. If /// `_mem` is NULL content of the texture is uninitialized. + /// @param[in] _external Native API pointer to texture. /// /// @attention C99's equivalent binding is `bgfx_create_texture_3d`. /// @@ -2922,6 +2926,7 @@ namespace bgfx , TextureFormat::Enum _format , uint64_t _flags = BGFX_TEXTURE_NONE|BGFX_SAMPLER_NONE , const Memory* _mem = NULL + , uint64_t _external = 0 ); /// Create Cube texture. @@ -2941,6 +2946,7 @@ namespace bgfx /// @param[in] _mem Texture data. If `_mem` is non-NULL, created texture will be immutable. If /// `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than /// 1, expected memory layout is texture and all mips together for each array element. + /// @param[in] _external Native API pointer to texture. /// /// @attention C99's equivalent binding is `bgfx_create_texture_cube`. /// @@ -2951,6 +2957,7 @@ namespace bgfx , TextureFormat::Enum _format , uint64_t _flags = BGFX_TEXTURE_NONE|BGFX_SAMPLER_NONE , const Memory* _mem = NULL + , uint64_t _external = 0 ); /// Update 2D texture. diff --git a/include/bgfx/c99/bgfx.h b/include/bgfx/c99/bgfx.h index 1bd3da826..df373e35d 100644 --- a/include/bgfx/c99/bgfx.h +++ b/include/bgfx/c99/bgfx.h @@ -661,6 +661,7 @@ typedef struct bgfx_platform_data_s * will create context/device. */ void* context; + void* queue; /** D3D12 Queue. If `NULL` bgfx will create queue. */ /** * GL back-buffer, or D3D render target view. If `NULL` bgfx will @@ -1884,11 +1885,12 @@ BGFX_C_API bgfx_texture_handle_t bgfx_create_texture(const bgfx_memory_t* _mem, * @param[in] _mem Texture data. If `_mem` is non-NULL, created texture will be immutable. If * `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than * 1, expected memory layout is texture and all mips together for each array element. + * @param[in] _external Native API pointer to texture. * * @returns Texture handle. * */ -BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_2d(uint16_t _width, uint16_t _height, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem); +BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_2d(uint16_t _width, uint16_t _height, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem, uint64_t _external); /** * Create texture with size based on back-buffer ratio. Texture will maintain ratio @@ -1928,11 +1930,12 @@ BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_2d_scaled(bgfx_backbuffer_r * @param[in] _mem Texture data. If `_mem` is non-NULL, created texture will be immutable. If * `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than * 1, expected memory layout is texture and all mips together for each array element. + * @param[in] _external Native API pointer to texture. * * @returns Texture handle. * */ -BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_3d(uint16_t _width, uint16_t _height, uint16_t _depth, bool _hasMips, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem); +BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_3d(uint16_t _width, uint16_t _height, uint16_t _depth, bool _hasMips, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem, uint64_t _external); /** * Create Cube texture. @@ -1950,12 +1953,12 @@ BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_3d(uint16_t _width, uint16_ * sampling. * @param[in] _mem Texture data. If `_mem` is non-NULL, created texture will be immutable. If * `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than - * 1, expected memory layout is texture and all mips together for each array element. + * @param[in] _external Native API pointer to texture. * * @returns Texture handle. * */ -BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_cube(uint16_t _size, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem); +BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_cube(uint16_t _size, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem, uint64_t _external); /** * Update 2D texture. @@ -3875,10 +3878,10 @@ struct bgfx_interface_vtbl bool (*is_frame_buffer_valid)(uint8_t _num, const bgfx_attachment_t* _attachment); void (*calc_texture_size)(bgfx_texture_info_t * _info, uint16_t _width, uint16_t _height, uint16_t _depth, bool _cubeMap, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format); bgfx_texture_handle_t (*create_texture)(const bgfx_memory_t* _mem, uint64_t _flags, uint8_t _skip, bgfx_texture_info_t* _info); - bgfx_texture_handle_t (*create_texture_2d)(uint16_t _width, uint16_t _height, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem); + bgfx_texture_handle_t (*create_texture_2d)(uint16_t _width, uint16_t _height, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem, uint64_t _external); bgfx_texture_handle_t (*create_texture_2d_scaled)(bgfx_backbuffer_ratio_t _ratio, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint64_t _flags); - bgfx_texture_handle_t (*create_texture_3d)(uint16_t _width, uint16_t _height, uint16_t _depth, bool _hasMips, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem); - bgfx_texture_handle_t (*create_texture_cube)(uint16_t _size, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem); + bgfx_texture_handle_t (*create_texture_3d)(uint16_t _width, uint16_t _height, uint16_t _depth, bool _hasMips, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem, uint64_t _external); + bgfx_texture_handle_t (*create_texture_cube)(uint16_t _size, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem, uint64_t _external); void (*update_texture_2d)(bgfx_texture_handle_t _handle, uint16_t _layer, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const bgfx_memory_t* _mem, uint16_t _pitch); void (*update_texture_3d)(bgfx_texture_handle_t _handle, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _z, uint16_t _width, uint16_t _height, uint16_t _depth, const bgfx_memory_t* _mem); void (*update_texture_cube)(bgfx_texture_handle_t _handle, uint16_t _layer, uint8_t _side, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const bgfx_memory_t* _mem, uint16_t _pitch); diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h index 16865531a..5bd95b47a 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(136) +#define BGFX_API_VERSION UINT32_C(137) /** * Color RGB/alpha/depth write. When it's not specified write will be disabled. @@ -316,6 +316,7 @@ #define BGFX_TEXTURE_SRGB UINT64_C(0x0000200000000000) //!< Sample texture as sRGB. #define BGFX_TEXTURE_BLIT_DST UINT64_C(0x0000400000000000) //!< Texture will be used as blit destination. #define BGFX_TEXTURE_READ_BACK UINT64_C(0x0000800000000000) //!< Texture will be used for read back from GPU. +#define BGFX_TEXTURE_EXTERNAL_SHARED UINT64_C(0x0001000000000000) //!< Texture is shared with other device or other process. #define BGFX_TEXTURE_RT_MSAA_X2 UINT64_C(0x0000002000000000) //!< Render target MSAAx2 mode. #define BGFX_TEXTURE_RT_MSAA_X4 UINT64_C(0x0000003000000000) //!< Render target MSAAx4 mode. @@ -485,15 +486,17 @@ #define BGFX_CAPS_TEXTURE_COMPARE_RESERVED UINT64_C(0x0000000000100000) #define BGFX_CAPS_TEXTURE_CUBE_ARRAY UINT64_C(0x0000000000200000) //!< Cubemap texture array is supported. #define BGFX_CAPS_TEXTURE_DIRECT_ACCESS UINT64_C(0x0000000000400000) //!< CPU direct access to GPU texture memory. -#define BGFX_CAPS_TEXTURE_READ_BACK UINT64_C(0x0000000000800000) //!< Read-back texture is supported. -#define BGFX_CAPS_TEXTURE_2D_ARRAY UINT64_C(0x0000000001000000) //!< 2D texture array is supported. -#define BGFX_CAPS_TEXTURE_3D UINT64_C(0x0000000002000000) //!< 3D textures are supported. -#define BGFX_CAPS_TRANSPARENT_BACKBUFFER UINT64_C(0x0000000004000000) //!< Transparent back buffer supported. -#define BGFX_CAPS_VARIABLE_RATE_SHADING UINT64_C(0x0000000008000000) //!< Variable Rate Shading -#define BGFX_CAPS_VERTEX_ATTRIB_HALF UINT64_C(0x0000000010000000) //!< Vertex attribute half-float is supported. -#define BGFX_CAPS_VERTEX_ATTRIB_UINT10 UINT64_C(0x0000000020000000) //!< Vertex attribute 10_10_10_2 is supported. -#define BGFX_CAPS_VERTEX_ID UINT64_C(0x0000000040000000) //!< Rendering with VertexID only is supported. -#define BGFX_CAPS_VIEWPORT_LAYER_ARRAY UINT64_C(0x0000000080000000) //!< Viewport layer is available in vertex shader. +#define BGFX_CAPS_TEXTURE_EXTERNAL UINT64_C(0x0000000000800000) //!< External texture is supported. +#define BGFX_CAPS_TEXTURE_EXTERNAL_SHARED UINT64_C(0x0000000001000000) //!< External shared texture is supported. +#define BGFX_CAPS_TEXTURE_READ_BACK UINT64_C(0x0000000002000000) //!< Read-back texture is supported. +#define BGFX_CAPS_TEXTURE_2D_ARRAY UINT64_C(0x0000000004000000) //!< 2D texture array is supported. +#define BGFX_CAPS_TEXTURE_3D UINT64_C(0x0000000008000000) //!< 3D textures are supported. +#define BGFX_CAPS_TRANSPARENT_BACKBUFFER UINT64_C(0x0000000010000000) //!< Transparent back buffer supported. +#define BGFX_CAPS_VARIABLE_RATE_SHADING UINT64_C(0x0000000020000000) //!< Variable Rate Shading +#define BGFX_CAPS_VERTEX_ATTRIB_HALF UINT64_C(0x0000000040000000) //!< Vertex attribute half-float is supported. +#define BGFX_CAPS_VERTEX_ATTRIB_UINT10 UINT64_C(0x0000000080000000) //!< Vertex attribute 10_10_10_2 is supported. +#define BGFX_CAPS_VERTEX_ID UINT64_C(0x0000000100000000) //!< Rendering with VertexID only is supported. +#define BGFX_CAPS_VIEWPORT_LAYER_ARRAY UINT64_C(0x0000000200000000) //!< Viewport layer is available in vertex shader. /// All texture compare modes are supported. #define BGFX_CAPS_TEXTURE_COMPARE_ALL (0 \ | BGFX_CAPS_TEXTURE_COMPARE_RESERVED \ diff --git a/scripts/bgfx.idl b/scripts/bgfx.idl index 8e33ad2d5..e6c5e0574 100644 --- a/scripts/bgfx.idl +++ b/scripts/bgfx.idl @@ -1,7 +1,7 @@ -- vim: syntax=lua -- bgfx interface -version(136) +version(137) typedef "bool" typedef "char" @@ -251,13 +251,14 @@ flag.Buffer { bits = 16, base = 8 } () flag.Texture { bits = 64 } - .None (0) - .MsaaSample (36) --- Texture will be used for MSAA sampling. - .Rt (37) --- Render target no MSAA. - .ComputeWrite (45) --- Texture will be used for compute write. - .Srgb (46) --- Sample texture as sRGB. - .BlitDst (47) --- Texture will be used as blit destination. - .ReadBack (48) --- Texture will be used for read back from GPU. + .None (0) + .MsaaSample (36) --- Texture will be used for MSAA sampling. + .Rt (37) --- Render target no MSAA. + .ComputeWrite (45) --- Texture will be used for compute write. + .Srgb (46) --- Sample texture as sRGB. + .BlitDst (47) --- Texture will be used as blit destination. + .ReadBack (48) --- Texture will be used for read back from GPU. + .ExternalShared (49) --- Texture is shared with other device or other process. () flag.TextureRtMsaa { bits = 64, shift = 36, range = 3 , base = 2 } @@ -388,6 +389,8 @@ flag.Caps { bits = 64, base = 1, name = "Caps" } .TextureCompareReserved .TextureCubeArray --- Cubemap texture array is supported. .TextureDirectAccess --- CPU direct access to GPU texture memory. + .TextureExternal --- External texture is supported. + .TextureExternalShared --- External shared texture is supported. .TextureReadBack --- Read-back texture is supported. .Texture_2dArray --- 2D texture array is supported. .Texture_3d --- 3D textures are supported. @@ -811,6 +814,8 @@ struct.PlatformData { ctor } .context "void*" --- GL context, D3D device, or Vulkan device. If `NULL`, bgfx --- will create context/device. + .queue "void*" + --- D3D12 Queue. If `NULL` bgfx will create queue. .backBuffer "void*" --- GL back-buffer, or D3D render target view. If `NULL` bgfx will --- create back-buffer color surface. @@ -1716,6 +1721,8 @@ func.createTexture2D .mem "const Memory*" --- Texture data. If `_mem` is non-NULL, created texture will be immutable. If { default = NULL } --- `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than --- 1, expected memory layout is texture and all mips together for each array element. + .external "uint64_t" --- Native API pointer to texture. + { default = 0 } --- Create texture with size based on back-buffer ratio. Texture will maintain ratio --- if back buffer resolution changes. @@ -1752,6 +1759,8 @@ func.createTexture3D .mem "const Memory*" --- Texture data. If `_mem` is non-NULL, created texture will be immutable. If { default = NULL } --- `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than --- 1, expected memory layout is texture and all mips together for each array element. + .external "uint64_t" --- Native API pointer to texture. + { default = 0 } --- Create Cube texture. func.createTextureCube @@ -1770,7 +1779,8 @@ func.createTextureCube --- sampling. .mem "const Memory*" --- Texture data. If `_mem` is non-NULL, created texture will be immutable. If { default = NULL } --- `_mem` is NULL content of the texture is uninitialized. When `_numLayers` is more than - --- 1, expected memory layout is texture and all mips together for each array element. + .external "uint64_t" --- Native API pointer to texture. + { default = 0 } --- Update 2D texture. --- diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 44e7065d1..59803e84a 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -473,7 +473,7 @@ namespace bgfx bx::write(&writer, tc, bx::ErrorAssert{}); rci->destroyTexture(_handle); - rci->createTexture(_handle, mem, _flags, 0); + rci->createTexture(_handle, mem, _flags, 0, 0); release(mem); @@ -1631,6 +1631,8 @@ namespace bgfx CAPS_FLAGS(BGFX_CAPS_TEXTURE_COMPARE_LEQUAL), CAPS_FLAGS(BGFX_CAPS_TEXTURE_CUBE_ARRAY), CAPS_FLAGS(BGFX_CAPS_TEXTURE_DIRECT_ACCESS), + CAPS_FLAGS(BGFX_CAPS_TEXTURE_EXTERNAL), + CAPS_FLAGS(BGFX_CAPS_TEXTURE_EXTERNAL_SHARED), CAPS_FLAGS(BGFX_CAPS_TEXTURE_READ_BACK), CAPS_FLAGS(BGFX_CAPS_TRANSPARENT_BACKBUFFER), CAPS_FLAGS(BGFX_CAPS_VARIABLE_RATE_SHADING), @@ -3293,7 +3295,11 @@ namespace bgfx uint8_t skip; _cmdbuf.read(skip); - void* ptr = m_renderCtx->createTexture(handle, mem, flags, skip); + uintptr_t external; + _cmdbuf.read(external); + + void* ptr = m_renderCtx->createTexture(handle, mem, flags, skip, external); + if (NULL != ptr) { setDirectAccessPtr(handle, ptr); @@ -3599,6 +3605,7 @@ namespace bgfx : ndt(NULL) , nwh(NULL) , context(NULL) + , queue(NULL) , backBuffer(NULL) , backBufferDS(NULL) , type(NativeWindowHandleType::Default) @@ -4997,7 +5004,7 @@ namespace bgfx TextureHandle createTexture(const Memory* _mem, uint64_t _flags, uint8_t _skip, TextureInfo* _info) { BX_ASSERT(NULL != _mem, "_mem can't be NULL"); - return s_ctx->createTexture(_mem, _flags, _skip, _info, BackbufferRatio::Count, false); + return s_ctx->createTexture(_mem, _flags, _skip, _info, BackbufferRatio::Count, false, 0); } void getTextureSizeFromRatio(BackbufferRatio::Enum _ratio, uint16_t& _width, uint16_t& _height) @@ -5018,7 +5025,17 @@ namespace bgfx _height = bx::max(1, _height); } - static TextureHandle createTexture2D(BackbufferRatio::Enum _ratio, uint16_t _width, uint16_t _height, bool _hasMips, uint16_t _numLayers, TextureFormat::Enum _format, uint64_t _flags, const Memory* _mem) + static TextureHandle createTexture2D( + BackbufferRatio::Enum _ratio + , uint16_t _width + , uint16_t _height + , bool _hasMips + , uint16_t _numLayers + , TextureFormat::Enum _format + , uint64_t _flags + , const Memory* _mem + , uint64_t _external + ) { if (BackbufferRatio::Count != _ratio) { @@ -5067,23 +5084,36 @@ namespace bgfx tc.m_mem = _mem; bx::write(&writer, tc, bx::ErrorAssert{}); - return s_ctx->createTexture(mem, _flags, 0, NULL, _ratio, NULL != _mem); + return s_ctx->createTexture(mem, _flags, 0, NULL, _ratio, NULL != _mem, _external); } - TextureHandle createTexture2D(uint16_t _width, uint16_t _height, bool _hasMips, uint16_t _numLayers, TextureFormat::Enum _format, uint64_t _flags, const Memory* _mem) + TextureHandle createTexture2D(uint16_t _width, uint16_t _height, bool _hasMips, uint16_t _numLayers, TextureFormat::Enum _format, uint64_t _flags, const Memory* _mem, uint64_t _external) { + BX_ASSERT(false + || 0 == _external + || 0 != (g_caps.supported & BGFX_CAPS_TEXTURE_EXTERNAL) + , "External texture is not supported! " + "Use bgfx::getCaps to check `BGFX_CAPS_TEXTURE_EXTERNAL` backend renderer capabilities." + ); BX_ASSERT(_width > 0 && _height > 0, "Invalid texture size (width %d, height %d).", _width, _height); - return createTexture2D(BackbufferRatio::Count, _width, _height, _hasMips, _numLayers, _format, _flags, _mem); + return createTexture2D(BackbufferRatio::Count, _width, _height, _hasMips, _numLayers, _format, _flags, _mem, _external); } TextureHandle createTexture2D(BackbufferRatio::Enum _ratio, bool _hasMips, uint16_t _numLayers, TextureFormat::Enum _format, uint64_t _flags) { BX_ASSERT(_ratio < BackbufferRatio::Count, "Invalid back buffer ratio."); - return createTexture2D(_ratio, 0, 0, _hasMips, _numLayers, _format, _flags, NULL); + return createTexture2D(_ratio, 0, 0, _hasMips, _numLayers, _format, _flags, NULL, 0); } - TextureHandle createTexture3D(uint16_t _width, uint16_t _height, uint16_t _depth, bool _hasMips, TextureFormat::Enum _format, uint64_t _flags, const Memory* _mem) + TextureHandle createTexture3D(uint16_t _width, uint16_t _height, uint16_t _depth, bool _hasMips, TextureFormat::Enum _format, uint64_t _flags, const Memory* _mem, uint64_t _external) { + BX_ASSERT(false + || 0 == _external + || 0 != (g_caps.supported & BGFX_CAPS_TEXTURE_EXTERNAL) + , "External texture is not supported! " + "Use bgfx::getCaps to check `BGFX_CAPS_TEXTURE_EXTERNAL` backend renderer capabilities." + ); + bx::ErrorAssert err; isTextureValid(_width, _height, _depth, false, 1, _format, _flags, &err); @@ -5123,11 +5153,18 @@ namespace bgfx tc.m_mem = _mem; bx::write(&writer, tc, bx::ErrorAssert{}); - return s_ctx->createTexture(mem, _flags, 0, NULL, BackbufferRatio::Count, NULL != _mem); + return s_ctx->createTexture(mem, _flags, 0, NULL, BackbufferRatio::Count, NULL != _mem, _external); } - TextureHandle createTextureCube(uint16_t _size, bool _hasMips, uint16_t _numLayers, TextureFormat::Enum _format, uint64_t _flags, const Memory* _mem) + TextureHandle createTextureCube(uint16_t _size, bool _hasMips, uint16_t _numLayers, TextureFormat::Enum _format, uint64_t _flags, const Memory* _mem, uint64_t _external) { + BX_ASSERT(false + || 0 == _external + || 0 != (g_caps.supported & BGFX_CAPS_TEXTURE_EXTERNAL) + , "External texture is not supported! " + "Use bgfx::getCaps to check `BGFX_CAPS_TEXTURE_EXTERNAL` backend renderer capabilities." + ); + bx::ErrorAssert err; isTextureValid(_size, _size, 0, true, _numLayers, _format, _flags, &err); @@ -5168,7 +5205,7 @@ namespace bgfx tc.m_mem = _mem; bx::write(&writer, tc, bx::ErrorAssert{}); - return s_ctx->createTexture(mem, _flags, 0, NULL, BackbufferRatio::Count, NULL != _mem); + return s_ctx->createTexture(mem, _flags, 0, NULL, BackbufferRatio::Count, NULL != _mem, _external); } void setName(TextureHandle _handle, const char* _name, int32_t _len) @@ -5999,6 +6036,8 @@ static_assert( (0 | BGFX_CAPS_TEXTURE_BLIT | BGFX_CAPS_TEXTURE_CUBE_ARRAY | BGFX_CAPS_TEXTURE_DIRECT_ACCESS + | BGFX_CAPS_TEXTURE_EXTERNAL + | BGFX_CAPS_TEXTURE_EXTERNAL_SHARED | BGFX_CAPS_TEXTURE_READ_BACK | BGFX_CAPS_VERTEX_ATTRIB_HALF | BGFX_CAPS_VERTEX_ATTRIB_UINT10 @@ -6027,6 +6066,8 @@ static_assert( (0 ^ BGFX_CAPS_TEXTURE_BLIT ^ BGFX_CAPS_TEXTURE_CUBE_ARRAY ^ BGFX_CAPS_TEXTURE_DIRECT_ACCESS + ^ BGFX_CAPS_TEXTURE_EXTERNAL + ^ BGFX_CAPS_TEXTURE_EXTERNAL_SHARED ^ BGFX_CAPS_TEXTURE_READ_BACK ^ BGFX_CAPS_VERTEX_ATTRIB_HALF ^ BGFX_CAPS_VERTEX_ATTRIB_UINT10 diff --git a/src/bgfx.idl.inl b/src/bgfx.idl.inl index 5558d35ef..bd7543348 100644 --- a/src/bgfx.idl.inl +++ b/src/bgfx.idl.inl @@ -469,10 +469,10 @@ BGFX_C_API bgfx_texture_handle_t bgfx_create_texture(const bgfx_memory_t* _mem, return handle_ret.c; } -BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_2d(uint16_t _width, uint16_t _height, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem) +BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_2d(uint16_t _width, uint16_t _height, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem, uint64_t _external) { union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle_ret; - handle_ret.cpp = bgfx::createTexture2D(_width, _height, _hasMips, _numLayers, (bgfx::TextureFormat::Enum)_format, _flags, (const bgfx::Memory*)_mem); + handle_ret.cpp = bgfx::createTexture2D(_width, _height, _hasMips, _numLayers, (bgfx::TextureFormat::Enum)_format, _flags, (const bgfx::Memory*)_mem, _external); return handle_ret.c; } @@ -483,17 +483,17 @@ BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_2d_scaled(bgfx_backbuffer_r return handle_ret.c; } -BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_3d(uint16_t _width, uint16_t _height, uint16_t _depth, bool _hasMips, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem) +BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_3d(uint16_t _width, uint16_t _height, uint16_t _depth, bool _hasMips, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem, uint64_t _external) { union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle_ret; - handle_ret.cpp = bgfx::createTexture3D(_width, _height, _depth, _hasMips, (bgfx::TextureFormat::Enum)_format, _flags, (const bgfx::Memory*)_mem); + handle_ret.cpp = bgfx::createTexture3D(_width, _height, _depth, _hasMips, (bgfx::TextureFormat::Enum)_format, _flags, (const bgfx::Memory*)_mem, _external); return handle_ret.c; } -BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_cube(uint16_t _size, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem) +BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_cube(uint16_t _size, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint64_t _flags, const bgfx_memory_t* _mem, uint64_t _external) { union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle_ret; - handle_ret.cpp = bgfx::createTextureCube(_size, _hasMips, _numLayers, (bgfx::TextureFormat::Enum)_format, _flags, (const bgfx::Memory*)_mem); + handle_ret.cpp = bgfx::createTextureCube(_size, _hasMips, _numLayers, (bgfx::TextureFormat::Enum)_format, _flags, (const bgfx::Memory*)_mem, _external); return handle_ret.c; } diff --git a/src/bgfx_p.h b/src/bgfx_p.h index cc31e875e..c1b8a9b01 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -3687,7 +3687,7 @@ namespace bgfx virtual void destroyShader(ShaderHandle _handle) = 0; virtual void createProgram(ProgramHandle _handle, ShaderHandle _vsh, ShaderHandle _fsh) = 0; virtual void destroyProgram(ProgramHandle _handle) = 0; - virtual void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip) = 0; + virtual void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) = 0; virtual void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) = 0; virtual void readTexture(TextureHandle _handle, void* _data, uint8_t _mip) = 0; virtual void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips, uint16_t _numLayers) = 0; @@ -5103,7 +5103,7 @@ namespace bgfx } } - BGFX_API_FUNC(TextureHandle createTexture(const Memory* _mem, uint64_t _flags, uint8_t _skip, TextureInfo* _info, BackbufferRatio::Enum _ratio, bool _immutable) ) + BGFX_API_FUNC(TextureHandle createTexture(const Memory* _mem, uint64_t _flags, uint8_t _skip, TextureInfo* _info, BackbufferRatio::Enum _ratio, bool _immutable, uint64_t _external) ) { BGFX_MUTEX_SCOPE(m_resourceApiLock); @@ -5181,6 +5181,7 @@ namespace bgfx cmdbuf.write(_mem); cmdbuf.write(_flags); cmdbuf.write(_skip); + cmdbuf.write(_external); setDebugNameForHandle(handle); diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 5c3f70ba4..e24c4462a 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -423,6 +423,7 @@ namespace bgfx { namespace d3d11 static const GUID WKPDID_D3DDebugObjectName = { 0x429b8c22, 0x9188, 0x4b0c, { 0x87, 0x42, 0xac, 0xb0, 0xbf, 0x85, 0xc2, 0x00 } }; static const GUID IID_ID3D11Texture2D = { 0x6f15aaf2, 0xd208, 0x4e89, { 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c } }; + static const GUID IID_ID3D11Resource = { 0xdc8e63f3, 0xd12b, 0x4952, { 0xb4, 0x7b, 0x5e, 0x45, 0x02, 0x6a, 0x86, 0x2d } }; static const GUID IID_ID3D11Device1 = { 0xa04bfb29, 0x08ef, 0x43d6, { 0xa4, 0x9c, 0xa9, 0xbd, 0xbd, 0xcb, 0xe6, 0x86 } }; static const GUID IID_ID3D11Device2 = { 0x9d06dffa, 0xd1e5, 0x4d07, { 0x83, 0xa8, 0x1b, 0xb1, 0x23, 0xf2, 0xf8, 0x41 } }; static const GUID IID_ID3D11Device3 = { 0xa05c8c37, 0xd2c6, 0x4732, { 0xb3, 0xa0, 0x9c, 0xe0, 0xb0, 0xdc, 0x9a, 0xe6 } }; @@ -1250,6 +1251,7 @@ namespace bgfx { namespace d3d11 | ((m_featureLevel >= D3D_FEATURE_LEVEL_11_0) ? BGFX_CAPS_PRIMITIVE_ID : 0) + | BGFX_CAPS_TEXTURE_EXTERNAL ); m_timerQuerySupport = m_featureLevel >= D3D_FEATURE_LEVEL_10_0; @@ -1861,9 +1863,10 @@ namespace bgfx { namespace d3d11 m_program[_handle.idx].destroy(); } - void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip) override + void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) override { - return m_textures[_handle.idx].create(_mem, _flags, _skip); + BX_UNUSED(_external); + return m_textures[_handle.idx].create(_mem, _flags, _skip, _external); } void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) override @@ -1915,7 +1918,7 @@ namespace bgfx { namespace d3d11 bx::write(&writer, tc, bx::ErrorAssert{}); texture.destroy(); - texture.create(mem, texture.m_flags, 0); + texture.create(mem, texture.m_flags, 0, NULL); release(mem); } @@ -4477,7 +4480,7 @@ namespace bgfx { namespace d3d11 } } - void* TextureD3D11::create(const Memory* _mem, uint64_t _flags, uint8_t _skip) + void* TextureD3D11::create(const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) { void* directAccessPtr = NULL; @@ -4602,12 +4605,14 @@ namespace bgfx { namespace d3d11 } } - const bool writeOnly = 0 != (m_flags&(BGFX_TEXTURE_RT_WRITE_ONLY|BGFX_TEXTURE_READ_BACK) ); - const bool computeWrite = 0 != (m_flags&BGFX_TEXTURE_COMPUTE_WRITE); - const bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK); - const bool srgb = 0 != (m_flags&BGFX_TEXTURE_SRGB); - const bool blit = 0 != (m_flags&BGFX_TEXTURE_BLIT_DST); - const bool readBack = 0 != (m_flags&BGFX_TEXTURE_READ_BACK); + const bool writeOnly = 0 != (m_flags & (BGFX_TEXTURE_RT_WRITE_ONLY|BGFX_TEXTURE_READ_BACK) ); + const bool computeWrite = 0 != (m_flags & BGFX_TEXTURE_COMPUTE_WRITE); + const bool renderTarget = 0 != (m_flags & BGFX_TEXTURE_RT_MASK); + const bool srgb = 0 != (m_flags & BGFX_TEXTURE_SRGB); + const bool blit = 0 != (m_flags & BGFX_TEXTURE_BLIT_DST); + const bool readBack = 0 != (m_flags & BGFX_TEXTURE_READ_BACK); + const bool externalShared = 0 != (m_flags & BGFX_TEXTURE_EXTERNAL_SHARED); + const uint32_t msaaQuality = bx::uint32_satsub( (m_flags&BGFX_TEXTURE_RT_MSAA_MASK)>>BGFX_TEXTURE_RT_MSAA_SHIFT, 1); const DXGI_SAMPLE_DESC& msaa = s_msaa[msaaQuality]; const bool msaaSample = true @@ -4651,161 +4656,185 @@ namespace bgfx { namespace d3d11 && !writeOnly ; - switch (m_type) + if (NULL != _external) { - case Texture2D: - case TextureCube: + if (externalShared) { - D3D11_TEXTURE2D_DESC desc = {}; - desc.Width = ti.width; - desc.Height = ti.height; - desc.MipLevels = ti.numMips; - desc.ArraySize = numSides; - desc.Format = format; - desc.SampleDesc = msaa; - desc.Usage = kk == 0 || blit ? D3D11_USAGE_DEFAULT : D3D11_USAGE_IMMUTABLE; - desc.BindFlags = writeOnly ? 0 : D3D11_BIND_SHADER_RESOURCE; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; + DX_CHECK(s_renderD3D11->m_device->OpenSharedResource(HANDLE(_external), IID_ID3D11Resource, (void**)&m_ptr) ); + } + else + { + m_ptr = (ID3D11Resource*)(_external); + } - if (bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ) ) + m_flags |= BGFX_SAMPLER_INTERNAL_SHARED; + } + else + { + switch (m_type) + { + case Texture2D: + case TextureCube: { - desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL; - desc.Usage = D3D11_USAGE_DEFAULT; - } - else if (renderTarget) - { - desc.BindFlags |= D3D11_BIND_RENDER_TARGET; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.MiscFlags |= 0 - | (1 < ti.numMips ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0) - ; - } + D3D11_TEXTURE2D_DESC desc = {}; + desc.Width = ti.width; + desc.Height = ti.height; + desc.MipLevels = ti.numMips; + desc.ArraySize = numSides; + desc.Format = format; + desc.SampleDesc = msaa; + desc.Usage = kk == 0 || blit ? D3D11_USAGE_DEFAULT : D3D11_USAGE_IMMUTABLE; + desc.BindFlags = writeOnly ? 0 : D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; - if (computeWrite) - { - desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS; - desc.Usage = D3D11_USAGE_DEFAULT; - } - - if (readBack) - { - desc.BindFlags = 0; - desc.Usage = D3D11_USAGE_STAGING; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - } - - if (imageContainer.m_cubeMap) - { - desc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE; - if (1 < ti.numLayers) + if (bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ) ) { - srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY; - srvd.TextureCubeArray.MipLevels = ti.numMips; - srvd.TextureCubeArray.NumCubes = ti.numLayers; + desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL; + desc.Usage = D3D11_USAGE_DEFAULT; } - else + else if (renderTarget) { - srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - srvd.TextureCube.MipLevels = ti.numMips; + desc.BindFlags |= D3D11_BIND_RENDER_TARGET; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.MiscFlags |= 0 + | (1 < ti.numMips ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0) + ; } - } - else - { - if (msaaSample) + + if (computeWrite) { + desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS; + desc.Usage = D3D11_USAGE_DEFAULT; + } + + if (readBack) + { + desc.BindFlags = 0; + desc.Usage = D3D11_USAGE_STAGING; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + } + + if (imageContainer.m_cubeMap) + { + desc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE; if (1 < ti.numLayers) { - srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; - srvd.Texture2DMSArray.ArraySize = ti.numLayers; + srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY; + srvd.TextureCubeArray.MipLevels = ti.numMips; + srvd.TextureCubeArray.NumCubes = ti.numLayers; } else { - srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + srvd.TextureCube.MipLevels = ti.numMips; } } else { - if (1 < ti.numLayers) + if (msaaSample) { - srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; - srvd.Texture2DArray.MipLevels = ti.numMips; - srvd.Texture2DArray.ArraySize = ti.numLayers; + if (1 < ti.numLayers) + { + srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; + srvd.Texture2DMSArray.ArraySize = ti.numLayers; + } + else + { + srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + } } else { - srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srvd.Texture2D.MipLevels = ti.numMips; + if (1 < ti.numLayers) + { + srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvd.Texture2DArray.MipLevels = ti.numMips; + srvd.Texture2DArray.ArraySize = ti.numLayers; + } + else + { + srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvd.Texture2D.MipLevels = ti.numMips; + } } } - } - if (needResolve) - { - DX_CHECK(s_renderD3D11->m_device->CreateTexture2D(&desc, NULL, &m_rt2d) ); - desc.BindFlags &= ~(D3D11_BIND_RENDER_TARGET|D3D11_BIND_DEPTH_STENCIL); - desc.SampleDesc = s_msaa[0]; - } + desc.MiscFlags |= externalShared ? D3D11_RESOURCE_MISC_SHARED : 0; - if (directAccess) - { - directAccessPtr = m_dar.createTexture2D(&desc, kk == 0 ? NULL : srd, &m_texture2d); + if (needResolve) + { + DX_CHECK(s_renderD3D11->m_device->CreateTexture2D(&desc, NULL, &m_rt2d) ); + desc.BindFlags &= ~(D3D11_BIND_RENDER_TARGET|D3D11_BIND_DEPTH_STENCIL); + desc.SampleDesc = s_msaa[0]; + } + + if (directAccess) + { + directAccessPtr = m_dar.createTexture2D(&desc, kk == 0 ? NULL : srd, &m_texture2d); + } + else + { + DX_CHECK(s_renderD3D11->m_device->CreateTexture2D(&desc, kk == 0 ? NULL : srd, &m_texture2d) ); + } } - else + break; + + case Texture3D: { - DX_CHECK(s_renderD3D11->m_device->CreateTexture2D(&desc, kk == 0 ? NULL : srd, &m_texture2d) ); + D3D11_TEXTURE3D_DESC desc = {}; + desc.Width = ti.width; + desc.Height = ti.height; + desc.Depth = ti.depth; + desc.MipLevels = ti.numMips; + desc.Format = format; + desc.Usage = kk == 0 || blit ? D3D11_USAGE_DEFAULT : D3D11_USAGE_IMMUTABLE; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + if (renderTarget) + { + desc.BindFlags |= D3D11_BIND_RENDER_TARGET; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.MiscFlags |= 0 + | (1 < ti.numMips ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0) + ; + } + + if (computeWrite) + { + desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS; + desc.Usage = D3D11_USAGE_DEFAULT; + } + + if (readBack) + { + desc.BindFlags = 0; + desc.Usage = D3D11_USAGE_STAGING; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + } + + srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + srvd.Texture3D.MipLevels = ti.numMips; + + desc.MiscFlags |= externalShared ? D3D11_RESOURCE_MISC_SHARED : 0; + + if (directAccess) + { + directAccessPtr = m_dar.createTexture3D(&desc, kk == 0 ? NULL : srd, &m_texture3d); + } + else + { + DX_CHECK(s_renderD3D11->m_device->CreateTexture3D(&desc, kk == 0 ? NULL : srd, &m_texture3d) ); + } } + break; } - break; - case Texture3D: + if (externalShared) { - D3D11_TEXTURE3D_DESC desc = {}; - desc.Width = ti.width; - desc.Height = ti.height; - desc.Depth = ti.depth; - desc.MipLevels = ti.numMips; - desc.Format = format; - desc.Usage = kk == 0 || blit ? D3D11_USAGE_DEFAULT : D3D11_USAGE_IMMUTABLE; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - if (renderTarget) - { - desc.BindFlags |= D3D11_BIND_RENDER_TARGET; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.MiscFlags |= 0 - | (1 < ti.numMips ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0) - ; - } - - if (computeWrite) - { - desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS; - desc.Usage = D3D11_USAGE_DEFAULT; - } - - if (readBack) - { - desc.BindFlags = 0; - desc.Usage = D3D11_USAGE_STAGING; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - } - - srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; - srvd.Texture3D.MipLevels = ti.numMips; - - if (directAccess) - { - directAccessPtr = m_dar.createTexture3D(&desc, kk == 0 ? NULL : srd, &m_texture3d); - } - else - { - DX_CHECK(s_renderD3D11->m_device->CreateTexture3D(&desc, kk == 0 ? NULL : srd, &m_texture3d) ); - } } - break; } if (!writeOnly) @@ -4843,6 +4872,7 @@ namespace bgfx { namespace d3d11 DX_RELEASE(m_rt, 0); DX_RELEASE(m_srv, 0); DX_RELEASE(m_uav, 0); + if (0 == (m_flags & BGFX_SAMPLER_INTERNAL_SHARED) ) { DX_RELEASE(m_ptr, 0); @@ -5099,7 +5129,6 @@ namespace bgfx { namespace d3d11 DX_CHECK(device->CreateDepthStencilView(depthStencil, NULL, &m_dsv) ); DX_RELEASE(depthStencil, 0); - m_srv[0] = NULL; m_nwh = _nwh; m_denseIdx = _denseIdx; m_num = 1; @@ -5324,9 +5353,13 @@ namespace bgfx { namespace d3d11 break; } - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc{}; - texture.m_srv->GetDesc(&srvDesc); - DX_CHECK(s_renderD3D11->m_device->CreateShaderResourceView(texture.m_ptr, &srvDesc, &m_srv[m_num])); + if (NULL != texture.m_srv) + { + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc{}; + texture.m_srv->GetDesc(&srvDesc); + DX_CHECK(s_renderD3D11->m_device->CreateShaderResourceView(texture.m_ptr, &srvDesc, &m_srv[m_num])); + } + m_num++; } else diff --git a/src/renderer_d3d11.h b/src/renderer_d3d11.h index c31b78123..31cf8f8b4 100644 --- a/src/renderer_d3d11.h +++ b/src/renderer_d3d11.h @@ -284,7 +284,7 @@ namespace bgfx { namespace d3d11 { } - void* create(const Memory* _mem, uint64_t _flags, uint8_t _skip); + void* create(const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external); void destroy(); void overrideInternal(uintptr_t _ptr, uint16_t _layerIndex); void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem); @@ -335,6 +335,9 @@ namespace bgfx { namespace d3d11 , m_numUav(0) , m_needPresent(false) { + bx::memSet(m_rtv, 0, sizeof(m_rtv) ); + bx::memSet(m_uav, 0, sizeof(m_uav) ); + bx::memSet(m_srv, 0, sizeof(m_srv) ); } void create(uint8_t _num, const Attachment* _attachment); diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 050a10ab2..c439d0e31 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -547,12 +547,12 @@ namespace bgfx { namespace d3d12 #endif // BX_PLATFORM_WINDOWS } - ID3D12Resource* createCommittedResource(ID3D12Device* _device, HeapProperty::Enum _heapProperty, const D3D12_RESOURCE_DESC* _resourceDesc, const D3D12_CLEAR_VALUE* _clearValue, bool _memSet = false) + ID3D12Resource* createCommittedResource(ID3D12Device* _device, HeapProperty::Enum _heapProperty, const D3D12_RESOURCE_DESC* _resourceDesc, const D3D12_CLEAR_VALUE* _clearValue, bool _memSet = false, D3D12_HEAP_FLAGS _heapFlags = D3D12_HEAP_FLAG_NONE) { const HeapProperty& heapProperty = s_heapProperties[_heapProperty]; ID3D12Resource* resource; DX_CHECK(_device->CreateCommittedResource(&heapProperty.m_properties - , D3D12_HEAP_FLAG_NONE + , _heapFlags , _resourceDesc , heapProperty.m_state , _clearValue @@ -581,7 +581,7 @@ namespace bgfx { namespace d3d12 return resource; } - ID3D12Resource* createCommittedResource(ID3D12Device* _device, HeapProperty::Enum _heapProperty, uint64_t _size, D3D12_RESOURCE_FLAGS _flags = D3D12_RESOURCE_FLAG_NONE) + ID3D12Resource* createCommittedResource(ID3D12Device* _device, HeapProperty::Enum _heapProperty, uint64_t _size, D3D12_RESOURCE_FLAGS _flags = D3D12_RESOURCE_FLAG_NONE, D3D12_HEAP_FLAGS _heapFlags = D3D12_HEAP_FLAG_NONE) { D3D12_RESOURCE_DESC resourceDesc = {}; resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; @@ -596,7 +596,7 @@ namespace bgfx { namespace d3d12 resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; resourceDesc.Flags = _flags; - return createCommittedResource(_device, _heapProperty, &resourceDesc, NULL); + return createCommittedResource(_device, _heapProperty, &resourceDesc, NULL, false, _heapFlags); } inline bool isLost(HRESULT _hr) @@ -1254,7 +1254,7 @@ namespace bgfx { namespace d3d12 initHeapProperties(m_device); - m_cmd.init(m_device); + m_cmd.init(m_device, (ID3D12CommandQueue*)g_platformData.queue); m_device->SetPrivateDataInterface(IID_ID3D12CommandQueue, m_cmd.m_commandQueue); errorState = ErrorState::CreatedCommandQueue; @@ -1624,6 +1624,7 @@ namespace bgfx { namespace d3d12 | BGFX_CAPS_TEXTURE_COMPARE_ALL | BGFX_CAPS_TEXTURE_CUBE_ARRAY | (m_directAccessSupport ? BGFX_CAPS_TEXTURE_DIRECT_ACCESS : 0) + | BGFX_CAPS_TEXTURE_EXTERNAL | BGFX_CAPS_TEXTURE_READ_BACK | (m_variableRateShadingSupport ? BGFX_CAPS_VARIABLE_RATE_SHADING : 0) | BGFX_CAPS_VERTEX_ATTRIB_HALF @@ -2125,9 +2126,9 @@ namespace bgfx { namespace d3d12 m_program[_handle.idx].destroy(); } - void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip) override + void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) override { - return m_textures[_handle.idx].create(_mem, _flags, _skip); + return m_textures[_handle.idx].create(_mem, _flags, _skip, _external); } void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) override @@ -2216,7 +2217,7 @@ namespace bgfx { namespace d3d12 bx::write(&writer, tc, bx::ErrorAssert{}); texture.destroy(); - texture.create(mem, texture.m_flags, 0); + texture.create(mem, texture.m_flags, 0, 0); release(mem); } @@ -2940,7 +2941,10 @@ namespace bgfx { namespace d3d12 { FrameBufferD3D12& frameBuffer = m_frameBuffers[m_fbh.idx]; - if (m_rtMsaa) frameBuffer.resolve(); + if (m_rtMsaa) + { + frameBuffer.resolve(); + } if (NULL == frameBuffer.m_swapChain) { @@ -2967,7 +2971,7 @@ namespace bgfx { namespace d3d12 if (NULL != m_swapChain) { m_rtvHandle = getCPUHandleHeapStart(m_rtvDescriptorHeap); - uint32_t rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + const uint32_t rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); m_rtvHandle.ptr += m_backBufferColorIdx * rtvDescriptorSize; m_dsvHandle = getCPUHandleHeapStart(m_dsvDescriptorHeap); @@ -4271,18 +4275,27 @@ namespace bgfx { namespace d3d12 return gpuHandle; } - void CommandQueueD3D12::init(ID3D12Device* _device) + void CommandQueueD3D12::init(ID3D12Device* _device, ID3D12CommandQueue* _queue) { - D3D12_COMMAND_QUEUE_DESC queueDesc; - queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - queueDesc.Priority = 0; - queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; - queueDesc.NodeMask = 1; - DX_CHECK(_device->CreateCommandQueue( - &queueDesc - , IID_ID3D12CommandQueue - , (void**)&m_commandQueue - ) ); + m_externalQueue = NULL != _queue; + + if (NULL != _queue) + { + m_commandQueue = _queue; + } + else + { + D3D12_COMMAND_QUEUE_DESC queueDesc; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + queueDesc.Priority = 0; + queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queueDesc.NodeMask = 1; + DX_CHECK(_device->CreateCommandQueue( + &queueDesc + , IID_ID3D12CommandQueue + , (void**)&m_commandQueue + ) ); + } m_completedFence = 0; m_currentFence = 0; @@ -4349,7 +4362,10 @@ namespace bgfx { namespace d3d12 DX_RELEASE(m_commandList[ii].m_commandList, 0); } - DX_RELEASE(m_commandQueue, 0); + if (!m_externalQueue) + { + DX_RELEASE(m_commandQueue, 0); + } const D3D12_RANGE range = { @@ -4384,6 +4400,11 @@ namespace bgfx { namespace d3d12 const uint32_t currentIdx = m_control.m_current; CommandList& commandList = m_commandList[currentIdx]; + for (TextureHandle th : m_external) + { + s_renderD3D12->m_textures[th.idx].setState(commandList.m_commandList, D3D12_RESOURCE_STATE_COMMON); + } + commandList.m_commandList->EndQuery( m_pipelineStatsQueryHeap , D3D12_QUERY_TYPE_PIPELINE_STATISTICS @@ -4485,6 +4506,25 @@ namespace bgfx { namespace d3d12 return false; } + void CommandQueueD3D12::addExternal(TextureHandle _handle) + { + m_external.push_back(_handle); + } + + void CommandQueueD3D12::removeExternal(TextureHandle _handle) + { + for (ExternalTextureArray::iterator it = m_external.begin(), itEnd = m_external.end(); it != itEnd; ++it) + { + if (it->idx == _handle.idx) + { + m_external.erase(it); + return; + } + } + + BX_ASSERT(false, "Removing external texture failed!"); + } + void BatchD3D12::create(uint32_t _maxDrawPerBatch) { m_maxDrawPerBatch = _maxDrawPerBatch; @@ -5392,7 +5432,7 @@ namespace bgfx { namespace d3d12 return result; } - void* TextureD3D12::create(const Memory* _mem, uint64_t _flags, uint8_t _skip) + void* TextureD3D12::create(const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) { bimg::ImageContainer imageContainer; @@ -5447,10 +5487,11 @@ namespace bgfx { namespace d3d12 const bool compressed = bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat) ); const bool swizzle = TextureFormat::BGRA8 == m_textureFormat && 0 != (m_flags&BGFX_TEXTURE_COMPUTE_WRITE); - const bool writeOnly = 0 != (m_flags&BGFX_TEXTURE_RT_WRITE_ONLY); - const bool computeWrite = 0 != (m_flags&BGFX_TEXTURE_COMPUTE_WRITE); - const bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK); - const bool blit = 0 != (m_flags&BGFX_TEXTURE_BLIT_DST); + const bool writeOnly = 0 != (m_flags & BGFX_TEXTURE_RT_WRITE_ONLY); + const bool computeWrite = 0 != (m_flags & BGFX_TEXTURE_COMPUTE_WRITE); + const bool renderTarget = 0 != (m_flags & BGFX_TEXTURE_RT_MASK); + const bool blit = 0 != (m_flags & BGFX_TEXTURE_BLIT_DST); + const bool externalShared = 0 != (m_flags & BGFX_TEXTURE_EXTERNAL_SHARED); const uint32_t msaaQuality = bx::uint32_satsub((m_flags & BGFX_TEXTURE_RT_MSAA_MASK) >> BGFX_TEXTURE_RT_MSAA_SHIFT, 1); const DXGI_SAMPLE_DESC& msaa = s_msaa[msaaQuality]; @@ -5720,7 +5761,46 @@ namespace bgfx { namespace d3d12 break; } - m_ptr = createCommittedResource(device, HeapProperty::Texture, &resourceDesc, clearValue, renderTarget); + if (0 != _external) + { + if (externalShared) + { + DX_CHECK(device->OpenSharedHandle(HANDLE(_external), IID_ID3D12Resource, (void**)&m_ptr) ); + } + else + { + m_ptr = (ID3D12Resource*)_external; + } + + m_flags |= BGFX_SAMPLER_INTERNAL_SHARED; + m_state = D3D12_RESOURCE_STATE_COMMON; + + s_renderD3D12->m_cmd.addExternal({ uint16_t(this - s_renderD3D12->m_textures) }); + } + else + { + m_ptr = createCommittedResource( + device + , HeapProperty::Texture + , &resourceDesc + , clearValue + , renderTarget + , externalShared + ? D3D12_HEAP_FLAG_SHARED + : D3D12_HEAP_FLAG_NONE + ); + + if (externalShared) + { + DX_CHECK(device->CreateSharedHandle( + m_ptr + , NULL + , GENERIC_ALL + , NULL + , &m_handle + ) ); + } + } if (directAccess) { @@ -5751,10 +5831,6 @@ namespace bgfx { namespace d3d12 s_renderD3D12->m_cmd.release(staging); } - else - { - setState(commandList, state); - } if (0 != kk) { @@ -5801,17 +5877,33 @@ namespace bgfx { namespace d3d12 m_directAccessPtr = NULL; } - if (0 == (m_flags & BGFX_SAMPLER_INTERNAL_SHARED) ) + const bool external = 0 != (m_flags & BGFX_SAMPLER_INTERNAL_SHARED); + const bool externalShared = 0 != (m_flags & BGFX_TEXTURE_EXTERNAL_SHARED); + + if (externalShared) + { +#if !BX_PLATFORM_LINUX + CloseHandle(m_handle); + m_handle = NULL; +#endif // !BX_PLATFORM_LINUX + } + + if (external) + { + s_renderD3D12->m_cmd.removeExternal({ uint16_t(this - s_renderD3D12->m_textures) }); + } + else { s_renderD3D12->m_cmd.release(m_ptr); - m_ptr = NULL; - m_state = D3D12_RESOURCE_STATE_COMMON; + } - if (NULL != m_singleMsaa) - { - s_renderD3D12->m_cmd.release(m_singleMsaa); - m_singleMsaa = NULL; - } + m_ptr = NULL; + m_state = D3D12_RESOURCE_STATE_COMMON; + + if (NULL != m_singleMsaa) + { + s_renderD3D12->m_cmd.release(m_singleMsaa); + m_singleMsaa = NULL; } } } diff --git a/src/renderer_d3d12.h b/src/renderer_d3d12.h index 0548fc5ca..cc20e1586 100644 --- a/src/renderer_d3d12.h +++ b/src/renderer_d3d12.h @@ -309,6 +309,7 @@ namespace bgfx { namespace d3d12 TextureD3D12() : m_ptr(NULL) , m_singleMsaa(NULL) + , m_handle(NULL) , m_directAccessPtr(NULL) , m_state(D3D12_RESOURCE_STATE_COMMON) , m_numMips(0) @@ -317,7 +318,7 @@ namespace bgfx { namespace d3d12 bx::memSet(&m_uavd, 0, sizeof(m_uavd) ); } - void* create(const Memory* _mem, uint64_t _flags, uint8_t _skip); + void* create(const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external); void destroy(); void overrideInternal(uintptr_t _ptr); void update(ID3D12GraphicsCommandList* _commandList, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem); @@ -328,6 +329,7 @@ namespace bgfx { namespace d3d12 D3D12_UNORDERED_ACCESS_VIEW_DESC m_uavd; ID3D12Resource* m_ptr; ID3D12Resource* m_singleMsaa; + HANDLE m_handle; void* m_directAccessPtr; D3D12_RESOURCE_STATES m_state; uint64_t m_flags; @@ -390,11 +392,12 @@ namespace bgfx { namespace d3d12 : m_currentFence(0) , m_completedFence(0) , m_control(BX_COUNTOF(m_commandList) ) + , m_externalQueue(false) { static_assert(BX_COUNTOF(m_commandList) == BX_COUNTOF(m_release) ); } - void init(ID3D12Device* _device); + void init(ID3D12Device* _device, ID3D12CommandQueue* _queue); void shutdown(); ID3D12GraphicsCommandList* alloc(); uint64_t kick(); @@ -403,6 +406,9 @@ namespace bgfx { namespace d3d12 void release(ID3D12Resource* _ptr); bool consume(uint32_t _ms = UINT32_MAX); + void addExternal(TextureHandle _handle); + void removeExternal(TextureHandle _handle); + struct CommandList { ID3D12GraphicsCommandList* m_commandList; @@ -455,7 +461,10 @@ namespace bgfx { namespace d3d12 CommandList m_commandList[kMaxCommandLists]; typedef stl::vector ResourceArray; ResourceArray m_release[kMaxCommandLists]; + typedef stl::vector ExternalTextureArray; + ExternalTextureArray m_external; bx::RingBufferControl m_control; + bool m_externalQueue; ID3D12Resource* m_pipelineStatsReadBack; ID3D12QueryHeap* m_pipelineStatsQueryHeap; diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 29693d0f5..a01d06f1a 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -3393,8 +3393,9 @@ namespace bgfx { namespace gl m_program[_handle.idx].destroy(); } - void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip) override + void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) override { + BX_UNUSED(_external); m_textures[_handle.idx].create(_mem, _flags, _skip); return NULL; } diff --git a/src/renderer_mtl.h b/src/renderer_mtl.h index ac1b54ba2..2d7c7f9a3 100644 --- a/src/renderer_mtl.h +++ b/src/renderer_mtl.h @@ -1392,30 +1392,9 @@ namespace bgfx { namespace mtl } } - void create(const Memory* _mem, uint64_t _flags, uint8_t _skip); - - void destroy() - { - if (0 == (m_flags & BGFX_SAMPLER_INTERNAL_SHARED) ) - { - MTL_RELEASE_W(m_ptr, 0); - MTL_RELEASE_W(m_ptrMsaa, 0); - } - - MTL_RELEASE_W(m_ptrStencil, 0); - - for (uint32_t ii = 0; ii < m_numMips; ++ii) - { - MTL_RELEASE_W(m_ptrMips[ii], 0); - } - } - - void overrideInternal(uintptr_t _ptr) - { - destroy(); - m_flags |= BGFX_SAMPLER_INTERNAL_SHARED; - m_ptr = id(_ptr); - } + void create(const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external); + void destroy(); + void overrideInternal(uintptr_t _ptr); void update( uint8_t _side diff --git a/src/renderer_mtl.mm b/src/renderer_mtl.mm index 31736c728..27ebde9d8 100644 --- a/src/renderer_mtl.mm +++ b/src/renderer_mtl.mm @@ -611,6 +611,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames | BGFX_CAPS_TEXTURE_2D_ARRAY | BGFX_CAPS_TEXTURE_3D | BGFX_CAPS_TEXTURE_BLIT + | BGFX_CAPS_TEXTURE_EXTERNAL | BGFX_CAPS_TEXTURE_READ_BACK | BGFX_CAPS_VERTEX_ATTRIB_HALF | BGFX_CAPS_VERTEX_ATTRIB_UINT10 @@ -1076,9 +1077,9 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames m_program[_handle.idx].destroy(); } - void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip) override + void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) override { - m_textures[_handle.idx].create(_mem, _flags, _skip); + m_textures[_handle.idx].create(_mem, _flags, _skip, _external); return NULL; } @@ -1145,7 +1146,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames bx::write(&writer, tc, bx::ErrorAssert{}); texture.destroy(); - texture.create(mem, texture.m_flags, 0); + texture.create(mem, texture.m_flags, 0, 0); release(mem); } @@ -3008,7 +3009,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); BufferMtl::create(_size, _data, _flags, stride, true); } - void TextureMtl::create(const Memory* _mem, uint64_t _flags, uint8_t _skip) + void TextureMtl::create(const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) { m_sampler = s_renderMtl->getSamplerState(uint32_t(_flags) ); @@ -3149,7 +3150,15 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } } - m_ptr = s_renderMtl->m_device.newTextureWithDescriptor(desc); + if (0 != _external) + { + m_ptr = id(_external); + m_flags |= BGFX_SAMPLER_INTERNAL_SHARED; + } + else + { + m_ptr = s_renderMtl->m_device.newTextureWithDescriptor(desc); + } if (sampleCount > 1) { @@ -3257,6 +3266,29 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } } + void TextureMtl::destroy() + { + if (0 == (m_flags & BGFX_SAMPLER_INTERNAL_SHARED) ) + { + MTL_RELEASE_W(m_ptr, 0); + } + + MTL_RELEASE_W(m_ptrMsaa, 0); + MTL_RELEASE_W(m_ptrStencil, 0); + + for (uint32_t ii = 0; ii < m_numMips; ++ii) + { + MTL_RELEASE_W(m_ptrMips[ii], 0); + } + } + + void TextureMtl::overrideInternal(uintptr_t _ptr) + { + destroy(); + m_flags |= BGFX_SAMPLER_INTERNAL_SHARED; + m_ptr = id(_ptr); + } + void TextureMtl::update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) { const uint32_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) ); diff --git a/src/renderer_noop.cpp b/src/renderer_noop.cpp index c6496a082..763cb1de7 100644 --- a/src/renderer_noop.cpp +++ b/src/renderer_noop.cpp @@ -164,7 +164,7 @@ namespace bgfx { namespace noop { } - void* createTexture(TextureHandle /*_handle*/, const Memory* /*_mem*/, uint64_t /*_flags*/, uint8_t /*_skip*/) override + void* createTexture(TextureHandle /*_handle*/, const Memory* /*_mem*/, uint64_t /*_flags*/, uint8_t /*_skip*/, uint64_t /*_external*/) override { return NULL; } diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index 44eb1ceec..c927c98c8 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -2418,9 +2418,9 @@ VK_IMPORT_DEVICE m_program[_handle.idx].destroy(); } - void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip) override + void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) override { - return m_textures[_handle.idx].create(m_commandBuffer, _mem, _flags, _skip); + return m_textures[_handle.idx].create(m_commandBuffer, _mem, _flags, _skip, _external); } void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) override @@ -2481,7 +2481,7 @@ VK_IMPORT_DEVICE bx::write(&writer, tc, bx::ErrorAssert{}); destroyTexture(_handle); - createTexture(_handle, mem, flags, 0); + createTexture(_handle, mem, flags, 0, 0); bgfx::release(mem); } @@ -2989,10 +2989,10 @@ VK_IMPORT_DEVICE for (uint8_t ii = 0, num = oldFrameBuffer.m_num; ii < num; ++ii) { TextureVK& texture = m_textures[oldFrameBuffer.m_texture[ii].idx]; - texture.setImageMemoryBarrier(m_commandBuffer, texture.m_sampledLayout); + texture.setState(m_commandBuffer, texture.m_sampledLayout); if (VK_NULL_HANDLE != texture.m_singleMsaaImage) { - texture.setImageMemoryBarrier(m_commandBuffer, texture.m_sampledLayout, true); + texture.setState(m_commandBuffer, texture.m_sampledLayout, true); } } @@ -3003,7 +3003,7 @@ VK_IMPORT_DEVICE if (!writeOnly) { - texture.setImageMemoryBarrier(m_commandBuffer, texture.m_sampledLayout); + texture.setState(m_commandBuffer, texture.m_sampledLayout); } } } @@ -3013,7 +3013,7 @@ VK_IMPORT_DEVICE for (uint8_t ii = 0, num = newFrameBuffer.m_num; ii < num; ++ii) { TextureVK& texture = m_textures[newFrameBuffer.m_texture[ii].idx]; - texture.setImageMemoryBarrier( + texture.setState( m_commandBuffer , VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ); @@ -3022,7 +3022,7 @@ VK_IMPORT_DEVICE if (isValid(newFrameBuffer.m_depth) ) { TextureVK& texture = m_textures[newFrameBuffer.m_depth.idx]; - texture.setImageMemoryBarrier( + texture.setState( m_commandBuffer , VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ); @@ -6323,13 +6323,13 @@ retry: ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ; - setImageMemoryBarrier(_commandBuffer, layout); + setState(_commandBuffer, layout); } return result; } - VkResult TextureVK::createImages(VkCommandBuffer _commandBuffer) + VkResult TextureVK::createImages(VkCommandBuffer _commandBuffer, uint64_t _external) { BGFX_PROFILER_SCOPE("TextureVK::createImages", kColorResource); @@ -6388,28 +6388,40 @@ retry: ; ici.tiling = VK_IMAGE_TILING_OPTIMAL; - result = vkCreateImage(device, &ici, allocatorCb, &m_textureImage); - if (VK_SUCCESS != result) + if (0 != _external) { - BX_TRACE("Create texture image error: vkCreateImage failed %d: %s.", result, getName(result) ); - return result; + static_assert(sizeof(m_textureImage) == sizeof(_external), "Size must match!"); + bx::memCopy(&m_textureImage, &_external, sizeof(VkImage) ); + m_textureDeviceMem = {}; + m_flags |= BGFX_SAMPLER_INTERNAL_SHARED; + + s_renderVK->m_cmd.addExternal({ uint16_t(this - s_renderVK->m_textures) }); } - - VkMemoryRequirements imageMemReq; - vkGetImageMemoryRequirements(device, m_textureImage, &imageMemReq); - - result = s_renderVK->allocateMemory(&imageMemReq, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &m_textureDeviceMem, false); - if (VK_SUCCESS != result) + else { - BX_TRACE("Create texture image error: allocateMemory failed %d: %s.", result, getName(result) ); - return result; - } + result = vkCreateImage(device, &ici, allocatorCb, &m_textureImage); + if (VK_SUCCESS != result) + { + BX_TRACE("Create texture image error: vkCreateImage failed %d: %s.", result, getName(result) ); + return result; + } - result = vkBindImageMemory(device, m_textureImage, m_textureDeviceMem.mem, m_textureDeviceMem.offset); - if (VK_SUCCESS != result) - { - BX_TRACE("Create texture image error: vkBindImageMemory failed %d: %s.", result, getName(result) ); - return result; + VkMemoryRequirements imageMemReq; + vkGetImageMemoryRequirements(device, m_textureImage, &imageMemReq); + + result = s_renderVK->allocateMemory(&imageMemReq, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &m_textureDeviceMem, false); + if (VK_SUCCESS != result) + { + BX_TRACE("Create texture image error: allocateMemory failed %d: %s.", result, getName(result) ); + return result; + } + + result = vkBindImageMemory(device, m_textureImage, m_textureDeviceMem.mem, m_textureDeviceMem.offset); + if (VK_SUCCESS != result) + { + BX_TRACE("Create texture image error: vkBindImageMemory failed %d: %s.", result, getName(result) ); + return result; + } } m_sampledLayout = m_flags & BGFX_TEXTURE_COMPUTE_WRITE @@ -6455,13 +6467,13 @@ retry: return result; } - setImageMemoryBarrier(_commandBuffer, m_sampledLayout, true); + setState(_commandBuffer, m_sampledLayout, true); } return result; } - void* TextureVK::create(VkCommandBuffer _commandBuffer, const Memory* _mem, uint64_t _flags, uint8_t _skip) + void* TextureVK::create(VkCommandBuffer _commandBuffer, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) { BGFX_PROFILER_SCOPE("TextureVK::create", kColorResource); @@ -6535,12 +6547,13 @@ retry: const bool compressed = bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat) ); const bool swizzle = TextureFormat::BGRA8 == m_textureFormat && 0 != (m_flags & BGFX_TEXTURE_COMPUTE_WRITE); - const bool writeOnly = 0 != (m_flags & BGFX_TEXTURE_RT_WRITE_ONLY); - const bool computeWrite = 0 != (m_flags & BGFX_TEXTURE_COMPUTE_WRITE); - const bool renderTarget = 0 != (m_flags & BGFX_TEXTURE_RT_MASK); - const bool blit = 0 != (m_flags & BGFX_TEXTURE_BLIT_DST); + const bool writeOnly = 0 != (m_flags & BGFX_TEXTURE_RT_WRITE_ONLY); + const bool computeWrite = 0 != (m_flags & BGFX_TEXTURE_COMPUTE_WRITE); + const bool renderTarget = 0 != (m_flags & BGFX_TEXTURE_RT_MASK); + const bool blit = 0 != (m_flags & BGFX_TEXTURE_BLIT_DST); + const bool externalShared = 0 != (m_flags & BGFX_TEXTURE_EXTERNAL_SHARED); - BX_UNUSED(swizzle, writeOnly, computeWrite, renderTarget, blit); + BX_UNUSED(swizzle, writeOnly, computeWrite, renderTarget, blit, externalShared); BX_TRACE( "Texture %3d: %s (requested: %s), %dx%dx%d%s RT[%c], BO[%c], CW[%c]%s." @@ -6557,7 +6570,7 @@ retry: , swizzle ? " (swizzle BGRA8 -> RGBA8)" : "" ); - VK_CHECK(createImages(_commandBuffer) ); + VK_CHECK(createImages(_commandBuffer, _external) ); // decode images struct ImageInfo @@ -6741,7 +6754,7 @@ retry: } else { - setImageMemoryBarrier(_commandBuffer, m_sampledLayout); + setState(_commandBuffer, m_sampledLayout); } bx::free(g_allocator, bufferCopyInfo); @@ -6765,10 +6778,20 @@ retry: m_readback.destroy(); - if (VK_NULL_HANDLE != m_textureImage) + const bool external = 0 != (m_flags & BGFX_SAMPLER_INTERNAL_SHARED); +// const bool externalShared = 0 != (m_flags & BGFX_TEXTURE_EXTERNAL_SHARED); + + if (external) { - s_renderVK->release(m_textureImage); - s_renderVK->recycleMemory(m_textureDeviceMem); + s_renderVK->m_cmd.removeExternal({ uint16_t(this - s_renderVK->m_textures) }); + } + else + { + if (VK_NULL_HANDLE != m_textureImage) + { + s_renderVK->release(m_textureImage); + s_renderVK->recycleMemory(m_textureDeviceMem); + } } if (VK_NULL_HANDLE != m_singleMsaaImage) @@ -6888,8 +6911,8 @@ retry: if (needResolve) { - setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true); + setState(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + setState(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true); VkImageResolve resolve; resolve.srcOffset.x = 0; @@ -6925,7 +6948,7 @@ retry: { BGFX_PROFILER_SCOPE("Resolve - Generate Mipmaps", kColorResource); - setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + setState(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); int32_t mipWidth = bx::max(int32_t(m_width) >> _mip, 1); int32_t mipHeight = bx::max(int32_t(m_height) >> _mip, 1); @@ -6962,7 +6985,7 @@ retry: blit.dstOffsets[1] = { mipWidth, mipHeight, 1 }; blit.dstSubresource.mipLevel = i; - vk::setImageMemoryBarrier( + setImageMemoryBarrier( _commandBuffer , m_textureImage , m_aspectFlags @@ -6986,7 +7009,7 @@ retry: ); } - vk::setImageMemoryBarrier( + setImageMemoryBarrier( _commandBuffer , m_textureImage , m_aspectFlags @@ -6999,8 +7022,8 @@ retry: ); } - setImageMemoryBarrier(_commandBuffer, oldLayout); - setImageMemoryBarrier(_commandBuffer, oldSingleMsaaLayout, true); + setState(_commandBuffer, oldLayout); + setState(_commandBuffer, oldSingleMsaaLayout, true); } void TextureVK::copyBufferToTexture(VkCommandBuffer _commandBuffer, VkBuffer _stagingBuffer, uint32_t _bufferImageCopyCount, VkBufferImageCopy* _bufferImageCopy) @@ -7012,7 +7035,7 @@ retry: : m_currentImageLayout ; - setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + setState(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); bimg::TextureFormat::Enum format = bimg::TextureFormat::Enum(m_textureFormat); const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(format); @@ -7035,14 +7058,15 @@ retry: , _bufferImageCopy ); - setImageMemoryBarrier(_commandBuffer, oldLayout); + setState(_commandBuffer, oldLayout); } - VkImageLayout TextureVK::setImageMemoryBarrier(VkCommandBuffer _commandBuffer, VkImageLayout _newImageLayout, bool _singleMsaaImage) + void TextureVK::setState(VkCommandBuffer _commandBuffer, VkImageLayout _newImageLayout, bool _singleMsaaImage) { - if (_singleMsaaImage && VK_NULL_HANDLE == m_singleMsaaImage) + if (_singleMsaaImage + && VK_NULL_HANDLE == m_singleMsaaImage) { - return VK_IMAGE_LAYOUT_UNDEFINED; + return; } VkImageLayout& currentLayout = _singleMsaaImage @@ -7050,28 +7074,23 @@ retry: : m_currentImageLayout ; - const VkImageLayout oldLayout = currentLayout; - - if (currentLayout == _newImageLayout) + if (currentLayout != _newImageLayout) { - return oldLayout; + const VkImage image = _singleMsaaImage + ? m_singleMsaaImage + : m_textureImage + ; + + setImageMemoryBarrier( + _commandBuffer + , image + , m_aspectFlags + , currentLayout + , _newImageLayout + ); + + currentLayout = _newImageLayout; } - - const VkImage image = _singleMsaaImage - ? m_singleMsaaImage - : m_textureImage - ; - - vk::setImageMemoryBarrier( - _commandBuffer - , image - , m_aspectFlags - , currentLayout - , _newImageLayout - ); - - currentLayout = _newImageLayout; - return oldLayout; } VkResult TextureVK::createView(uint32_t _layer, uint32_t _numLayers, uint32_t _mip, uint32_t _numMips, VkImageViewType _type, VkImageAspectFlags _aspectMask, bool _renderTarget, ::VkImageView* _view) const @@ -7081,18 +7100,18 @@ retry: if (VK_IMAGE_VIEW_TYPE_3D == m_type) { BX_ASSERT(false - || !_renderTarget - || !(m_aspectFlags & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) ) + || !_renderTarget + || !(m_aspectFlags & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) ) , "3D image can't be a depth attachment" - ); + ); } if (VK_IMAGE_VIEW_TYPE_CUBE == _type || VK_IMAGE_VIEW_TYPE_CUBE_ARRAY == _type) { BX_ASSERT(_numLayers % 6 == 0, ""); - BX_ASSERT( - VK_IMAGE_VIEW_TYPE_3D != m_type + BX_ASSERT(false + || VK_IMAGE_VIEW_TYPE_3D != m_type , "3D image can't be aliased as a cube texture" ); } @@ -8746,6 +8765,11 @@ retry: { const VkDevice device = s_renderVK->m_device; + for (TextureHandle th : m_external) + { + s_renderVK->m_textures[th.idx].setState(m_activeCommandBuffer, VK_IMAGE_LAYOUT_UNDEFINED); + } + setMemoryBarrier( m_activeCommandBuffer , VK_PIPELINE_STAGE_ALL_COMMANDS_BIT @@ -8865,6 +8889,25 @@ retry: m_release[m_consumeIndex].clear(); } + void CommandQueueVK::addExternal(TextureHandle _handle) + { + m_external.push_back(_handle); + } + + void CommandQueueVK::removeExternal(TextureHandle _handle) + { + for (ExternalTextureArray::iterator it = m_external.begin(), itEnd = m_external.end(); it != itEnd; ++it) + { + if (it->idx == _handle.idx) + { + m_external.erase(it); + return; + } + } + + BX_ASSERT(false, "Removing external texture failed!"); + } + void RendererContextVK::submitBlit(BlitState& _bs, uint16_t _view) { BGFX_PROFILER_SCOPE("RendererContextVK::submitBlit", kColorFrame); @@ -8896,15 +8939,17 @@ retry: TextureVK& src = m_textures[blit.m_src.idx]; TextureVK& dst = m_textures[blit.m_dst.idx]; - src.setImageMemoryBarrier( + src.setState( m_commandBuffer - , blit.m_src.idx == blit.m_dst.idx ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL + , blit.m_src.idx == blit.m_dst.idx + ? VK_IMAGE_LAYOUT_GENERAL + : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL , VK_NULL_HANDLE != src.m_singleMsaaImage ); if (blit.m_src.idx != blit.m_dst.idx) { - dst.setImageMemoryBarrier(m_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + dst.setState(m_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); } const uint16_t srcSamples = VK_NULL_HANDLE != src.m_singleMsaaImage ? 1 : src.m_sampler.Count; @@ -8981,8 +9026,8 @@ retry: TextureVK& src = m_textures[blit.m_src.idx]; TextureVK& dst = m_textures[blit.m_dst.idx]; - src.setImageMemoryBarrier(m_commandBuffer, srcLayouts[item], VK_NULL_HANDLE != src.m_singleMsaaImage); - dst.setImageMemoryBarrier(m_commandBuffer, dstLayouts[item]); + src.setState(m_commandBuffer, srcLayouts[item], VK_NULL_HANDLE != src.m_singleMsaaImage); + dst.setState(m_commandBuffer, dstLayouts[item]); } } diff --git a/src/renderer_vk.h b/src/renderer_vk.h index 051dee119..8d15f353f 100644 --- a/src/renderer_vk.h +++ b/src/renderer_vk.h @@ -746,7 +746,7 @@ VK_DESTROY_FUNC(DescriptorSet); { } - void* create(VkCommandBuffer _commandBuffer, const Memory* _mem, uint64_t _flags, uint8_t _skip); + void* create(VkCommandBuffer _commandBuffer, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external); // internal render target VkResult create(VkCommandBuffer _commandBuffer, uint32_t _width, uint32_t _height, uint64_t _flags, VkFormat _format); @@ -756,7 +756,7 @@ VK_DESTROY_FUNC(DescriptorSet); void resolve(VkCommandBuffer _commandBuffer, uint8_t _resolve, uint32_t _layer, uint32_t _numLayers, uint32_t _mip); void copyBufferToTexture(VkCommandBuffer _commandBuffer, VkBuffer _stagingBuffer, uint32_t _bufferImageCopyCount, VkBufferImageCopy* _bufferImageCopy); - VkImageLayout setImageMemoryBarrier(VkCommandBuffer _commandBuffer, VkImageLayout _newImageLayout, bool _singleMsaaImage = false); + void setState(VkCommandBuffer _commandBuffer, VkImageLayout _newImageLayout, bool _singleMsaaImage = false); VkResult createView(uint32_t _layer, uint32_t _numLayers, uint32_t _mip, uint32_t _numMips, VkImageViewType _type, VkImageAspectFlags _aspectMask, bool _renderTarget, ::VkImageView* _view) const; @@ -778,20 +778,20 @@ VK_DESTROY_FUNC(DescriptorSet); VkComponentMapping m_components; VkImageAspectFlags m_aspectFlags; - VkImage m_textureImage; + VkImage m_textureImage; DeviceMemoryAllocationVK m_textureDeviceMem; - VkImageLayout m_currentImageLayout; + VkImageLayout m_currentImageLayout; - VkImage m_singleMsaaImage; + VkImage m_singleMsaaImage; DeviceMemoryAllocationVK m_singleMsaaDeviceMem; - VkImageLayout m_currentSingleMsaaImageLayout; + VkImageLayout m_currentSingleMsaaImageLayout; VkImageLayout m_sampledLayout; ReadbackVK m_readback; private: - VkResult createImages(VkCommandBuffer _commandBuffer); + VkResult createImages(VkCommandBuffer _commandBuffer, uint64_t _external = 0); static VkImageAspectFlags getAspectMask(VkFormat _format); }; @@ -947,6 +947,9 @@ VK_DESTROY_FUNC(DescriptorSet); void recycleMemory(DeviceMemoryAllocationVK _mem); void consume(); + void addExternal(TextureHandle _handle); + void removeExternal(TextureHandle _handle); + uint32_t m_queueFamily; VkQueue m_queue; @@ -984,6 +987,8 @@ VK_DESTROY_FUNC(DescriptorSet); typedef stl::vector ResourceArray; ResourceArray m_release[BGFX_CONFIG_MAX_FRAME_LATENCY]; stl::vector m_recycleAllocs[BGFX_CONFIG_MAX_FRAME_LATENCY]; + typedef stl::vector ExternalTextureArray; + ExternalTextureArray m_external; private: template diff --git a/src/renderer_webgpu.cpp b/src/renderer_webgpu.cpp index e82bd16d7..98fc281e7 100644 --- a/src/renderer_webgpu.cpp +++ b/src/renderer_webgpu.cpp @@ -1493,8 +1493,9 @@ WGPU_IMPORT m_program[_handle.idx].destroy(); } - void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip) override + void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) override { + BX_UNUSED(_external); m_textures[_handle.idx].create(_mem, _flags, _skip); return NULL; } diff --git a/src/version.h b/src/version.h index 7c0c17e5e..6dba71b0d 100644 --- a/src/version.h +++ b/src/version.h @@ -9,5 +9,5 @@ * */ -#define BGFX_REV_NUMBER 9143 -#define BGFX_REV_SHA1 "90d61887acd560b9c1eca2a0d76b7f0fe1ad8866" +#define BGFX_REV_NUMBER 9149 +#define BGFX_REV_SHA1 "f446c319d65b5e9a4d4070100e3fc571f5b35ea5"