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;