diff --git a/bindings/bf/bgfx.bf b/bindings/bf/bgfx.bf index 4d4e8edd9..9e98e9092 100644 --- a/bindings/bf/bgfx.bf +++ b/bindings/bf/bgfx.bf @@ -687,6 +687,16 @@ public static class bgfx /// Texture is shared with other device or other process. /// ExternalShared = 0x0001000000000000, + + /// + /// Texture may be sampled and rendered with either sRGB-ness, + /// not just the one implied by its format. Every bind and + /// attachment must then state the encoding it wants (see + /// `BGFX_SAMPLER_SRGB`, `BGFX_ATTACHMENT_SRGB`). Costs nothing + /// until used, but may disable texture compression on some + /// hardware. + /// + SrgbMutable = 0x0040000000000000, ReservedShift = 60, ReservedMask = 0xf000000000000000, @@ -856,6 +866,14 @@ public static class bgfx /// Sample stencil instead of depth. /// SampleStencil = 0x00100000, + + /// + /// Sample with sRGB conversion; absence of this flag samples + /// without it. Only affects textures created + /// `BGFX_TEXTURE_SRGB_MUTABLE`, which must state the encoding + /// explicitly on every bind; ignored for any other texture. + /// + Srgb = 0x00200000, Point = 0x00000540, UvwMirror = 0x00000015, UvwClamp = 0x0000002a, @@ -1341,6 +1359,14 @@ public static class bgfx /// Bind the stencil aspect read-only. /// ReadOnlyStencil = 0x00000004, + + /// + /// Render with sRGB conversion; absence of this flag renders without + /// it. Only affects textures created `BGFX_TEXTURE_SRGB_MUTABLE`, + /// which must state the encoding explicitly on every attachment; + /// ignored for any other texture. + /// + Srgb = 0x00000008, } [AllowDuplicates] @@ -4702,6 +4728,20 @@ public static class bgfx [LinkName("bgfx_encoder_set_uniform")] public static extern void encoder_set_uniform(Encoder* _this, UniformHandle _handle, void* _value, uint16 _num); + /// + /// Set shader uniform parameter by reference. Unlike `Encoder::setUniform`, the data + /// is not copied immediately; the renderer reads it from `_value` at frame render + /// time. The pointer must remain valid and unchanged until the frame is rendered + /// (up to two `bgfx::frame` calls with multithreaded submission). + /// + /// + /// Uniform. + /// Pointer to uniform data. Must stay valid until the frame is rendered. + /// Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation. + /// + [LinkName("bgfx_encoder_set_uniform_ref")] + public static extern void encoder_set_uniform_ref(Encoder* _this, UniformHandle _handle, void* _value, uint16 _num); + /// /// Set shader uniform parameter for view. /// @@ -5013,9 +5053,11 @@ public static class bgfx /// Compute stage. /// Index buffer handle. /// Buffer access. See `Access::Enum`. + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// [LinkName("bgfx_encoder_set_compute_index_buffer")] - public static extern void encoder_set_compute_index_buffer(Encoder* _this, uint8 _stage, IndexBufferHandle _handle, Access _access); + public static extern void encoder_set_compute_index_buffer(Encoder* _this, uint8 _stage, IndexBufferHandle _handle, Access _access, uint32 _offset, uint32 _size); /// /// Set compute vertex buffer. @@ -5024,9 +5066,11 @@ public static class bgfx /// Compute stage. /// Vertex buffer handle. /// Buffer access. See `Access::Enum`. + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// [LinkName("bgfx_encoder_set_compute_vertex_buffer")] - public static extern void encoder_set_compute_vertex_buffer(Encoder* _this, uint8 _stage, VertexBufferHandle _handle, Access _access); + public static extern void encoder_set_compute_vertex_buffer(Encoder* _this, uint8 _stage, VertexBufferHandle _handle, Access _access, uint32 _offset, uint32 _size); /// /// Set compute dynamic index buffer. @@ -5035,9 +5079,11 @@ public static class bgfx /// Compute stage. /// Dynamic index buffer handle. /// Buffer access. See `Access::Enum`. + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// [LinkName("bgfx_encoder_set_compute_dynamic_index_buffer")] - public static extern void encoder_set_compute_dynamic_index_buffer(Encoder* _this, uint8 _stage, DynamicIndexBufferHandle _handle, Access _access); + public static extern void encoder_set_compute_dynamic_index_buffer(Encoder* _this, uint8 _stage, DynamicIndexBufferHandle _handle, Access _access, uint32 _offset, uint32 _size); /// /// Set compute dynamic vertex buffer. @@ -5046,9 +5092,11 @@ public static class bgfx /// Compute stage. /// Dynamic vertex buffer handle. /// Buffer access. See `Access::Enum`. + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// [LinkName("bgfx_encoder_set_compute_dynamic_vertex_buffer")] - public static extern void encoder_set_compute_dynamic_vertex_buffer(Encoder* _this, uint8 _stage, DynamicVertexBufferHandle _handle, Access _access); + public static extern void encoder_set_compute_dynamic_vertex_buffer(Encoder* _this, uint8 _stage, DynamicVertexBufferHandle _handle, Access _access, uint32 _offset, uint32 _size); /// /// Set compute indirect buffer. @@ -5459,6 +5507,20 @@ public static class bgfx [LinkName("bgfx_set_uniform")] public static extern void set_uniform(UniformHandle _handle, void* _value, uint16 _num); + /// + /// Set shader uniform parameter by reference. Unlike `bgfx::setUniform`, the data + /// is not copied immediately; the renderer reads it from `_value` at frame render + /// time. The pointer must remain valid and unchanged until the frame is rendered + /// (up to two `bgfx::frame` calls with multithreaded submission). + /// + /// + /// Uniform. + /// Pointer to uniform data. Must stay valid until the frame is rendered. + /// Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation. + /// + [LinkName("bgfx_set_uniform_ref")] + public static extern void set_uniform_ref(UniformHandle _handle, void* _value, uint16 _num); + /// /// Set index buffer for draw primitive. /// @@ -5739,9 +5801,11 @@ public static class bgfx /// Compute stage. /// Index buffer handle. /// Buffer access. See `Access::Enum`. + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// [LinkName("bgfx_set_compute_index_buffer")] - public static extern void set_compute_index_buffer(uint8 _stage, IndexBufferHandle _handle, Access _access); + public static extern void set_compute_index_buffer(uint8 _stage, IndexBufferHandle _handle, Access _access, uint32 _offset, uint32 _size); /// /// Set compute vertex buffer. @@ -5750,9 +5814,11 @@ public static class bgfx /// Compute stage. /// Vertex buffer handle. /// Buffer access. See `Access::Enum`. + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// [LinkName("bgfx_set_compute_vertex_buffer")] - public static extern void set_compute_vertex_buffer(uint8 _stage, VertexBufferHandle _handle, Access _access); + public static extern void set_compute_vertex_buffer(uint8 _stage, VertexBufferHandle _handle, Access _access, uint32 _offset, uint32 _size); /// /// Set compute dynamic index buffer. @@ -5761,9 +5827,11 @@ public static class bgfx /// Compute stage. /// Dynamic index buffer handle. /// Buffer access. See `Access::Enum`. + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// [LinkName("bgfx_set_compute_dynamic_index_buffer")] - public static extern void set_compute_dynamic_index_buffer(uint8 _stage, DynamicIndexBufferHandle _handle, Access _access); + public static extern void set_compute_dynamic_index_buffer(uint8 _stage, DynamicIndexBufferHandle _handle, Access _access, uint32 _offset, uint32 _size); /// /// Set compute dynamic vertex buffer. @@ -5772,9 +5840,11 @@ public static class bgfx /// Compute stage. /// Dynamic vertex buffer handle. /// Buffer access. See `Access::Enum`. + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// [LinkName("bgfx_set_compute_dynamic_vertex_buffer")] - public static extern void set_compute_dynamic_vertex_buffer(uint8 _stage, DynamicVertexBufferHandle _handle, Access _access); + public static extern void set_compute_dynamic_vertex_buffer(uint8 _stage, DynamicVertexBufferHandle _handle, Access _access, uint32 _offset, uint32 _size); /// /// Set compute indirect buffer. diff --git a/bindings/c3/bgfx.c3 b/bindings/c3/bgfx.c3 index 002561d1f..dc0fe7dc8 100644 --- a/bindings/c3/bgfx.c3 +++ b/bindings/c3/bgfx.c3 @@ -431,6 +431,14 @@ constdef TextureFlags : inline ulong // Texture is shared with other device or other process. EXTERNALSHARED = 0x0001000000000000, + + // Texture may be sampled and rendered with either sRGB-ness, + // not just the one implied by its format. Every bind and + // attachment must then state the encoding it wants (see + // `BGFX_SAMPLER_SRGB`, `BGFX_ATTACHMENT_SRGB`). Costs nothing + // until used, but may disable texture compression on some + // hardware. + SRGBMUTABLE = 0x0040000000000000, RESERVEDSHIFT = 60, RESERVEDMASK = 0xf000000000000000, @@ -543,6 +551,12 @@ constdef SamplerFlags : inline uint // Sample stencil instead of depth. SAMPLESTENCIL = 0x00100000, + + // Sample with sRGB conversion; absence of this flag samples + // without it. Only affects textures created + // `BGFX_TEXTURE_SRGB_MUTABLE`, which must state the encoding + // explicitly on every bind; ignored for any other texture. + SRGB = 0x00200000, POINT = 0x00000540, UVWMIRROR = 0x00000015, UVWCLAMP = 0x0000002a, @@ -850,6 +864,12 @@ constdef AttachmentFlags : inline uint // Bind the stencil aspect read-only. READONLYSTENCIL = 0x00000004, + + // Render with sRGB conversion; absence of this flag renders without + // it. Only affects textures created `BGFX_TEXTURE_SRGB_MUTABLE`, + // which must state the encoding explicitly on every attachment; + // ignored for any other texture. + SRGB = 0x00000008, } constdef PciIdFlags : inline ushort @@ -3406,6 +3426,15 @@ extern fn uint encoder_alloc_transform(Encoder* _this, Transform* _transform, us // _num : `Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.` extern fn void encoder_set_uniform(Encoder* _this, UniformHandle _handle, void* _value, ushort _num) @cname("bgfx_encoder_set_uniform"); +// Set shader uniform parameter by reference. Unlike `Encoder::setUniform`, the data +// is not copied immediately; the renderer reads it from `_value` at frame render +// time. The pointer must remain valid and unchanged until the frame is rendered +// (up to two `bgfx::frame` calls with multithreaded submission). +// _handle : `Uniform.` +// _value : `Pointer to uniform data. Must stay valid until the frame is rendered.` +// _num : `Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.` +extern fn void encoder_set_uniform_ref(Encoder* _this, UniformHandle _handle, void* _value, ushort _num) @cname("bgfx_encoder_set_uniform_ref"); + // Set shader uniform parameter for view. // // @attention Uniform must be created with `bgfx::UniformFreq::View` argument. @@ -3599,25 +3628,33 @@ extern fn void encoder_submit_indirect_count(Encoder* _this, ushort _id, Program // _stage : `Compute stage.` // _handle : `Index buffer handle.` // _access : `Buffer access. See `Access::Enum`.` -extern fn void encoder_set_compute_index_buffer(Encoder* _this, char _stage, IndexBufferHandle _handle, Access _access) @cname("bgfx_encoder_set_compute_index_buffer"); +// _offset : `Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes.` +// _size : `Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer.` +extern fn void encoder_set_compute_index_buffer(Encoder* _this, char _stage, IndexBufferHandle _handle, Access _access, uint _offset, uint _size) @cname("bgfx_encoder_set_compute_index_buffer"); // Set compute vertex buffer. // _stage : `Compute stage.` // _handle : `Vertex buffer handle.` // _access : `Buffer access. See `Access::Enum`.` -extern fn void encoder_set_compute_vertex_buffer(Encoder* _this, char _stage, VertexBufferHandle _handle, Access _access) @cname("bgfx_encoder_set_compute_vertex_buffer"); +// _offset : `Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes.` +// _size : `Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer.` +extern fn void encoder_set_compute_vertex_buffer(Encoder* _this, char _stage, VertexBufferHandle _handle, Access _access, uint _offset, uint _size) @cname("bgfx_encoder_set_compute_vertex_buffer"); // Set compute dynamic index buffer. // _stage : `Compute stage.` // _handle : `Dynamic index buffer handle.` // _access : `Buffer access. See `Access::Enum`.` -extern fn void encoder_set_compute_dynamic_index_buffer(Encoder* _this, char _stage, DynamicIndexBufferHandle _handle, Access _access) @cname("bgfx_encoder_set_compute_dynamic_index_buffer"); +// _offset : `Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes.` +// _size : `Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer.` +extern fn void encoder_set_compute_dynamic_index_buffer(Encoder* _this, char _stage, DynamicIndexBufferHandle _handle, Access _access, uint _offset, uint _size) @cname("bgfx_encoder_set_compute_dynamic_index_buffer"); // Set compute dynamic vertex buffer. // _stage : `Compute stage.` // _handle : `Dynamic vertex buffer handle.` // _access : `Buffer access. See `Access::Enum`.` -extern fn void encoder_set_compute_dynamic_vertex_buffer(Encoder* _this, char _stage, DynamicVertexBufferHandle _handle, Access _access) @cname("bgfx_encoder_set_compute_dynamic_vertex_buffer"); +// _offset : `Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes.` +// _size : `Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer.` +extern fn void encoder_set_compute_dynamic_vertex_buffer(Encoder* _this, char _stage, DynamicVertexBufferHandle _handle, Access _access, uint _offset, uint _size) @cname("bgfx_encoder_set_compute_dynamic_vertex_buffer"); // Set compute indirect buffer. // _stage : `Compute stage.` @@ -3899,6 +3936,15 @@ extern fn uint alloc_transform(Transform* _transform, ushort _num) @cname("bgfx_ // _num : `Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.` extern fn void set_uniform(UniformHandle _handle, void* _value, ushort _num) @cname("bgfx_set_uniform"); +// Set shader uniform parameter by reference. Unlike `bgfx::setUniform`, the data +// is not copied immediately; the renderer reads it from `_value` at frame render +// time. The pointer must remain valid and unchanged until the frame is rendered +// (up to two `bgfx::frame` calls with multithreaded submission). +// _handle : `Uniform.` +// _value : `Pointer to uniform data. Must stay valid until the frame is rendered.` +// _num : `Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.` +extern fn void set_uniform_ref(UniformHandle _handle, void* _value, ushort _num) @cname("bgfx_set_uniform_ref"); + // Set index buffer for draw primitive. // _handle : `Index buffer.` // _firstIndex : `First index to render.` @@ -4071,25 +4117,33 @@ extern fn void submit_indirect_count(ushort _id, ProgramHandle _program, Indirec // _stage : `Compute stage.` // _handle : `Index buffer handle.` // _access : `Buffer access. See `Access::Enum`.` -extern fn void set_compute_index_buffer(char _stage, IndexBufferHandle _handle, Access _access) @cname("bgfx_set_compute_index_buffer"); +// _offset : `Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes.` +// _size : `Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer.` +extern fn void set_compute_index_buffer(char _stage, IndexBufferHandle _handle, Access _access, uint _offset, uint _size) @cname("bgfx_set_compute_index_buffer"); // Set compute vertex buffer. // _stage : `Compute stage.` // _handle : `Vertex buffer handle.` // _access : `Buffer access. See `Access::Enum`.` -extern fn void set_compute_vertex_buffer(char _stage, VertexBufferHandle _handle, Access _access) @cname("bgfx_set_compute_vertex_buffer"); +// _offset : `Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes.` +// _size : `Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer.` +extern fn void set_compute_vertex_buffer(char _stage, VertexBufferHandle _handle, Access _access, uint _offset, uint _size) @cname("bgfx_set_compute_vertex_buffer"); // Set compute dynamic index buffer. // _stage : `Compute stage.` // _handle : `Dynamic index buffer handle.` // _access : `Buffer access. See `Access::Enum`.` -extern fn void set_compute_dynamic_index_buffer(char _stage, DynamicIndexBufferHandle _handle, Access _access) @cname("bgfx_set_compute_dynamic_index_buffer"); +// _offset : `Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes.` +// _size : `Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer.` +extern fn void set_compute_dynamic_index_buffer(char _stage, DynamicIndexBufferHandle _handle, Access _access, uint _offset, uint _size) @cname("bgfx_set_compute_dynamic_index_buffer"); // Set compute dynamic vertex buffer. // _stage : `Compute stage.` // _handle : `Dynamic vertex buffer handle.` // _access : `Buffer access. See `Access::Enum`.` -extern fn void set_compute_dynamic_vertex_buffer(char _stage, DynamicVertexBufferHandle _handle, Access _access) @cname("bgfx_set_compute_dynamic_vertex_buffer"); +// _offset : `Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes.` +// _size : `Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer.` +extern fn void set_compute_dynamic_vertex_buffer(char _stage, DynamicVertexBufferHandle _handle, Access _access, uint _offset, uint _size) @cname("bgfx_set_compute_dynamic_vertex_buffer"); // Set compute indirect buffer. // _stage : `Compute stage.` diff --git a/bindings/cs/bgfx.cs b/bindings/cs/bgfx.cs index 7f344cec4..3b20bc4f5 100644 --- a/bindings/cs/bgfx.cs +++ b/bindings/cs/bgfx.cs @@ -686,6 +686,16 @@ public static partial class bgfx /// Texture is shared with other device or other process. /// ExternalShared = 0x0001000000000000, + + /// + /// Texture may be sampled and rendered with either sRGB-ness, + /// not just the one implied by its format. Every bind and + /// attachment must then state the encoding it wants (see + /// `BGFX_SAMPLER_SRGB`, `BGFX_ATTACHMENT_SRGB`). Costs nothing + /// until used, but may disable texture compression on some + /// hardware. + /// + SrgbMutable = 0x0040000000000000, ReservedShift = 60, ReservedMask = 0xf000000000000000, @@ -855,6 +865,14 @@ public static partial class bgfx /// Sample stencil instead of depth. /// SampleStencil = 0x00100000, + + /// + /// Sample with sRGB conversion; absence of this flag samples + /// without it. Only affects textures created + /// `BGFX_TEXTURE_SRGB_MUTABLE`, which must state the encoding + /// explicitly on every bind; ignored for any other texture. + /// + Srgb = 0x00200000, Point = 0x00000540, UvwMirror = 0x00000015, UvwClamp = 0x0000002a, @@ -1340,6 +1358,14 @@ public static partial class bgfx /// Bind the stencil aspect read-only. /// ReadOnlyStencil = 0x00000004, + + /// + /// Render with sRGB conversion; absence of this flag renders without + /// it. Only affects textures created `BGFX_TEXTURE_SRGB_MUTABLE`, + /// which must state the encoding explicitly on every attachment; + /// ignored for any other texture. + /// + Srgb = 0x00000008, } [Flags] @@ -4649,6 +4675,20 @@ public static partial class bgfx [DllImport(DllName, EntryPoint="bgfx_encoder_set_uniform", CallingConvention = CallingConvention.Cdecl)] public static extern unsafe void encoder_set_uniform(Encoder* _this, UniformHandle _handle, void* _value, ushort _num); + /// + /// Set shader uniform parameter by reference. Unlike `Encoder::setUniform`, the data + /// is not copied immediately; the renderer reads it from `_value` at frame render + /// time. The pointer must remain valid and unchanged until the frame is rendered + /// (up to two `bgfx::frame` calls with multithreaded submission). + /// + /// + /// Uniform. + /// Pointer to uniform data. Must stay valid until the frame is rendered. + /// Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation. + /// + [DllImport(DllName, EntryPoint="bgfx_encoder_set_uniform_ref", CallingConvention = CallingConvention.Cdecl)] + public static extern unsafe void encoder_set_uniform_ref(Encoder* _this, UniformHandle _handle, void* _value, ushort _num); + /// /// Set shader uniform parameter for view. /// @@ -4960,9 +5000,11 @@ public static partial class bgfx /// Compute stage. /// Index buffer handle. /// Buffer access. See `Access::Enum`. + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// [DllImport(DllName, EntryPoint="bgfx_encoder_set_compute_index_buffer", CallingConvention = CallingConvention.Cdecl)] - public static extern unsafe void encoder_set_compute_index_buffer(Encoder* _this, byte _stage, IndexBufferHandle _handle, Access _access); + public static extern unsafe void encoder_set_compute_index_buffer(Encoder* _this, byte _stage, IndexBufferHandle _handle, Access _access, uint _offset, uint _size); /// /// Set compute vertex buffer. @@ -4971,9 +5013,11 @@ public static partial class bgfx /// Compute stage. /// Vertex buffer handle. /// Buffer access. See `Access::Enum`. + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// [DllImport(DllName, EntryPoint="bgfx_encoder_set_compute_vertex_buffer", CallingConvention = CallingConvention.Cdecl)] - public static extern unsafe void encoder_set_compute_vertex_buffer(Encoder* _this, byte _stage, VertexBufferHandle _handle, Access _access); + public static extern unsafe void encoder_set_compute_vertex_buffer(Encoder* _this, byte _stage, VertexBufferHandle _handle, Access _access, uint _offset, uint _size); /// /// Set compute dynamic index buffer. @@ -4982,9 +5026,11 @@ public static partial class bgfx /// Compute stage. /// Dynamic index buffer handle. /// Buffer access. See `Access::Enum`. + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// [DllImport(DllName, EntryPoint="bgfx_encoder_set_compute_dynamic_index_buffer", CallingConvention = CallingConvention.Cdecl)] - public static extern unsafe void encoder_set_compute_dynamic_index_buffer(Encoder* _this, byte _stage, DynamicIndexBufferHandle _handle, Access _access); + public static extern unsafe void encoder_set_compute_dynamic_index_buffer(Encoder* _this, byte _stage, DynamicIndexBufferHandle _handle, Access _access, uint _offset, uint _size); /// /// Set compute dynamic vertex buffer. @@ -4993,9 +5039,11 @@ public static partial class bgfx /// Compute stage. /// Dynamic vertex buffer handle. /// Buffer access. See `Access::Enum`. + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// [DllImport(DllName, EntryPoint="bgfx_encoder_set_compute_dynamic_vertex_buffer", CallingConvention = CallingConvention.Cdecl)] - public static extern unsafe void encoder_set_compute_dynamic_vertex_buffer(Encoder* _this, byte _stage, DynamicVertexBufferHandle _handle, Access _access); + public static extern unsafe void encoder_set_compute_dynamic_vertex_buffer(Encoder* _this, byte _stage, DynamicVertexBufferHandle _handle, Access _access, uint _offset, uint _size); /// /// Set compute indirect buffer. @@ -5406,6 +5454,20 @@ public static partial class bgfx [DllImport(DllName, EntryPoint="bgfx_set_uniform", CallingConvention = CallingConvention.Cdecl)] public static extern unsafe void set_uniform(UniformHandle _handle, void* _value, ushort _num); + /// + /// Set shader uniform parameter by reference. Unlike `bgfx::setUniform`, the data + /// is not copied immediately; the renderer reads it from `_value` at frame render + /// time. The pointer must remain valid and unchanged until the frame is rendered + /// (up to two `bgfx::frame` calls with multithreaded submission). + /// + /// + /// Uniform. + /// Pointer to uniform data. Must stay valid until the frame is rendered. + /// Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation. + /// + [DllImport(DllName, EntryPoint="bgfx_set_uniform_ref", CallingConvention = CallingConvention.Cdecl)] + public static extern unsafe void set_uniform_ref(UniformHandle _handle, void* _value, ushort _num); + /// /// Set index buffer for draw primitive. /// @@ -5686,9 +5748,11 @@ public static partial class bgfx /// Compute stage. /// Index buffer handle. /// Buffer access. See `Access::Enum`. + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// [DllImport(DllName, EntryPoint="bgfx_set_compute_index_buffer", CallingConvention = CallingConvention.Cdecl)] - public static extern unsafe void set_compute_index_buffer(byte _stage, IndexBufferHandle _handle, Access _access); + public static extern unsafe void set_compute_index_buffer(byte _stage, IndexBufferHandle _handle, Access _access, uint _offset, uint _size); /// /// Set compute vertex buffer. @@ -5697,9 +5761,11 @@ public static partial class bgfx /// Compute stage. /// Vertex buffer handle. /// Buffer access. See `Access::Enum`. + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// [DllImport(DllName, EntryPoint="bgfx_set_compute_vertex_buffer", CallingConvention = CallingConvention.Cdecl)] - public static extern unsafe void set_compute_vertex_buffer(byte _stage, VertexBufferHandle _handle, Access _access); + public static extern unsafe void set_compute_vertex_buffer(byte _stage, VertexBufferHandle _handle, Access _access, uint _offset, uint _size); /// /// Set compute dynamic index buffer. @@ -5708,9 +5774,11 @@ public static partial class bgfx /// Compute stage. /// Dynamic index buffer handle. /// Buffer access. See `Access::Enum`. + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// [DllImport(DllName, EntryPoint="bgfx_set_compute_dynamic_index_buffer", CallingConvention = CallingConvention.Cdecl)] - public static extern unsafe void set_compute_dynamic_index_buffer(byte _stage, DynamicIndexBufferHandle _handle, Access _access); + public static extern unsafe void set_compute_dynamic_index_buffer(byte _stage, DynamicIndexBufferHandle _handle, Access _access, uint _offset, uint _size); /// /// Set compute dynamic vertex buffer. @@ -5719,9 +5787,11 @@ public static partial class bgfx /// Compute stage. /// Dynamic vertex buffer handle. /// Buffer access. See `Access::Enum`. + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// [DllImport(DllName, EntryPoint="bgfx_set_compute_dynamic_vertex_buffer", CallingConvention = CallingConvention.Cdecl)] - public static extern unsafe void set_compute_dynamic_vertex_buffer(byte _stage, DynamicVertexBufferHandle _handle, Access _access); + public static extern unsafe void set_compute_dynamic_vertex_buffer(byte _stage, DynamicVertexBufferHandle _handle, Access _access, uint _offset, uint _size); /// /// Set compute indirect buffer. diff --git a/bindings/d/package.d b/bindings/d/package.d index 1c538f182..b21159824 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 = 160; +enum uint apiVersion = 161; alias ViewID = ushort; @@ -312,6 +312,15 @@ enum Texture: Texture_{ 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. + /** + Texture may be sampled and rendered with either sRGB-ness, + not just the one implied by its format. Every bind and + attachment must then state the encoding it wants (see + `BGFX_SAMPLER_SRGB`, `BGFX_ATTACHMENT_SRGB`). Costs nothing + until used, but may disable texture compression on some + hardware. + */ + srgbMutable = 0x0040_0000_0000_0000, } ///Do not use! Top nibble is reserved for internal texture flags (see bgfx_p.h). @@ -422,6 +431,13 @@ alias Sampler_ = uint; enum Sampler: Sampler_{ none = 0x0000_0000, sampleStencil = 0x0010_0000, ///Sample stencil instead of depth. + /** + Sample with sRGB conversion; absence of this flag samples + without it. Only affects textures created + `BGFX_TEXTURE_SRGB_MUTABLE`, which must state the encoding + explicitly on every bind; ignored for any other texture. + */ + srgb = 0x0020_0000, point = SamplerMin.point | SamplerMag.point | SamplerMIP.point, uvwMirror = SamplerU.mirror | SamplerV.mirror | SamplerW.mirror, uvwClamp = SamplerU.clamp | SamplerV.clamp | SamplerW.clamp, @@ -610,6 +626,13 @@ enum Attachment: Attachment_{ */ readOnlyDepth = 0x02, readOnlyStencil = 0x04, ///Bind the stencil aspect read-only. + /** + Render with sRGB conversion; absence of this flag renders without + it. Only affects textures created `BGFX_TEXTURE_SRGB_MUTABLE`, + which must state the encoding explicitly on every attachment; + ignored for any other texture. + */ + srgb = 0x08, } alias PCIID_ = ushort; @@ -1970,6 +1993,19 @@ extern(C++, "bgfx") struct Encoder{ */ {q{void}, q{setUniform}, q{UniformHandle handle, const(void)* value, ushort num=1}, ext: `C++`}, + /** + Set shader uniform parameter by reference. Unlike `Encoder::setUniform`, the data + is not copied immediately; the renderer reads it from `_value` at frame render + time. The pointer must remain valid and unchanged until the frame is rendered + (up to two `bgfx::frame` calls with multithreaded submission). + Params: + handle = Uniform. + value = Pointer to uniform data. Must stay valid until the frame is rendered. + num = Number of elements. Passing `UINT16_MAX` will + use the _num passed on uniform creation. + */ + {q{void}, q{setUniformRef}, q{UniformHandle handle, const(void)* value, ushort num=ushort.max}, ext: `C++`}, + /** Set index buffer for draw primitive. Params: @@ -2248,8 +2284,11 @@ extern(C++, "bgfx") struct Encoder{ stage = Compute stage. handle = Index buffer handle. access = Buffer access. See `Access::Enum`. + offset = Byte offset the shader's view of the buffer starts at. + Must be a multiple of 256 bytes. + size = Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. */ - {q{void}, q{setBuffer}, q{ubyte stage, IndexBufferHandle handle, bgfx.impl.Access.Enum access}, ext: `C++`}, + {q{void}, q{setBuffer}, q{ubyte stage, IndexBufferHandle handle, bgfx.impl.Access.Enum access, uint offset=0, uint size=uint.max}, ext: `C++`}, /** Set compute vertex buffer. @@ -2257,8 +2296,11 @@ extern(C++, "bgfx") struct Encoder{ stage = Compute stage. handle = Vertex buffer handle. access = Buffer access. See `Access::Enum`. + offset = Byte offset the shader's view of the buffer starts at. + Must be a multiple of 256 bytes. + size = Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. */ - {q{void}, q{setBuffer}, q{ubyte stage, VertexBufferHandle handle, bgfx.impl.Access.Enum access}, ext: `C++`}, + {q{void}, q{setBuffer}, q{ubyte stage, VertexBufferHandle handle, bgfx.impl.Access.Enum access, uint offset=0, uint size=uint.max}, ext: `C++`}, /** Set compute dynamic index buffer. @@ -2266,8 +2308,11 @@ extern(C++, "bgfx") struct Encoder{ stage = Compute stage. handle = Dynamic index buffer handle. access = Buffer access. See `Access::Enum`. + offset = Byte offset the shader's view of the buffer starts at. + Must be a multiple of 256 bytes. + size = Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. */ - {q{void}, q{setBuffer}, q{ubyte stage, DynamicIndexBufferHandle handle, bgfx.impl.Access.Enum access}, ext: `C++`}, + {q{void}, q{setBuffer}, q{ubyte stage, DynamicIndexBufferHandle handle, bgfx.impl.Access.Enum access, uint offset=0, uint size=uint.max}, ext: `C++`}, /** Set compute dynamic vertex buffer. @@ -2275,8 +2320,11 @@ extern(C++, "bgfx") struct Encoder{ stage = Compute stage. handle = Dynamic vertex buffer handle. access = Buffer access. See `Access::Enum`. + offset = Byte offset the shader's view of the buffer starts at. + Must be a multiple of 256 bytes. + size = Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. */ - {q{void}, q{setBuffer}, q{ubyte stage, DynamicVertexBufferHandle handle, bgfx.impl.Access.Enum access}, ext: `C++`}, + {q{void}, q{setBuffer}, q{ubyte stage, DynamicVertexBufferHandle handle, bgfx.impl.Access.Enum access, uint offset=0, uint size=uint.max}, ext: `C++`}, /** Set compute indirect buffer. @@ -4069,6 +4117,19 @@ mixin(joinFnBinds((){ */ {q{void}, q{setUniform}, q{UniformHandle handle, const(void)* value, ushort num=1}, ext: `C++, "bgfx"`}, + /** + * Set shader uniform parameter by reference. Unlike `bgfx::setUniform`, the data + * is not copied immediately; the renderer reads it from `_value` at frame render + * time. The pointer must remain valid and unchanged until the frame is rendered + * (up to two `bgfx::frame` calls with multithreaded submission). + Params: + handle = Uniform. + value = Pointer to uniform data. Must stay valid until the frame is rendered. + num = Number of elements. Passing `UINT16_MAX` will + use the _num passed on uniform creation. + */ + {q{void}, q{setUniformRef}, q{UniformHandle handle, const(void)* value, ushort num=ushort.max}, ext: `C++, "bgfx"`}, + /** * Set index buffer for draw primitive. Params: @@ -4345,8 +4406,11 @@ mixin(joinFnBinds((){ stage = Compute stage. handle = Index buffer handle. access = Buffer access. See `Access::Enum`. + offset = Byte offset the shader's view of the buffer starts at. + Must be a multiple of 256 bytes. + size = Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. */ - {q{void}, q{setBuffer}, q{ubyte stage, IndexBufferHandle handle, bgfx.impl.Access.Enum access}, ext: `C++, "bgfx"`}, + {q{void}, q{setBuffer}, q{ubyte stage, IndexBufferHandle handle, bgfx.impl.Access.Enum access, uint offset=0, uint size=uint.max}, ext: `C++, "bgfx"`}, /** * Set compute vertex buffer. @@ -4354,8 +4418,11 @@ mixin(joinFnBinds((){ stage = Compute stage. handle = Vertex buffer handle. access = Buffer access. See `Access::Enum`. + offset = Byte offset the shader's view of the buffer starts at. + Must be a multiple of 256 bytes. + size = Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. */ - {q{void}, q{setBuffer}, q{ubyte stage, VertexBufferHandle handle, bgfx.impl.Access.Enum access}, ext: `C++, "bgfx"`}, + {q{void}, q{setBuffer}, q{ubyte stage, VertexBufferHandle handle, bgfx.impl.Access.Enum access, uint offset=0, uint size=uint.max}, ext: `C++, "bgfx"`}, /** * Set compute dynamic index buffer. @@ -4363,8 +4430,11 @@ mixin(joinFnBinds((){ stage = Compute stage. handle = Dynamic index buffer handle. access = Buffer access. See `Access::Enum`. + offset = Byte offset the shader's view of the buffer starts at. + Must be a multiple of 256 bytes. + size = Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. */ - {q{void}, q{setBuffer}, q{ubyte stage, DynamicIndexBufferHandle handle, bgfx.impl.Access.Enum access}, ext: `C++, "bgfx"`}, + {q{void}, q{setBuffer}, q{ubyte stage, DynamicIndexBufferHandle handle, bgfx.impl.Access.Enum access, uint offset=0, uint size=uint.max}, ext: `C++, "bgfx"`}, /** * Set compute dynamic vertex buffer. @@ -4372,8 +4442,11 @@ mixin(joinFnBinds((){ stage = Compute stage. handle = Dynamic vertex buffer handle. access = Buffer access. See `Access::Enum`. + offset = Byte offset the shader's view of the buffer starts at. + Must be a multiple of 256 bytes. + size = Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. */ - {q{void}, q{setBuffer}, q{ubyte stage, DynamicVertexBufferHandle handle, bgfx.impl.Access.Enum access}, ext: `C++, "bgfx"`}, + {q{void}, q{setBuffer}, q{ubyte stage, DynamicVertexBufferHandle handle, bgfx.impl.Access.Enum access, uint offset=0, uint size=uint.max}, ext: `C++, "bgfx"`}, /** * Set compute indirect buffer. diff --git a/bindings/py/bgfx.py b/bindings/py/bgfx.py index 6c1864fbe..490c29d26 100644 --- a/bindings/py/bgfx.py +++ b/bindings/py/bgfx.py @@ -414,6 +414,7 @@ class TextureFlags(enum.IntFlag): BlitDst = 0x400000000000 ReadBack = 0x800000000000 ExternalShared = 0x1000000000000 + SrgbMutable = 0x40000000000000 ReservedShift = 0x3c ReservedMask = 0xf000000000000000 RtMsaaX2 = 0x2000000000 @@ -469,6 +470,7 @@ class SamplerFlags(enum.IntFlag): ReservedMask = 0xf0000000 None_ = 0x0 SampleStencil = 0x100000 + Srgb = 0x200000 Point = 0x540 UvwMirror = 0x15 UvwClamp = 0x2a @@ -625,6 +627,7 @@ class AttachmentFlags(enum.IntFlag): AutoGenMips = 0x1 ReadOnlyDepth = 0x2 ReadOnlyStencil = 0x4 + Srgb = 0x8 class PciIdFlags(enum.IntFlag): None_ = 0x0 @@ -1624,6 +1627,10 @@ def _bind(lib): bgfx_encoder_set_uniform = lib.bgfx_encoder_set_uniform bgfx_encoder_set_uniform.argtypes = [ctypes.POINTER(Encoder), UniformHandle, ctypes.c_void_p, ctypes.c_uint16] bgfx_encoder_set_uniform.restype = None + global bgfx_encoder_set_uniform_ref + bgfx_encoder_set_uniform_ref = lib.bgfx_encoder_set_uniform_ref + bgfx_encoder_set_uniform_ref.argtypes = [ctypes.POINTER(Encoder), UniformHandle, ctypes.c_void_p, ctypes.c_uint16] + bgfx_encoder_set_uniform_ref.restype = None global bgfx_set_view_uniform bgfx_set_view_uniform = lib.bgfx_set_view_uniform bgfx_set_view_uniform.argtypes = [ctypes.c_uint16, UniformHandle, ctypes.c_void_p, ctypes.c_uint16] @@ -1718,19 +1725,19 @@ def _bind(lib): bgfx_encoder_submit_indirect_count.restype = None global bgfx_encoder_set_compute_index_buffer bgfx_encoder_set_compute_index_buffer = lib.bgfx_encoder_set_compute_index_buffer - bgfx_encoder_set_compute_index_buffer.argtypes = [ctypes.POINTER(Encoder), ctypes.c_uint8, IndexBufferHandle, ctypes.c_int] + bgfx_encoder_set_compute_index_buffer.argtypes = [ctypes.POINTER(Encoder), ctypes.c_uint8, IndexBufferHandle, ctypes.c_int, ctypes.c_uint32, ctypes.c_uint32] bgfx_encoder_set_compute_index_buffer.restype = None global bgfx_encoder_set_compute_vertex_buffer bgfx_encoder_set_compute_vertex_buffer = lib.bgfx_encoder_set_compute_vertex_buffer - bgfx_encoder_set_compute_vertex_buffer.argtypes = [ctypes.POINTER(Encoder), ctypes.c_uint8, VertexBufferHandle, ctypes.c_int] + bgfx_encoder_set_compute_vertex_buffer.argtypes = [ctypes.POINTER(Encoder), ctypes.c_uint8, VertexBufferHandle, ctypes.c_int, ctypes.c_uint32, ctypes.c_uint32] bgfx_encoder_set_compute_vertex_buffer.restype = None global bgfx_encoder_set_compute_dynamic_index_buffer bgfx_encoder_set_compute_dynamic_index_buffer = lib.bgfx_encoder_set_compute_dynamic_index_buffer - bgfx_encoder_set_compute_dynamic_index_buffer.argtypes = [ctypes.POINTER(Encoder), ctypes.c_uint8, DynamicIndexBufferHandle, ctypes.c_int] + bgfx_encoder_set_compute_dynamic_index_buffer.argtypes = [ctypes.POINTER(Encoder), ctypes.c_uint8, DynamicIndexBufferHandle, ctypes.c_int, ctypes.c_uint32, ctypes.c_uint32] bgfx_encoder_set_compute_dynamic_index_buffer.restype = None global bgfx_encoder_set_compute_dynamic_vertex_buffer bgfx_encoder_set_compute_dynamic_vertex_buffer = lib.bgfx_encoder_set_compute_dynamic_vertex_buffer - bgfx_encoder_set_compute_dynamic_vertex_buffer.argtypes = [ctypes.POINTER(Encoder), ctypes.c_uint8, DynamicVertexBufferHandle, ctypes.c_int] + bgfx_encoder_set_compute_dynamic_vertex_buffer.argtypes = [ctypes.POINTER(Encoder), ctypes.c_uint8, DynamicVertexBufferHandle, ctypes.c_int, ctypes.c_uint32, ctypes.c_uint32] bgfx_encoder_set_compute_dynamic_vertex_buffer.restype = None global bgfx_encoder_set_compute_indirect_buffer bgfx_encoder_set_compute_indirect_buffer = lib.bgfx_encoder_set_compute_indirect_buffer @@ -1836,6 +1843,10 @@ def _bind(lib): bgfx_set_uniform = lib.bgfx_set_uniform bgfx_set_uniform.argtypes = [UniformHandle, ctypes.c_void_p, ctypes.c_uint16] bgfx_set_uniform.restype = None + global bgfx_set_uniform_ref + bgfx_set_uniform_ref = lib.bgfx_set_uniform_ref + bgfx_set_uniform_ref.argtypes = [UniformHandle, ctypes.c_void_p, ctypes.c_uint16] + bgfx_set_uniform_ref.restype = None global bgfx_set_index_buffer bgfx_set_index_buffer = lib.bgfx_set_index_buffer bgfx_set_index_buffer.argtypes = [IndexBufferHandle, ctypes.c_uint32, ctypes.c_uint32] @@ -1922,19 +1933,19 @@ def _bind(lib): bgfx_submit_indirect_count.restype = None global bgfx_set_compute_index_buffer bgfx_set_compute_index_buffer = lib.bgfx_set_compute_index_buffer - bgfx_set_compute_index_buffer.argtypes = [ctypes.c_uint8, IndexBufferHandle, ctypes.c_int] + bgfx_set_compute_index_buffer.argtypes = [ctypes.c_uint8, IndexBufferHandle, ctypes.c_int, ctypes.c_uint32, ctypes.c_uint32] bgfx_set_compute_index_buffer.restype = None global bgfx_set_compute_vertex_buffer bgfx_set_compute_vertex_buffer = lib.bgfx_set_compute_vertex_buffer - bgfx_set_compute_vertex_buffer.argtypes = [ctypes.c_uint8, VertexBufferHandle, ctypes.c_int] + bgfx_set_compute_vertex_buffer.argtypes = [ctypes.c_uint8, VertexBufferHandle, ctypes.c_int, ctypes.c_uint32, ctypes.c_uint32] bgfx_set_compute_vertex_buffer.restype = None global bgfx_set_compute_dynamic_index_buffer bgfx_set_compute_dynamic_index_buffer = lib.bgfx_set_compute_dynamic_index_buffer - bgfx_set_compute_dynamic_index_buffer.argtypes = [ctypes.c_uint8, DynamicIndexBufferHandle, ctypes.c_int] + bgfx_set_compute_dynamic_index_buffer.argtypes = [ctypes.c_uint8, DynamicIndexBufferHandle, ctypes.c_int, ctypes.c_uint32, ctypes.c_uint32] bgfx_set_compute_dynamic_index_buffer.restype = None global bgfx_set_compute_dynamic_vertex_buffer bgfx_set_compute_dynamic_vertex_buffer = lib.bgfx_set_compute_dynamic_vertex_buffer - bgfx_set_compute_dynamic_vertex_buffer.argtypes = [ctypes.c_uint8, DynamicVertexBufferHandle, ctypes.c_int] + bgfx_set_compute_dynamic_vertex_buffer.argtypes = [ctypes.c_uint8, DynamicVertexBufferHandle, ctypes.c_int, ctypes.c_uint32, ctypes.c_uint32] bgfx_set_compute_dynamic_vertex_buffer.restype = None global bgfx_set_compute_indirect_buffer bgfx_set_compute_indirect_buffer = lib.bgfx_set_compute_indirect_buffer diff --git a/bindings/py/bgfx.pyi b/bindings/py/bgfx.pyi index 7a8a5e5e1..78839acb0 100644 --- a/bindings/py/bgfx.pyi +++ b/bindings/py/bgfx.pyi @@ -778,6 +778,13 @@ class TextureFlags(enum.IntFlag): ReadBack = 0x800000000000 # Texture is shared with other device or other process. ExternalShared = 0x1000000000000 + # Texture may be sampled and rendered with either sRGB-ness, + # not just the one implied by its format. Every bind and + # attachment must then state the encoding it wants (see + # `BGFX_SAMPLER_SRGB`, `BGFX_ATTACHMENT_SRGB`). Costs nothing + # until used, but may disable texture compression on some + # hardware. + SrgbMutable = 0x40000000000000 # Do not use! Top nibble is reserved for internal texture flags (see bgfx_p.h). ReservedShift = 0x3c # Do not use! Top nibble is reserved for internal texture flags (see bgfx_p.h). @@ -865,6 +872,11 @@ class SamplerFlags(enum.IntFlag): None_ = 0x0 # Sample stencil instead of depth. SampleStencil = 0x100000 + # Sample with sRGB conversion; absence of this flag samples + # without it. Only affects textures created + # `BGFX_TEXTURE_SRGB_MUTABLE`, which must state the encoding + # explicitly on every bind; ignored for any other texture. + Srgb = 0x200000 Point = 0x540 UvwMirror = 0x15 UvwClamp = 0x2a @@ -1148,6 +1160,11 @@ class AttachmentFlags(enum.IntFlag): ReadOnlyDepth = 0x2 # Bind the stencil aspect read-only. ReadOnlyStencil = 0x4 + # Render with sRGB conversion; absence of this flag renders without + # it. Only affects textures created `BGFX_TEXTURE_SRGB_MUTABLE`, + # which must state the encoding explicitly on every attachment; + # ignored for any other texture. + Srgb = 0x8 class PciIdFlags(enum.IntFlag): # Autoselect adapter. @@ -2741,6 +2758,12 @@ def bgfx_encoder_alloc_transform(_this: Optional[Union[Encoder, _Pointer[Encoder # Set shader uniform parameter for draw primitive. def bgfx_encoder_set_uniform(_this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], _handle: UniformHandle, _value: Any, _num: int, /) -> None: ... +# Set shader uniform parameter by reference. Unlike `Encoder::setUniform`, the data +# is not copied immediately; the renderer reads it from `_value` at frame render +# time. The pointer must remain valid and unchanged until the frame is rendered +# (up to two `bgfx::frame` calls with multithreaded submission). +def bgfx_encoder_set_uniform_ref(_this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], _handle: UniformHandle, _value: Any, _num: int, /) -> None: ... + # Set shader uniform parameter for view. # # @attention Uniform must be created with `bgfx::UniformFreq::View` argument. @@ -2904,16 +2927,48 @@ def bgfx_encoder_submit_indirect_count( ) -> None: ... # Set compute index buffer. -def bgfx_encoder_set_compute_index_buffer(_this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], _stage: int, _handle: IndexBufferHandle, _access: Union[Access, int], /) -> None: ... +def bgfx_encoder_set_compute_index_buffer( + _this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], + _stage: int, + _handle: IndexBufferHandle, + _access: Union[Access, int], + _offset: int, + _size: int, + /, +) -> None: ... # Set compute vertex buffer. -def bgfx_encoder_set_compute_vertex_buffer(_this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], _stage: int, _handle: VertexBufferHandle, _access: Union[Access, int], /) -> None: ... +def bgfx_encoder_set_compute_vertex_buffer( + _this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], + _stage: int, + _handle: VertexBufferHandle, + _access: Union[Access, int], + _offset: int, + _size: int, + /, +) -> None: ... # Set compute dynamic index buffer. -def bgfx_encoder_set_compute_dynamic_index_buffer(_this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], _stage: int, _handle: DynamicIndexBufferHandle, _access: Union[Access, int], /) -> None: ... +def bgfx_encoder_set_compute_dynamic_index_buffer( + _this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], + _stage: int, + _handle: DynamicIndexBufferHandle, + _access: Union[Access, int], + _offset: int, + _size: int, + /, +) -> None: ... # Set compute dynamic vertex buffer. -def bgfx_encoder_set_compute_dynamic_vertex_buffer(_this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], _stage: int, _handle: DynamicVertexBufferHandle, _access: Union[Access, int], /) -> None: ... +def bgfx_encoder_set_compute_dynamic_vertex_buffer( + _this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], + _stage: int, + _handle: DynamicVertexBufferHandle, + _access: Union[Access, int], + _offset: int, + _size: int, + /, +) -> None: ... # Set compute indirect buffer. def bgfx_encoder_set_compute_indirect_buffer(_this: Optional[Union[Encoder, _Pointer[Encoder], ctypes.Array]], _stage: int, _handle: IndirectBufferHandle, _access: Union[Access, int], /) -> None: ... @@ -3160,6 +3215,12 @@ def bgfx_alloc_transform(_transform: Optional[Union[Transform, _Pointer[Transfor # Set shader uniform parameter for draw primitive. def bgfx_set_uniform(_handle: UniformHandle, _value: Any, _num: int, /) -> None: ... +# Set shader uniform parameter by reference. Unlike `bgfx::setUniform`, the data +# is not copied immediately; the renderer reads it from `_value` at frame render +# time. The pointer must remain valid and unchanged until the frame is rendered +# (up to two `bgfx::frame` calls with multithreaded submission). +def bgfx_set_uniform_ref(_handle: UniformHandle, _value: Any, _num: int, /) -> None: ... + # Set index buffer for draw primitive. def bgfx_set_index_buffer(_handle: IndexBufferHandle, _firstIndex: int, _numIndices: int, /) -> None: ... @@ -3274,16 +3335,16 @@ def bgfx_submit_indirect_count( ) -> None: ... # Set compute index buffer. -def bgfx_set_compute_index_buffer(_stage: int, _handle: IndexBufferHandle, _access: Union[Access, int], /) -> None: ... +def bgfx_set_compute_index_buffer(_stage: int, _handle: IndexBufferHandle, _access: Union[Access, int], _offset: int, _size: int, /) -> None: ... # Set compute vertex buffer. -def bgfx_set_compute_vertex_buffer(_stage: int, _handle: VertexBufferHandle, _access: Union[Access, int], /) -> None: ... +def bgfx_set_compute_vertex_buffer(_stage: int, _handle: VertexBufferHandle, _access: Union[Access, int], _offset: int, _size: int, /) -> None: ... # Set compute dynamic index buffer. -def bgfx_set_compute_dynamic_index_buffer(_stage: int, _handle: DynamicIndexBufferHandle, _access: Union[Access, int], /) -> None: ... +def bgfx_set_compute_dynamic_index_buffer(_stage: int, _handle: DynamicIndexBufferHandle, _access: Union[Access, int], _offset: int, _size: int, /) -> None: ... # Set compute dynamic vertex buffer. -def bgfx_set_compute_dynamic_vertex_buffer(_stage: int, _handle: DynamicVertexBufferHandle, _access: Union[Access, int], /) -> None: ... +def bgfx_set_compute_dynamic_vertex_buffer(_stage: int, _handle: DynamicVertexBufferHandle, _access: Union[Access, int], _offset: int, _size: int, /) -> None: ... # Set compute indirect buffer. def bgfx_set_compute_indirect_buffer(_stage: int, _handle: IndirectBufferHandle, _access: Union[Access, int], /) -> None: ... diff --git a/bindings/zig/bgfx.zig b/bindings/zig/bgfx.zig index fb910ed13..25622afa7 100644 --- a/bindings/zig/bgfx.zig +++ b/bindings/zig/bgfx.zig @@ -419,6 +419,14 @@ pub const TextureFlags_ReadBack: TextureFlags = 0x0000800000000000 /// Texture is shared with other device or other process. pub const TextureFlags_ExternalShared: TextureFlags = 0x0001000000000000; + +/// Texture may be sampled and rendered with either sRGB-ness, +/// not just the one implied by its format. Every bind and +/// attachment must then state the encoding it wants (see +/// `BGFX_SAMPLER_SRGB`, `BGFX_ATTACHMENT_SRGB`). Costs nothing +/// until used, but may disable texture compression on some +/// hardware. +pub const TextureFlags_SrgbMutable: TextureFlags = 0x0040000000000000; pub const TextureFlags_ReservedShift: TextureFlags = 60; pub const TextureFlags_ReservedMask: TextureFlags = 0xf000000000000000; @@ -529,6 +537,12 @@ pub const SamplerFlags_None: SamplerFlags = 0x00000000; /// Sample stencil instead of depth. pub const SamplerFlags_SampleStencil: SamplerFlags = 0x00100000; + +/// Sample with sRGB conversion; absence of this flag samples +/// without it. Only affects textures created +/// `BGFX_TEXTURE_SRGB_MUTABLE`, which must state the encoding +/// explicitly on every bind; ignored for any other texture. +pub const SamplerFlags_Srgb: SamplerFlags = 0x00200000; pub const SamplerFlags_Point: SamplerFlags = 0x00000540; pub const SamplerFlags_UvwMirror: SamplerFlags = 0x00000015; pub const SamplerFlags_UvwClamp: SamplerFlags = 0x0000002a; @@ -821,6 +835,12 @@ pub const AttachmentFlags_ReadOnlyDepth: AttachmentFlags = 0x00000002; /// Bind the stencil aspect read-only. pub const AttachmentFlags_ReadOnlyStencil: AttachmentFlags = 0x00000004; +/// Render with sRGB conversion; absence of this flag renders without +/// it. Only affects textures created `BGFX_TEXTURE_SRGB_MUTABLE`, +/// which must state the encoding explicitly on every attachment; +/// ignored for any other texture. +pub const AttachmentFlags_Srgb: AttachmentFlags = 0x00000008; + pub const PciIdFlags = u16; /// Autoselect adapter. pub const PciIdFlags_None: PciIdFlags = 0x0000; @@ -2027,6 +2047,16 @@ pub const Init = extern struct { pub inline fn setUniform(self: ?*Encoder, _handle: UniformHandle, _value: ?*const anyopaque, _num: u16) void { return bgfx_encoder_set_uniform(self, _handle, _value, _num); } + /// Set shader uniform parameter by reference. Unlike `Encoder::setUniform`, the data + /// is not copied immediately; the renderer reads it from `_value` at frame render + /// time. The pointer must remain valid and unchanged until the frame is rendered + /// (up to two `bgfx::frame` calls with multithreaded submission). + /// Uniform. + /// Pointer to uniform data. Must stay valid until the frame is rendered. + /// Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation. + pub inline fn setUniformRef(self: ?*Encoder, _handle: UniformHandle, _value: ?*const anyopaque, _num: u16) void { + return bgfx_encoder_set_uniform_ref(self, _handle, _value, _num); + } /// Set index buffer for draw primitive. /// Index buffer. /// First index to render. @@ -2222,29 +2252,37 @@ pub const Init = extern struct { /// Compute stage. /// Index buffer handle. /// Buffer access. See `Access::Enum`. - pub inline fn setComputeIndexBuffer(self: ?*Encoder, _stage: u8, _handle: IndexBufferHandle, _access: Access) void { - return bgfx_encoder_set_compute_index_buffer(self, _stage, _handle, _access); + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. + pub inline fn setComputeIndexBuffer(self: ?*Encoder, _stage: u8, _handle: IndexBufferHandle, _access: Access, _offset: u32, _size: u32) void { + return bgfx_encoder_set_compute_index_buffer(self, _stage, _handle, _access, _offset, _size); } /// Set compute vertex buffer. /// Compute stage. /// Vertex buffer handle. /// Buffer access. See `Access::Enum`. - pub inline fn setComputeVertexBuffer(self: ?*Encoder, _stage: u8, _handle: VertexBufferHandle, _access: Access) void { - return bgfx_encoder_set_compute_vertex_buffer(self, _stage, _handle, _access); + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. + pub inline fn setComputeVertexBuffer(self: ?*Encoder, _stage: u8, _handle: VertexBufferHandle, _access: Access, _offset: u32, _size: u32) void { + return bgfx_encoder_set_compute_vertex_buffer(self, _stage, _handle, _access, _offset, _size); } /// Set compute dynamic index buffer. /// Compute stage. /// Dynamic index buffer handle. /// Buffer access. See `Access::Enum`. - pub inline fn setComputeDynamicIndexBuffer(self: ?*Encoder, _stage: u8, _handle: DynamicIndexBufferHandle, _access: Access) void { - return bgfx_encoder_set_compute_dynamic_index_buffer(self, _stage, _handle, _access); + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. + pub inline fn setComputeDynamicIndexBuffer(self: ?*Encoder, _stage: u8, _handle: DynamicIndexBufferHandle, _access: Access, _offset: u32, _size: u32) void { + return bgfx_encoder_set_compute_dynamic_index_buffer(self, _stage, _handle, _access, _offset, _size); } /// Set compute dynamic vertex buffer. /// Compute stage. /// Dynamic vertex buffer handle. /// Buffer access. See `Access::Enum`. - pub inline fn setComputeDynamicVertexBuffer(self: ?*Encoder, _stage: u8, _handle: DynamicVertexBufferHandle, _access: Access) void { - return bgfx_encoder_set_compute_dynamic_vertex_buffer(self, _stage, _handle, _access); + /// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. + /// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. + pub inline fn setComputeDynamicVertexBuffer(self: ?*Encoder, _stage: u8, _handle: DynamicVertexBufferHandle, _access: Access, _offset: u32, _size: u32) void { + return bgfx_encoder_set_compute_dynamic_vertex_buffer(self, _stage, _handle, _access, _offset, _size); } /// Set compute indirect buffer. /// Compute stage. @@ -3810,6 +3848,15 @@ extern fn bgfx_encoder_alloc_transform(self: ?*Encoder, _transform: [*c]Transfor /// Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation. extern fn bgfx_encoder_set_uniform(self: ?*Encoder, _handle: UniformHandle, _value: ?*const anyopaque, _num: u16) void; +/// Set shader uniform parameter by reference. Unlike `Encoder::setUniform`, the data +/// is not copied immediately; the renderer reads it from `_value` at frame render +/// time. The pointer must remain valid and unchanged until the frame is rendered +/// (up to two `bgfx::frame` calls with multithreaded submission). +/// Uniform. +/// Pointer to uniform data. Must stay valid until the frame is rendered. +/// Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation. +extern fn bgfx_encoder_set_uniform_ref(self: ?*Encoder, _handle: UniformHandle, _value: ?*const anyopaque, _num: u16) void; + /// Set shader uniform parameter for view. /// /// @attention Uniform must be created with `bgfx::UniformFreq::View` argument. @@ -4009,25 +4056,33 @@ extern fn bgfx_encoder_submit_indirect_count(self: ?*Encoder, _id: ViewId, _prog /// Compute stage. /// Index buffer handle. /// Buffer access. See `Access::Enum`. -extern fn bgfx_encoder_set_compute_index_buffer(self: ?*Encoder, _stage: u8, _handle: IndexBufferHandle, _access: Access) void; +/// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. +/// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. +extern fn bgfx_encoder_set_compute_index_buffer(self: ?*Encoder, _stage: u8, _handle: IndexBufferHandle, _access: Access, _offset: u32, _size: u32) void; /// Set compute vertex buffer. /// Compute stage. /// Vertex buffer handle. /// Buffer access. See `Access::Enum`. -extern fn bgfx_encoder_set_compute_vertex_buffer(self: ?*Encoder, _stage: u8, _handle: VertexBufferHandle, _access: Access) void; +/// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. +/// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. +extern fn bgfx_encoder_set_compute_vertex_buffer(self: ?*Encoder, _stage: u8, _handle: VertexBufferHandle, _access: Access, _offset: u32, _size: u32) void; /// Set compute dynamic index buffer. /// Compute stage. /// Dynamic index buffer handle. /// Buffer access. See `Access::Enum`. -extern fn bgfx_encoder_set_compute_dynamic_index_buffer(self: ?*Encoder, _stage: u8, _handle: DynamicIndexBufferHandle, _access: Access) void; +/// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. +/// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. +extern fn bgfx_encoder_set_compute_dynamic_index_buffer(self: ?*Encoder, _stage: u8, _handle: DynamicIndexBufferHandle, _access: Access, _offset: u32, _size: u32) void; /// Set compute dynamic vertex buffer. /// Compute stage. /// Dynamic vertex buffer handle. /// Buffer access. See `Access::Enum`. -extern fn bgfx_encoder_set_compute_dynamic_vertex_buffer(self: ?*Encoder, _stage: u8, _handle: DynamicVertexBufferHandle, _access: Access) void; +/// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. +/// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. +extern fn bgfx_encoder_set_compute_dynamic_vertex_buffer(self: ?*Encoder, _stage: u8, _handle: DynamicVertexBufferHandle, _access: Access, _offset: u32, _size: u32) void; /// Set compute indirect buffer. /// Compute stage. @@ -4357,6 +4412,18 @@ pub inline fn setUniform(_handle: UniformHandle, _value: ?*const anyopaque, _num } extern fn bgfx_set_uniform(_handle: UniformHandle, _value: ?*const anyopaque, _num: u16) void; +/// Set shader uniform parameter by reference. Unlike `bgfx::setUniform`, the data +/// is not copied immediately; the renderer reads it from `_value` at frame render +/// time. The pointer must remain valid and unchanged until the frame is rendered +/// (up to two `bgfx::frame` calls with multithreaded submission). +/// Uniform. +/// Pointer to uniform data. Must stay valid until the frame is rendered. +/// Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation. +pub inline fn setUniformRef(_handle: UniformHandle, _value: ?*const anyopaque, _num: u16) void { + return bgfx_set_uniform_ref(_handle, _value, _num); +} +extern fn bgfx_set_uniform_ref(_handle: UniformHandle, _value: ?*const anyopaque, _num: u16) void; + /// Set index buffer for draw primitive. /// Index buffer. /// First index to render. @@ -4592,37 +4659,45 @@ extern fn bgfx_submit_indirect_count(_id: ViewId, _program: ProgramHandle, _indi /// Compute stage. /// Index buffer handle. /// Buffer access. See `Access::Enum`. -pub inline fn setComputeIndexBuffer(_stage: u8, _handle: IndexBufferHandle, _access: Access) void { - return bgfx_set_compute_index_buffer(_stage, _handle, _access); +/// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. +/// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. +pub inline fn setComputeIndexBuffer(_stage: u8, _handle: IndexBufferHandle, _access: Access, _offset: u32, _size: u32) void { + return bgfx_set_compute_index_buffer(_stage, _handle, _access, _offset, _size); } -extern fn bgfx_set_compute_index_buffer(_stage: u8, _handle: IndexBufferHandle, _access: Access) void; +extern fn bgfx_set_compute_index_buffer(_stage: u8, _handle: IndexBufferHandle, _access: Access, _offset: u32, _size: u32) void; /// Set compute vertex buffer. /// Compute stage. /// Vertex buffer handle. /// Buffer access. See `Access::Enum`. -pub inline fn setComputeVertexBuffer(_stage: u8, _handle: VertexBufferHandle, _access: Access) void { - return bgfx_set_compute_vertex_buffer(_stage, _handle, _access); +/// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. +/// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. +pub inline fn setComputeVertexBuffer(_stage: u8, _handle: VertexBufferHandle, _access: Access, _offset: u32, _size: u32) void { + return bgfx_set_compute_vertex_buffer(_stage, _handle, _access, _offset, _size); } -extern fn bgfx_set_compute_vertex_buffer(_stage: u8, _handle: VertexBufferHandle, _access: Access) void; +extern fn bgfx_set_compute_vertex_buffer(_stage: u8, _handle: VertexBufferHandle, _access: Access, _offset: u32, _size: u32) void; /// Set compute dynamic index buffer. /// Compute stage. /// Dynamic index buffer handle. /// Buffer access. See `Access::Enum`. -pub inline fn setComputeDynamicIndexBuffer(_stage: u8, _handle: DynamicIndexBufferHandle, _access: Access) void { - return bgfx_set_compute_dynamic_index_buffer(_stage, _handle, _access); +/// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. +/// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. +pub inline fn setComputeDynamicIndexBuffer(_stage: u8, _handle: DynamicIndexBufferHandle, _access: Access, _offset: u32, _size: u32) void { + return bgfx_set_compute_dynamic_index_buffer(_stage, _handle, _access, _offset, _size); } -extern fn bgfx_set_compute_dynamic_index_buffer(_stage: u8, _handle: DynamicIndexBufferHandle, _access: Access) void; +extern fn bgfx_set_compute_dynamic_index_buffer(_stage: u8, _handle: DynamicIndexBufferHandle, _access: Access, _offset: u32, _size: u32) void; /// Set compute dynamic vertex buffer. /// Compute stage. /// Dynamic vertex buffer handle. /// Buffer access. See `Access::Enum`. -pub inline fn setComputeDynamicVertexBuffer(_stage: u8, _handle: DynamicVertexBufferHandle, _access: Access) void { - return bgfx_set_compute_dynamic_vertex_buffer(_stage, _handle, _access); +/// Byte offset the shader's view of the buffer starts at. Must be a multiple of 256 bytes. +/// Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. +pub inline fn setComputeDynamicVertexBuffer(_stage: u8, _handle: DynamicVertexBufferHandle, _access: Access, _offset: u32, _size: u32) void { + return bgfx_set_compute_dynamic_vertex_buffer(_stage, _handle, _access, _offset, _size); } -extern fn bgfx_set_compute_dynamic_vertex_buffer(_stage: u8, _handle: DynamicVertexBufferHandle, _access: Access) void; +extern fn bgfx_set_compute_dynamic_vertex_buffer(_stage: u8, _handle: DynamicVertexBufferHandle, _access: Access, _offset: u32, _size: u32) void; /// Set compute indirect buffer. /// Compute stage. diff --git a/docs/bgfx.rst b/docs/bgfx.rst index 199e96bce..776ee1555 100644 --- a/docs/bgfx.rst +++ b/docs/bgfx.rst @@ -472,6 +472,7 @@ Set shader uniform parameters for draw calls. .. doxygenfunction:: bgfx::setViewUniform .. doxygenfunction:: bgfx::setFrameUniform .. doxygenfunction:: bgfx::setUniform +.. doxygenfunction:: bgfx::setUniformRef Submit ****** @@ -497,10 +498,10 @@ Bind buffers to compute stages. :members: .. doxygenfunction:: bgfx::read(const BufferRegion & _src, void* _data) -.. doxygenfunction:: bgfx::setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access) -.. doxygenfunction:: bgfx::setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access) -.. doxygenfunction:: bgfx::setBuffer(uint8_t _stage, DynamicIndexBufferHandle _handle, Access::Enum _access) -.. doxygenfunction:: bgfx::setBuffer(uint8_t _stage, DynamicVertexBufferHandle _handle, Access::Enum _access) +.. doxygenfunction:: bgfx::setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access, uint32_t _offset = 0, uint32_t _size = UINT32_MAX) +.. doxygenfunction:: bgfx::setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access, uint32_t _offset = 0, uint32_t _size = UINT32_MAX) +.. doxygenfunction:: bgfx::setBuffer(uint8_t _stage, DynamicIndexBufferHandle _handle, Access::Enum _access, uint32_t _offset = 0, uint32_t _size = UINT32_MAX) +.. doxygenfunction:: bgfx::setBuffer(uint8_t _stage, DynamicVertexBufferHandle _handle, Access::Enum _access, uint32_t _offset = 0, uint32_t _size = UINT32_MAX) .. doxygenfunction:: bgfx::setBuffer(uint8_t _stage, IndirectBufferHandle _handle, Access::Enum _access) Images @@ -611,6 +612,7 @@ Textures .. doxygendefine:: BGFX_TEXTURE_BLIT_DST .. doxygendefine:: BGFX_TEXTURE_READ_BACK .. doxygendefine:: BGFX_TEXTURE_EXTERNAL_SHARED +.. doxygendefine:: BGFX_TEXTURE_SRGB_MUTABLE .. doxygendefine:: BGFX_TEXTURE_RT_WRITE_ONLY diff --git a/include/bgfx/bgfx.h b/include/bgfx/bgfx.h index b1cb697d6..6c56eafa9 100644 --- a/include/bgfx/bgfx.h +++ b/include/bgfx/bgfx.h @@ -1495,6 +1495,24 @@ namespace bgfx , uint16_t _num = 1 ); + /// Set shader uniform parameter by reference. Unlike `Encoder::setUniform`, the data + /// is not copied immediately; the renderer reads it from `_value` at frame render + /// time. The pointer must remain valid and unchanged until the frame is rendered + /// (up to two `bgfx::frame` calls with multithreaded submission). + /// + /// @param[in] _handle Uniform. + /// @param[in] _value Pointer to uniform data. Must stay valid until the frame is rendered. + /// @param[in] _num Number of elements. Passing `UINT16_MAX` will + /// use the _num passed on uniform creation. + /// + /// @attention C99's equivalent binding is `bgfx_encoder_set_uniform_ref`. + /// + void setUniformRef( + UniformHandle _handle + , const void* _value + , uint16_t _num = UINT16_MAX + ); + /// Set index buffer for draw primitive. /// /// @param[in] _handle Index buffer. @@ -1870,6 +1888,9 @@ namespace bgfx /// @param[in] _stage Compute stage. /// @param[in] _handle Index buffer handle. /// @param[in] _access Buffer access. See `Access::Enum`. + /// @param[in] _offset Byte offset the shader's view of the buffer starts at. + /// Must be a multiple of 256 bytes. + /// @param[in] _size Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// /// @attention C99's equivalent binding is `bgfx_encoder_set_compute_index_buffer`. /// @@ -1877,6 +1898,8 @@ namespace bgfx uint8_t _stage , IndexBufferHandle _handle , Access::Enum _access + , uint32_t _offset = 0 + , uint32_t _size = UINT32_MAX ); /// Set compute vertex buffer. @@ -1884,6 +1907,9 @@ namespace bgfx /// @param[in] _stage Compute stage. /// @param[in] _handle Vertex buffer handle. /// @param[in] _access Buffer access. See `Access::Enum`. + /// @param[in] _offset Byte offset the shader's view of the buffer starts at. + /// Must be a multiple of 256 bytes. + /// @param[in] _size Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// /// @attention C99's equivalent binding is `bgfx_encoder_set_compute_vertex_buffer`. /// @@ -1891,6 +1917,8 @@ namespace bgfx uint8_t _stage , VertexBufferHandle _handle , Access::Enum _access + , uint32_t _offset = 0 + , uint32_t _size = UINT32_MAX ); /// Set compute dynamic index buffer. @@ -1898,6 +1926,9 @@ namespace bgfx /// @param[in] _stage Compute stage. /// @param[in] _handle Dynamic index buffer handle. /// @param[in] _access Buffer access. See `Access::Enum`. + /// @param[in] _offset Byte offset the shader's view of the buffer starts at. + /// Must be a multiple of 256 bytes. + /// @param[in] _size Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// /// @attention C99's equivalent binding is `bgfx_encoder_set_compute_dynamic_index_buffer`. /// @@ -1905,6 +1936,8 @@ namespace bgfx uint8_t _stage , DynamicIndexBufferHandle _handle , Access::Enum _access + , uint32_t _offset = 0 + , uint32_t _size = UINT32_MAX ); /// Set compute dynamic vertex buffer. @@ -1912,6 +1945,9 @@ namespace bgfx /// @param[in] _stage Compute stage. /// @param[in] _handle Dynamic vertex buffer handle. /// @param[in] _access Buffer access. See `Access::Enum`. + /// @param[in] _offset Byte offset the shader's view of the buffer starts at. + /// Must be a multiple of 256 bytes. + /// @param[in] _size Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// /// @attention C99's equivalent binding is `bgfx_encoder_set_compute_dynamic_vertex_buffer`. /// @@ -1919,6 +1955,8 @@ namespace bgfx uint8_t _stage , DynamicVertexBufferHandle _handle , Access::Enum _access + , uint32_t _offset = 0 + , uint32_t _size = UINT32_MAX ); /// Set compute indirect buffer. @@ -4632,6 +4670,24 @@ namespace bgfx , uint16_t _num = 1 ); + /// Set shader uniform parameter by reference. Unlike `bgfx::setUniform`, the data + /// is not copied immediately; the renderer reads it from `_value` at frame render + /// time. The pointer must remain valid and unchanged until the frame is rendered + /// (up to two `bgfx::frame` calls with multithreaded submission). + /// + /// @param[in] _handle Uniform. + /// @param[in] _value Pointer to uniform data. Must stay valid until the frame is rendered. + /// @param[in] _num Number of elements. Passing `UINT16_MAX` will + /// use the _num passed on uniform creation. + /// + /// @attention C99's equivalent binding is `bgfx_set_uniform_ref`. + /// + void setUniformRef( + UniformHandle _handle + , const void* _value + , uint16_t _num = UINT16_MAX + ); + /// Set index buffer for draw primitive. /// /// @param[in] _handle Index buffer. @@ -5005,6 +5061,9 @@ namespace bgfx /// @param[in] _stage Compute stage. /// @param[in] _handle Index buffer handle. /// @param[in] _access Buffer access. See `Access::Enum`. + /// @param[in] _offset Byte offset the shader's view of the buffer starts at. + /// Must be a multiple of 256 bytes. + /// @param[in] _size Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// /// @attention C99's equivalent binding is `bgfx_set_compute_index_buffer`. /// @@ -5012,6 +5071,8 @@ namespace bgfx uint8_t _stage , IndexBufferHandle _handle , Access::Enum _access + , uint32_t _offset = 0 + , uint32_t _size = UINT32_MAX ); /// Set compute vertex buffer. @@ -5019,6 +5080,9 @@ namespace bgfx /// @param[in] _stage Compute stage. /// @param[in] _handle Vertex buffer handle. /// @param[in] _access Buffer access. See `Access::Enum`. + /// @param[in] _offset Byte offset the shader's view of the buffer starts at. + /// Must be a multiple of 256 bytes. + /// @param[in] _size Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// /// @attention C99's equivalent binding is `bgfx_set_compute_vertex_buffer`. /// @@ -5026,6 +5090,8 @@ namespace bgfx uint8_t _stage , VertexBufferHandle _handle , Access::Enum _access + , uint32_t _offset = 0 + , uint32_t _size = UINT32_MAX ); /// Set compute dynamic index buffer. @@ -5033,6 +5099,9 @@ namespace bgfx /// @param[in] _stage Compute stage. /// @param[in] _handle Dynamic index buffer handle. /// @param[in] _access Buffer access. See `Access::Enum`. + /// @param[in] _offset Byte offset the shader's view of the buffer starts at. + /// Must be a multiple of 256 bytes. + /// @param[in] _size Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// /// @attention C99's equivalent binding is `bgfx_set_compute_dynamic_index_buffer`. /// @@ -5040,6 +5109,8 @@ namespace bgfx uint8_t _stage , DynamicIndexBufferHandle _handle , Access::Enum _access + , uint32_t _offset = 0 + , uint32_t _size = UINT32_MAX ); /// Set compute dynamic vertex buffer. @@ -5047,6 +5118,9 @@ namespace bgfx /// @param[in] _stage Compute stage. /// @param[in] _handle Dynamic vertex buffer handle. /// @param[in] _access Buffer access. See `Access::Enum`. + /// @param[in] _offset Byte offset the shader's view of the buffer starts at. + /// Must be a multiple of 256 bytes. + /// @param[in] _size Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. /// /// @attention C99's equivalent binding is `bgfx_set_compute_dynamic_vertex_buffer`. /// @@ -5054,6 +5128,8 @@ namespace bgfx uint8_t _stage , DynamicVertexBufferHandle _handle , Access::Enum _access + , uint32_t _offset = 0 + , uint32_t _size = UINT32_MAX ); /// Set compute indirect buffer. diff --git a/include/bgfx/c99/bgfx.h b/include/bgfx/c99/bgfx.h index 4e1ab6882..2e24f2928 100644 --- a/include/bgfx/c99/bgfx.h +++ b/include/bgfx/c99/bgfx.h @@ -3224,6 +3224,20 @@ BGFX_C_API uint32_t bgfx_encoder_alloc_transform(bgfx_encoder_t* _this, bgfx_tra */ BGFX_C_API void bgfx_encoder_set_uniform(bgfx_encoder_t* _this, bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num); +/** + * Set shader uniform parameter by reference. Unlike `Encoder::setUniform`, the data + * is not copied immediately; the renderer reads it from `_value` at frame render + * time. The pointer must remain valid and unchanged until the frame is rendered + * (up to two `bgfx::frame` calls with multithreaded submission). + * + * @param[in] _handle Uniform. + * @param[in] _value Pointer to uniform data. Must stay valid until the frame is rendered. + * @param[in] _num Number of elements. Passing `UINT16_MAX` will + * use the _num passed on uniform creation. + * + */ +BGFX_C_API void bgfx_encoder_set_uniform_ref(bgfx_encoder_t* _this, bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num); + /** * Set shader uniform parameter for view. * @@ -3521,9 +3535,12 @@ BGFX_C_API void bgfx_encoder_submit_indirect_count(bgfx_encoder_t* _this, bgfx_v * @param[in] _stage Compute stage. * @param[in] _handle Index buffer handle. * @param[in] _access Buffer access. See `Access::Enum`. + * @param[in] _offset Byte offset the shader's view of the buffer starts at. + * Must be a multiple of 256 bytes. + * @param[in] _size Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. * */ -BGFX_C_API void bgfx_encoder_set_compute_index_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access); +BGFX_C_API void bgfx_encoder_set_compute_index_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size); /** * Set compute vertex buffer. @@ -3531,9 +3548,12 @@ BGFX_C_API void bgfx_encoder_set_compute_index_buffer(bgfx_encoder_t* _this, uin * @param[in] _stage Compute stage. * @param[in] _handle Vertex buffer handle. * @param[in] _access Buffer access. See `Access::Enum`. + * @param[in] _offset Byte offset the shader's view of the buffer starts at. + * Must be a multiple of 256 bytes. + * @param[in] _size Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. * */ -BGFX_C_API void bgfx_encoder_set_compute_vertex_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_vertex_buffer_handle_t _handle, bgfx_access_t _access); +BGFX_C_API void bgfx_encoder_set_compute_vertex_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_vertex_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size); /** * Set compute dynamic index buffer. @@ -3541,9 +3561,12 @@ BGFX_C_API void bgfx_encoder_set_compute_vertex_buffer(bgfx_encoder_t* _this, ui * @param[in] _stage Compute stage. * @param[in] _handle Dynamic index buffer handle. * @param[in] _access Buffer access. See `Access::Enum`. + * @param[in] _offset Byte offset the shader's view of the buffer starts at. + * Must be a multiple of 256 bytes. + * @param[in] _size Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. * */ -BGFX_C_API void bgfx_encoder_set_compute_dynamic_index_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_dynamic_index_buffer_handle_t _handle, bgfx_access_t _access); +BGFX_C_API void bgfx_encoder_set_compute_dynamic_index_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_dynamic_index_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size); /** * Set compute dynamic vertex buffer. @@ -3551,9 +3574,12 @@ BGFX_C_API void bgfx_encoder_set_compute_dynamic_index_buffer(bgfx_encoder_t* _t * @param[in] _stage Compute stage. * @param[in] _handle Dynamic vertex buffer handle. * @param[in] _access Buffer access. See `Access::Enum`. + * @param[in] _offset Byte offset the shader's view of the buffer starts at. + * Must be a multiple of 256 bytes. + * @param[in] _size Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. * */ -BGFX_C_API void bgfx_encoder_set_compute_dynamic_vertex_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_dynamic_vertex_buffer_handle_t _handle, bgfx_access_t _access); +BGFX_C_API void bgfx_encoder_set_compute_dynamic_vertex_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_dynamic_vertex_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size); /** * Set compute indirect buffer. @@ -3951,6 +3977,20 @@ BGFX_C_API uint32_t bgfx_alloc_transform(bgfx_transform_t* _transform, uint16_t */ BGFX_C_API void bgfx_set_uniform(bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num); +/** + * Set shader uniform parameter by reference. Unlike `bgfx::setUniform`, the data + * is not copied immediately; the renderer reads it from `_value` at frame render + * time. The pointer must remain valid and unchanged until the frame is rendered + * (up to two `bgfx::frame` calls with multithreaded submission). + * + * @param[in] _handle Uniform. + * @param[in] _value Pointer to uniform data. Must stay valid until the frame is rendered. + * @param[in] _num Number of elements. Passing `UINT16_MAX` will + * use the _num passed on uniform creation. + * + */ +BGFX_C_API void bgfx_set_uniform_ref(bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num); + /** * Set index buffer for draw primitive. * @@ -4219,9 +4259,12 @@ BGFX_C_API void bgfx_submit_indirect_count(bgfx_view_id_t _id, bgfx_program_hand * @param[in] _stage Compute stage. * @param[in] _handle Index buffer handle. * @param[in] _access Buffer access. See `Access::Enum`. + * @param[in] _offset Byte offset the shader's view of the buffer starts at. + * Must be a multiple of 256 bytes. + * @param[in] _size Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. * */ -BGFX_C_API void bgfx_set_compute_index_buffer(uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access); +BGFX_C_API void bgfx_set_compute_index_buffer(uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size); /** * Set compute vertex buffer. @@ -4229,9 +4272,12 @@ BGFX_C_API void bgfx_set_compute_index_buffer(uint8_t _stage, bgfx_index_buffer_ * @param[in] _stage Compute stage. * @param[in] _handle Vertex buffer handle. * @param[in] _access Buffer access. See `Access::Enum`. + * @param[in] _offset Byte offset the shader's view of the buffer starts at. + * Must be a multiple of 256 bytes. + * @param[in] _size Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. * */ -BGFX_C_API void bgfx_set_compute_vertex_buffer(uint8_t _stage, bgfx_vertex_buffer_handle_t _handle, bgfx_access_t _access); +BGFX_C_API void bgfx_set_compute_vertex_buffer(uint8_t _stage, bgfx_vertex_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size); /** * Set compute dynamic index buffer. @@ -4239,9 +4285,12 @@ BGFX_C_API void bgfx_set_compute_vertex_buffer(uint8_t _stage, bgfx_vertex_buffe * @param[in] _stage Compute stage. * @param[in] _handle Dynamic index buffer handle. * @param[in] _access Buffer access. See `Access::Enum`. + * @param[in] _offset Byte offset the shader's view of the buffer starts at. + * Must be a multiple of 256 bytes. + * @param[in] _size Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. * */ -BGFX_C_API void bgfx_set_compute_dynamic_index_buffer(uint8_t _stage, bgfx_dynamic_index_buffer_handle_t _handle, bgfx_access_t _access); +BGFX_C_API void bgfx_set_compute_dynamic_index_buffer(uint8_t _stage, bgfx_dynamic_index_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size); /** * Set compute dynamic vertex buffer. @@ -4249,9 +4298,12 @@ BGFX_C_API void bgfx_set_compute_dynamic_index_buffer(uint8_t _stage, bgfx_dynam * @param[in] _stage Compute stage. * @param[in] _handle Dynamic vertex buffer handle. * @param[in] _access Buffer access. See `Access::Enum`. + * @param[in] _offset Byte offset the shader's view of the buffer starts at. + * Must be a multiple of 256 bytes. + * @param[in] _size Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. * */ -BGFX_C_API void bgfx_set_compute_dynamic_vertex_buffer(uint8_t _stage, bgfx_dynamic_vertex_buffer_handle_t _handle, bgfx_access_t _access); +BGFX_C_API void bgfx_set_compute_dynamic_vertex_buffer(uint8_t _stage, bgfx_dynamic_vertex_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size); /** * Set compute indirect buffer. @@ -4552,6 +4604,7 @@ typedef enum bgfx_function_id BGFX_FUNCTION_ID_ENCODER_SET_TRANSFORM_CACHED, BGFX_FUNCTION_ID_ENCODER_ALLOC_TRANSFORM, BGFX_FUNCTION_ID_ENCODER_SET_UNIFORM, + BGFX_FUNCTION_ID_ENCODER_SET_UNIFORM_REF, BGFX_FUNCTION_ID_SET_VIEW_UNIFORM, BGFX_FUNCTION_ID_SET_FRAME_UNIFORM, BGFX_FUNCTION_ID_ENCODER_SET_INDEX_BUFFER, @@ -4605,6 +4658,7 @@ typedef enum bgfx_function_id BGFX_FUNCTION_ID_SET_TRANSFORM_CACHED, BGFX_FUNCTION_ID_ALLOC_TRANSFORM, BGFX_FUNCTION_ID_SET_UNIFORM, + BGFX_FUNCTION_ID_SET_UNIFORM_REF, BGFX_FUNCTION_ID_SET_INDEX_BUFFER, BGFX_FUNCTION_ID_SET_DYNAMIC_INDEX_BUFFER, BGFX_FUNCTION_ID_SET_TRANSIENT_INDEX_BUFFER, @@ -4783,6 +4837,7 @@ struct bgfx_interface_vtbl void (*encoder_set_transform_cached)(bgfx_encoder_t* _this, uint32_t _cache, uint16_t _num); uint32_t (*encoder_alloc_transform)(bgfx_encoder_t* _this, bgfx_transform_t* _transform, uint16_t _num); void (*encoder_set_uniform)(bgfx_encoder_t* _this, bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num); + void (*encoder_set_uniform_ref)(bgfx_encoder_t* _this, bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num); void (*set_view_uniform)(bgfx_view_id_t _id, bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num); void (*set_frame_uniform)(bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num); void (*encoder_set_index_buffer)(bgfx_encoder_t* _this, bgfx_index_buffer_handle_t _handle, uint32_t _firstIndex, uint32_t _numIndices); @@ -4806,10 +4861,10 @@ struct bgfx_interface_vtbl void (*encoder_submit_occlusion_query)(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_occlusion_query_handle_t _occlusionQuery, uint32_t _depth, uint8_t _flags); void (*encoder_submit_indirect)(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, uint32_t _start, uint32_t _num, uint32_t _depth, uint8_t _flags); void (*encoder_submit_indirect_count)(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, uint32_t _start, bgfx_index_buffer_handle_t _numHandle, uint32_t _numIndex, uint32_t _numMax, uint32_t _depth, uint8_t _flags); - void (*encoder_set_compute_index_buffer)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access); - void (*encoder_set_compute_vertex_buffer)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_vertex_buffer_handle_t _handle, bgfx_access_t _access); - void (*encoder_set_compute_dynamic_index_buffer)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_dynamic_index_buffer_handle_t _handle, bgfx_access_t _access); - void (*encoder_set_compute_dynamic_vertex_buffer)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_dynamic_vertex_buffer_handle_t _handle, bgfx_access_t _access); + void (*encoder_set_compute_index_buffer)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size); + void (*encoder_set_compute_vertex_buffer)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_vertex_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size); + void (*encoder_set_compute_dynamic_index_buffer)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_dynamic_index_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size); + void (*encoder_set_compute_dynamic_vertex_buffer)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_dynamic_vertex_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size); void (*encoder_set_compute_indirect_buffer)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_indirect_buffer_handle_t _handle, bgfx_access_t _access); void (*encoder_set_image)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_texture_handle_t _handle, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format); void (*encoder_set_image_view)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_texture_handle_t _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format); @@ -4836,6 +4891,7 @@ struct bgfx_interface_vtbl void (*set_transform_cached)(uint32_t _cache, uint16_t _num); uint32_t (*alloc_transform)(bgfx_transform_t* _transform, uint16_t _num); void (*set_uniform)(bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num); + void (*set_uniform_ref)(bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num); void (*set_index_buffer)(bgfx_index_buffer_handle_t _handle, uint32_t _firstIndex, uint32_t _numIndices); void (*set_dynamic_index_buffer)(bgfx_dynamic_index_buffer_handle_t _handle, uint32_t _firstIndex, uint32_t _numIndices); void (*set_transient_index_buffer)(const bgfx_transient_index_buffer_t* _tib, uint32_t _firstIndex, uint32_t _numIndices); @@ -4857,10 +4913,10 @@ struct bgfx_interface_vtbl void (*submit_occlusion_query)(bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_occlusion_query_handle_t _occlusionQuery, uint32_t _depth, uint8_t _flags); void (*submit_indirect)(bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, uint32_t _start, uint32_t _num, uint32_t _depth, uint8_t _flags); void (*submit_indirect_count)(bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_indirect_buffer_handle_t _indirectHandle, uint32_t _start, bgfx_index_buffer_handle_t _numHandle, uint32_t _numIndex, uint32_t _numMax, uint32_t _depth, uint8_t _flags); - void (*set_compute_index_buffer)(uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access); - void (*set_compute_vertex_buffer)(uint8_t _stage, bgfx_vertex_buffer_handle_t _handle, bgfx_access_t _access); - void (*set_compute_dynamic_index_buffer)(uint8_t _stage, bgfx_dynamic_index_buffer_handle_t _handle, bgfx_access_t _access); - void (*set_compute_dynamic_vertex_buffer)(uint8_t _stage, bgfx_dynamic_vertex_buffer_handle_t _handle, bgfx_access_t _access); + void (*set_compute_index_buffer)(uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size); + void (*set_compute_vertex_buffer)(uint8_t _stage, bgfx_vertex_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size); + void (*set_compute_dynamic_index_buffer)(uint8_t _stage, bgfx_dynamic_index_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size); + void (*set_compute_dynamic_vertex_buffer)(uint8_t _stage, bgfx_dynamic_vertex_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size); void (*set_compute_indirect_buffer)(uint8_t _stage, bgfx_indirect_buffer_handle_t _handle, bgfx_access_t _access); void (*set_image)(uint8_t _stage, bgfx_texture_handle_t _handle, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format); void (*set_image_view)(uint8_t _stage, bgfx_texture_handle_t _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format); diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h index 16d7331e9..79204634c 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(160) +#define BGFX_API_VERSION UINT32_C(161) /** * Color RGB/alpha/depth write. When it's not specified write will be disabled. @@ -294,6 +294,14 @@ #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. +/// Texture may be sampled and rendered with either sRGB-ness, +/// not just the one implied by its format. Every bind and +/// attachment must then state the encoding it wants (see +/// `BGFX_SAMPLER_SRGB`, `BGFX_ATTACHMENT_SRGB`). Costs nothing +/// until used, but may disable texture compression on some +/// hardware. +#define BGFX_TEXTURE_SRGB_MUTABLE UINT64_C(0x0040000000000000) + /** * Do not use! Top nibble is reserved for internal texture flags (see bgfx_p.h). * @@ -368,6 +376,12 @@ #define BGFX_SAMPLER_NONE UINT32_C(0x00000000) #define BGFX_SAMPLER_SAMPLE_STENCIL UINT32_C(0x00100000) //!< Sample stencil instead of depth. + +/// Sample with sRGB conversion; absence of this flag samples +/// without it. Only affects textures created +/// `BGFX_TEXTURE_SRGB_MUTABLE`, which must state the encoding +/// explicitly on every bind; ignored for any other texture. +#define BGFX_SAMPLER_SRGB UINT32_C(0x00200000) #define BGFX_SAMPLER_POINT (0 \ | BGFX_SAMPLER_MIN_POINT \ | BGFX_SAMPLER_MAG_POINT \ @@ -546,6 +560,12 @@ #define BGFX_ATTACHMENT_READ_ONLY_DEPTH UINT8_C(0x02) #define BGFX_ATTACHMENT_READ_ONLY_STENCIL UINT8_C(0x04) //!< Bind the stencil aspect read-only. +/// Render with sRGB conversion; absence of this flag renders without +/// it. Only affects textures created `BGFX_TEXTURE_SRGB_MUTABLE`, +/// which must state the encoding explicitly on every attachment; +/// ignored for any other texture. +#define BGFX_ATTACHMENT_SRGB UINT8_C(0x08) + #define BGFX_PCI_ID_NONE UINT16_C(0x0000) //!< Autoselect adapter. #define BGFX_PCI_ID_SOFTWARE_RASTERIZER UINT16_C(0x0001) //!< Software rasterizer. #define BGFX_PCI_ID_AMD UINT16_C(0x1002) //!< AMD adapter. diff --git a/scripts/bgfx.idl b/scripts/bgfx.idl index a825d8c4b..4c06ae2f5 100644 --- a/scripts/bgfx.idl +++ b/scripts/bgfx.idl @@ -1,7 +1,7 @@ -- vim: syntax=lua -- bgfx interface -version(160) +version(161) typedef "bool" typedef "char" @@ -241,6 +241,12 @@ flag.Texture { bits = 64, section = "Textures" } .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. + .SrgbMutable (55) --- Texture may be sampled and rendered with either sRGB-ness, + --- not just the one implied by its format. Every bind and + --- attachment must then state the encoding it wants (see + --- `BGFX_SAMPLER_SRGB`, `BGFX_ATTACHMENT_SRGB`). Costs nothing + --- until used, but may disable texture compression on some + --- hardware. () --- Do not use! Top nibble is reserved for internal texture flags (see bgfx_p.h). @@ -306,6 +312,10 @@ flag.SamplerReserved { bits = 32, shift = 28, range = 4 } flag.Sampler { bits = 32 } .None .SampleStencil (21) --- Sample stencil instead of depth. + .Srgb (22) --- Sample with sRGB conversion; absence of this flag samples + --- without it. Only affects textures created + --- `BGFX_TEXTURE_SRGB_MUTABLE`, which must state the encoding + --- explicitly on every bind; ignored for any other texture. .Point { "MinPoint", "MagPoint", "MipPoint" } .UvwMirror { "UMirror", "VMirror", "WMirror" } .UvwClamp { "UClamp", "VClamp", "WClamp" } @@ -457,6 +467,10 @@ flag.Attachment { bits = 8 } .ReadOnlyDepth --- Bind the depth aspect read-only (read-only depth-stencil view) so the --- attachment can be sampled as a texture in the same pass. .ReadOnlyStencil --- Bind the stencil aspect read-only. + .Srgb --- Render with sRGB conversion; absence of this flag renders without + --- it. Only affects textures created `BGFX_TEXTURE_SRGB_MUTABLE`, + --- which must state the encoding explicitly on every attachment; + --- ignored for any other texture. () flag.PciId { bits = 16, const, section = "Initialization and Shutdown" } @@ -2790,6 +2804,18 @@ func.Encoder.setUniform { section = "Draw/Uniforms" } --- use the _num passed on uniform creation. { default = 1 } +--- Set shader uniform parameter by reference. Unlike `Encoder::setUniform`, the data +--- is not copied immediately; the renderer reads it from `_value` at frame render +--- time. The pointer must remain valid and unchanged until the frame is rendered +--- (up to two `bgfx::frame` calls with multithreaded submission). +func.Encoder.setUniformRef { section = "Draw/Uniforms" } + "void" + .handle "UniformHandle" --- Uniform. + .value "const void*" --- Pointer to uniform data. Must stay valid until the frame is rendered. + .num "uint16_t" --- Number of elements. Passing `UINT16_MAX` will + --- use the _num passed on uniform creation. + { default = "UINT16_MAX" } + --- Set shader uniform parameter for view. --- --- @attention Uniform must be created with `bgfx::UniformFreq::View` argument. @@ -3082,6 +3108,11 @@ func.Encoder.setBuffer { cname = "set_compute_index_buffer", section = "Compute/ .stage "uint8_t" --- Compute stage. .handle "IndexBufferHandle" --- Index buffer handle. .access "Access::Enum" --- Buffer access. See `Access::Enum`. + .offset "uint32_t" --- Byte offset the shader's view of the buffer starts at. + --- Must be a multiple of 256 bytes. + { default = 0 } + .size "uint32_t" --- Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. + { default = UINT32_MAX } --- Set compute vertex buffer. func.Encoder.setBuffer { cname = "set_compute_vertex_buffer", section = "Compute/Buffers" } @@ -3089,6 +3120,11 @@ func.Encoder.setBuffer { cname = "set_compute_vertex_buffer", section = "Compute .stage "uint8_t" --- Compute stage. .handle "VertexBufferHandle" --- Vertex buffer handle. .access "Access::Enum" --- Buffer access. See `Access::Enum`. + .offset "uint32_t" --- Byte offset the shader's view of the buffer starts at. + --- Must be a multiple of 256 bytes. + { default = 0 } + .size "uint32_t" --- Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. + { default = UINT32_MAX } --- Set compute dynamic index buffer. func.Encoder.setBuffer { cname = "set_compute_dynamic_index_buffer", section = "Compute/Buffers" } @@ -3096,6 +3132,11 @@ func.Encoder.setBuffer { cname = "set_compute_dynamic_index_buffer", section = " .stage "uint8_t" --- Compute stage. .handle "DynamicIndexBufferHandle" --- Dynamic index buffer handle. .access "Access::Enum" --- Buffer access. See `Access::Enum`. + .offset "uint32_t" --- Byte offset the shader's view of the buffer starts at. + --- Must be a multiple of 256 bytes. + { default = 0 } + .size "uint32_t" --- Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. + { default = UINT32_MAX } --- Set compute dynamic vertex buffer. func.Encoder.setBuffer { cname = "set_compute_dynamic_vertex_buffer", section = "Compute/Buffers" } @@ -3103,6 +3144,11 @@ func.Encoder.setBuffer { cname = "set_compute_dynamic_vertex_buffer", section = .stage "uint8_t" --- Compute stage. .handle "DynamicVertexBufferHandle" --- Dynamic vertex buffer handle. .access "Access::Enum" --- Buffer access. See `Access::Enum`. + .offset "uint32_t" --- Byte offset the shader's view of the buffer starts at. + --- Must be a multiple of 256 bytes. + { default = 0 } + .size "uint32_t" --- Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. + { default = UINT32_MAX } --- Set compute indirect buffer. func.Encoder.setBuffer { cname = "set_compute_indirect_buffer", section = "Compute/Buffers" } @@ -3447,6 +3493,18 @@ func.setUniform { section = "Draw/Uniforms" } --- use the _num passed on uniform creation. { default = 1 } +--- Set shader uniform parameter by reference. Unlike `bgfx::setUniform`, the data +--- is not copied immediately; the renderer reads it from `_value` at frame render +--- time. The pointer must remain valid and unchanged until the frame is rendered +--- (up to two `bgfx::frame` calls with multithreaded submission). +func.setUniformRef { section = "Draw/Uniforms" } + "void" + .handle "UniformHandle" --- Uniform. + .value "const void*" --- Pointer to uniform data. Must stay valid until the frame is rendered. + .num "uint16_t" --- Number of elements. Passing `UINT16_MAX` will + --- use the _num passed on uniform creation. + { default = "UINT16_MAX" } + --- Set index buffer for draw primitive. func.setIndexBuffer { cpponly, section = "Draw/Buffers" } "void" @@ -3713,6 +3771,11 @@ func.setBuffer { cname = "set_compute_index_buffer", section = "Compute/Buffers" .stage "uint8_t" --- Compute stage. .handle "IndexBufferHandle" --- Index buffer handle. .access "Access::Enum" --- Buffer access. See `Access::Enum`. + .offset "uint32_t" --- Byte offset the shader's view of the buffer starts at. + --- Must be a multiple of 256 bytes. + { default = 0 } + .size "uint32_t" --- Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. + { default = UINT32_MAX } --- Set compute vertex buffer. func.setBuffer { cname = "set_compute_vertex_buffer", section = "Compute/Buffers" } @@ -3720,6 +3783,11 @@ func.setBuffer { cname = "set_compute_vertex_buffer", section = "Compute/Buffers .stage "uint8_t" --- Compute stage. .handle "VertexBufferHandle" --- Vertex buffer handle. .access "Access::Enum" --- Buffer access. See `Access::Enum`. + .offset "uint32_t" --- Byte offset the shader's view of the buffer starts at. + --- Must be a multiple of 256 bytes. + { default = 0 } + .size "uint32_t" --- Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. + { default = UINT32_MAX } --- Set compute dynamic index buffer. func.setBuffer { cname = "set_compute_dynamic_index_buffer", section = "Compute/Buffers" } @@ -3727,6 +3795,11 @@ func.setBuffer { cname = "set_compute_dynamic_index_buffer", section = "Compute/ .stage "uint8_t" --- Compute stage. .handle "DynamicIndexBufferHandle" --- Dynamic index buffer handle. .access "Access::Enum" --- Buffer access. See `Access::Enum`. + .offset "uint32_t" --- Byte offset the shader's view of the buffer starts at. + --- Must be a multiple of 256 bytes. + { default = 0 } + .size "uint32_t" --- Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. + { default = UINT32_MAX } --- Set compute dynamic vertex buffer. func.setBuffer { cname = "set_compute_dynamic_vertex_buffer", section = "Compute/Buffers" } @@ -3734,6 +3807,11 @@ func.setBuffer { cname = "set_compute_dynamic_vertex_buffer", section = "Compute .stage "uint8_t" --- Compute stage. .handle "DynamicVertexBufferHandle" --- Dynamic vertex buffer handle. .access "Access::Enum" --- Buffer access. See `Access::Enum`. + .offset "uint32_t" --- Byte offset the shader's view of the buffer starts at. + --- Must be a multiple of 256 bytes. + { default = 0 } + .size "uint32_t" --- Bytes bound from the offset, `UINT32_MAX` for the rest of the buffer. + { default = UINT32_MAX } --- Set compute indirect buffer. func.setBuffer { cname = "set_compute_indirect_buffer", section = "Compute/Buffers" } diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 060e206ef..197820bbb 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -1899,6 +1899,13 @@ namespace bgfx write(_value, g_uniformTypeSize[_type]*_num); } + void UniformBuffer::writeUniformRef(UniformType::Enum _type, uint16_t _loc, const void* _ptr, uint16_t _num) + { + const uint32_t opcode = encodeOpcode(uint8_t(_type) | kUniformRefBit, _loc, _num, true); + write(opcode); + write(&_ptr, sizeof(_ptr) ); + } + void UniformBuffer::writeUniformHandle(uint8_t _type, uint16_t _loc, UniformHandle _handle, uint16_t _num) { const uint32_t opcode = encodeOpcode(_type, _loc, _num, false); @@ -3061,6 +3068,18 @@ namespace bgfx uint16_t copy; UniformBuffer::decodeOpcode(opcode, type, loc, num, copy); + if (type & kUniformRefBit) + { + type &= ~kUniformRefBit; + const void* ptr; + bx::memCopy(&ptr, _uniformBuffer->read(sizeof(ptr) ), sizeof(ptr) ); + if (UniformType::Count > type) + { + _renderCtx->updateUniform(loc, ptr, g_uniformTypeSize[type]*num); + } + continue; + } + const uint32_t size = g_uniformTypeSize[type]*num; const char* data = _uniformBuffer->read(size); @@ -4409,6 +4428,16 @@ namespace bgfx BGFX_ENCODER(setUniform(uniform.m_type, _handle, _value, UINT16_MAX != _num ? _num : uniform.m_num) ); } + void Encoder::setUniformRef(UniformHandle _handle, const void* _ptr, uint16_t _num) + { + BGFX_CHECK_HANDLE("setUniformRef", s_ctx->m_uniformHandle, _handle); + const UniformRef& uniform = s_ctx->m_uniformRef[_handle.idx]; + BX_ASSERT(uniform.m_freq == UniformFreq::Draw, "Setting uniform per draw call, but uniform is created with different bgfx::UniformFreq::Enum!"); + BX_ASSERT(isValid(_handle) && 0 < uniform.m_refCount, "Setting invalid uniform (handle %3d)!", _handle.idx); + BX_ASSERT(_num == UINT16_MAX || uniform.m_num >= _num, "Truncated uniform update. %d (max: %d)", _num, uniform.m_num); + BGFX_ENCODER(setUniformRef(uniform.m_type, _handle, _ptr, UINT16_MAX != _num ? _num : uniform.m_num) ); + } + void Encoder::setIndexBuffer(IndexBufferHandle _handle) { setIndexBuffer(_handle, 0, UINT32_MAX); @@ -4625,34 +4654,38 @@ namespace bgfx BGFX_ENCODER(submit(_id, _program, _indirectHandle, _start, _numHandle, _numIndex, _numMax, _depth, _flags) ); } - void Encoder::setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access) + void Encoder::setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access, uint32_t _offset, uint32_t _size) { BX_ASSERT(_stage < g_caps.limits.maxComputeBindings, "Invalid stage %d (max %d).", _stage, g_caps.limits.maxComputeBindings); BGFX_CHECK_HANDLE("setBuffer", s_ctx->m_indexBufferHandle, _handle); - BGFX_ENCODER(setBuffer(_stage, _handle, _access) ); + BX_ASSERT(0 == _offset % kBufferBindingOffsetAlign, "Buffer binding offset %d is not a multiple of %d bytes.", _offset, kBufferBindingOffsetAlign); + BGFX_ENCODER(setBuffer(_stage, _handle, _access, _offset, _size) ); } - void Encoder::setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access) + void Encoder::setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access, uint32_t _offset, uint32_t _size) { BX_ASSERT(_stage < g_caps.limits.maxComputeBindings, "Invalid stage %d (max %d).", _stage, g_caps.limits.maxComputeBindings); BGFX_CHECK_HANDLE("setBuffer", s_ctx->m_vertexBufferHandle, _handle); - BGFX_ENCODER(setBuffer(_stage, _handle, _access) ); + BX_ASSERT(0 == _offset % kBufferBindingOffsetAlign, "Buffer binding offset %d is not a multiple of %d bytes.", _offset, kBufferBindingOffsetAlign); + BGFX_ENCODER(setBuffer(_stage, _handle, _access, _offset, _size) ); } - void Encoder::setBuffer(uint8_t _stage, DynamicIndexBufferHandle _handle, Access::Enum _access) + void Encoder::setBuffer(uint8_t _stage, DynamicIndexBufferHandle _handle, Access::Enum _access, uint32_t _offset, uint32_t _size) { BX_ASSERT(_stage < g_caps.limits.maxComputeBindings, "Invalid stage %d (max %d).", _stage, g_caps.limits.maxComputeBindings); BGFX_CHECK_HANDLE("setBuffer", s_ctx->m_dynamicIndexBufferHandle, _handle); + BX_ASSERT(0 == _offset % kBufferBindingOffsetAlign, "Buffer binding offset %d is not a multiple of %d bytes.", _offset, kBufferBindingOffsetAlign); const DynamicIndexBuffer& dib = s_ctx->m_dynamicIndexBuffers[_handle.idx]; - BGFX_ENCODER(setBuffer(_stage, dib.m_handle, _access) ); + BGFX_ENCODER(setBuffer(_stage, dib.m_handle, _access, _offset, _size) ); } - void Encoder::setBuffer(uint8_t _stage, DynamicVertexBufferHandle _handle, Access::Enum _access) + void Encoder::setBuffer(uint8_t _stage, DynamicVertexBufferHandle _handle, Access::Enum _access, uint32_t _offset, uint32_t _size) { BX_ASSERT(_stage < g_caps.limits.maxComputeBindings, "Invalid stage %d (max %d).", _stage, g_caps.limits.maxComputeBindings); BGFX_CHECK_HANDLE("setBuffer", s_ctx->m_dynamicVertexBufferHandle, _handle); + BX_ASSERT(0 == _offset % kBufferBindingOffsetAlign, "Buffer binding offset %d is not a multiple of %d bytes.", _offset, kBufferBindingOffsetAlign); const DynamicVertexBuffer& dvb = s_ctx->m_dynamicVertexBuffers[_handle.idx]; - BGFX_ENCODER(setBuffer(_stage, dvb.m_handle, _access) ); + BGFX_ENCODER(setBuffer(_stage, dvb.m_handle, _access, _offset, _size) ); } void Encoder::setBuffer(uint8_t _stage, IndirectBufferHandle _handle, Access::Enum _access) @@ -6767,6 +6800,12 @@ namespace bgfx s_ctx->m_encoder0->setUniform(_handle, _value, _num); } + void setUniformRef(UniformHandle _handle, const void* _ptr, uint16_t _num) + { + BGFX_CHECK_ENCODER0(); + s_ctx->m_encoder0->setUniformRef(_handle, _ptr, _num); + } + void setViewUniform(ViewId _id, UniformHandle _handle, const void* _value, uint16_t _num) { BX_ASSERT(checkView(_id), "Invalid view id: %d", _id); @@ -6948,28 +6987,28 @@ namespace bgfx s_ctx->m_encoder0->submit(_id, _program, _indirectHandle, _start, _numHandle, _numIndex, _numMax, _depth, _flags); } - void setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access) + void setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access, uint32_t _offset, uint32_t _size) { BGFX_CHECK_ENCODER0(); - s_ctx->m_encoder0->setBuffer(_stage, _handle, _access); + s_ctx->m_encoder0->setBuffer(_stage, _handle, _access, _offset, _size); } - void setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access) + void setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access, uint32_t _offset, uint32_t _size) { BGFX_CHECK_ENCODER0(); - s_ctx->m_encoder0->setBuffer(_stage, _handle, _access); + s_ctx->m_encoder0->setBuffer(_stage, _handle, _access, _offset, _size); } - void setBuffer(uint8_t _stage, DynamicIndexBufferHandle _handle, Access::Enum _access) + void setBuffer(uint8_t _stage, DynamicIndexBufferHandle _handle, Access::Enum _access, uint32_t _offset, uint32_t _size) { BGFX_CHECK_ENCODER0(); - s_ctx->m_encoder0->setBuffer(_stage, _handle, _access); + s_ctx->m_encoder0->setBuffer(_stage, _handle, _access, _offset, _size); } - void setBuffer(uint8_t _stage, DynamicVertexBufferHandle _handle, Access::Enum _access) + void setBuffer(uint8_t _stage, DynamicVertexBufferHandle _handle, Access::Enum _access, uint32_t _offset, uint32_t _size) { BGFX_CHECK_ENCODER0(); - s_ctx->m_encoder0->setBuffer(_stage, _handle, _access); + s_ctx->m_encoder0->setBuffer(_stage, _handle, _access, _offset, _size); } void setBuffer(uint8_t _stage, IndirectBufferHandle _handle, Access::Enum _access) diff --git a/src/bgfx.idl.inl b/src/bgfx.idl.inl index 33ae0bc9e..30bc021e5 100644 --- a/src/bgfx.idl.inl +++ b/src/bgfx.idl.inl @@ -859,6 +859,13 @@ BGFX_C_API void bgfx_encoder_set_uniform(bgfx_encoder_t* _this, bgfx_uniform_han This->setUniform(handle.cpp, _value, _num); } +BGFX_C_API void bgfx_encoder_set_uniform_ref(bgfx_encoder_t* _this, bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num) +{ + bgfx::Encoder* This = (bgfx::Encoder*)_this; + union { bgfx_uniform_handle_t c; bgfx::UniformHandle cpp; } handle = { _handle }; + This->setUniformRef(handle.cpp, _value, _num); +} + BGFX_C_API void bgfx_set_view_uniform(bgfx_view_id_t _id, bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num) { union { bgfx_uniform_handle_t c; bgfx::UniformHandle cpp; } handle = { _handle }; @@ -1020,32 +1027,32 @@ BGFX_C_API void bgfx_encoder_submit_indirect_count(bgfx_encoder_t* _this, bgfx_v This->submit((bgfx::ViewId)_id, program.cpp, indirectHandle.cpp, _start, numHandle.cpp, _numIndex, _numMax, _depth, _flags); } -BGFX_C_API void bgfx_encoder_set_compute_index_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access) +BGFX_C_API void bgfx_encoder_set_compute_index_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size) { bgfx::Encoder* This = (bgfx::Encoder*)_this; union { bgfx_index_buffer_handle_t c; bgfx::IndexBufferHandle cpp; } handle = { _handle }; - This->setBuffer(_stage, handle.cpp, (bgfx::Access::Enum)_access); + This->setBuffer(_stage, handle.cpp, (bgfx::Access::Enum)_access, _offset, _size); } -BGFX_C_API void bgfx_encoder_set_compute_vertex_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_vertex_buffer_handle_t _handle, bgfx_access_t _access) +BGFX_C_API void bgfx_encoder_set_compute_vertex_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_vertex_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size) { bgfx::Encoder* This = (bgfx::Encoder*)_this; union { bgfx_vertex_buffer_handle_t c; bgfx::VertexBufferHandle cpp; } handle = { _handle }; - This->setBuffer(_stage, handle.cpp, (bgfx::Access::Enum)_access); + This->setBuffer(_stage, handle.cpp, (bgfx::Access::Enum)_access, _offset, _size); } -BGFX_C_API void bgfx_encoder_set_compute_dynamic_index_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_dynamic_index_buffer_handle_t _handle, bgfx_access_t _access) +BGFX_C_API void bgfx_encoder_set_compute_dynamic_index_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_dynamic_index_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size) { bgfx::Encoder* This = (bgfx::Encoder*)_this; union { bgfx_dynamic_index_buffer_handle_t c; bgfx::DynamicIndexBufferHandle cpp; } handle = { _handle }; - This->setBuffer(_stage, handle.cpp, (bgfx::Access::Enum)_access); + This->setBuffer(_stage, handle.cpp, (bgfx::Access::Enum)_access, _offset, _size); } -BGFX_C_API void bgfx_encoder_set_compute_dynamic_vertex_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_dynamic_vertex_buffer_handle_t _handle, bgfx_access_t _access) +BGFX_C_API void bgfx_encoder_set_compute_dynamic_vertex_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_dynamic_vertex_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size) { bgfx::Encoder* This = (bgfx::Encoder*)_this; union { bgfx_dynamic_vertex_buffer_handle_t c; bgfx::DynamicVertexBufferHandle cpp; } handle = { _handle }; - This->setBuffer(_stage, handle.cpp, (bgfx::Access::Enum)_access); + This->setBuffer(_stage, handle.cpp, (bgfx::Access::Enum)_access, _offset, _size); } BGFX_C_API void bgfx_encoder_set_compute_indirect_buffer(bgfx_encoder_t* _this, uint8_t _stage, bgfx_indirect_buffer_handle_t _handle, bgfx_access_t _access) @@ -1205,6 +1212,12 @@ BGFX_C_API void bgfx_set_uniform(bgfx_uniform_handle_t _handle, const void* _val bgfx::setUniform(handle.cpp, _value, _num); } +BGFX_C_API void bgfx_set_uniform_ref(bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num) +{ + union { bgfx_uniform_handle_t c; bgfx::UniformHandle cpp; } handle = { _handle }; + bgfx::setUniformRef(handle.cpp, _value, _num); +} + BGFX_C_API void bgfx_set_index_buffer(bgfx_index_buffer_handle_t _handle, uint32_t _firstIndex, uint32_t _numIndices) { union { bgfx_index_buffer_handle_t c; bgfx::IndexBufferHandle cpp; } handle = { _handle }; @@ -1333,28 +1346,28 @@ BGFX_C_API void bgfx_submit_indirect_count(bgfx_view_id_t _id, bgfx_program_hand bgfx::submit((bgfx::ViewId)_id, program.cpp, indirectHandle.cpp, _start, numHandle.cpp, _numIndex, _numMax, _depth, _flags); } -BGFX_C_API void bgfx_set_compute_index_buffer(uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access) +BGFX_C_API void bgfx_set_compute_index_buffer(uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size) { union { bgfx_index_buffer_handle_t c; bgfx::IndexBufferHandle cpp; } handle = { _handle }; - bgfx::setBuffer(_stage, handle.cpp, (bgfx::Access::Enum)_access); + bgfx::setBuffer(_stage, handle.cpp, (bgfx::Access::Enum)_access, _offset, _size); } -BGFX_C_API void bgfx_set_compute_vertex_buffer(uint8_t _stage, bgfx_vertex_buffer_handle_t _handle, bgfx_access_t _access) +BGFX_C_API void bgfx_set_compute_vertex_buffer(uint8_t _stage, bgfx_vertex_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size) { union { bgfx_vertex_buffer_handle_t c; bgfx::VertexBufferHandle cpp; } handle = { _handle }; - bgfx::setBuffer(_stage, handle.cpp, (bgfx::Access::Enum)_access); + bgfx::setBuffer(_stage, handle.cpp, (bgfx::Access::Enum)_access, _offset, _size); } -BGFX_C_API void bgfx_set_compute_dynamic_index_buffer(uint8_t _stage, bgfx_dynamic_index_buffer_handle_t _handle, bgfx_access_t _access) +BGFX_C_API void bgfx_set_compute_dynamic_index_buffer(uint8_t _stage, bgfx_dynamic_index_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size) { union { bgfx_dynamic_index_buffer_handle_t c; bgfx::DynamicIndexBufferHandle cpp; } handle = { _handle }; - bgfx::setBuffer(_stage, handle.cpp, (bgfx::Access::Enum)_access); + bgfx::setBuffer(_stage, handle.cpp, (bgfx::Access::Enum)_access, _offset, _size); } -BGFX_C_API void bgfx_set_compute_dynamic_vertex_buffer(uint8_t _stage, bgfx_dynamic_vertex_buffer_handle_t _handle, bgfx_access_t _access) +BGFX_C_API void bgfx_set_compute_dynamic_vertex_buffer(uint8_t _stage, bgfx_dynamic_vertex_buffer_handle_t _handle, bgfx_access_t _access, uint32_t _offset, uint32_t _size) { union { bgfx_dynamic_vertex_buffer_handle_t c; bgfx::DynamicVertexBufferHandle cpp; } handle = { _handle }; - bgfx::setBuffer(_stage, handle.cpp, (bgfx::Access::Enum)_access); + bgfx::setBuffer(_stage, handle.cpp, (bgfx::Access::Enum)_access, _offset, _size); } BGFX_C_API void bgfx_set_compute_indirect_buffer(uint8_t _stage, bgfx_indirect_buffer_handle_t _handle, bgfx_access_t _access) @@ -1596,6 +1609,7 @@ BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version) bgfx_encoder_set_transform_cached, bgfx_encoder_alloc_transform, bgfx_encoder_set_uniform, + bgfx_encoder_set_uniform_ref, bgfx_set_view_uniform, bgfx_set_frame_uniform, bgfx_encoder_set_index_buffer, @@ -1649,6 +1663,7 @@ BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version) bgfx_set_transform_cached, bgfx_alloc_transform, bgfx_set_uniform, + bgfx_set_uniform_ref, bgfx_set_index_buffer, bgfx_set_dynamic_index_buffer, bgfx_set_transient_index_buffer, diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 2d6515872..f0ae31a79 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -2148,10 +2148,11 @@ namespace bgfx static constexpr uint8_t kConstantOpcodeCopyShift = 0; static constexpr uint32_t kConstantOpcodeCopyMask = UINT32_C(0x00000001); - static constexpr uint8_t kUniformFragmentBit = 0x10; - static constexpr uint8_t kUniformSamplerBit = 0x20; - static constexpr uint8_t kUniformReadOnlyBit = 0x40; - static constexpr uint8_t kUniformCompareBit = 0x80; + static constexpr uint8_t kUniformRefBit = 0x08; + static constexpr uint8_t kUniformFragmentBit = 0x10; + static constexpr uint8_t kUniformSamplerBit = 0x20; + static constexpr uint8_t kUniformReadOnlyBit = 0x40; + static constexpr uint8_t kUniformCompareBit = 0x80; static constexpr uint8_t kUniformMask = 0 | kUniformFragmentBit | kUniformSamplerBit @@ -2294,6 +2295,7 @@ namespace bgfx } void writeUniform(UniformType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num = 1); + void writeUniformRef(UniformType::Enum _type, uint16_t _loc, const void* _ptr, uint16_t _num = 1); void writeUniformHandle(uint8_t _type, uint16_t _loc, UniformHandle _handle, uint16_t _num = 1); void writeMarker(const bx::StringView& _name); @@ -2380,6 +2382,8 @@ namespace bgfx UniformRegInfo m_info[BGFX_CONFIG_MAX_UNIFORMS]; }; + static constexpr uint32_t kBufferBindingOffsetAlign = 256; + struct Binding { enum Enum @@ -2398,6 +2402,7 @@ namespace bgfx // compares deterministically when used as a bind-state key. bx::memSet(this, 0, sizeof(*this) ); m_samplerFlags = BGFX_SAMPLER_NONE; + m_size = UINT32_MAX; m_numLayers = UINT16_MAX; m_idx = kInvalidHandle; m_numMips = UINT8_MAX; @@ -2406,6 +2411,8 @@ namespace bgfx void setTexture(TextureHandle _handle, uint32_t _samplerFlags, uint8_t _firstMip = 0, uint8_t _numMips = UINT8_MAX) { m_samplerFlags = _samplerFlags; + m_offset = 0; + m_size = UINT32_MAX; m_firstLayer = 0; m_numLayers = UINT16_MAX; m_idx = _handle.idx; @@ -2420,6 +2427,8 @@ namespace bgfx void setTexture(TextureHandle _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, uint32_t _samplerFlags) { m_samplerFlags = _samplerFlags; + m_offset = 0; + m_size = UINT32_MAX; m_firstLayer = _firstLayer; m_numLayers = _numLayers; m_idx = _handle.idx; @@ -2431,9 +2440,11 @@ namespace bgfx m_pad = 0; } - void setIndexBuffer(IndexBufferHandle _handle, Access::Enum _access) + void setIndexBuffer(IndexBufferHandle _handle, Access::Enum _access, uint32_t _offset = 0, uint32_t _size = UINT32_MAX) { m_samplerFlags = BGFX_SAMPLER_NONE; + m_offset = _offset; + m_size = _size; m_firstLayer = 0; m_numLayers = UINT16_MAX; m_idx = _handle.idx; @@ -2445,9 +2456,11 @@ namespace bgfx m_pad = 0; } - void setBuffer(VertexBufferHandle _handle, Access::Enum _access) + void setBuffer(VertexBufferHandle _handle, Access::Enum _access, uint32_t _offset = 0, uint32_t _size = UINT32_MAX) { m_samplerFlags = BGFX_SAMPLER_NONE; + m_offset = _offset; + m_size = _size; m_firstLayer = 0; m_numLayers = UINT16_MAX; m_idx = _handle.idx; @@ -2467,6 +2480,8 @@ namespace bgfx void setImage(TextureHandle _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format) { m_samplerFlags = BGFX_SAMPLER_NONE; + m_offset = 0; + m_size = UINT32_MAX; m_firstLayer = _firstLayer; m_numLayers = _numLayers; m_idx = _handle.idx; @@ -2484,6 +2499,8 @@ namespace bgfx } uint32_t m_samplerFlags; + uint32_t m_offset; + uint32_t m_size; uint16_t m_firstLayer; uint16_t m_numLayers; uint16_t m_idx; @@ -2494,7 +2511,7 @@ namespace bgfx uint8_t m_numMips; uint8_t m_pad; }; - static_assert(16 == sizeof(Binding), "Binding size changed. Whole struct must be properly initialized for hashing and comparing!"); + static_assert(24 == sizeof(Binding), "Binding size changed. Whole struct must be properly initialized for hashing and comparing!"); static_assert(bx::hasUniqueObjectRepresentation() , "Binding is hashed and compared as bytes, so it must not have padding. Add an explicit member to fill the hole." ); @@ -4013,6 +4030,23 @@ namespace bgfx uniformBuffer->writeUniform(_type, _handle.idx, _value, _num); } + void setUniformRef(UniformType::Enum _type, UniformHandle _handle, const void* _ptr, uint16_t _num) + { + if (BX_ENABLED(BGFX_CONFIG_DEBUG_UNIFORM) ) + { + BX_ASSERT(m_uniformSet.end() == m_uniformSet.find(_handle.idx) + , "Uniform %d (%s) was already set for this draw call." + , _handle.idx + , getName(_handle) + ); + m_uniformSet.insert(_handle.idx); + } + + UniformBuffer::update(&m_frame->m_uniformBuffer[m_uniformIdx]); + UniformBuffer* uniformBuffer = m_frame->m_uniformBuffer[m_uniformIdx]; + uniformBuffer->writeUniformRef(_type, _handle.idx, _ptr, _num); + } + void setState(uint64_t _state, uint32_t _rgba) { const uint8_t blend = ( (_state&BGFX_STATE_BLEND_MASK )>>BGFX_STATE_BLEND_SHIFT )&0xff; @@ -4288,17 +4322,17 @@ namespace bgfx } } - void setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access) + void setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access, uint32_t _offset = 0, uint32_t _size = UINT32_MAX) { Binding bind; - bind.setIndexBuffer(_handle, _access); + bind.setIndexBuffer(_handle, _access, _offset, _size); setBind(_stage, bind); } - void setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access) + void setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access, uint32_t _offset = 0, uint32_t _size = UINT32_MAX) { Binding bind; - bind.setBuffer(_handle, _access); + bind.setBuffer(_handle, _access, _offset, _size); setBind(_stage, bind); } diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index eec2bfa8d..254fa584e 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -343,6 +343,55 @@ namespace bgfx { namespace d3d11 }; static_assert(Attrib::Count == BX_COUNTOF(s_attrib) ); + struct SrgbFormatGroup + { + DXGI_FORMAT m_typeless; + DXGI_FORMAT m_linear; + DXGI_FORMAT m_srgb; + }; + + static const SrgbFormatGroup s_srgbFormatGroup[] = + { + { DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB }, + { DXGI_FORMAT_B8G8R8A8_TYPELESS, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB }, + { DXGI_FORMAT_BC1_TYPELESS, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM_SRGB }, + { DXGI_FORMAT_BC2_TYPELESS, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM_SRGB }, + { DXGI_FORMAT_BC3_TYPELESS, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM_SRGB }, + { DXGI_FORMAT_BC7_TYPELESS, DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_UNORM_SRGB }, + }; + + static const SrgbFormatGroup* findSrgbFormatGroup(DXGI_FORMAT _format) + { + for (uint32_t ii = 0; ii < BX_COUNTOF(s_srgbFormatGroup); ++ii) + { + const SrgbFormatGroup& sa = s_srgbFormatGroup[ii]; + if (_format == sa.m_linear + || _format == sa.m_srgb) + { + return &sa; + } + } + + return NULL; + } + + static DXGI_FORMAT srgbFormat(DXGI_FORMAT _format, bool _srgb) + { + const SrgbFormatGroup* group = findSrgbFormatGroup(_format); + return NULL == group + ? _format + : (_srgb ? group->m_srgb : group->m_linear) + ; + } + + static SrgbSelect::Enum srgbSelect(uint32_t _flags, uint32_t _bit) + { + return 0 != (_flags & _bit) + ? SrgbSelect::Srgb + : SrgbSelect::Linear + ; + } + static const DXGI_FORMAT s_attribType[][4][2] = { { // Int8 @@ -1762,6 +1811,7 @@ namespace bgfx { namespace d3d11 void destroyIndexBuffer(IndexBufferHandle _handle) override { + m_srvUavLru.invalidateWithParent(bufferViewParent(_handle.idx, false) ); m_indexBuffers[_handle.idx].destroy(); } @@ -1783,6 +1833,7 @@ namespace bgfx { namespace d3d11 void destroyVertexBuffer(VertexBufferHandle _handle) override { + m_srvUavLru.invalidateWithParent(bufferViewParent(_handle.idx, true) ); m_vertexBuffers[_handle.idx].destroy(); } @@ -1798,6 +1849,7 @@ namespace bgfx { namespace d3d11 void destroyDynamicIndexBuffer(IndexBufferHandle _handle) override { + m_srvUavLru.invalidateWithParent(bufferViewParent(_handle.idx, false) ); m_indexBuffers[_handle.idx].destroy(); } @@ -1814,6 +1866,7 @@ namespace bgfx { namespace d3d11 void destroyDynamicVertexBuffer(VertexBufferHandle _handle) override { + m_srvUavLru.invalidateWithParent(bufferViewParent(_handle.idx, true) ); m_vertexBuffers[_handle.idx].destroy(); } @@ -2636,6 +2689,26 @@ namespace bgfx { namespace d3d11 } } + bool findPendingResolve(TextureHandle _handle, uint8_t& _flags) const + { + if (isValid(m_fbh) + && m_rtMsaa) + { + const FrameBufferD3D11& frameBuffer = m_frameBuffers[m_fbh.idx]; + + for (uint32_t ii = 0; ii < frameBuffer.m_numTh; ++ii) + { + if (frameBuffer.m_attachment[ii].handle.idx == _handle.idx) + { + _flags = frameBuffer.m_attachment[ii].flags; + return true; + } + } + } + + return false; + } + FrameBufferD3D11& getFrameBuffer(FrameBufferHandle _fbh) { return m_frameBuffers[isValid(_fbh) ? _fbh.idx : kMainFrameBufferIdx]; @@ -3076,7 +3149,7 @@ namespace bgfx { namespace d3d11 DX_CHECK(m_device->CreateRasterizerState(&desc, &rs) ); } - m_rasterizerStateCache.add(_state, rs); + m_rasterizerStateCache.add(key, rs); } m_deviceCtx->RSSetState(rs); @@ -3231,6 +3304,112 @@ namespace bgfx { namespace d3d11 commitTextureStage(); } + static uint16_t bufferViewParent(uint16_t _idx, bool _vertex) + { + BX_ASSERT(_idx < 0x4000, "Buffer handle %d does not fit the view cache's parent tag.", _idx); + return uint16_t( (_vertex ? 0x8000 : 0x4000) | _idx); + } + + static void bufferViewFields(D3D11_SHADER_RESOURCE_VIEW_DESC& _desc, UINT*& _first, UINT*& _num) + { + const bool ex = D3D11_SRV_DIMENSION_BUFFEREX == _desc.ViewDimension; + _first = ex ? &_desc.BufferEx.FirstElement : &_desc.Buffer.FirstElement; + _num = ex ? &_desc.BufferEx.NumElements : &_desc.Buffer.NumElements; + } + + static void bufferViewFields(D3D11_UNORDERED_ACCESS_VIEW_DESC& _desc, UINT*& _first, UINT*& _num) + { + _first = &_desc.Buffer.FirstElement; + _num = &_desc.Buffer.NumElements; + } + + template + ViewT* getCachedBufferView(ViewT* _whole, const BufferD3D11& _buffer, uint16_t _parent, bool _srv, uint32_t _offset, uint32_t _size) + { + if (NULL == _whole + || (0 == _offset && UINT32_MAX == _size) ) + { + return _whole; + } + + DescT desc; + _whole->GetDesc(&desc); + + UINT* firstPtr = NULL; + UINT* numPtr = NULL; + bufferViewFields(desc, firstPtr, numPtr); + UINT& first = *firstPtr; + UINT& num = *numPtr; + + const UINT wholeFirst = first; + const UINT wholeNum = num; + + const uint32_t stride = bx::max(1, _buffer.m_size / bx::max(1, wholeNum) ); + const uint32_t offset = bx::min(_offset, _buffer.m_size); + const uint32_t range = UINT32_MAX == _size + ? _buffer.m_size - offset + : bx::min(_size, _buffer.m_size - offset) + ; + + const uint32_t newFirst = offset / stride; + const uint32_t newNum = range / stride; + + if (0 == newNum + || (newFirst == wholeFirst && newNum == wholeNum) ) + { + return _whole; + } + + first = newFirst; + num = newNum; + + bx::HashMurmur2A murmur; + murmur.begin(); + murmur.add(_parent); + murmur.add(_srv ? 1u : 0u); + murmur.add(uint32_t(first) ); + murmur.add(uint32_t(num) ); + const uint32_t hash = murmur.end(); + + IUnknown** ptr = m_srvUavLru.find(hash); + if (NULL != ptr) + { + return static_cast(*ptr); + } + + ViewT* view = NULL; + createBufferView(_buffer.m_ptr, desc, &view); + if (NULL == view) + { + return _whole; + } + + m_srvUavLru.add(hash, view, _parent); + return view; + } + + void createBufferView(ID3D11Buffer* _ptr, const D3D11_SHADER_RESOURCE_VIEW_DESC& _desc, ID3D11ShaderResourceView** _out) + { + DX_CHECK(m_device->CreateShaderResourceView(_ptr, &_desc, _out) ); + } + + void createBufferView(ID3D11Buffer* _ptr, const D3D11_UNORDERED_ACCESS_VIEW_DESC& _desc, ID3D11UnorderedAccessView** _out) + { + DX_CHECK(m_device->CreateUnorderedAccessView(_ptr, &_desc, _out) ); + } + + ID3D11ShaderResourceView* getCachedBufferSrv(const BufferD3D11& _buffer, uint16_t _parent, bool _raw, uint32_t _offset, uint32_t _size) + { + return getCachedBufferView( + _raw ? _buffer.m_srvRaw : _buffer.m_srv, _buffer, _parent, true, _offset, _size); + } + + ID3D11UnorderedAccessView* getCachedBufferUav(const BufferD3D11& _buffer, uint16_t _parent, bool _raw, uint32_t _offset, uint32_t _size) + { + return getCachedBufferView( + _raw ? _buffer.m_uavRaw : _buffer.m_uav, _buffer, _parent, false, _offset, _size); + } + ID3D11UnorderedAccessView* getCachedUav(TextureHandle _handle, uint8_t _mip, uint16_t _firstLayer = 0, uint16_t _numLayers = UINT16_MAX) { const bool arrayed = UINT16_MAX != _numLayers; @@ -3250,7 +3429,7 @@ namespace bgfx { namespace d3d11 TextureD3D11& texture = m_textures[_handle.idx]; D3D11_UNORDERED_ACCESS_VIEW_DESC desc; - desc.Format = texture.getSrvFormat(); + desc.Format = texture.getUavFormat(); switch (texture.m_type) { case TextureD3D11::Texture2D: @@ -3302,7 +3481,7 @@ namespace bgfx { namespace d3d11 return uav; } - ID3D11ShaderResourceView* getCachedSrv(TextureHandle _handle, uint8_t _firstMip, uint8_t _numMips = 1, uint16_t _firstLayer = 0, uint16_t _numLayers = UINT16_MAX, bool _compute = false, bool _stencil = false, bool _asArray = false) + ID3D11ShaderResourceView* getCachedSrv(TextureHandle _handle, uint8_t _firstMip, uint8_t _numMips = 1, uint16_t _firstLayer = 0, uint16_t _numLayers = UINT16_MAX, bool _compute = false, bool _stencil = false, bool _asArray = false, SrgbSelect::Enum _srgb = SrgbSelect::Native) { const TextureD3D11& texture = m_textures[_handle.idx]; @@ -3319,6 +3498,7 @@ namespace bgfx { namespace d3d11 murmur.add(_asArray); murmur.add(_compute); murmur.add(_stencil); + murmur.add(_srgb); uint32_t hash = murmur.end(); IUnknown** ptr = m_srvUavLru.find(hash); @@ -3331,7 +3511,7 @@ namespace bgfx { namespace d3d11 D3D11_SHADER_RESOURCE_VIEW_DESC desc; desc.Format = !_stencil - ? texture.getSrvFormat() + ? texture.getSrvFormat(_srgb) : (DXGI_FORMAT_R32G8X24_TYPELESS == s_textureFormat[texture.m_textureFormat].m_fmt ? DXGI_FORMAT_X32_TYPELESS_G8X24_UINT : DXGI_FORMAT_X24_TYPELESS_G8_UINT) @@ -4779,6 +4959,31 @@ namespace bgfx { namespace d3d11 srvd.Format = getSrvFormat(); } + if (0 != (m_flags & BGFX_TEXTURE_SRGB_MUTABLE) ) + { + const SrgbFormatGroup* group = findSrgbFormatGroup(format); + if (NULL != group) + { + format = group->m_typeless; + } + else + { + BX_WARN(false, "BGFX_TEXTURE_SRGB_MUTABLE is not supported for texture format %d", m_textureFormat); + m_flags &= ~BGFX_TEXTURE_SRGB_MUTABLE; + } + } + + if (srgb + && (computeWrite || blitUav) + && 0 == (m_flags & BGFX_TEXTURE_SRGB_MUTABLE) ) + { + const SrgbFormatGroup* group = findSrgbFormatGroup(format); + if (NULL != group) + { + format = group->m_typeless; + } + } + const bool external = 0 != _external; const bool directAccess = s_renderD3D11->m_directAccessSupport && !renderTarget @@ -5019,7 +5224,7 @@ namespace bgfx { namespace d3d11 if (computeWrite) { D3D11_UNORDERED_ACCESS_VIEW_DESC uavd; - uavd.Format = getSrvFormat(); + uavd.Format = getUavFormat(); switch (m_type) { case TextureCube: @@ -5162,6 +5367,7 @@ namespace bgfx { namespace d3d11 const uint32_t subres = _mip + ( (layer + _side) * m_numMips); const bool depth = bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ); uint32_t rectPitch = _rect.m_width*bpp/8; + uint32_t srcRows = _rect.m_height; if (bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat) ) ) { const uint32_t blockW = blockInfo.blockWidth; @@ -5171,10 +5377,11 @@ namespace bgfx { namespace d3d11 box.right = box.left + alignedW; box.bottom = box.top + alignedH; rectPitch = (alignedW / blockW) * blockInfo.blockSize; + srcRows = alignedH / blockH; } const uint32_t srcPitch = UINT16_MAX == _pitch ? rectPitch : _pitch; - const uint32_t slicePitch = rectPitch*_rect.m_height; + const uint32_t slicePitch = rectPitch*srcRows; const bool convert = m_textureFormat != m_requestedFormat; @@ -5244,14 +5451,56 @@ namespace bgfx { namespace d3d11 } } - deviceCtx->UpdateSubresource( - m_ptr - , subres - , depth ? NULL : &box - , data - , copyPitch - , TextureD3D11::Texture3D == m_type ? slicePitch : 0 - ); + const bool stageOverhang = true + && TextureD3D11::Texture3D == m_type + && bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat) ) + && ( (0 != box.left && box.right > bx::max(1, m_width >> _mip) ) + || (0 != box.top && box.bottom > bx::max(1, m_height >> _mip) ) ) + ; + + if (stageOverhang) + { + D3D11_TEXTURE3D_DESC desc; + m_texture3d->GetDesc(&desc); + desc.Width = box.right - box.left; + desc.Height = box.bottom - box.top; + desc.Depth = box.back - box.front; + desc.MipLevels = 1; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = 0; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + ID3D11Texture3D* staging = NULL; + DX_CHECK(s_renderD3D11->m_device->CreateTexture3D(&desc, NULL, &staging) ); + + deviceCtx->UpdateSubresource(staging, 0, NULL, data, copyPitch, slicePitch); + + const D3D11_BOX srcBox = + { + .left = 0, + .top = 0, + .front = 0, + .right = desc.Width, + .bottom = desc.Height, + .back = desc.Depth, + }; + + deviceCtx->CopySubresourceRegion(m_ptr, subres, box.left, box.top, box.front, staging, 0, &srcBox); + + DX_RELEASE(staging, 0); + } + else + { + deviceCtx->UpdateSubresource( + m_ptr + , subres + , depth ? NULL : &box + , data + , copyPitch + , TextureD3D11::Texture3D == m_type ? slicePitch : 0 + ); + } if (NULL != temp) { @@ -5282,6 +5531,9 @@ namespace bgfx { namespace d3d11 || TextureDimension::Dimension2DArray == _dimension) ; + const bool srgbMutable = 0 != (m_flags & BGFX_TEXTURE_SRGB_MUTABLE); + const SrgbSelect::Enum srgb = srgbSelect(_flags, BGFX_SAMPLER_SRGB); + if (asArray) { ts.m_srv[_stage] = s_renderD3D11->getCachedSrv( @@ -5293,6 +5545,7 @@ namespace bgfx { namespace d3d11 , false , 0 != (flags & BGFX_SAMPLER_SAMPLE_STENCIL) , true + , srgb ); } else if (0 != (flags & BGFX_SAMPLER_SAMPLE_STENCIL) ) @@ -5307,7 +5560,8 @@ namespace bgfx { namespace d3d11 , true ); } - else if (!fullRange) + else if (!fullRange + || srgbMutable) { ts.m_srv[_stage] = s_renderD3D11->getCachedSrv( TextureHandle{ uint16_t(this - s_renderD3D11->m_textures) } @@ -5315,6 +5569,10 @@ namespace bgfx { namespace d3d11 , numMips , _firstLayer , numLayers + , false + , false + , false + , srgb ); } else @@ -5335,7 +5593,7 @@ namespace bgfx { namespace d3d11 { const DXGI_FORMAT resolveFormat = bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ) ? s_textureFormat[m_textureFormat].m_fmt - : getSrvFormat() + : getSrvFormat(srgbSelect(_resolve, BGFX_ATTACHMENT_SRGB) ) ; for (uint32_t ii = _layer, end = _layer + _numLayers; ii < end; ++ii) @@ -5372,30 +5630,45 @@ namespace bgfx { namespace d3d11 ; } - DXGI_FORMAT TextureD3D11::getSrvFormat() const + DXGI_FORMAT TextureD3D11::getSrvFormat(SrgbSelect::Enum _srgb) const { if (bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ) ) { return s_textureFormat[m_textureFormat].m_fmtSrv; } + DXGI_FORMAT format; + if (TextureFormat::BGRA8 == m_textureFormat && ( (0 != (m_flags&BGFX_TEXTURE_COMPUTE_WRITE) && 0 == (g_caps.formats[TextureFormat::BGRA8] & BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE) ) || 0 != (m_flags&BGFX_TEXTURE_INTERNAL_VIDEO_DECODE_DST) ) ) { - return 0 != (m_flags&BGFX_TEXTURE_SRGB) + format = 0 != (m_flags&BGFX_TEXTURE_SRGB) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM ; } + else + { + format = 0 != (m_flags&BGFX_TEXTURE_SRGB) + ? s_textureFormat[m_textureFormat].m_fmtSrgb + : s_textureFormat[m_textureFormat].m_fmt + ; + } - return 0 != (m_flags&BGFX_TEXTURE_SRGB) - ? s_textureFormat[m_textureFormat].m_fmtSrgb - : s_textureFormat[m_textureFormat].m_fmt + return SrgbSelect::Native != _srgb + && 0 != (m_flags & BGFX_TEXTURE_SRGB_MUTABLE) + ? srgbFormat(format, SrgbSelect::Srgb == _srgb) + : format ; } + DXGI_FORMAT TextureD3D11::getUavFormat() const + { + return srgbFormat(getSrvFormat(), false); + } + void FrameBufferD3D11::create(uint8_t _num, const Attachment* _attachment) { for (uint32_t ii = 0; ii < BX_COUNTOF(m_rtv); ++ii) @@ -5793,7 +6066,7 @@ namespace bgfx { namespace d3d11 } D3D11_RENDER_TARGET_VIEW_DESC desc; - desc.Format = texture.getSrvFormat(); + desc.Format = texture.getSrvFormat(srgbSelect(at.flags, BGFX_ATTACHMENT_SRGB) ); switch (texture.m_type) { default: @@ -6271,6 +6544,7 @@ namespace bgfx { namespace d3d11 } const DXGI_FORMAT dxgiFormat = texture.getSrvFormat(); + const DXGI_FORMAT uavFormat = texture.getUavFormat(); const uint32_t numElements = (_blit.m_rowPitch * _blit.m_height) / bpp; ID3D11ShaderResourceView* srv = NULL; @@ -6289,7 +6563,7 @@ namespace bgfx { namespace d3d11 DX_CHECK(m_device->CreateShaderResourceView(texture.m_ptr, &srvd, &srv) ); D3D11_UNORDERED_ACCESS_VIEW_DESC uavd = {}; - uavd.Format = dxgiFormat; + uavd.Format = uavFormat; uavd.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; uavd.Buffer.FirstElement = offset / bpp; uavd.Buffer.NumElements = numElements; @@ -6307,7 +6581,7 @@ namespace bgfx { namespace d3d11 DX_CHECK(m_device->CreateShaderResourceView(buffer.m_ptr, &srvd, &srv) ); D3D11_UNORDERED_ACCESS_VIEW_DESC uavd = {}; - uavd.Format = dxgiFormat; + uavd.Format = uavFormat; uavd.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; uavd.Texture2DArray.MipSlice = _blit.m_dstMip; uavd.Texture2DArray.FirstArraySlice = _blit.m_dstZ; @@ -6409,11 +6683,14 @@ namespace bgfx { namespace d3d11 const bool srcReadsMsaaRt = NULL != src.m_rt && dst.isMsaaSurface(); + uint8_t resolveFlags = BGFX_ATTACHMENT_NONE; + if (NULL != src.m_rt && !srcReadsMsaaRt - && 0 == blit.m_srcMip) + && 0 == blit.m_srcMip + && findPendingResolve(TextureHandle{blit.m_src.idx}, resolveFlags) ) { - src.resolve(BGFX_ATTACHMENT_NONE, blit.m_srcZ, 1, 0); + src.resolve(resolveFlags & BGFX_ATTACHMENT_SRGB, blit.m_srcZ, 1, 0); } if ( src.isMsaaSurface() @@ -6804,21 +7081,22 @@ namespace bgfx { namespace d3d11 : m_vertexBuffers[bind.m_idx] ; const ProgramD3D11* program = m_currentProgram; + const uint16_t parent = bufferViewParent(bind.m_idx, Binding::VertexBuffer == bind.m_type); if (Access::Read != bind.m_access) { - uav[stage] = NULL != program && program->isRawUav(stage) - ? buffer.m_uavRaw - : buffer.m_uav - ; + uav[stage] = getCachedBufferUav(buffer, parent + , NULL != program && program->isRawUav(stage) + , bind.m_offset, bind.m_size + ); m_textureStage.m_srv[stage] = NULL; m_textureStage.m_sampler[stage] = NULL; } else { - m_textureStage.m_srv[stage] = NULL != program && program->isRawSrv(stage) - ? buffer.m_srvRaw - : buffer.m_srv - ; + m_textureStage.m_srv[stage] = getCachedBufferSrv(buffer, parent + , NULL != program && program->isRawSrv(stage) + , bind.m_offset, bind.m_size + ); } } break; @@ -7163,22 +7441,23 @@ namespace bgfx { namespace d3d11 : m_vertexBuffers[bind.m_idx] ; const ProgramD3D11* program = m_currentProgram; + const uint16_t parent = bufferViewParent(bind.m_idx, Binding::VertexBuffer == bind.m_type); if (Access::Read != bind.m_access && NULL != buffer.m_uav) { m_textureStage.m_srv[stage] = NULL; m_textureStage.m_sampler[stage] = NULL; - m_textureStage.m_uav[stage] = NULL != program && program->isRawUav(stage) - ? buffer.m_uavRaw - : buffer.m_uav - ; + m_textureStage.m_uav[stage] = getCachedBufferUav(buffer, parent + , NULL != program && program->isRawUav(stage) + , bind.m_offset, bind.m_size + ); } else { - m_textureStage.m_srv[stage] = NULL != program && program->isRawSrv(stage) - ? buffer.m_srvRaw - : buffer.m_srv - ; + m_textureStage.m_srv[stage] = getCachedBufferSrv(buffer, parent + , NULL != program && program->isRawSrv(stage) + , bind.m_offset, bind.m_size + ); m_textureStage.m_sampler[stage] = NULL; m_textureStage.m_uav[stage] = NULL; } diff --git a/src/renderer_d3d11.h b/src/renderer_d3d11.h index effeabb08..e2e59c6f0 100644 --- a/src/renderer_d3d11.h +++ b/src/renderer_d3d11.h @@ -307,6 +307,16 @@ namespace bgfx { namespace d3d11 uint32_t size; }; + struct SrgbSelect + { + enum Enum + { + Native, + Linear, + Srgb, + }; + }; + struct DirectAccessResourceD3D11 { DirectAccessResourceD3D11() @@ -358,7 +368,8 @@ namespace bgfx { namespace d3d11 void commit(uint8_t _stage, uint32_t _flags, const float _palette[][4], uint16_t _firstLayer = 0, uint16_t _numLayers = UINT16_MAX, uint8_t _firstMip = 0, uint8_t _numMips = UINT8_MAX, TextureDimension::Enum _dimension = TextureDimension::Count); void resolve(uint8_t _resolve, uint32_t _layer, uint32_t _numLayers, uint32_t _mip) const; TextureHandle getHandle() const; - DXGI_FORMAT getSrvFormat() const; + DXGI_FORMAT getSrvFormat(SrgbSelect::Enum _srgb = SrgbSelect::Native) const; + DXGI_FORMAT getUavFormat() const; bool isMsaaSurface() const; union diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index c07427443..a85e118a3 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -8,6 +8,7 @@ #if BGFX_CONFIG_RENDERER_DIRECT3D12 # include "renderer_d3d12.h" # include "video_d3d12.h" +# include #if !BX_PLATFORM_WINDOWS && !BX_PLATFORM_LINUX # include @@ -320,6 +321,55 @@ namespace bgfx { namespace d3d12 }; static_assert(TextureFormat::Count == BX_COUNTOF(s_textureFormat) ); + struct SrgbFormatGroup + { + DXGI_FORMAT m_typeless; + DXGI_FORMAT m_linear; + DXGI_FORMAT m_srgb; + }; + + static const SrgbFormatGroup s_srgbFormatGroup[] = + { + { DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB }, + { DXGI_FORMAT_B8G8R8A8_TYPELESS, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB }, + { DXGI_FORMAT_BC1_TYPELESS, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM_SRGB }, + { DXGI_FORMAT_BC2_TYPELESS, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM_SRGB }, + { DXGI_FORMAT_BC3_TYPELESS, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM_SRGB }, + { DXGI_FORMAT_BC7_TYPELESS, DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_UNORM_SRGB }, + }; + + static const SrgbFormatGroup* findSrgbFormatGroup(DXGI_FORMAT _format) + { + for (uint32_t ii = 0; ii < BX_COUNTOF(s_srgbFormatGroup); ++ii) + { + const SrgbFormatGroup& sa = s_srgbFormatGroup[ii]; + if (_format == sa.m_linear + || _format == sa.m_srgb) + { + return &sa; + } + } + + return NULL; + } + + static DXGI_FORMAT srgbFormat(DXGI_FORMAT _format, bool _srgb) + { + const SrgbFormatGroup* group = findSrgbFormatGroup(_format); + return NULL == group + ? _format + : (_srgb ? group->m_srgb : group->m_linear) + ; + } + + static SrgbSelect::Enum srgbSelect(uint32_t _flags, uint32_t _bit) + { + return 0 != (_flags & _bit) + ? SrgbSelect::Srgb + : SrgbSelect::Linear + ; + } + static DXGI_FORMAT getBackBufferDepthStencilFormat(const SwapChain& _swapChain) { return bimg::isDepth(bimg::TextureFormat::Enum(_swapChain.formatDepthStencil) ) @@ -2220,7 +2270,7 @@ namespace bgfx { namespace d3d12 for (const D3D12_AUTO_BREADCRUMB_NODE* node = breadcrumbs.pHeadAutoBreadcrumbNode; NULL != node; node = node->pNext) { const uint32_t last = NULL != node->pLastBreadcrumbValue ? *node->pLastBreadcrumbValue : 0; - BX_TRACE("DRED: command list '%s' on queue '%s': %d of %d breadcrumbs completed%s" + _BGFX_TRACE("DRED: command list '%s' on queue '%s': %d of %d breadcrumbs completed%s" , NULL != node->pCommandListDebugNameA ? node->pCommandListDebugNameA : "?" , NULL != node->pCommandQueueDebugNameA ? node->pCommandQueueDebugNameA : "?" , last @@ -2235,7 +2285,7 @@ namespace bgfx { namespace d3d12 const uint32_t to = bx::min(node->BreadcrumbCount, last + 4); for (uint32_t ii = from; ii < to; ++ii) { - BX_TRACE("DRED: [%d] %s%s" + _BGFX_TRACE("DRED: [%d] %s%s" , ii , getBreadcrumbOpName(node->pCommandHistory[ii]) , ii == last ? " <-- executing when the device was removed" : "" @@ -2249,7 +2299,7 @@ namespace bgfx { namespace d3d12 if (SUCCEEDED(dred->GetPageFaultAllocationOutput(&pageFault) ) ) { - BX_TRACE( + _BGFX_TRACE( "DRED: page fault VA 0x%016" PRIx64 , uint64_t(pageFault.PageFaultVA) ); @@ -2259,7 +2309,7 @@ namespace bgfx { namespace d3d12 ; node = node->pNext ) { - BX_TRACE( + _BGFX_TRACE( "DRED: live allocation type %d '%s'" , node->AllocationType , NULL != node->ObjectNameA ? node->ObjectNameA : "?" @@ -2271,7 +2321,7 @@ namespace bgfx { namespace d3d12 ; node = node->pNext ) { - BX_TRACE( + _BGFX_TRACE( "DRED: recently freed allocation type %d '%s'" , node->AllocationType , NULL != node->ObjectNameA ? node->ObjectNameA : "?" @@ -2295,6 +2345,7 @@ namespace bgfx { namespace d3d12 : S_OK ; + dumpInfoQueue(); dumpDeviceRemovedExtendedData(); BGFX_FATAL(false @@ -3351,6 +3402,26 @@ namespace bgfx { namespace d3d12 } } + bool findPendingResolve(TextureHandle _handle, uint8_t& _flags) const + { + if (isValid(m_fbh) + && m_rtMsaa) + { + const FrameBufferD3D12& frameBuffer = m_frameBuffers[m_fbh.idx]; + + for (uint32_t ii = 0; ii < frameBuffer.m_numTh; ++ii) + { + if (frameBuffer.m_attachment[ii].handle.idx == _handle.idx) + { + _flags = frameBuffer.m_attachment[ii].flags; + return true; + } + } + } + + return false; + } + void setFrameBuffer(FrameBufferHandle _fbh, bool _msaa = true) { resolveFrameBuffer(_fbh); @@ -3904,7 +3975,7 @@ namespace bgfx { namespace d3d12 for (uint8_t ii = 0, num = frameBuffer.m_num; ii < num; ++ii) { - murmur.add(m_textures[frameBuffer.m_texture[ii].idx].m_srvd.Format); + murmur.add(frameBuffer.m_rtvFormat[ii]); } murmur.add(isValid(frameBuffer.m_depth) @@ -4019,7 +4090,7 @@ namespace bgfx { namespace d3d12 for (uint8_t ii = 0, num = frameBuffer.m_num; ii < num; ++ii) { - desc.RTVFormats[ii] = m_textures[frameBuffer.m_texture[ii].idx].m_srvd.Format; + desc.RTVFormats[ii] = frameBuffer.m_rtvFormat[ii]; } if (isValid(frameBuffer.m_depth) ) @@ -4670,17 +4741,20 @@ namespace bgfx { namespace d3d12 alloc(_gpuHandle, cpuHandle); } - void ScratchBufferD3D12::allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, TextureD3D12& _texture, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, bool _stencil, TextureDimension::Enum _dimension) + void ScratchBufferD3D12::allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, TextureD3D12& _texture, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, bool _stencil, TextureDimension::Enum _dimension, SrgbSelect::Enum _srgb) { ID3D12Device* device = s_renderD3D12->m_device; const uint8_t numMips = bx::min(_numMips, uint8_t(_texture.m_numMips - _firstMip) ); const uint16_t numLayers = bx::min(_numLayers, uint16_t(_texture.m_numLayers - _firstLayer) ); + const bool srgbMutable = 0 != (_texture.m_flags & BGFX_TEXTURE_SRGB_MUTABLE); + const bool fullRange = 0 == _firstMip && 0 == _firstLayer && numMips >= _texture.m_numMips && numLayers >= _texture.m_numLayers + && !srgbMutable ; const bool asArray = TextureD3D12::TextureCube == _texture.m_type @@ -4713,6 +4787,8 @@ namespace bgfx { namespace d3d12 bx::memCopy(&tmpSrvd, srvd, sizeof(tmpSrvd) ); srvd = &tmpSrvd; + srvd->Format = _texture.getSrvFormat(_srgb); + switch (_texture.m_srvd.ViewDimension) { default: @@ -4945,9 +5021,36 @@ namespace bgfx { namespace d3d12 device->CreateShaderResourceView(_resource, &_desc, cpuHandle); } - void ScratchBufferD3D12::allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, BufferD3D12& _buffer, bool _raw) + template + static void bufferViewRange(Ty& _desc, uint32_t _bufferSize, uint32_t _offset, uint32_t _size) { - allocSrv(_gpuHandle, _buffer.m_ptr, _raw ? _buffer.m_srvdRaw : _buffer.m_srvd); + const uint32_t numElements = uint32_t(_desc.Buffer.NumElements); + const uint32_t stride = 0 != numElements ? bx::max(1, _bufferSize / numElements) : 1; + const uint32_t offset = bx::min(_offset, _bufferSize); + const uint32_t range = UINT32_MAX == _size + ? _bufferSize - offset + : bx::min(_size, _bufferSize - offset) + ; + BX_ASSERT(0 == offset % stride, "Buffer range offset %u is not a multiple of the view's element size %u.", offset, stride); + + if (0 != range / stride) + { + _desc.Buffer.FirstElement = offset / stride; + _desc.Buffer.NumElements = range / stride; + } + } + + void ScratchBufferD3D12::allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, BufferD3D12& _buffer, bool _raw, uint32_t _offset, uint32_t _size) + { + if (0 == _offset && UINT32_MAX == _size) + { + allocSrv(_gpuHandle, _buffer.m_ptr, _raw ? _buffer.m_srvdRaw : _buffer.m_srvd); + return; + } + + D3D12_SHADER_RESOURCE_VIEW_DESC desc = _raw ? _buffer.m_srvdRaw : _buffer.m_srvd; + bufferViewRange(desc, _buffer.m_size, _offset, _size); + allocSrv(_gpuHandle, _buffer.m_ptr, desc); } void ScratchBufferD3D12::allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, ID3D12Resource* _resource, const D3D12_UNORDERED_ACCESS_VIEW_DESC& _desc) @@ -4963,9 +5066,17 @@ namespace bgfx { namespace d3d12 device->CreateUnorderedAccessView(_resource, NULL, &_desc, cpuHandle); } - void ScratchBufferD3D12::allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, BufferD3D12& _buffer, bool _raw) + void ScratchBufferD3D12::allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, BufferD3D12& _buffer, bool _raw, uint32_t _offset, uint32_t _size) { - allocUav(_gpuHandle, _buffer.m_ptr, _raw ? _buffer.m_uavdRaw : _buffer.m_uavd); + if (0 == _offset && UINT32_MAX == _size) + { + allocUav(_gpuHandle, _buffer.m_ptr, _raw ? _buffer.m_uavdRaw : _buffer.m_uavd); + return; + } + + D3D12_UNORDERED_ACCESS_VIEW_DESC desc = _raw ? _buffer.m_uavdRaw : _buffer.m_uavd; + bufferViewRange(desc, _buffer.m_size, _offset, _size); + allocUav(_gpuHandle, _buffer.m_ptr, desc); } void ChunkedScratchBufferD3D12::createUniform(uint32_t _chunkSize, uint32_t _numChunks) @@ -6598,6 +6709,20 @@ namespace bgfx { namespace d3d12 m_uavd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; } + if (0 != (m_flags & BGFX_TEXTURE_SRGB_MUTABLE) ) + { + const SrgbFormatGroup* group = findSrgbFormatGroup(format); + if (NULL != group) + { + format = group->m_typeless; + } + else + { + BX_WARN(false, "BGFX_TEXTURE_SRGB_MUTABLE is not supported for texture format %d", m_textureFormat); + m_flags &= ~BGFX_TEXTURE_SRGB_MUTABLE; + } + } + ID3D12Device* device = s_renderD3D12->m_device; ID3D12GraphicsCommandList* commandList = s_renderD3D12->m_commandList; @@ -6633,7 +6758,10 @@ namespace bgfx { namespace d3d12 state &= ~D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; clearValue = (D3D12_CLEAR_VALUE*)BX_STACK_ALLOC(sizeof(D3D12_CLEAR_VALUE) ); - clearValue->Format = resourceDesc.Format; + clearValue->Format = 0 != (m_flags & BGFX_TEXTURE_SRGB_MUTABLE) + ? m_srvd.Format + : resourceDesc.Format + ; clearValue->Color[0] = 0.0f; clearValue->Color[1] = 0.0f; clearValue->Color[2] = 0.0f; @@ -7209,7 +7337,12 @@ namespace bgfx { namespace d3d12 void TextureD3D12::resolve(ID3D12GraphicsCommandList* _commandList, uint8_t _resolve, uint32_t _layer, uint32_t _numLayers, uint32_t _mip) { - bool needResolve = NULL != m_singleMsaa; + const bx::EncodingType::Enum encoding = bx::EncodingType::Enum(bimg::getBlockInfo(bimg::TextureFormat::Enum(m_textureFormat) ).encoding); + const bool resolvable = bx::EncodingType::Int != encoding + && bx::EncodingType::Uint != encoding + ; + + bool needResolve = NULL != m_singleMsaa && resolvable; if (needResolve) { D3D12_RESOURCE_STATES state = setState(_commandList, D3D12_RESOURCE_STATE_RESOLVE_SOURCE); @@ -7221,12 +7354,22 @@ namespace bgfx { namespace d3d12 ); const TextureFormatInfo& tfi = s_textureFormat[m_textureFormat]; - const bool useSrgb = true - && 0 != (m_flags & BGFX_TEXTURE_SRGB) - && !bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ) - && DXGI_FORMAT_UNKNOWN != tfi.m_fmtSrgb - ; - const DXGI_FORMAT resolveFormat = useSrgb ? tfi.m_fmtSrgb : tfi.m_fmt; + const bool isDepthFormat = bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ); + DXGI_FORMAT resolveFormat; + + if (0 != (m_flags & BGFX_TEXTURE_SRGB_MUTABLE) + && !isDepthFormat) + { + resolveFormat = getSrvFormat(srgbSelect(_resolve, BGFX_ATTACHMENT_SRGB) ); + } + else + { + const bool useSrgb = 0 != (m_flags & BGFX_TEXTURE_SRGB) + && !isDepthFormat + && DXGI_FORMAT_UNKNOWN != tfi.m_fmtSrgb + ; + resolveFormat = useSrgb ? tfi.m_fmtSrgb : tfi.m_fmt; + } for (uint32_t ii = _layer, end = _layer + _numLayers; ii < end; ++ii) { @@ -7315,6 +7458,15 @@ namespace bgfx { namespace d3d12 return getNumPtrMips() * getNumSlices(); } + DXGI_FORMAT TextureD3D12::getSrvFormat(SrgbSelect::Enum _srgb) const + { + return SrgbSelect::Native != _srgb + && 0 != (m_flags & BGFX_TEXTURE_SRGB_MUTABLE) + ? srgbFormat(m_srvd.Format, SrgbSelect::Srgb == _srgb) + : m_srvd.Format + ; + } + D3D12_RESOURCE_STATES TextureD3D12::setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state) { if (NULL != m_subStates) @@ -8044,7 +8196,8 @@ namespace bgfx { namespace d3d12 D3D12_CPU_DESCRIPTOR_HANDLE rtv = { rtvDescriptor.ptr + m_num * rtvDescriptorSize }; D3D12_RENDER_TARGET_VIEW_DESC desc; - desc.Format = texture.m_srvd.Format; + desc.Format = texture.getSrvFormat(srgbSelect(at.flags, BGFX_ATTACHMENT_SRGB) ); + m_rtvFormat[m_num] = desc.Format; switch (texture.m_type) { @@ -8915,11 +9068,14 @@ namespace bgfx { namespace d3d12 if (currentSrc.idx != blit.m_src.idx) { + uint8_t resolveFlags = BGFX_ATTACHMENT_NONE; + if (NULL != src.m_singleMsaa && !dst.isMultisampled() - && 0 == blit.m_srcMip) + && 0 == blit.m_srcMip + && findPendingResolve(TextureHandle{blit.m_src.idx}, resolveFlags) ) { - src.resolve(m_commandList, BGFX_ATTACHMENT_NONE, blit.m_srcZ, 1, 0); + src.resolve(m_commandList, resolveFlags & BGFX_ATTACHMENT_SRGB, blit.m_srcZ, 1, 0); } if (D3D12_RESOURCE_STATES(UINT32_MAX) != srcState) @@ -9551,6 +9707,7 @@ namespace bgfx { namespace d3d12 scratchBuffer.allocSrv(srvHandle[stage], texture, bind.m_firstLayer, bind.m_numLayers, bind.m_firstMip, bind.m_numMips , 0 != (resolvedFlags & BGFX_SAMPLER_SAMPLE_STENCIL) , program.getTextureDimension(uint8_t(stage) ) + , srgbSelect(resolvedFlags, BGFX_SAMPLER_SRGB) ); samplerFlags[stage] = resolvedFlags & (BGFX_SAMPLER_BITS_MASK | BGFX_SAMPLER_BORDER_COLOR_MASK | BGFX_SAMPLER_COMPARE_MASK); @@ -9569,12 +9726,12 @@ namespace bgfx { namespace d3d12 if (Access::Read != bind.m_access) { buffer.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - scratchBuffer.allocUav(srvHandle[stage], buffer, 0 != (currentRawUavMask & (UINT32_C(1) << stage) ) ); + scratchBuffer.allocUav(srvHandle[stage], buffer, 0 != (currentRawUavMask & (UINT32_C(1) << stage) ), bind.m_offset, bind.m_size); } else { buffer.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); - scratchBuffer.allocSrv(srvHandle[stage], buffer, 0 != (currentRawSrvMask & (UINT32_C(1) << stage) ) ); + scratchBuffer.allocSrv(srvHandle[stage], buffer, 0 != (currentRawSrvMask & (UINT32_C(1) << stage) ), bind.m_offset, bind.m_size); } ++numSet; @@ -9928,6 +10085,7 @@ namespace bgfx { namespace d3d12 scratchBuffer.allocSrv(srvHandle[stage], texture, bind.m_firstLayer, bind.m_numLayers, bind.m_firstMip, bind.m_numMips , 0 != (resolvedFlags & BGFX_SAMPLER_SAMPLE_STENCIL) , program.getTextureDimension(uint8_t(stage) ) + , srgbSelect(resolvedFlags, BGFX_SAMPLER_SRGB) ); samplerFlags[stage] = resolvedFlags & (BGFX_SAMPLER_BITS_MASK | BGFX_SAMPLER_BORDER_COLOR_MASK | BGFX_SAMPLER_COMPARE_MASK); @@ -9948,12 +10106,12 @@ namespace bgfx { namespace d3d12 if (Access::Read != bind.m_access) { buffer.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - scratchBuffer.allocUav(srvHandle[stage], buffer, 0 != (currentRawUavMask & (UINT32_C(1) << stage) ) ); + scratchBuffer.allocUav(srvHandle[stage], buffer, 0 != (currentRawUavMask & (UINT32_C(1) << stage) ), bind.m_offset, bind.m_size); } else { buffer.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); - scratchBuffer.allocSrv(srvHandle[stage], buffer, 0 != (currentRawSrvMask & (UINT32_C(1) << stage) ) ); + scratchBuffer.allocSrv(srvHandle[stage], buffer, 0 != (currentRawSrvMask & (UINT32_C(1) << stage) ), bind.m_offset, bind.m_size); } ++numSet; diff --git a/src/renderer_d3d12.h b/src/renderer_d3d12.h index 4a3756682..47922de18 100644 --- a/src/renderer_d3d12.h +++ b/src/renderer_d3d12.h @@ -104,6 +104,16 @@ namespace bgfx { namespace d3d12 }; }; + struct SrgbSelect + { + enum Enum + { + Native, + Linear, + Srgb, + }; + }; + class ScratchBufferD3D12 { public: @@ -128,13 +138,13 @@ namespace bgfx { namespace d3d12 void allocEmpty(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle); - void allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct TextureD3D12& _texture, uint16_t _firstLayer = 0, uint16_t _numLayers = UINT16_MAX, uint8_t _firstMip = 0, uint8_t _numMips = UINT8_MAX, bool _stencil = false, TextureDimension::Enum _dimension = TextureDimension::Count); - void allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct BufferD3D12& _buffer, bool _raw); + void allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct TextureD3D12& _texture, uint16_t _firstLayer = 0, uint16_t _numLayers = UINT16_MAX, uint8_t _firstMip = 0, uint8_t _numMips = UINT8_MAX, bool _stencil = false, TextureDimension::Enum _dimension = TextureDimension::Count, SrgbSelect::Enum _srgb = SrgbSelect::Native); + void allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct BufferD3D12& _buffer, bool _raw, uint32_t _offset = 0, uint32_t _size = UINT32_MAX); void allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct TextureD3D12& _texture, uint8_t _mip = 0, uint16_t _firstLayer = 0, uint16_t _numLayers = UINT16_MAX); void allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, ID3D12Resource* _resource, const D3D12_SHADER_RESOURCE_VIEW_DESC& _desc); - void allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct BufferD3D12& _buffer, bool _raw); + void allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct BufferD3D12& _buffer, bool _raw, uint32_t _offset = 0, uint32_t _size = UINT32_MAX); void allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, ID3D12Resource* _resource, const D3D12_UNORDERED_ACCESS_VIEW_DESC& _desc); void allocSrvArray(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct TextureD3D12& _texture, uint32_t _numSlices); @@ -466,6 +476,8 @@ namespace bgfx { namespace d3d12 bool isMsaaSurface() const; bool isMultisampled() const; + DXGI_FORMAT getSrvFormat(SrgbSelect::Enum _srgb = SrgbSelect::Native) const; + D3D12_SHADER_RESOURCE_VIEW_DESC m_srvd; D3D12_UNORDERED_ACCESS_VIEW_DESC m_uavd; D3D12_CPU_DESCRIPTOR_HANDLE m_srvHandle; @@ -531,6 +543,7 @@ namespace bgfx { namespace d3d12 } TextureHandle m_texture[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; + DXGI_FORMAT m_rtvFormat[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; TextureHandle m_depth; Dxgi::SwapChainI* m_swapChain; DXGI_FORMAT m_swapChainFormat; diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 48d6aba9c..d913e7552 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -738,6 +738,7 @@ namespace bgfx { namespace gl EXT_texture_shared_exponent, EXT_texture_snorm, EXT_texture_sRGB, + EXT_texture_sRGB_decode, EXT_texture_storage, EXT_texture_swizzle, EXT_texture_view, @@ -971,6 +972,7 @@ namespace bgfx { namespace gl { "EXT_texture_shared_exponent", false, true }, { "EXT_texture_snorm", BGFX_CONFIG_RENDERER_OPENGL >= 30, true }, { "EXT_texture_sRGB", false, true }, + { "EXT_texture_sRGB_decode", false, true }, { "EXT_texture_storage", false, true }, { "EXT_texture_swizzle", false, true }, { "EXT_texture_view", false, true }, @@ -2212,6 +2214,24 @@ namespace bgfx { namespace gl bool m_detachShader; }; + static void glBindStorageBuffer(uint32_t _index, GLuint _id, uint32_t _bufferSize, uint32_t _offset, uint32_t _size) + { + const uint32_t offset = bx::min(_offset, _bufferSize); + const uint32_t range = UINT32_MAX == _size + ? _bufferSize - offset + : bx::min(_size, _bufferSize - offset) + ; + + if (0 == range + || (0 == offset && range == _bufferSize) ) + { + GL_CHECK(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, _index, _id) ); + return; + } + + GL_CHECK(glBindBufferRange(GL_SHADER_STORAGE_BUFFER, _index, _id, offset, range) ); + } + struct RendererContextGL : public RendererContextI { RendererContextGL() @@ -2234,6 +2254,7 @@ namespace bgfx { namespace gl , m_vaoSupport(false) , m_samplerObjectSupport(false) , m_srgbWriteControlSupport(BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) ) + , m_srgbDecodeSupport(false) , m_borderColorSupport(BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) ) , m_programBinarySupport(false) , m_textureSwizzleSupport(false) @@ -2970,6 +2991,8 @@ namespace bgfx { namespace gl GL_CHECK(glGetIntegerv(GL_MAX_SAMPLES, &m_maxMsaa) ); } + m_srgbDecodeSupport = s_extension[Extension::EXT_texture_sRGB_decode].m_supported; + if (s_extension[Extension::OES_read_format].m_supported && (s_extension[Extension::IMG_read_format].m_supported || s_extension[Extension::EXT_read_format_bgra].m_supported) ) { @@ -4032,6 +4055,25 @@ namespace bgfx { namespace gl ); } + bool isPendingResolve(TextureHandle _handle) const + { + if (isValid(m_fbh) + && m_rtMsaa) + { + const FrameBufferGL& frameBuffer = m_frameBuffers[m_fbh.idx]; + + for (uint32_t ii = 0; ii < frameBuffer.m_numTh; ++ii) + { + if (frameBuffer.m_attachment[ii].handle.idx == _handle.idx) + { + return true; + } + } + } + + return false; + } + void resolveFrameBuffer(FrameBufferHandle _fbh) { if (isValid(m_fbh) @@ -4118,11 +4160,15 @@ namespace bgfx { namespace gl GL_CHECK(glDisable(GL_FRAMEBUFFER_SRGB) ); } } - else + else if (m_frameBuffers[_fbh.idx].isSrgbWrite() ) { // actual sRGB write/blending determined by FBO's color attachments format GL_CHECK(glEnable(GL_FRAMEBUFFER_SRGB) ); } + else + { + GL_CHECK(glDisable(GL_FRAMEBUFFER_SRGB) ); + } } GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_currentFbo) ); @@ -4435,9 +4481,11 @@ namespace bgfx { namespace gl if (0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & _flags) ) { const uint32_t index = (_flags & BGFX_SAMPLER_BORDER_COLOR_MASK) >> BGFX_SAMPLER_BORDER_COLOR_SHIFT; + const uint32_t srgb = _flags & BGFX_SAMPLER_SRGB; _flags &= ~BGFX_SAMPLER_RESERVED_MASK; _flags &= BGFX_SAMPLER_BITS_MASK; + _flags |= srgb; _flags |= _numMips<m_srgbDecodeSupport + && s_renderGL->m_srgbWriteControlSupport + && GL_ZERO != s_textureFormat[m_textureFormat].m_internalFmtSrgb) + { + _flags |= BGFX_TEXTURE_SRGB; + } + else + { + BX_WARN(false, "BGFX_TEXTURE_SRGB_MUTABLE is not supported for texture format %d", m_textureFormat); + _flags &= ~BGFX_TEXTURE_SRGB_MUTABLE; + } + } + const bool computeWrite = 0 != (_flags&BGFX_TEXTURE_COMPUTE_WRITE); const bool srgb = 0 != (_flags&BGFX_TEXTURE_SRGB); const bool msaaSample = 0 != (_flags&BGFX_TEXTURE_MSAA_SAMPLE); @@ -6585,7 +6657,7 @@ namespace bgfx { namespace gl ; } - const uint32_t flags = (0 != (BGFX_SAMPLER_INTERNAL_DEFAULT & _flags) ? m_flags : _flags) & BGFX_SAMPLER_BITS_MASK; + const uint32_t flags = (0 != (BGFX_SAMPLER_INTERNAL_DEFAULT & _flags) ? m_flags : _flags) & (BGFX_SAMPLER_BITS_MASK|BGFX_SAMPLER_SRGB); bool hasBorderColor = false; bx::HashMurmur2A murmur; @@ -6657,6 +6729,19 @@ namespace bgfx { namespace gl GL_CHECK(glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, s_cmpFunc[cmpFunc]) ); } + if (s_renderGL->m_srgbDecodeSupport + && 0 != (m_flags & BGFX_TEXTURE_SRGB) ) + { + const bool decode = 0 == (m_flags & BGFX_TEXTURE_SRGB_MUTABLE) + || 0 != (flags & BGFX_SAMPLER_SRGB) + ; + + GL_CHECK(glTexParameteri(target + , GL_TEXTURE_SRGB_DECODE_EXT + , decode ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT + ) ); + } + m_currentSamplerHash = hash; } } @@ -6800,13 +6885,18 @@ namespace bgfx { namespace gl } } + const uint32_t samplerFlags = 0 != (m_flags & BGFX_TEXTURE_SRGB_MUTABLE) + ? flags + : flags | BGFX_SAMPLER_SRGB + ; + if (s_renderGL->m_samplerObjectSupport) { - s_renderGL->setSamplerState(_stage, m_numMips, flags, _palette[index]); + s_renderGL->setSamplerState(_stage, m_numMips, samplerFlags, _palette[index]); } else { - setSamplerState(flags, _palette[index]); + setSamplerState(samplerFlags, _palette[index]); } if (id == m_id @@ -7681,6 +7771,23 @@ namespace bgfx { namespace gl return denseIdx; } + bool FrameBufferGL::isSrgbWrite() const + { + for (uint32_t ii = 0; ii < m_numTh; ++ii) + { + const Attachment& at = m_attachment[ii]; + + if (isValid(at.handle) + && 0 != (s_renderGL->m_textures[at.handle.idx].m_flags & BGFX_TEXTURE_SRGB_MUTABLE) + && 0 == (at.flags & BGFX_ATTACHMENT_SRGB) ) + { + return false; + } + } + + return true; + } + void FrameBufferGL::resolve() { if (0 != m_fbo[1]) @@ -8325,7 +8432,8 @@ namespace bgfx { namespace gl const bool srcReadsMsaaRbo = 0 != src.m_rbo && dst.isMsaaSurface(); if (!srcReadsMsaaRbo - && 0 == bi.m_srcMip) + && 0 == bi.m_srcMip + && isPendingResolve(TextureHandle{bi.m_src.idx}) ) { resolveMsaaRbo(src, m_currentFbo); } @@ -8367,7 +8475,8 @@ namespace bgfx { namespace gl , "Blitting 3D regions is not supported" ); - if (0 == bi.m_srcMip) + if (0 == bi.m_srcMip + && isPendingResolve(TextureHandle{bi.m_src.idx}) ) { resolveMsaaRbo(src, m_currentFbo); } @@ -8734,7 +8843,7 @@ namespace bgfx { namespace gl case Binding::IndexBuffer: { const IndexBufferGL& buffer = m_indexBuffers[bind.m_idx]; - GL_CHECK(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, ii, buffer.m_id) ); + glBindStorageBuffer(ii, buffer.m_id, buffer.m_size, bind.m_offset, bind.m_size); barrier |= GL_SHADER_STORAGE_BARRIER_BIT; if (Access::Read != Access::Enum(bind.m_access) ) { @@ -8749,7 +8858,7 @@ namespace bgfx { namespace gl case Binding::VertexBuffer: { const VertexBufferGL& buffer = m_vertexBuffers[bind.m_idx]; - GL_CHECK(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, ii, buffer.m_id) ); + glBindStorageBuffer(ii, buffer.m_id, buffer.m_size, bind.m_offset, bind.m_size); barrier |= GL_SHADER_STORAGE_BARRIER_BIT; if (Access::Read != Access::Enum(bind.m_access) ) { @@ -9373,14 +9482,14 @@ namespace bgfx { namespace gl case Binding::IndexBuffer: { const IndexBufferGL& buffer = m_indexBuffers[bind.m_idx]; - GL_CHECK(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, stage, buffer.m_id) ); + glBindStorageBuffer(stage, buffer.m_id, buffer.m_size, bind.m_offset, bind.m_size); } break; case Binding::VertexBuffer: { const VertexBufferGL& buffer = m_vertexBuffers[bind.m_idx]; - GL_CHECK(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, stage, buffer.m_id) ); + glBindStorageBuffer(stage, buffer.m_id, buffer.m_size, bind.m_offset, bind.m_size); } break; } diff --git a/src/renderer_gl.h b/src/renderer_gl.h index 4aafe7849..75a49775c 100644 --- a/src/renderer_gl.h +++ b/src/renderer_gl.h @@ -922,6 +922,18 @@ typedef double GLdouble; # define GL_SHADER_STORAGE_BUFFER 0x90D2 #endif // GL_SHADER_STORAGE_BUFFER +#ifndef GL_TEXTURE_SRGB_DECODE_EXT +# define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 +#endif // GL_TEXTURE_SRGB_DECODE_EXT + +#ifndef GL_DECODE_EXT +# define GL_DECODE_EXT 0x8A49 +#endif // GL_DECODE_EXT + +#ifndef GL_SKIP_DECODE_EXT +# define GL_SKIP_DECODE_EXT 0x8A4A +#endif // GL_SKIP_DECODE_EXT + #ifndef GL_IMAGE_1D # define GL_IMAGE_1D 0x904C #endif // GL_IMAGE_1D @@ -1568,6 +1580,7 @@ namespace bgfx { namespace gl uint16_t destroy(); void resolve(); void discard(uint16_t _flags); + bool isSrgbWrite() const; void createSwapChainFbo(const SwapChain& _desc); void destroySwapChainFbo(); diff --git a/src/renderer_mtl.cpp b/src/renderer_mtl.cpp index 7fedd1be3..312d42962 100644 --- a/src/renderer_mtl.cpp +++ b/src/renderer_mtl.cpp @@ -864,6 +864,17 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames struct RendererContextMtl; static RendererContextMtl* s_renderMtl; + static uint32_t getBufferBindOffset(const Binding& _bind, uint32_t _size) + { + const uint32_t offset = bx::min(_bind.m_offset, _size); + const uint32_t range = UINT32_MAX == _bind.m_size + ? _size - offset + : bx::min(_bind.m_size, _size - offset) + ; + + return 0 != range ? offset : 0; + } + struct RendererContextMtl : public RendererContextI { RendererContextMtl() @@ -2604,12 +2615,17 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames for (uint32_t ii = 0; ii < frameBuffer.m_num; ++ii) { const TextureMtl& texture = m_textures[frameBuffer.m_colorHandle[ii].idx]; - _renderPassDescriptor->colorAttachments()->object(ii)->setTexture(texture.m_ptrMsaa - ? texture.m_ptrMsaa - : texture.m_ptr + const bool alt = texture.useAltFormat(frameBuffer.m_colorAttachment[ii].flags, BGFX_ATTACHMENT_SRGB); + + MTL::Texture* ptr = alt ? texture.m_ptrAlt : texture.m_ptr; + MTL::Texture* ptrMsaa = alt ? texture.m_ptrMsaaAlt : texture.m_ptrMsaa; + + _renderPassDescriptor->colorAttachments()->object(ii)->setTexture(ptrMsaa + ? ptrMsaa + : ptr ); - _renderPassDescriptor->colorAttachments()->object(ii)->setResolveTexture(texture.m_ptrMsaa - ? texture.m_ptr + _renderPassDescriptor->colorAttachments()->object(ii)->setResolveTexture(ptrMsaa + ? ptr : NULL ); @@ -3116,7 +3132,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames ? texture.m_ptrMsaa->sampleCount() : 1 ); - pd->colorAttachments()->object(ii)->setPixelFormat(texture.m_ptr->pixelFormat() ); + pd->colorAttachments()->object(ii)->setPixelFormat(texture.getAttachmentPixelFormat(frameBuffer.m_colorAttachment[ii].flags) ); } if (isValid(frameBuffer.m_depthHandle) ) @@ -4259,6 +4275,24 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames format = tfi.fmt; } + const bool srgbMutable = true + && 0 != (_flags & BGFX_TEXTURE_SRGB_MUTABLE) + && MTL::PixelFormatInvalid != tfi.fmt + && MTL::PixelFormatInvalid != tfi.fmtSrgb + ; + + if (0 != (_flags & BGFX_TEXTURE_SRGB_MUTABLE) + && !srgbMutable) + { + BX_WARN(false, "BGFX_TEXTURE_SRGB_MUTABLE is not supported for texture format %d", m_textureFormat); + m_flags &= ~BGFX_TEXTURE_SRGB_MUTABLE; + } + + const MTL::PixelFormat altFormat = format == tfi.fmtSrgb + ? tfi.fmt + : tfi.fmtSrgb + ; + desc->setPixelFormat(format); desc->setWidth(ti.width); desc->setHeight(ti.height); @@ -4291,7 +4325,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames | (computeWrite ? MTL::TextureUsageShaderWrite : 0) | (isVideoDecodeDst? MTL::TextureUsageShaderWrite : 0) | (renderTarget ? MTL::TextureUsageRenderTarget : 0) - | (packedDepthStencil ? MTL::TextureUsagePixelFormatView : 0) + | (packedDepthStencil || srgbMutable ? MTL::TextureUsagePixelFormatView : 0) ; desc->setUsage(usage); @@ -4307,6 +4341,12 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames m_ptr = s_renderMtl->m_device->newTexture(desc); } + if (srgbMutable + && NULL != m_ptr) + { + m_ptrAlt = m_ptr->newTextureView(altFormat); + } + if (sampleCount > 1) { desc->setTextureType(ti.numLayers > 1 @@ -4322,6 +4362,12 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames } m_ptrMsaa = s_renderMtl->m_device->newTexture(desc); + + if (srgbMutable + && NULL != m_ptrMsaa) + { + m_ptrMsaaAlt = m_ptrMsaa->newTextureView(altFormat); + } } if (m_requestedFormat == TextureFormat::D24S8 @@ -4454,6 +4500,8 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames MTL_RELEASE_W(m_ptrMsaa, 0); MTL_RELEASE_W(m_ptrStencil, 0); + MTL_RELEASE_W(m_ptrAlt, 0); + MTL_RELEASE_W(m_ptrMsaaAlt, 0); for (stl::unordered_map::iterator it = m_ptrViews.begin(), itEnd = m_ptrViews.end(); it != itEnd; ++it) { @@ -4606,7 +4654,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames MTL::Texture* ptr = _mip != UINT8_MAX ? getTextureImage(_mip, _firstLayer, _numLayers) - : getTextureView(_firstLayer, _numLayers, _firstMip, _numMips, sampleStencil) + : getTextureView(_firstLayer, _numLayers, _firstMip, _numMips, sampleStencil, useAltFormat(flags, BGFX_SAMPLER_SRGB) ) ; if (_vertex) @@ -4632,7 +4680,26 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames } } - MTL::Texture* TextureMtl::getTextureView(uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, bool _stencil) + bool TextureMtl::useAltFormat(uint32_t _flags, uint32_t _bit) const + { + if (NULL == m_ptrAlt) + { + return false; + } + + const bool srgb = m_ptr->pixelFormat() == s_textureFormat[m_textureFormat].fmtSrgb; + return srgb != (0 != (_flags & _bit) ); + } + + MTL::PixelFormat TextureMtl::getAttachmentPixelFormat(uint8_t _flags) const + { + return useAltFormat(_flags, BGFX_ATTACHMENT_SRGB) + ? m_ptrAlt->pixelFormat() + : m_ptr->pixelFormat() + ; + } + + MTL::Texture* TextureMtl::getTextureView(uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, bool _stencil, bool _alt) { MTL::Texture* ptr = _stencil && NULL != m_ptrStencil ? m_ptrStencil @@ -4644,7 +4711,15 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames return NULL; } - MTL::PixelFormat format = ptr->pixelFormat(); + const bool alt = _alt + && !_stencil + && NULL != m_ptrAlt + ; + + MTL::PixelFormat format = alt + ? m_ptrAlt->pixelFormat() + : ptr->pixelFormat() + ; if (_stencil && ptr == m_ptr) @@ -4678,11 +4753,18 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames return ptr; } + if (fullRange + && alt) + { + return m_ptrAlt; + } + const uint64_t key = 0 | uint64_t(firstMip) | (uint64_t(numMips) << 8) | (uint64_t(firstLayer) << 16) | (uint64_t(numLayers) << 32) + | (uint64_t(alt) << 62) | (uint64_t(_stencil) << 63) ; @@ -5175,7 +5257,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames for (uint32_t ii = 0; ii < m_num; ++ii) { const TextureMtl& texture = s_renderMtl->m_textures[m_colorHandle[ii].idx]; - murmur.add(uint32_t(texture.m_ptr->pixelFormat() ) ); + murmur.add(uint32_t(texture.getAttachmentPixelFormat(m_colorAttachment[ii].flags) ) ); } if (!isValid(m_depthHandle) ) @@ -6484,7 +6566,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames ? m_indexBuffers[bind.m_idx] : m_vertexBuffers[bind.m_idx] ; - m_computeCommandEncoder->setBuffer(buffer.m_ptr, 0, stage + 1); + m_computeCommandEncoder->setBuffer(buffer.m_ptr, getBufferBindOffset(bind, buffer.m_size), stage + 1); } break; } @@ -6919,14 +7001,16 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames : m_vertexBuffers[bind.m_idx] ; + const uint32_t offset = getBufferBindOffset(bind, buffer.m_size); + if (0 != (bindingTypes[stage] & PipelineStateMtl::BindToVertexShader) ) { - rce->setVertexBuffer(buffer.m_ptr, 0, stage + 1); + rce->setVertexBuffer(buffer.m_ptr, offset, stage + 1); } if (0 != (bindingTypes[stage] & PipelineStateMtl::BindToFragmentShader) ) { - rce->setFragmentBuffer(buffer.m_ptr, 0, stage + 1); + rce->setFragmentBuffer(buffer.m_ptr, offset, stage + 1); } } break; diff --git a/src/renderer_mtl.h b/src/renderer_mtl.h index 873e3735d..a4250bceb 100644 --- a/src/renderer_mtl.h +++ b/src/renderer_mtl.h @@ -435,6 +435,8 @@ namespace bgfx { namespace mtl : m_ptr(NULL) , m_ptrMsaa(NULL) , m_ptrStencil(NULL) + , m_ptrAlt(NULL) + , m_ptrMsaaAlt(NULL) , m_sampler(NULL) , m_videoDecoder(NULL) , m_flags(0) @@ -472,11 +474,16 @@ namespace bgfx { namespace mtl ); MTL::Texture* getTextureImage(uint8_t _mip, uint16_t _firstLayer = 0, uint16_t _numLayers = UINT16_MAX); - MTL::Texture* getTextureView(uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, bool _stencil = false); + MTL::Texture* getTextureView(uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, bool _stencil = false, bool _alt = false); + + bool useAltFormat(uint32_t _flags, uint32_t _bit) const; + MTL::PixelFormat getAttachmentPixelFormat(uint8_t _flags) const; MTL::Texture* m_ptr; MTL::Texture* m_ptrMsaa; MTL::Texture* m_ptrStencil; // for emulating packed depth/stencil formats - only for iOS8... + MTL::Texture* m_ptrAlt; + MTL::Texture* m_ptrMsaaAlt; stl::unordered_map m_ptrViews; MTL::SamplerState* m_sampler; VideoDecoderMtl* m_videoDecoder; diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index 20dd85f65..23ba5ef2e 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -3372,6 +3372,29 @@ VK_IMPORT_DEVICE ; } + bool findPendingResolve(TextureHandle _handle, uint8_t& _flags) const + { + if (isValid(m_fbh) ) + { + const FrameBufferVK& frameBuffer = m_frameBuffers[m_fbh.idx]; + + if (!frameBuffer.isSwapChain() + && frameBuffer.m_needResolve) + { + for (uint32_t ii = 0; ii < frameBuffer.m_numTh; ++ii) + { + if (frameBuffer.m_attachment[ii].handle.idx == _handle.idx) + { + _flags = frameBuffer.m_attachment[ii].flags; + return true; + } + } + } + } + + return false; + } + void setFrameBuffer(FrameBufferHandle _fbh) { BGFX_PROFILER_SCOPE("RendererContextVK::setFrameBuffer()", kColorFrame); @@ -3895,7 +3918,7 @@ VK_IMPORT_DEVICE for (uint8_t ii = 0; ii < _num; ++ii) { const TextureVK& texture = m_textures[_attachments[ii].handle.idx]; - formats[ii] = texture.m_format; + formats[ii] = texture.getViewFormat(_attachments[ii].flags, BGFX_ATTACHMENT_SRGB); aspects[ii] = texture.m_aspectFlags; samples = texture.m_sampler.Sample; @@ -4045,7 +4068,7 @@ VK_IMPORT_DEVICE return sampler; } - VkImageView getCachedImageView(TextureHandle _handle, uint32_t _mip, uint32_t _numMips, VkImageViewType _type, bool _stencil = false, uint32_t _firstLayer = 0, uint32_t _numLayers = UINT32_MAX) + VkImageView getCachedImageView(TextureHandle _handle, uint32_t _mip, uint32_t _numMips, VkImageViewType _type, bool _stencil = false, uint32_t _firstLayer = 0, uint32_t _numLayers = UINT32_MAX, uint32_t _samplerFlags = 0) { const TextureVK& texture = m_textures[_handle.idx]; @@ -4056,6 +4079,8 @@ VK_IMPORT_DEVICE const uint32_t firstMip = bx::min(_mip, texture.m_numMips); const uint32_t numMips = bx::min(_numMips, texture.m_numMips - firstMip); + const VkFormat format = texture.getViewFormat(_samplerFlags, BGFX_SAMPLER_SRGB); + bx::HashMurmur2A hash; hash.begin(); hash.add(_handle.idx); @@ -4065,6 +4090,7 @@ VK_IMPORT_DEVICE hash.add(_stencil); hash.add(firstLayer); hash.add(numLayers); + hash.add(format); uint32_t hashKey = hash.end(); VkImageView* viewCached = m_imageViewCache.find(hashKey); @@ -4080,7 +4106,7 @@ VK_IMPORT_DEVICE ; VkImageView view; - VK_CHECK(texture.createView(firstLayer, numLayers, firstMip, numMips, _type, aspectMask, false, &view) ); + VK_CHECK(texture.createView(firstLayer, numLayers, firstMip, numMips, _type, aspectMask, false, &view, format) ); m_imageViewCache.add(hashKey, view, _handle.idx); return view; @@ -4555,9 +4581,15 @@ VK_IMPORT_DEVICE : m_indexBuffers[bind.m_idx] ; + const uint32_t offset = bx::min(bind.m_offset, sb.m_size); + const uint32_t range = UINT32_MAX == bind.m_size + ? sb.m_size - offset + : bx::min(bind.m_size, sb.m_size - offset) + ; + bufferInfo[bufferCount].buffer = sb.m_buffer; - bufferInfo[bufferCount].offset = 0; - bufferInfo[bufferCount].range = sb.m_size; + bufferInfo[bufferCount].offset = 0 != range ? offset : 0; + bufferInfo[bufferCount].range = 0 != range ? range : sb.m_size; wds[wdsCount].pBufferInfo = &bufferInfo[bufferCount]; ++bufferCount; @@ -4592,6 +4624,7 @@ VK_IMPORT_DEVICE , sampleStencil , bind.m_firstLayer , bind.m_numLayers + , samplerFlags ); wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; @@ -6870,6 +6903,10 @@ VK_DESTROY ? VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR : 0 ) + | (0 != (m_flags & BGFX_TEXTURE_SRGB_MUTABLE) + ? VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT + : 0 + ) ; ici.pQueueFamilyIndices = NULL; ici.queueFamilyIndexCount = 0; @@ -6963,9 +7000,13 @@ VK_DESTROY VkImageCreateInfo ici_resolve = ici; ici_resolve.samples = s_msaa[0].Sample; ici_resolve.mipLevels = m_numMips; - ici_resolve.usage &= ~VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; ici_resolve.flags &= ~VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; + if (0 == (m_flags & BGFX_TEXTURE_SRGB_MUTABLE) ) + { + ici_resolve.usage &= ~VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + } + result = vkCreateImage(device, &ici_resolve, allocatorCb, &m_singleMsaaImage); if (VK_SUCCESS != result) { @@ -7529,37 +7570,49 @@ VK_DESTROY if (needResolve) { - setState(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - setState(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true); + const VkFormat resolveFormat = getViewFormat(_resolve, BGFX_ATTACHMENT_SRGB); - VkImageResolve resolve; - resolve.srcOffset.x = 0; - resolve.srcOffset.y = 0; - resolve.srcOffset.z = 0; - resolve.dstOffset.x = 0; - resolve.dstOffset.y = 0; - resolve.dstOffset.z = 0; - resolve.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - resolve.srcSubresource.mipLevel = _mip; - resolve.srcSubresource.baseArrayLayer = _layer; - resolve.srcSubresource.layerCount = numLayers; - resolve.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - resolve.dstSubresource.mipLevel = _mip; - resolve.dstSubresource.baseArrayLayer = _layer; - resolve.dstSubresource.layerCount = numLayers; - resolve.extent.width = m_width; - resolve.extent.height = m_height; - resolve.extent.depth = 1; + if (resolveFormat != m_format) + { + resolveRenderPass(_commandBuffer, resolveFormat, _layer, numLayers, _mip); + setState(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true); + } + else + { + setState(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + setState(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true); - vkCmdResolveImage( - _commandBuffer - , m_textureImage - , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL - , m_singleMsaaImage - , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL - , 1 - , &resolve - ); + const VkImageResolve resolve = + { + .srcSubresource = + { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = _mip, + .baseArrayLayer = _layer, + .layerCount = numLayers, + }, + .srcOffset = { .x = 0, .y = 0, .z = 0 }, + .dstSubresource = + { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = _mip, + .baseArrayLayer = _layer, + .layerCount = numLayers, + }, + .dstOffset = { .x = 0, .y = 0, .z = 0 }, + .extent = { .width = m_width, .height = m_height, .depth = 1 }, + }; + + vkCmdResolveImage( + _commandBuffer + , m_textureImage + , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL + , m_singleMsaaImage + , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL + , 1 + , &resolve + ); + } const bool autoGenMips = true && 0 != (_resolve & BGFX_ATTACHMENT_AUTO_GEN_MIPS) @@ -7722,6 +7775,90 @@ VK_DESTROY setState(_commandBuffer, oldSingleMsaaLayout, true); } + void TextureVK::resolveRenderPass(VkCommandBuffer _commandBuffer, VkFormat _format, uint32_t _layer, uint32_t _numLayers, uint32_t _mip) + { + const VkDevice device = s_renderVK->m_device; + const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb; + + setState(_commandBuffer, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + setState(_commandBuffer, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true); + + const VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT; + const bool resolve = true; + + ::VkRenderPass renderPass = VK_NULL_HANDLE; + VK_CHECK(s_renderVK->getRenderPass(1, &_format, &aspect, &resolve, m_sampler.Sample, BGFX_CLEAR_NONE, 0, &renderPass, NULL) ); + + const uint32_t width = bx::max(m_width >> _mip, 1); + const uint32_t height = bx::max(m_height >> _mip, 1); + + for (uint32_t ii = _layer, end = _layer + _numLayers; ii < end; ++ii) + { + VkImageViewCreateInfo ivci = + { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .pNext = NULL, + .flags = 0, + .image = m_textureImage, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = _format, + .components = { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }, + .subresourceRange = + { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = _mip, + .levelCount = 1, + .baseArrayLayer = ii, + .layerCount = 1, + }, + }; + + VkImageView views[2]; + VK_CHECK(vkCreateImageView(device, &ivci, allocatorCb, &views[0]) ); + + ivci.image = m_singleMsaaImage; + VK_CHECK(vkCreateImageView(device, &ivci, allocatorCb, &views[1]) ); + + VkFramebufferCreateInfo fci = + { + .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + .pNext = NULL, + .flags = 0, + .renderPass = renderPass, + .attachmentCount = BX_COUNTOF(views), + .pAttachments = &views[0], + .width = width, + .height = height, + .layers = 1, + }; + + VkFramebuffer framebuffer; + VK_CHECK(vkCreateFramebuffer(device, &fci, allocatorCb, &framebuffer) ); + + VkRenderPassBeginInfo rpbi = + { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .pNext = NULL, + .renderPass = renderPass, + .framebuffer = framebuffer, + .renderArea = + { + .offset = { .x = 0, .y = 0 }, + .extent = { .width = width, .height = height }, + }, + .clearValueCount = 0, + .pClearValues = NULL, + }; + + vkCmdBeginRenderPass(_commandBuffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE); + vkCmdEndRenderPass(_commandBuffer); + + release(framebuffer); + release(views[0]); + release(views[1]); + } + } + void TextureVK::copyBufferToTexture(VkCommandBuffer _commandBuffer, VkBuffer _stagingBuffer, uint32_t _bufferImageCopyCount, VkBufferImageCopy* _bufferImageCopy) { BGFX_PROFILER_SCOPE("TextureVK::copyBufferToTexture", kColorResource); @@ -7827,7 +7964,21 @@ VK_DESTROY } } - VkResult TextureVK::createView(uint32_t _layer, uint32_t _numLayers, uint32_t _mip, uint32_t _numMips, VkImageViewType _type, VkImageAspectFlags _aspectMask, bool _renderTarget, ::VkImageView* _view) const + VkFormat TextureVK::getViewFormat(uint32_t _flags, uint32_t _bit) const + { + if (0 == (m_flags & BGFX_TEXTURE_SRGB_MUTABLE) + || bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ) ) + { + return m_format; + } + + const TextureFormatInfo& tfi = s_textureFormat[m_textureFormat]; + const VkFormat format = 0 != (_flags & _bit) ? tfi.m_fmtSrgb : tfi.m_fmt; + + return VK_FORMAT_UNDEFINED != format ? format : m_format; + } + + VkResult TextureVK::createView(uint32_t _layer, uint32_t _numLayers, uint32_t _mip, uint32_t _numMips, VkImageViewType _type, VkImageAspectFlags _aspectMask, bool _renderTarget, ::VkImageView* _view, VkFormat _format) const { VkResult result = VK_SUCCESS; @@ -7859,7 +8010,7 @@ VK_DESTROY : m_textureImage ; viewInfo.viewType = _type; - viewInfo.format = m_format; + viewInfo.format = VK_FORMAT_UNDEFINED != _format ? _format : m_format; viewInfo.components = _renderTarget ? VkComponentMapping{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY } : m_components @@ -9215,6 +9366,7 @@ VK_DESTROY , texture.m_aspectFlags , true , &m_textureImageViews[ii] + , texture.getViewFormat(at.flags, BGFX_ATTACHMENT_SRGB) ) ); if (texture.m_aspectFlags & VK_IMAGE_ASPECT_COLOR_BIT) @@ -9768,10 +9920,13 @@ VK_DESTROY TextureVK& src = m_textures[blit.m_src.idx]; TextureVK& dst = m_textures[blit.m_dst.idx]; + uint8_t resolveFlags = BGFX_ATTACHMENT_NONE; + if (blitReadsSingleMsaa(src, dst) - && 0 == blit.m_srcMip) + && 0 == blit.m_srcMip + && findPendingResolve(TextureHandle{blit.m_src.idx}, resolveFlags) ) { - src.resolve(m_commandBuffer, BGFX_ATTACHMENT_NONE, blit.m_srcZ, 1, 0); + src.resolve(m_commandBuffer, resolveFlags & BGFX_ATTACHMENT_SRGB, blit.m_srcZ, 1, 0); } srcLayouts[item] = blitReadsSingleMsaa(src, dst) @@ -9996,7 +10151,87 @@ VK_DESTROY }, }; - if (resolve) + const bimg::ImageBlockInfo& srcBlockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(src.m_textureFormat) ); + const bimg::ImageBlockInfo& dstBlockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(dst.m_textureFormat) ); + + const bool stageCompressed3D = true + && !resolve + && !srcSingleMsaa + && blit.m_src.idx != blit.m_dst.idx + && bimg::isCompressed(bimg::TextureFormat::Enum(src.m_textureFormat) ) + && ( (isSrc3D && (0 != srcMipWidth % srcBlockInfo.blockWidth || 0 != srcMipHeight % srcBlockInfo.blockHeight) ) + || (isDst3D && (0 != dstMipWidth % dstBlockInfo.blockWidth || 0 != dstMipHeight % dstBlockInfo.blockHeight) ) ) + ; + + if (stageCompressed3D) + { + const uint32_t numBlocksX = (copyInfo.extent.width + srcBlockInfo.blockWidth - 1) / srcBlockInfo.blockWidth; + const uint32_t numBlocksY = (copyInfo.extent.height + srcBlockInfo.blockHeight - 1) / srcBlockInfo.blockHeight; + const uint32_t size = numBlocksX * numBlocksY * srcBlockInfo.blockSize * depth; + + StagingBufferVK stagingBuffer = allocFromScratchStagingBuffer(size, srcBlockInfo.blockSize); + + const VkBufferImageCopy toBuffer = + { + .bufferOffset = stagingBuffer.m_offset, + .bufferRowLength = 0, + .bufferImageHeight = 0, + .imageSubresource = copyInfo.srcSubresource, + .imageOffset = copyInfo.srcOffset, + .imageExtent = + { + .width = copyInfo.extent.width, + .height = copyInfo.extent.height, + .depth = isSrc3D ? depth : 1, + }, + }; + + vkCmdCopyImageToBuffer( + m_commandBuffer + , src.m_textureImage + , src.m_currentImageLayout + , stagingBuffer.m_buffer + , 1 + , &toBuffer + ); + + setMemoryBarrier( + m_commandBuffer + , VK_PIPELINE_STAGE_TRANSFER_BIT + , VK_PIPELINE_STAGE_TRANSFER_BIT + ); + + const VkBufferImageCopy fromBuffer = + { + .bufferOffset = stagingBuffer.m_offset, + .bufferRowLength = numBlocksX * srcBlockInfo.blockWidth, + .bufferImageHeight = numBlocksY * srcBlockInfo.blockHeight, + .imageSubresource = copyInfo.dstSubresource, + .imageOffset = copyInfo.dstOffset, + .imageExtent = + { + .width = bx::min(numBlocksX * dstBlockInfo.blockWidth, dstMipWidth - blit.m_dstX), + .height = bx::min(numBlocksY * dstBlockInfo.blockHeight, dstMipHeight - blit.m_dstY), + .depth = isDst3D ? depth : 1, + }, + }; + + vkCmdCopyBufferToImage( + m_commandBuffer + , stagingBuffer.m_buffer + , dst.m_textureImage + , dst.m_currentImageLayout + , 1 + , &fromBuffer + ); + + if (!stagingBuffer.m_isFromScratch) + { + release(stagingBuffer.m_buffer); + recycleMemory(stagingBuffer.m_deviceMem); + } + } + else if (resolve) { const VkImageResolve resolveInfo = { diff --git a/src/renderer_vk.h b/src/renderer_vk.h index 9cdf8cf86..e26c64014 100644 --- a/src/renderer_vk.h +++ b/src/renderer_vk.h @@ -723,7 +723,11 @@ VK_DESTROY_FUNC(DescriptorSet); void copyBufferToTexture(VkCommandBuffer _commandBuffer, VkBuffer _stagingBuffer, uint32_t _bufferImageCopyCount, VkBufferImageCopy* _bufferImageCopy); 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; + VkResult createView(uint32_t _layer, uint32_t _numLayers, uint32_t _mip, uint32_t _numMips, VkImageViewType _type, VkImageAspectFlags _aspectMask, bool _renderTarget, ::VkImageView* _view, VkFormat _format = VK_FORMAT_UNDEFINED) const; + + VkFormat getViewFormat(uint32_t _flags, uint32_t _bit) const; + + void resolveRenderPass(VkCommandBuffer _commandBuffer, VkFormat _format, uint32_t _layer, uint32_t _numLayers, uint32_t _mip); void* m_directAccessPtr; uint64_t m_flags; diff --git a/src/renderer_webgpu.cpp b/src/renderer_webgpu.cpp index 0b4faeb32..f7ace0d84 100644 --- a/src/renderer_webgpu.cpp +++ b/src/renderer_webgpu.cpp @@ -3646,6 +3646,9 @@ WGPU_IMPORT , bind.m_numLayers , viewDimension , sampleStencil + , Binding::Texture == bind.m_type + ? texture.getViewFormat(resolvedFlags, BGFX_SAMPLER_SRGB) + : WGPUTextureFormat_Undefined ), }; @@ -3674,13 +3677,20 @@ WGPU_IMPORT : m_vertexBuffers[bind.m_idx] ; + const uint32_t bufferSize = bx::alignUp(buffer.m_size, 4); + const uint32_t offset = bx::min(bind.m_offset, bufferSize); + const uint32_t range = UINT32_MAX == bind.m_size + ? bufferSize - offset + : bx::min(bind.m_size, bufferSize - offset) + ; + bindGroupEntry[entryCount++] = { .nextInChain = NULL, .binding = shaderBind.binding, .buffer = buffer.m_buffer, - .offset = 0, - .size = buffer.m_size, + .offset = 0 != range ? offset : 0, + .size = 0 != range ? range : bufferSize, .sampler = NULL, .textureView = NULL, }; @@ -3805,7 +3815,7 @@ WGPU_IMPORT { const WGPUTextureFormat format = isSwapChain ? _fb.m_swapChain.m_viewFormat - : m_textures[_fb.m_texture[ii].idx].m_fmt + : _fb.m_colorFormat[ii] ; const WGPUBlendState* blend = independentBlendEnable && 0 != ii @@ -3854,7 +3864,7 @@ WGPU_IMPORT for (uint8_t ii = 0; ii < _fb.m_numColorAttachments; ++ii) { - _murmur.add(m_textures[_fb.m_texture[ii].idx].m_fmt); + _murmur.add(_fb.m_colorFormat[ii]); } _murmur.add(NULL != _fb.m_depthStencilView); @@ -4065,11 +4075,28 @@ WGPU_IMPORT return s_renderWGPU->m_cmd.m_currentFrameInFlight; } + static void writeBufferAligned(WGPUBuffer _buffer, uint32_t _offset, const void* _data, uint32_t _size) + { + const uint32_t alignedSize = bx::alignUp(_size, 4); + + if (alignedSize == _size) + { + s_renderWGPU->m_cmd.writeBuffer(_buffer, _offset, _data, _size); + return; + } + + uint8_t* temp = (uint8_t*)bx::alloc(g_allocator, alignedSize); + bx::memCopy(temp, _data, _size); + bx::memSet(&temp[_size], 0, alignedSize - _size); + s_renderWGPU->m_cmd.writeBuffer(_buffer, _offset, temp, alignedSize); + bx::free(g_allocator, temp); + } + void BufferWGPU::create(uint32_t _size, void* _data, uint16_t _flags, bool _vertex, uint32_t _stride) { BX_UNUSED(_stride); - m_size = bx::alignUp(_size, 4); + m_size = _size; m_flags = _flags; const bool indirect = !!(m_flags & BGFX_BUFFER_DRAW_INDIRECT); @@ -4088,7 +4115,7 @@ WGPU_IMPORT ) | WGPUBufferUsage_CopyDst , - .size = m_size, + .size = bx::alignUp(m_size, 4), .mappedAtCreation = false, }; @@ -4096,14 +4123,14 @@ WGPU_IMPORT if (NULL != _data) { - s_renderWGPU->m_cmd.writeBuffer(m_buffer, 0, _data, m_size); + writeBufferAligned(m_buffer, 0, _data, m_size); } } void BufferWGPU::update(uint32_t _offset, uint32_t _size, void* _data, bool _discard) const { BX_UNUSED(_discard); - s_renderWGPU->m_cmd.writeBuffer(m_buffer, _offset, _data, bx::alignUp(_size, 4) ); + writeBufferAligned(m_buffer, _offset, _data, _size); } void BufferWGPU::destroy() @@ -4688,6 +4715,25 @@ WGPU_IMPORT : s_textureFormat[m_textureFormat].m_fmt ; + WGPUTextureFormat viewFormat = WGPUTextureFormat_Undefined; + + if (0 != (m_flags & BGFX_TEXTURE_SRGB_MUTABLE) ) + { + const TextureFormatInfo& tfi = s_textureFormat[m_textureFormat]; + + if (!swizzle + && WGPUTextureFormat_Undefined != tfi.m_fmt + && WGPUTextureFormat_Undefined != tfi.m_fmtSrgb) + { + viewFormat = srgb ? tfi.m_fmt : tfi.m_fmtSrgb; + } + else + { + BX_WARN(false, "BGFX_TEXTURE_SRGB_MUTABLE is not supported for texture format %d", m_textureFormat); + m_flags &= ~BGFX_TEXTURE_SRGB_MUTABLE; + } + } + const uint32_t sampleCount = needResolve ? 1 : m_msaaCount; WGPUTextureDescriptor textureDesc = @@ -4715,18 +4761,26 @@ WGPU_IMPORT .format = m_fmt, .mipLevelCount = 1 < sampleCount ? 1u : uint32_t(m_numMips), .sampleCount = sampleCount, - .viewFormatCount = 0, - .viewFormats = NULL, + .viewFormatCount = WGPUTextureFormat_Undefined != viewFormat ? 1u : 0u, + .viewFormats = WGPUTextureFormat_Undefined != viewFormat ? &viewFormat : NULL, }; m_texture = WGPU_CHECK(wgpuDeviceCreateTexture(s_renderWGPU->m_device, &textureDesc) ); if (needResolve) { - textureDesc.usage = WGPUTextureUsage_RenderAttachment; - textureDesc.mipLevelCount = 1; - textureDesc.sampleCount = m_msaaCount; + textureDesc.usage = WGPUTextureUsage_RenderAttachment; + textureDesc.mipLevelCount = 1; + textureDesc.sampleCount = m_msaaCount; + textureDesc.viewFormatCount = 0; + textureDesc.viewFormats = NULL; m_textureMsaa = WGPU_CHECK(wgpuDeviceCreateTexture(s_renderWGPU->m_device, &textureDesc) ); + + if (WGPUTextureFormat_Undefined != viewFormat) + { + textureDesc.format = viewFormat; + m_textureMsaaAlt = WGPU_CHECK(wgpuDeviceCreateTexture(s_renderWGPU->m_device, &textureDesc) ); + } } WGPUTexelCopyTextureInfo copyTextureDst = @@ -4848,6 +4902,7 @@ WGPU_IMPORT wgpuDestroy(m_texture); wgpuDestroy(m_textureMsaa); + wgpuDestroy(m_textureMsaaAlt); } void TextureWGPU::clear(uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers) @@ -5046,8 +5101,36 @@ WGPU_IMPORT return sampler; } - WGPUTextureView TextureWGPU::getTextureView(uint8_t _baseMipLevel, uint8_t _mipLevelCount, bool _storage, uint16_t _baseArrayLayer, uint16_t _arrayLayerCount, WGPUTextureViewDimension _viewDimension, bool _stencil) const + WGPUTextureFormat TextureWGPU::getViewFormat(uint32_t _flags, uint32_t _bit) const { + if (0 == (m_flags & BGFX_TEXTURE_SRGB_MUTABLE) ) + { + return m_fmt; + } + + const TextureFormatInfo& tfi = s_textureFormat[m_textureFormat]; + const WGPUTextureFormat format = 0 != (_flags & _bit) ? tfi.m_fmtSrgb : tfi.m_fmt; + + return WGPUTextureFormat_Undefined != format ? format : m_fmt; + } + + WGPUTextureView TextureWGPU::getTextureView(uint8_t _baseMipLevel, uint8_t _mipLevelCount, bool _storage, uint16_t _baseArrayLayer, uint16_t _arrayLayerCount, WGPUTextureViewDimension _viewDimension, bool _stencil, WGPUTextureFormat _format) const + { + const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(m_textureFormat) ); + const bool depthOnly = !_stencil + && 0 < blockInfo.depthBits + && 0 < blockInfo.stencilBits + ; + + const WGPUTextureFormat format = _stencil + ? WGPUTextureFormat_Stencil8 + : depthOnly + ? WGPUTextureFormat_Undefined + : _storage || WGPUTextureFormat_Undefined == _format + ? m_fmt + : _format + ; + bx::HashMurmur3 murmur; murmur.begin(); murmur.add(uintptr_t(this) ); @@ -5058,6 +5141,7 @@ WGPU_IMPORT murmur.add(_arrayLayerCount); murmur.add(_viewDimension); murmur.add(_stencil); + murmur.add(format); const uint32_t hash = murmur.end(); WGPUTextureView textureView = s_renderWGPU->m_textureViewStateCache.find(hash); @@ -5090,10 +5174,7 @@ WGPU_IMPORT { .nextInChain = NULL, .label = WGPU_STRING_VIEW_INIT, - .format = _stencil - ? WGPUTextureFormat_Stencil8 - : m_fmt - , + .format = format, .dimension = tvd, .baseMipLevel = _baseMipLevel, .mipLevelCount = UINT8_MAX == _mipLevelCount ? WGPU_MIP_LEVEL_COUNT_UNDEFINED : _mipLevelCount, @@ -5101,6 +5182,8 @@ WGPU_IMPORT .arrayLayerCount = arrayLayerCount, .aspect = _stencil ? WGPUTextureAspect_StencilOnly + : depthOnly + ? WGPUTextureAspect_DepthOnly : WGPUTextureAspect_All , .usage = 0 @@ -5724,12 +5807,13 @@ WGPU_IMPORT { const Attachment& at = m_attachment[ii]; const TextureWGPU& texture = s_renderWGPU->m_textures[at.handle.idx]; + const WGPUTextureFormat viewFormat = texture.getViewFormat(at.flags, BGFX_ATTACHMENT_SRGB); WGPUTextureViewDescriptor textureViewDesc = { .nextInChain = NULL, .label = WGPU_STRING_VIEW_INIT, - .format = texture.m_fmt, + .format = viewFormat, .dimension = at.numLayers > 1 ? WGPUTextureViewDimension_2DArray : WGPUTextureViewDimension_2D, .baseMipLevel = at.mip, .mipLevelCount = 1, @@ -5744,7 +5828,10 @@ WGPU_IMPORT WGPUTextureViewDescriptor msaaViewDesc = textureViewDesc; msaaViewDesc.baseMipLevel = 0; - WGPUTexture attachment = isMsaa ? texture.m_textureMsaa : texture.m_texture; + WGPUTexture attachment = isMsaa + ? (viewFormat != texture.m_fmt && NULL != texture.m_textureMsaaAlt ? texture.m_textureMsaaAlt : texture.m_textureMsaa) + : texture.m_texture + ; WGPUTextureView attachmentView = WGPU_CHECK(wgpuTextureCreateView(attachment, isMsaa ? &msaaViewDesc : &textureViewDesc) ); if (bimg::isDepth(bimg::TextureFormat::Enum(texture.m_textureFormat) ) ) @@ -5766,6 +5853,7 @@ WGPU_IMPORT m_textureView[m_numColorAttachments] = attachmentView; m_resolveView[m_numColorAttachments] = resolveView; + m_colorFormat[m_numColorAttachments] = viewFormat; m_texture[m_numColorAttachments] = at.handle; m_numColorAttachments++; } diff --git a/src/renderer_webgpu.h b/src/renderer_webgpu.h index c433f18a1..bd88a8c04 100644 --- a/src/renderer_webgpu.h +++ b/src/renderer_webgpu.h @@ -635,6 +635,7 @@ namespace wgpu { TextureWGPU() : m_texture(NULL) , m_textureMsaa(NULL) + , m_textureMsaaAlt(NULL) , m_msaaCount(1) , m_type(Texture2D) { @@ -646,10 +647,12 @@ namespace wgpu { void clear(uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers); WGPUSampler getSamplerState(uint32_t _samplerFlags) const; - WGPUTextureView getTextureView(uint8_t _baseMipLevel, uint8_t _mipLevelCount, bool _storage, uint16_t _baseArrayLayer = 0, uint16_t _arrayLayerCount = UINT16_MAX, WGPUTextureViewDimension _viewDimension = WGPUTextureViewDimension_Undefined, bool _stencil = false) const; + WGPUTextureView getTextureView(uint8_t _baseMipLevel, uint8_t _mipLevelCount, bool _storage, uint16_t _baseArrayLayer = 0, uint16_t _arrayLayerCount = UINT16_MAX, WGPUTextureViewDimension _viewDimension = WGPUTextureViewDimension_Undefined, bool _stencil = false, WGPUTextureFormat _format = WGPUTextureFormat_Undefined) const; + WGPUTextureFormat getViewFormat(uint32_t _flags, uint32_t _bit) const; WGPUTexture m_texture; WGPUTexture m_textureMsaa; + WGPUTexture m_textureMsaaAlt; WGPUTextureViewDimension m_viewDimension; WGPUTextureFormat m_fmt; @@ -745,6 +748,7 @@ namespace wgpu { Attachment m_attachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; WGPUTextureView m_textureView[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; WGPUTextureView m_resolveView[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; + WGPUTextureFormat m_colorFormat[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; WGPUTextureView m_depthStencilView; uint8_t m_formatDepthStencil;