diff --git a/bindings/bf/bgfx.bf b/bindings/bf/bgfx.bf
index 39f28662d..005c00f90 100644
--- a/bindings/bf/bgfx.bf
+++ b/bindings/bf/bgfx.bf
@@ -1847,6 +1847,27 @@ public static class bgfx
Count
}
+ [AllowDuplicates]
+ public enum UniformFreq : uint32
+ {
+ ///
+ /// Changing per draw call.
+ ///
+ Draw,
+
+ ///
+ /// Changing per view.
+ ///
+ View,
+
+ ///
+ /// Changing per frame.
+ ///
+ Frame,
+
+ Count
+ }
+
[AllowDuplicates]
public enum BackbufferRatio : uint32
{
@@ -3432,6 +3453,41 @@ public static class bgfx
[LinkName("bgfx_create_uniform")]
public static extern UniformHandle create_uniform(char8* _name, UniformType _type, uint16 _num);
+ ///
+ /// Create shader uniform parameter.
+ /// @remarks
+ /// 1. Uniform names are unique. It's valid to call `bgfx::createUniform`
+ /// multiple times with the same uniform name. The library will always
+ /// return the same handle, but the handle reference count will be
+ /// incremented. This means that the same number of `bgfx::destroyUniform`
+ /// must be called to properly destroy the uniform.
+ /// 2. Predefined uniforms (declared in `bgfx_shader.sh`):
+ /// - `u_viewRect vec4(x, y, width, height)` - view rectangle for current
+ /// view, in pixels.
+ /// - `u_viewTexel vec4(1.0/width, 1.0/height, undef, undef)` - inverse
+ /// width and height
+ /// - `u_view mat4` - view matrix
+ /// - `u_invView mat4` - inverted view matrix
+ /// - `u_proj mat4` - projection matrix
+ /// - `u_invProj mat4` - inverted projection matrix
+ /// - `u_viewProj mat4` - concatenated view projection matrix
+ /// - `u_invViewProj mat4` - concatenated inverted view projection matrix
+ /// - `u_model mat4[BGFX_CONFIG_MAX_BONES]` - array of model matrices.
+ /// - `u_modelView mat4` - concatenated model view matrix, only first
+ /// model matrix from array is used.
+ /// - `u_invModelView mat4` - inverted concatenated model view matrix.
+ /// - `u_modelViewProj mat4` - concatenated model view projection matrix.
+ /// - `u_alphaRef float` - alpha reference value for alpha test.
+ ///
+ ///
+ /// Uniform name in shader.
+ /// Uniform change frequency (See: `bgfx::UniformFreq`).
+ /// Type of uniform (See: `bgfx::UniformType`).
+ /// Number of elements in array.
+ ///
+ [LinkName("bgfx_create_uniform_with_freq")]
+ public static extern UniformHandle create_uniform_with_freq(char8* _name, UniformFreq _freq, UniformType _type, uint16 _num);
+
///
/// Retrieve uniform info.
///
@@ -3804,6 +3860,31 @@ 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 for view.
+ /// @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
+ ///
+ ///
+ /// View id.
+ /// Uniform.
+ /// Pointer to uniform data.
+ /// Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.
+ ///
+ [LinkName("bgfx_set_view_uniform")]
+ public static extern void set_view_uniform(ViewId _id, UniformHandle _handle, void* _value, uint16 _num);
+
+ ///
+ /// Set shader uniform parameter for frame.
+ /// @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
+ ///
+ ///
+ /// Uniform.
+ /// Pointer to uniform data.
+ /// Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.
+ ///
+ [LinkName("bgfx_set_frame_uniform")]
+ public static extern void set_frame_uniform(UniformHandle _handle, void* _value, uint16 _num);
+
///
/// Set index buffer for draw primitive.
///
diff --git a/bindings/c3/bgfx.c3 b/bindings/c3/bgfx.c3
index 4eab1f66b..9ea22ca84 100644
--- a/bindings/c3/bgfx.c3
+++ b/bindings/c3/bgfx.c3
@@ -1185,6 +1185,20 @@ enum UniformType : uint
COUNT
}
+enum UniformFreq : uint
+{
+ // Changing per draw call.
+ DRAW,
+
+ // Changing per view.
+ VIEW,
+
+ // Changing per frame.
+ FRAME,
+
+ COUNT
+}
+
enum BackbufferRatio : uint
{
// Equal to backbuffer.
@@ -2452,6 +2466,36 @@ extern fn void destroy_frame_buffer(FrameBufferHandle _handle) @extern("bgfx_des
// _num : `Number of elements in array.`
extern fn UniformHandle create_uniform(ZString _name, UniformType _type, ushort _num) @extern("bgfx_create_uniform");
+// Create shader uniform parameter.
+// @remarks
+// 1. Uniform names are unique. It's valid to call `bgfx::createUniform`
+// multiple times with the same uniform name. The library will always
+// return the same handle, but the handle reference count will be
+// incremented. This means that the same number of `bgfx::destroyUniform`
+// must be called to properly destroy the uniform.
+// 2. Predefined uniforms (declared in `bgfx_shader.sh`):
+// - `u_viewRect vec4(x, y, width, height)` - view rectangle for current
+// view, in pixels.
+// - `u_viewTexel vec4(1.0/width, 1.0/height, undef, undef)` - inverse
+// width and height
+// - `u_view mat4` - view matrix
+// - `u_invView mat4` - inverted view matrix
+// - `u_proj mat4` - projection matrix
+// - `u_invProj mat4` - inverted projection matrix
+// - `u_viewProj mat4` - concatenated view projection matrix
+// - `u_invViewProj mat4` - concatenated inverted view projection matrix
+// - `u_model mat4[BGFX_CONFIG_MAX_BONES]` - array of model matrices.
+// - `u_modelView mat4` - concatenated model view matrix, only first
+// model matrix from array is used.
+// - `u_invModelView mat4` - inverted concatenated model view matrix.
+// - `u_modelViewProj mat4` - concatenated model view projection matrix.
+// - `u_alphaRef float` - alpha reference value for alpha test.
+// _name : `Uniform name in shader.`
+// _freq : `Uniform change frequency (See: `bgfx::UniformFreq`).`
+// _type : `Type of uniform (See: `bgfx::UniformType`).`
+// _num : `Number of elements in array.`
+extern fn UniformHandle create_uniform_with_freq(ZString _name, UniformFreq _freq, UniformType _type, ushort _num) @extern("bgfx_create_uniform_with_freq");
+
// Retrieve uniform info.
// _handle : `Handle to uniform object.`
// _info : `Uniform info.`
@@ -2666,6 +2710,21 @@ 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) @extern("bgfx_encoder_set_uniform");
+// Set shader uniform parameter for view.
+// @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
+// _id : `View id.`
+// _handle : `Uniform.`
+// _value : `Pointer to uniform data.`
+// _num : `Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.`
+extern fn void set_view_uniform(ushort _id, UniformHandle _handle, void* _value, ushort _num) @extern("bgfx_set_view_uniform");
+
+// Set shader uniform parameter for frame.
+// @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
+// _handle : `Uniform.`
+// _value : `Pointer to uniform data.`
+// _num : `Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.`
+extern fn void set_frame_uniform(UniformHandle _handle, void* _value, ushort _num) @extern("bgfx_set_frame_uniform");
+
// Set index buffer for draw primitive.
// _handle : `Index buffer.`
// _firstIndex : `First index to render.`
diff --git a/bindings/cs/bgfx.cs b/bindings/cs/bgfx.cs
index 2c07d4b73..ee0f5286a 100644
--- a/bindings/cs/bgfx.cs
+++ b/bindings/cs/bgfx.cs
@@ -1839,6 +1839,26 @@ public static partial class bgfx
Count
}
+ public enum UniformFreq
+ {
+ ///
+ /// Changing per draw call.
+ ///
+ Draw,
+
+ ///
+ /// Changing per view.
+ ///
+ View,
+
+ ///
+ /// Changing per frame.
+ ///
+ Frame,
+
+ Count
+ }
+
public enum BackbufferRatio
{
///
@@ -3386,6 +3406,41 @@ public static partial class bgfx
[DllImport(DllName, EntryPoint="bgfx_create_uniform", CallingConvention = CallingConvention.Cdecl)]
public static extern unsafe UniformHandle create_uniform([MarshalAs(UnmanagedType.LPStr)] string _name, UniformType _type, ushort _num);
+ ///
+ /// Create shader uniform parameter.
+ /// @remarks
+ /// 1. Uniform names are unique. It's valid to call `bgfx::createUniform`
+ /// multiple times with the same uniform name. The library will always
+ /// return the same handle, but the handle reference count will be
+ /// incremented. This means that the same number of `bgfx::destroyUniform`
+ /// must be called to properly destroy the uniform.
+ /// 2. Predefined uniforms (declared in `bgfx_shader.sh`):
+ /// - `u_viewRect vec4(x, y, width, height)` - view rectangle for current
+ /// view, in pixels.
+ /// - `u_viewTexel vec4(1.0/width, 1.0/height, undef, undef)` - inverse
+ /// width and height
+ /// - `u_view mat4` - view matrix
+ /// - `u_invView mat4` - inverted view matrix
+ /// - `u_proj mat4` - projection matrix
+ /// - `u_invProj mat4` - inverted projection matrix
+ /// - `u_viewProj mat4` - concatenated view projection matrix
+ /// - `u_invViewProj mat4` - concatenated inverted view projection matrix
+ /// - `u_model mat4[BGFX_CONFIG_MAX_BONES]` - array of model matrices.
+ /// - `u_modelView mat4` - concatenated model view matrix, only first
+ /// model matrix from array is used.
+ /// - `u_invModelView mat4` - inverted concatenated model view matrix.
+ /// - `u_modelViewProj mat4` - concatenated model view projection matrix.
+ /// - `u_alphaRef float` - alpha reference value for alpha test.
+ ///
+ ///
+ /// Uniform name in shader.
+ /// Uniform change frequency (See: `bgfx::UniformFreq`).
+ /// Type of uniform (See: `bgfx::UniformType`).
+ /// Number of elements in array.
+ ///
+ [DllImport(DllName, EntryPoint="bgfx_create_uniform_with_freq", CallingConvention = CallingConvention.Cdecl)]
+ public static extern unsafe UniformHandle create_uniform_with_freq([MarshalAs(UnmanagedType.LPStr)] string _name, UniformFreq _freq, UniformType _type, ushort _num);
+
///
/// Retrieve uniform info.
///
@@ -3758,6 +3813,31 @@ 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 for view.
+ /// @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
+ ///
+ ///
+ /// View id.
+ /// Uniform.
+ /// Pointer to uniform data.
+ /// Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.
+ ///
+ [DllImport(DllName, EntryPoint="bgfx_set_view_uniform", CallingConvention = CallingConvention.Cdecl)]
+ public static extern unsafe void set_view_uniform(ushort _id, UniformHandle _handle, void* _value, ushort _num);
+
+ ///
+ /// Set shader uniform parameter for frame.
+ /// @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
+ ///
+ ///
+ /// Uniform.
+ /// Pointer to uniform data.
+ /// Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.
+ ///
+ [DllImport(DllName, EntryPoint="bgfx_set_frame_uniform", CallingConvention = CallingConvention.Cdecl)]
+ public static extern unsafe void set_frame_uniform(UniformHandle _handle, void* _value, ushort _num);
+
///
/// Set index buffer for draw primitive.
///
diff --git a/bindings/d/impl.d b/bindings/d/impl.d
index d96108c2e..08c09a7d3 100644
--- a/bindings/d/impl.d
+++ b/bindings/d/impl.d
@@ -54,6 +54,11 @@ extern(C++, "bgfx") package final abstract class UniformType{
sampler,end,vec4,mat3,mat4,count
}
}
+extern(C++, "bgfx") package final abstract class UniformFreq{
+ enum Enum{
+ draw,view,frame,count
+ }
+}
extern(C++, "bgfx") package final abstract class BackbufferRatio{
enum Enum{
equal,half,quarter,eighth,sixteenth,double_,count
diff --git a/bindings/d/package.d b/bindings/d/package.d
index d9989f2f4..34ad90ac0 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 = 133;
+enum uint apiVersion = 134;
alias ViewID = ushort;
@@ -771,6 +771,14 @@ enum UniformType: bgfx.impl.UniformType.Enum{
count = bgfx.impl.UniformType.Enum.count,
}
+///Uniform frequency enum.
+enum UniformFreq: bgfx.impl.UniformFreq.Enum{
+ draw = bgfx.impl.UniformFreq.Enum.draw,
+ view = bgfx.impl.UniformFreq.Enum.view,
+ frame = bgfx.impl.UniformFreq.Enum.frame,
+ count = bgfx.impl.UniformFreq.Enum.count,
+}
+
///Backbuffer ratio enum.
enum BackbufferRatio: bgfx.impl.BackbufferRatio.Enum{
equal = bgfx.impl.BackbufferRatio.Enum.equal,
@@ -2848,6 +2856,39 @@ mixin(joinFnBinds((){
*/
{q{UniformHandle}, q{createUniform}, q{const(char)* name, bgfx.impl.UniformType.Enum type, ushort num=1}, ext: `C++, "bgfx"`},
+ /**
+ * Create shader uniform parameter.
+ * Remarks:
+ * 1. Uniform names are unique. It's valid to call `bgfx::createUniform`
+ * multiple times with the same uniform name. The library will always
+ * return the same handle, but the handle reference count will be
+ * incremented. This means that the same number of `bgfx::destroyUniform`
+ * must be called to properly destroy the uniform.
+ * 2. Predefined uniforms (declared in `bgfx_shader.sh`):
+ * - `u_viewRect vec4(x, y, width, height)` - view rectangle for current
+ * view, in pixels.
+ * - `u_viewTexel vec4(1.0/width, 1.0/height, undef, undef)` - inverse
+ * width and height
+ * - `u_view mat4` - view matrix
+ * - `u_invView mat4` - inverted view matrix
+ * - `u_proj mat4` - projection matrix
+ * - `u_invProj mat4` - inverted projection matrix
+ * - `u_viewProj mat4` - concatenated view projection matrix
+ * - `u_invViewProj mat4` - concatenated inverted view projection matrix
+ * - `u_model mat4[BGFX_CONFIG_MAX_BONES]` - array of model matrices.
+ * - `u_modelView mat4` - concatenated model view matrix, only first
+ * model matrix from array is used.
+ * - `u_invModelView mat4` - inverted concatenated model view matrix.
+ * - `u_modelViewProj mat4` - concatenated model view projection matrix.
+ * - `u_alphaRef float` - alpha reference value for alpha test.
+ Params:
+ name = Uniform name in shader.
+ freq = Uniform change frequency (See: `bgfx::UniformFreq`).
+ type = Type of uniform (See: `bgfx::UniformType`).
+ num = Number of elements in array.
+ */
+ {q{UniformHandle}, q{createUniform}, q{const(char)* name, bgfx.impl.UniformFreq.Enum freq, bgfx.impl.UniformType.Enum type, ushort num=1}, ext: `C++, "bgfx"`},
+
/**
* Retrieve uniform info.
Params:
@@ -3065,6 +3106,29 @@ mixin(joinFnBinds((){
*/
{q{void}, q{end}, q{Encoder* encoder}, ext: `C++, "bgfx"`},
+ /**
+ * Set shader uniform parameter for view.
+ * Attention: Uniform must be created with `bgfx::UniformFreq::View` argument.
+ Params:
+ id = View id.
+ handle = Uniform.
+ value = Pointer to uniform data.
+ num = Number of elements. Passing `UINT16_MAX` will
+ use the _num passed on uniform creation.
+ */
+ {q{void}, q{setViewUniform}, q{ViewID id, UniformHandle handle, const(void)* value, ushort num=1}, ext: `C++, "bgfx"`},
+
+ /**
+ * Set shader uniform parameter for frame.
+ * Attention: Uniform must be created with `bgfx::UniformFreq::View` argument.
+ Params:
+ handle = Uniform.
+ value = Pointer to uniform data.
+ num = Number of elements. Passing `UINT16_MAX` will
+ use the _num passed on uniform creation.
+ */
+ {q{void}, q{setFrameUniform}, q{UniformHandle handle, const(void)* value, ushort num=1}, ext: `C++, "bgfx"`},
+
/**
* Request screen shot of window back buffer.
* Remarks:
diff --git a/bindings/zig/bgfx.zig b/bindings/zig/bgfx.zig
index 0c6bb2635..e1157755a 100644
--- a/bindings/zig/bgfx.zig
+++ b/bindings/zig/bgfx.zig
@@ -1151,6 +1151,19 @@ pub const UniformType = enum(c_int) {
Count
};
+pub const UniformFreq = enum(c_int) {
+ /// Changing per draw call.
+ Draw,
+
+ /// Changing per view.
+ View,
+
+ /// Changing per frame.
+ Frame,
+
+ Count
+};
+
pub const BackbufferRatio = enum(c_int) {
/// Equal to backbuffer.
Equal,
@@ -2760,6 +2773,39 @@ pub inline fn createUniform(_name: [*c]const u8, _type: UniformType, _num: u16)
}
extern fn bgfx_create_uniform(_name: [*c]const u8, _type: UniformType, _num: u16) UniformHandle;
+/// Create shader uniform parameter.
+/// @remarks
+/// 1. Uniform names are unique. It's valid to call `bgfx::createUniform`
+/// multiple times with the same uniform name. The library will always
+/// return the same handle, but the handle reference count will be
+/// incremented. This means that the same number of `bgfx::destroyUniform`
+/// must be called to properly destroy the uniform.
+/// 2. Predefined uniforms (declared in `bgfx_shader.sh`):
+/// - `u_viewRect vec4(x, y, width, height)` - view rectangle for current
+/// view, in pixels.
+/// - `u_viewTexel vec4(1.0/width, 1.0/height, undef, undef)` - inverse
+/// width and height
+/// - `u_view mat4` - view matrix
+/// - `u_invView mat4` - inverted view matrix
+/// - `u_proj mat4` - projection matrix
+/// - `u_invProj mat4` - inverted projection matrix
+/// - `u_viewProj mat4` - concatenated view projection matrix
+/// - `u_invViewProj mat4` - concatenated inverted view projection matrix
+/// - `u_model mat4[BGFX_CONFIG_MAX_BONES]` - array of model matrices.
+/// - `u_modelView mat4` - concatenated model view matrix, only first
+/// model matrix from array is used.
+/// - `u_invModelView mat4` - inverted concatenated model view matrix.
+/// - `u_modelViewProj mat4` - concatenated model view projection matrix.
+/// - `u_alphaRef float` - alpha reference value for alpha test.
+/// Uniform name in shader.
+/// Uniform change frequency (See: `bgfx::UniformFreq`).
+/// Type of uniform (See: `bgfx::UniformType`).
+/// Number of elements in array.
+pub inline fn createUniformWithFreq(_name: [*c]const u8, _freq: UniformFreq, _type: UniformType, _num: u16) UniformHandle {
+ return bgfx_create_uniform_with_freq(_name, _freq, _type, _num);
+}
+extern fn bgfx_create_uniform_with_freq(_name: [*c]const u8, _freq: UniformFreq, _type: UniformType, _num: u16) UniformHandle;
+
/// Retrieve uniform info.
/// Handle to uniform object.
/// Uniform info.
@@ -3040,6 +3086,27 @@ 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 for view.
+/// @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
+/// View id.
+/// Uniform.
+/// Pointer to uniform data.
+/// Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.
+pub inline fn setViewUniform(_id: ViewId, _handle: UniformHandle, _value: ?*const anyopaque, _num: u16) void {
+ return bgfx_set_view_uniform(_id, _handle, _value, _num);
+}
+extern fn bgfx_set_view_uniform(_id: ViewId, _handle: UniformHandle, _value: ?*const anyopaque, _num: u16) void;
+
+/// Set shader uniform parameter for frame.
+/// @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
+/// Uniform.
+/// Pointer to uniform data.
+/// Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.
+pub inline fn setFrameUniform(_handle: UniformHandle, _value: ?*const anyopaque, _num: u16) void {
+ return bgfx_set_frame_uniform(_handle, _value, _num);
+}
+extern fn bgfx_set_frame_uniform(_handle: UniformHandle, _value: ?*const anyopaque, _num: u16) void;
+
/// Set index buffer for draw primitive.
/// Index buffer.
/// First index to render.
diff --git a/examples/04-mesh/mesh.cpp b/examples/04-mesh/mesh.cpp
index 62d49ca7c..123cc56e2 100644
--- a/examples/04-mesh/mesh.cpp
+++ b/examples/04-mesh/mesh.cpp
@@ -49,7 +49,7 @@ public:
, 0
);
- u_time = bgfx::createUniform("u_time", bgfx::UniformType::Vec4);
+ u_time = bgfx::createUniform("u_time", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
// Create program from shaders.
m_program = loadProgram("vs_mesh", "fs_mesh");
@@ -104,7 +104,7 @@ public:
bgfx::touch(0);
float time = (float)( (bx::getHPCounter()-m_timeOffset)/double(bx::getHPFrequency() ) );
- bgfx::setUniform(u_time, &time);
+ bgfx::setFrameUniform(u_time, &time);
const bx::Vec3 at = { 0.0f, 1.0f, 0.0f };
const bx::Vec3 eye = { 0.0f, 1.0f, -2.5f };
diff --git a/examples/08-update/update.cpp b/examples/08-update/update.cpp
index f5f5b7ba7..6a774c2e0 100644
--- a/examples/08-update/update.cpp
+++ b/examples/08-update/update.cpp
@@ -367,7 +367,7 @@ public:
s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Sampler);
// Create time uniform.
- u_time = bgfx::createUniform("u_time", bgfx::UniformType::Vec4);
+ u_time = bgfx::createUniform("u_time", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
for(uint32_t ii = 0; ii m_updateTime)
{
diff --git a/examples/09-hdr/hdr.cpp b/examples/09-hdr/hdr.cpp
index 838a0051e..69ceec58d 100644
--- a/examples/09-hdr/hdr.cpp
+++ b/examples/09-hdr/hdr.cpp
@@ -187,9 +187,11 @@ public:
s_texLum = bgfx::createUniform("s_texLum", bgfx::UniformType::Sampler);
s_texBlur = bgfx::createUniform("s_texBlur", bgfx::UniformType::Sampler);
u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Mat4);
- u_tonemap = bgfx::createUniform("u_tonemap", bgfx::UniformType::Vec4);
u_offset = bgfx::createUniform("u_offset", bgfx::UniformType::Vec4, 16);
+ // Tonemap value will be updated once per frame.
+ u_tonemap = bgfx::createUniform("u_tonemap", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+
m_mesh = meshLoad("meshes/bunny.bin");
m_fbh.idx = bgfx::kInvalidHandle;
@@ -515,7 +517,8 @@ public:
// Set view and projection matrix for view hdrMesh.
bgfx::setViewTransform(hdrMesh, view, proj);
- float tonemap[4] = { m_middleGray, bx::square(m_white), m_threshold, m_time };
+ const float tonemap[4] = { m_middleGray, bx::square(m_white), m_threshold, m_time };
+ bgfx::setFrameUniform(u_tonemap, tonemap);
// Render skybox into view hdrSkybox.
bgfx::setTexture(0, s_texCube, m_uffizi);
@@ -526,7 +529,6 @@ public:
// Render m_mesh into view hdrMesh.
bgfx::setTexture(0, s_texCube, m_uffizi);
- bgfx::setUniform(u_tonemap, tonemap);
meshSubmit(m_mesh, hdrMesh, m_meshProgram, NULL);
// Calculate luminance.
@@ -569,14 +571,12 @@ public:
bgfx::setTexture(0, s_texColor, m_fbtextures[0]);
bgfx::setTexture(1, s_texLum, bgfx::getTexture(m_lum[4]) );
bgfx::setState(BGFX_STATE_WRITE_RGB|BGFX_STATE_WRITE_A);
- bgfx::setUniform(u_tonemap, tonemap);
screenSpaceQuad(m_caps->originBottomLeft);
bgfx::submit(hdrBrightness, m_brightProgram);
// m_blur m_bright pass vertically.
bgfx::setTexture(0, s_texColor, bgfx::getTexture(m_bright) );
bgfx::setState(BGFX_STATE_WRITE_RGB|BGFX_STATE_WRITE_A);
- bgfx::setUniform(u_tonemap, tonemap);
screenSpaceQuad(m_caps->originBottomLeft);
bgfx::submit(hdrVBlur, m_blurProgram);
diff --git a/examples/13-stencil/stencil.cpp b/examples/13-stencil/stencil.cpp
index d082677ac..34f2a7e4b 100644
--- a/examples/13-stencil/stencil.cpp
+++ b/examples/13-stencil/stencil.cpp
@@ -288,21 +288,22 @@ struct Uniforms
m_lightRgbInnerR[ii][3] = 1.0f;
}
+ u_ambient = bgfx::createUniform("u_ambient", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+ u_diffuse = bgfx::createUniform("u_diffuse", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+ u_specular_shininess = bgfx::createUniform("u_specular_shininess", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+
u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4);
- u_ambient = bgfx::createUniform("u_ambient", bgfx::UniformType::Vec4);
- u_diffuse = bgfx::createUniform("u_diffuse", bgfx::UniformType::Vec4);
- u_specular_shininess = bgfx::createUniform("u_specular_shininess", bgfx::UniformType::Vec4);
u_color = bgfx::createUniform("u_color", bgfx::UniformType::Vec4);
u_lightPosRadius = bgfx::createUniform("u_lightPosRadius", bgfx::UniformType::Vec4, MAX_NUM_LIGHTS);
u_lightRgbInnerR = bgfx::createUniform("u_lightRgbInnerR", bgfx::UniformType::Vec4, MAX_NUM_LIGHTS);
}
//call this once at initialization
- void submitConstUniforms()
+ void submitFrameUniforms()
{
- bgfx::setUniform(u_ambient, &m_ambient);
- bgfx::setUniform(u_diffuse, &m_diffuse);
- bgfx::setUniform(u_specular_shininess, &m_specular_shininess);
+ bgfx::setFrameUniform(u_ambient, &m_ambient);
+ bgfx::setFrameUniform(u_diffuse, &m_diffuse);
+ bgfx::setFrameUniform(u_specular_shininess, &m_specular_shininess);
}
//call this before each draw call
@@ -979,7 +980,7 @@ public:
imguiEndFrame();
- s_uniforms.submitConstUniforms();
+ s_uniforms.submitFrameUniforms();
// Update settings.
uint8_t numLights = (uint8_t)m_numLights;
diff --git a/examples/16-shadowmaps/shadowmaps.cpp b/examples/16-shadowmaps/shadowmaps.cpp
index f648a624a..c90d1105e 100644
--- a/examples/16-shadowmaps/shadowmaps.cpp
+++ b/examples/16-shadowmaps/shadowmaps.cpp
@@ -385,55 +385,49 @@ struct Uniforms
m_csmFarDistances[2] = 180.0f;
m_csmFarDistances[3] = 1000.0f;
- m_tetraNormalGreen[0] = 0.0f;
- m_tetraNormalGreen[1] = -0.57735026f;
- m_tetraNormalGreen[2] = 0.81649661f;
-
- m_tetraNormalYellow[0] = 0.0f;
- m_tetraNormalYellow[1] = -0.57735026f;
- m_tetraNormalYellow[2] = -0.81649661f;
-
- m_tetraNormalBlue[0] = -0.81649661f;
- m_tetraNormalBlue[1] = 0.57735026f;
- m_tetraNormalBlue[2] = 0.0f;
-
- m_tetraNormalRed[0] = 0.81649661f;
- m_tetraNormalRed[1] = 0.57735026f;
- m_tetraNormalRed[2] = 0.0f;
-
m_XNum = 2.0f;
m_YNum = 2.0f;
m_XOffset = 10.0f/512.0f;
m_YOffset = 10.0f/512.0f;
u_params0 = bgfx::createUniform("u_params0", bgfx::UniformType::Vec4);
- u_params1 = bgfx::createUniform("u_params1", bgfx::UniformType::Vec4);
- u_params2 = bgfx::createUniform("u_params2", bgfx::UniformType::Vec4);
+ u_params1 = bgfx::createUniform("u_params1", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+ u_params2 = bgfx::createUniform("u_params2", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
u_color = bgfx::createUniform("u_color", bgfx::UniformType::Vec4);
- u_smSamplingParams = bgfx::createUniform("u_smSamplingParams", bgfx::UniformType::Vec4);
- u_csmFarDistances = bgfx::createUniform("u_csmFarDistances", bgfx::UniformType::Vec4);
+ u_smSamplingParams = bgfx::createUniform("u_smSamplingParams", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+ u_csmFarDistances = bgfx::createUniform("u_csmFarDistances", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
u_lightMtx = bgfx::createUniform("u_lightMtx", bgfx::UniformType::Mat4);
- u_tetraNormalGreen = bgfx::createUniform("u_tetraNormalGreen", bgfx::UniformType::Vec4);
- u_tetraNormalYellow = bgfx::createUniform("u_tetraNormalYellow", bgfx::UniformType::Vec4);
- u_tetraNormalBlue = bgfx::createUniform("u_tetraNormalBlue", bgfx::UniformType::Vec4);
- u_tetraNormalRed = bgfx::createUniform("u_tetraNormalRed", bgfx::UniformType::Vec4);
+ u_tetraNormalGreen = bgfx::createUniform("u_tetraNormalGreen", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+ u_tetraNormalYellow = bgfx::createUniform("u_tetraNormalYellow", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+ u_tetraNormalBlue = bgfx::createUniform("u_tetraNormalBlue", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+ u_tetraNormalRed = bgfx::createUniform("u_tetraNormalRed", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+
+ const float tetraNormalGreen[] = { 0.0f, -0.57735026f, 0.81649661f };
+ const float tetraNormalYellow[] = { 0.0f, -0.57735026f, -0.81649661f };
+ const float tetraNormalBlue[] = { -0.81649661f, 0.57735026f, 0.0f };
+ const float tetraNormalRed[] = { 0.81649661f, 0.57735026f, 0.0f };
+
+ bgfx::setFrameUniform(u_tetraNormalGreen, tetraNormalGreen);
+ bgfx::setFrameUniform(u_tetraNormalYellow, tetraNormalYellow);
+ bgfx::setFrameUniform(u_tetraNormalBlue, tetraNormalBlue);
+ bgfx::setFrameUniform(u_tetraNormalRed, tetraNormalRed);
u_shadowMapMtx0 = bgfx::createUniform("u_shadowMapMtx0", bgfx::UniformType::Mat4);
u_shadowMapMtx1 = bgfx::createUniform("u_shadowMapMtx1", bgfx::UniformType::Mat4);
u_shadowMapMtx2 = bgfx::createUniform("u_shadowMapMtx2", bgfx::UniformType::Mat4);
u_shadowMapMtx3 = bgfx::createUniform("u_shadowMapMtx3", bgfx::UniformType::Mat4);
- u_lightPosition = bgfx::createUniform("u_lightPosition", bgfx::UniformType::Vec4);
- u_lightAmbientPower = bgfx::createUniform("u_lightAmbientPower", bgfx::UniformType::Vec4);
- u_lightDiffusePower = bgfx::createUniform("u_lightDiffusePower", bgfx::UniformType::Vec4);
- u_lightSpecularPower = bgfx::createUniform("u_lightSpecularPower", bgfx::UniformType::Vec4);
- u_lightSpotDirectionInner = bgfx::createUniform("u_lightSpotDirectionInner", bgfx::UniformType::Vec4);
- u_lightAttenuationSpotOuter = bgfx::createUniform("u_lightAttenuationSpotOuter", bgfx::UniformType::Vec4);
+ u_lightPosition = bgfx::createUniform("u_lightPosition", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+ u_lightAmbientPower = bgfx::createUniform("u_lightAmbientPower", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+ u_lightDiffusePower = bgfx::createUniform("u_lightDiffusePower", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+ u_lightSpecularPower = bgfx::createUniform("u_lightSpecularPower", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+ u_lightSpotDirectionInner = bgfx::createUniform("u_lightSpotDirectionInner", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+ u_lightAttenuationSpotOuter = bgfx::createUniform("u_lightAttenuationSpotOuter", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
- u_materialKa = bgfx::createUniform("u_materialKa", bgfx::UniformType::Vec4);
- u_materialKd = bgfx::createUniform("u_materialKd", bgfx::UniformType::Vec4);
- u_materialKs = bgfx::createUniform("u_materialKs", bgfx::UniformType::Vec4);
+ u_materialKa = bgfx::createUniform("u_materialKa", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+ u_materialKd = bgfx::createUniform("u_materialKd", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
+ u_materialKs = bgfx::createUniform("u_materialKs", bgfx::UniformFreq::Frame, bgfx::UniformType::Vec4);
}
@@ -450,33 +444,24 @@ struct Uniforms
m_shadowMapMtx3 = _shadowMapMtx3;
}
- // Call this once at initialization.
- void submitConstUniforms()
- {
- bgfx::setUniform(u_tetraNormalGreen, m_tetraNormalGreen);
- bgfx::setUniform(u_tetraNormalYellow, m_tetraNormalYellow);
- bgfx::setUniform(u_tetraNormalBlue, m_tetraNormalBlue);
- bgfx::setUniform(u_tetraNormalRed, m_tetraNormalRed);
- }
-
// Call this once per frame.
void submitPerFrameUniforms()
{
- bgfx::setUniform(u_params1, m_params1);
- bgfx::setUniform(u_params2, m_params2);
- bgfx::setUniform(u_smSamplingParams, m_paramsBlur);
- bgfx::setUniform(u_csmFarDistances, m_csmFarDistances);
+ bgfx::setFrameUniform(u_params1, m_params1);
+ bgfx::setFrameUniform(u_params2, m_params2);
+ bgfx::setFrameUniform(u_smSamplingParams, m_paramsBlur);
+ bgfx::setFrameUniform(u_csmFarDistances, m_csmFarDistances);
- bgfx::setUniform(u_materialKa, &m_materialPtr->m_ka);
- bgfx::setUniform(u_materialKd, &m_materialPtr->m_kd);
- bgfx::setUniform(u_materialKs, &m_materialPtr->m_ks);
+ bgfx::setFrameUniform(u_materialKa, &m_materialPtr->m_ka);
+ bgfx::setFrameUniform(u_materialKd, &m_materialPtr->m_kd);
+ bgfx::setFrameUniform(u_materialKs, &m_materialPtr->m_ks);
- bgfx::setUniform(u_lightPosition, &m_lightPtr->m_position_viewSpace);
- bgfx::setUniform(u_lightAmbientPower, &m_lightPtr->m_ambientPower);
- bgfx::setUniform(u_lightDiffusePower, &m_lightPtr->m_diffusePower);
- bgfx::setUniform(u_lightSpecularPower, &m_lightPtr->m_specularPower);
- bgfx::setUniform(u_lightSpotDirectionInner, &m_lightPtr->m_spotDirectionInner_viewSpace);
- bgfx::setUniform(u_lightAttenuationSpotOuter, &m_lightPtr->m_attenuationSpotOuter);
+ bgfx::setFrameUniform(u_lightPosition, &m_lightPtr->m_position_viewSpace);
+ bgfx::setFrameUniform(u_lightAmbientPower, &m_lightPtr->m_ambientPower);
+ bgfx::setFrameUniform(u_lightDiffusePower, &m_lightPtr->m_diffusePower);
+ bgfx::setFrameUniform(u_lightSpecularPower, &m_lightPtr->m_specularPower);
+ bgfx::setFrameUniform(u_lightSpotDirectionInner, &m_lightPtr->m_spotDirectionInner_viewSpace);
+ bgfx::setFrameUniform(u_lightAttenuationSpotOuter, &m_lightPtr->m_attenuationSpotOuter);
}
// Call this before each draw call.
@@ -576,10 +561,6 @@ struct Uniforms
float m_paramsBlur[4];
};
- float m_tetraNormalGreen[3];
- float m_tetraNormalYellow[3];
- float m_tetraNormalBlue[3];
- float m_tetraNormalRed[3];
float m_csmFarDistances[4];
float* m_lightMtxPtr;
@@ -1252,7 +1233,6 @@ public:
, &m_shadowMapMtx[ShadowMapRenderTargets::Third][0]
, &m_shadowMapMtx[ShadowMapRenderTargets::Fourth][0]
);
- s_uniforms.submitConstUniforms();
// Settings.
ShadowMapSettings smSettings[LightType::Count][DepthImpl::Count][SmImpl::Count] =
@@ -1807,10 +1787,6 @@ public:
float currentShadowMapSizef = float(int16_t(m_currentShadowMapSize) );
s_uniforms.m_shadowMapTexelSize = 1.0f / currentShadowMapSizef;
- s_uniforms.submitConstUniforms();
-
- // s_uniforms.submitConstUniforms();
-
// Imgui.
imguiBeginFrame(m_mouseState.m_mx
, m_mouseState.m_my
diff --git a/examples/42-bunnylod/bunnylod.cpp b/examples/42-bunnylod/bunnylod.cpp
index 7192b4def..e1d8b417c 100644
--- a/examples/42-bunnylod/bunnylod.cpp
+++ b/examples/42-bunnylod/bunnylod.cpp
@@ -285,8 +285,6 @@ public:
, 0
);
- u_tint = bgfx::createUniform("u_tint", bgfx::UniformType::Vec4);
-
// Create program from shaders.
m_program = loadProgram("vs_bunnylod", "fs_bunnylod");
@@ -309,7 +307,6 @@ public:
bgfx::destroy(m_program);
bgfx::destroy(m_vb);
bgfx::destroy(m_ib);
- bgfx::destroy(u_tint);
bx::free(entry::getAllocator(), m_map);
bx::free(entry::getAllocator(), m_triangle);
@@ -432,8 +429,6 @@ public:
bgfx::touch(0);
float time = (float)( (bx::getHPCounter()-m_timeOffset)/double(bx::getHPFrequency() ) );
- const float BasicColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
- bgfx::setUniform(u_tint, BasicColor);
const bx::Vec3 at = { 0.0f, 1.0f, 0.0f };
const bx::Vec3 eye = { 0.0f, 1.0f, -2.5f };
@@ -493,7 +488,6 @@ public:
bgfx::VertexBufferHandle m_vb;
bgfx::DynamicIndexBufferHandle m_ib;
bgfx::ProgramHandle m_program;
- bgfx::UniformHandle u_tint;
};
} // namespace
diff --git a/include/bgfx/bgfx.h b/include/bgfx/bgfx.h
index 0edaf887b..e570926bd 100644
--- a/include/bgfx/bgfx.h
+++ b/include/bgfx/bgfx.h
@@ -284,6 +284,23 @@ namespace bgfx
};
};
+ /// Uniform frequency enum.
+ ///
+ /// @attention C99's equivalent binding is `bgfx_bgfx_uniform_freq_t`.
+ ///
+ struct UniformFreq
+ {
+ /// Uniform frequency:
+ enum Enum
+ {
+ Draw, //!< Changing per draw call.
+ View, //!< Changing per view.
+ Frame, //!< Changing per frame.
+
+ Count
+ };
+ };
+
/// Backbuffer ratio enum.
///
/// @attention C99's equivalent binding is `bgfx_backbuffer_ratio_t`.
@@ -3279,6 +3296,48 @@ namespace bgfx
, uint16_t _num = 1
);
+ /// Create shader uniform parameter.
+ ///
+ /// @param[in] _name Uniform name in shader.
+ /// @param[in] _freq Uniform change frequency (See: `bgfx::UniformFreq`).
+ /// @param[in] _type Type of uniform (See: `bgfx::UniformType`).
+ /// @param[in] _num Number of elements in array.
+ ///
+ /// @returns Handle to uniform object.
+ ///
+ /// @remarks
+ /// 1. Uniform names are unique. It's valid to call `bgfx::createUniform`
+ /// multiple times with the same uniform name. The library will always
+ /// return the same handle, but the handle reference count will be
+ /// incremented. This means that the same number of `bgfx::destroyUniform`
+ /// must be called to properly destroy the uniform.
+ /// 2. Predefined uniforms (declared in `bgfx_shader.sh`):
+ /// - `u_viewRect vec4(x, y, width, height)` - view rectangle for current
+ /// view, in pixels.
+ /// - `u_viewTexel vec4(1.0/width, 1.0/height, undef, undef)` - inverse
+ /// width and height
+ /// - `u_view mat4` - view matrix
+ /// - `u_invView mat4` - inverted view matrix
+ /// - `u_proj mat4` - projection matrix
+ /// - `u_invProj mat4` - inverted projection matrix
+ /// - `u_viewProj mat4` - concatenated view projection matrix
+ /// - `u_invViewProj mat4` - concatenated inverted view projection matrix
+ /// - `u_model mat4[BGFX_CONFIG_MAX_BONES]` - array of model matrices.
+ /// - `u_modelView mat4` - concatenated model view matrix, only first
+ /// model matrix from array is used.
+ /// - `u_invModelView mat4` - inverted concatenated model view matrix.
+ /// - `u_modelViewProj mat4` - concatenated model view projection matrix.
+ /// - `u_alphaRef float` - alpha reference value for alpha test.
+ ///
+ /// @attention C99's equivalent binding is `bgfx_create_uniform_with_freq`.
+ ///
+ UniformHandle createUniform(
+ const char* _name
+ , UniformFreq::Enum _freq
+ , UniformType::Enum _type
+ , uint16_t _num = 1
+ );
+
/// Retrieve uniform info.
///
/// @param[in] _handle Handle to uniform object.
@@ -3740,6 +3799,40 @@ namespace bgfx
, uint16_t _num = 1
);
+ /// Set shader uniform parameter for view.
+ ///
+ /// @param[in] _id View id.
+ /// @param[in] _handle Uniform.
+ /// @param[in] _value Pointer to uniform data.
+ /// @param[in] _num Number of elements. Passing `UINT16_MAX` will
+ /// use the _num passed on uniform creation.
+ ///
+ /// @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
+ /// @attention C99's equivalent binding is `bgfx_set_view_uniform`.
+ ///
+ void setViewUniform(
+ ViewId _id
+ , UniformHandle _handle
+ , const void* _value
+ , uint16_t _num = 1
+ );
+
+ /// Set shader uniform parameter for frame.
+ ///
+ /// @param[in] _handle Uniform.
+ /// @param[in] _value Pointer to uniform data.
+ /// @param[in] _num Number of elements. Passing `UINT16_MAX` will
+ /// use the _num passed on uniform creation.
+ ///
+ /// @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
+ /// @attention C99's equivalent binding is `bgfx_set_frame_uniform`.
+ ///
+ void setFrameUniform(
+ UniformHandle _handle
+ , const void* _value
+ , uint16_t _num = 1
+ );
+
/// Set index buffer for draw primitive.
///
/// @param[in] _handle Index buffer.
diff --git a/include/bgfx/c99/bgfx.h b/include/bgfx/c99/bgfx.h
index 1c470a534..71a5b2da9 100644
--- a/include/bgfx/c99/bgfx.h
+++ b/include/bgfx/c99/bgfx.h
@@ -288,6 +288,20 @@ typedef enum bgfx_uniform_type
} bgfx_uniform_type_t;
+/**
+ * Uniform frequency enum.
+ *
+ */
+typedef enum bgfx_uniform_freq
+{
+ BGFX_UNIFORM_FREQ_DRAW, /** ( 0) Changing per draw call. */
+ BGFX_UNIFORM_FREQ_VIEW, /** ( 1) Changing per view. */
+ BGFX_UNIFORM_FREQ_FRAME, /** ( 2) Changing per frame. */
+
+ BGFX_UNIFORM_FREQ_COUNT
+
+} bgfx_uniform_freq_t;
+
/**
* Backbuffer ratio enum.
*
@@ -2200,6 +2214,42 @@ BGFX_C_API void bgfx_destroy_frame_buffer(bgfx_frame_buffer_handle_t _handle);
*/
BGFX_C_API bgfx_uniform_handle_t bgfx_create_uniform(const char* _name, bgfx_uniform_type_t _type, uint16_t _num);
+/**
+ * Create shader uniform parameter.
+ * @remarks
+ * 1. Uniform names are unique. It's valid to call `bgfx::createUniform`
+ * multiple times with the same uniform name. The library will always
+ * return the same handle, but the handle reference count will be
+ * incremented. This means that the same number of `bgfx::destroyUniform`
+ * must be called to properly destroy the uniform.
+ * 2. Predefined uniforms (declared in `bgfx_shader.sh`):
+ * - `u_viewRect vec4(x, y, width, height)` - view rectangle for current
+ * view, in pixels.
+ * - `u_viewTexel vec4(1.0/width, 1.0/height, undef, undef)` - inverse
+ * width and height
+ * - `u_view mat4` - view matrix
+ * - `u_invView mat4` - inverted view matrix
+ * - `u_proj mat4` - projection matrix
+ * - `u_invProj mat4` - inverted projection matrix
+ * - `u_viewProj mat4` - concatenated view projection matrix
+ * - `u_invViewProj mat4` - concatenated inverted view projection matrix
+ * - `u_model mat4[BGFX_CONFIG_MAX_BONES]` - array of model matrices.
+ * - `u_modelView mat4` - concatenated model view matrix, only first
+ * model matrix from array is used.
+ * - `u_invModelView mat4` - inverted concatenated model view matrix.
+ * - `u_modelViewProj mat4` - concatenated model view projection matrix.
+ * - `u_alphaRef float` - alpha reference value for alpha test.
+ *
+ * @param[in] _name Uniform name in shader.
+ * @param[in] _freq Uniform change frequency (See: `bgfx::UniformFreq`).
+ * @param[in] _type Type of uniform (See: `bgfx::UniformType`).
+ * @param[in] _num Number of elements in array.
+ *
+ * @returns Handle to uniform object.
+ *
+ */
+BGFX_C_API bgfx_uniform_handle_t bgfx_create_uniform_with_freq(const char* _name, bgfx_uniform_freq_t _freq, bgfx_uniform_type_t _type, uint16_t _num);
+
/**
* Retrieve uniform info.
*
@@ -2573,6 +2623,31 @@ 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 for view.
+ * @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
+ *
+ * @param[in] _id View id.
+ * @param[in] _handle Uniform.
+ * @param[in] _value Pointer to uniform data.
+ * @param[in] _num Number of elements. Passing `UINT16_MAX` will
+ * use the _num passed on uniform creation.
+ *
+ */
+BGFX_C_API void bgfx_set_view_uniform(bgfx_view_id_t _id, bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num);
+
+/**
+ * Set shader uniform parameter for frame.
+ * @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
+ *
+ * @param[in] _handle Uniform.
+ * @param[in] _value Pointer to uniform data.
+ * @param[in] _num Number of elements. Passing `UINT16_MAX` will
+ * use the _num passed on uniform creation.
+ *
+ */
+BGFX_C_API void bgfx_set_frame_uniform(bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num);
+
/**
* Set index buffer for draw primitive.
*
@@ -3604,6 +3679,7 @@ typedef enum bgfx_function_id
BGFX_FUNCTION_ID_GET_TEXTURE,
BGFX_FUNCTION_ID_DESTROY_FRAME_BUFFER,
BGFX_FUNCTION_ID_CREATE_UNIFORM,
+ BGFX_FUNCTION_ID_CREATE_UNIFORM_WITH_FREQ,
BGFX_FUNCTION_ID_GET_UNIFORM_INFO,
BGFX_FUNCTION_ID_DESTROY_UNIFORM,
BGFX_FUNCTION_ID_CREATE_OCCLUSION_QUERY,
@@ -3636,6 +3712,8 @@ 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_SET_VIEW_UNIFORM,
+ BGFX_FUNCTION_ID_SET_FRAME_UNIFORM,
BGFX_FUNCTION_ID_ENCODER_SET_INDEX_BUFFER,
BGFX_FUNCTION_ID_ENCODER_SET_DYNAMIC_INDEX_BUFFER,
BGFX_FUNCTION_ID_ENCODER_SET_TRANSIENT_INDEX_BUFFER,
@@ -3811,6 +3889,7 @@ struct bgfx_interface_vtbl
bgfx_texture_handle_t (*get_texture)(bgfx_frame_buffer_handle_t _handle, uint8_t _attachment);
void (*destroy_frame_buffer)(bgfx_frame_buffer_handle_t _handle);
bgfx_uniform_handle_t (*create_uniform)(const char* _name, bgfx_uniform_type_t _type, uint16_t _num);
+ bgfx_uniform_handle_t (*create_uniform_with_freq)(const char* _name, bgfx_uniform_freq_t _freq, bgfx_uniform_type_t _type, uint16_t _num);
void (*get_uniform_info)(bgfx_uniform_handle_t _handle, bgfx_uniform_info_t * _info);
void (*destroy_uniform)(bgfx_uniform_handle_t _handle);
bgfx_occlusion_query_handle_t (*create_occlusion_query)(void);
@@ -3843,6 +3922,8 @@ 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 (*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);
void (*encoder_set_dynamic_index_buffer)(bgfx_encoder_t* _this, bgfx_dynamic_index_buffer_handle_t _handle, uint32_t _firstIndex, uint32_t _numIndices);
void (*encoder_set_transient_index_buffer)(bgfx_encoder_t* _this, const bgfx_transient_index_buffer_t* _tib, uint32_t _firstIndex, uint32_t _numIndices);
diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h
index 215ddc348..b74c6534e 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(133)
+#define BGFX_API_VERSION UINT32_C(134)
/**
* Color RGB/alpha/depth write. When it's not specified write will be disabled.
diff --git a/scripts/bgfx.idl b/scripts/bgfx.idl
index 6d1d1aa01..e3e4f4a20 100644
--- a/scripts/bgfx.idl
+++ b/scripts/bgfx.idl
@@ -1,7 +1,7 @@
-- vim: syntax=lua
-- bgfx interface
-version(133)
+version(134)
typedef "bool"
typedef "char"
@@ -631,6 +631,13 @@ enum.UniformType { comment = "Uniform types:" }
.Mat4 --- 4x4 matrix.
()
+--- Uniform frequency enum.
+enum.UniformFreq { comment = "Uniform frequency:" }
+ .Draw --- Changing per draw call.
+ .View --- Changing per view.
+ .Frame --- Changing per frame.
+ ()
+
--- Backbuffer ratio enum.
enum.BackbufferRatio { comment = "Backbuffer ratios:" }
.Equal --- Equal to backbuffer.
@@ -1980,6 +1987,41 @@ func.createUniform
.num "uint16_t" --- Number of elements in array.
{ default = 1 }
+--- Create shader uniform parameter.
+---
+--- @remarks
+--- 1. Uniform names are unique. It's valid to call `bgfx::createUniform`
+--- multiple times with the same uniform name. The library will always
+--- return the same handle, but the handle reference count will be
+--- incremented. This means that the same number of `bgfx::destroyUniform`
+--- must be called to properly destroy the uniform.
+---
+--- 2. Predefined uniforms (declared in `bgfx_shader.sh`):
+--- - `u_viewRect vec4(x, y, width, height)` - view rectangle for current
+--- view, in pixels.
+--- - `u_viewTexel vec4(1.0/width, 1.0/height, undef, undef)` - inverse
+--- width and height
+--- - `u_view mat4` - view matrix
+--- - `u_invView mat4` - inverted view matrix
+--- - `u_proj mat4` - projection matrix
+--- - `u_invProj mat4` - inverted projection matrix
+--- - `u_viewProj mat4` - concatenated view projection matrix
+--- - `u_invViewProj mat4` - concatenated inverted view projection matrix
+--- - `u_model mat4[BGFX_CONFIG_MAX_BONES]` - array of model matrices.
+--- - `u_modelView mat4` - concatenated model view matrix, only first
+--- model matrix from array is used.
+--- - `u_invModelView mat4` - inverted concatenated model view matrix.
+--- - `u_modelViewProj mat4` - concatenated model view projection matrix.
+--- - `u_alphaRef float` - alpha reference value for alpha test.
+---
+func.createUniform { cname = "create_uniform_with_freq" }
+ "UniformHandle" --- Handle to uniform object.
+ .name "const char*" --- Uniform name in shader.
+ .freq "UniformFreq::Enum" --- Uniform change frequency (See: `bgfx::UniformFreq`).
+ .type "UniformType::Enum" --- Type of uniform (See: `bgfx::UniformType`).
+ .num "uint16_t" --- Number of elements in array.
+ { default = 1 }
+
--- Retrieve uniform info.
func.getUniformInfo
"void"
@@ -2294,6 +2336,31 @@ func.Encoder.setUniform
--- use the _num passed on uniform creation.
{ default = 1 }
+--- Set shader uniform parameter for view.
+---
+--- @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
+---
+func.setViewUniform
+ "void"
+ .id "ViewId" --- View id.
+ .handle "UniformHandle" --- Uniform.
+ .value "const void*" --- Pointer to uniform data.
+ .num "uint16_t" --- Number of elements. Passing `UINT16_MAX` will
+ --- use the _num passed on uniform creation.
+ { default = 1 }
+
+--- Set shader uniform parameter for frame.
+---
+--- @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
+---
+func.setFrameUniform
+ "void"
+ .handle "UniformHandle" --- Uniform.
+ .value "const void*" --- Pointer to uniform data.
+ .num "uint16_t" --- Number of elements. Passing `UINT16_MAX` will
+ --- use the _num passed on uniform creation.
+ { default = 1 }
+
--- Set index buffer for draw primitive.
func.Encoder.setIndexBuffer { cpponly }
"void"
diff --git a/src/bgfx.cpp b/src/bgfx.cpp
index ad1b668cd..317628498 100644
--- a/src/bgfx.cpp
+++ b/src/bgfx.cpp
@@ -1430,6 +1430,8 @@ namespace bgfx
}
bx::radixSort(m_blitKeys, (uint32_t*)&s_ctx->m_tempKeys, m_numBlitItems);
+
+ m_uniformCacheFrame.sort(viewRemap, s_ctx->m_tempKeys);
}
RenderFrame::Enum renderFrame(int32_t _msecs)
@@ -1610,6 +1612,18 @@ namespace bgfx
BX_TRACE("\t C Seq %016" PRIx64, kSortKeyComputeSeqMask);
BX_TRACE("\t C Program %016" PRIx64, kSortKeyComputeProgramMask);
+ BX_TRACE("");
+ BX_TRACE("Blit key masks:");
+ BX_TRACE("\tView %08" PRIx32, BlitKey::kViewMask);
+ BX_TRACE("\tItem %08" PRIx32, BlitKey::kItemMask);
+
+ BX_TRACE("");
+ BX_TRACE("Uniform cache key masks:");
+ BX_TRACE("\tView %016" PRIx64, UniformCacheKey::kViewMask);
+ BX_TRACE("\tHandle %016" PRIx64, UniformCacheKey::kHandleMask);
+ BX_TRACE("\tOffset %016" PRIx64, UniformCacheKey::kOffsetMask);
+ BX_TRACE("\tSize %016" PRIx64, UniformCacheKey::kSizeMask);
+
BX_TRACE("");
BX_TRACE("Capabilities (renderer %s, vendor 0x%04x, device 0x%04x):"
, s_ctx->m_renderCtx->getRendererName()
@@ -1779,7 +1793,12 @@ namespace bgfx
const char* getName(UniformHandle _handle)
{
- return s_ctx->m_uniformRef[_handle.idx].m_name.getCPtr();
+ return getUniformRef(_handle).m_name.getCPtr();
+ }
+
+ const UniformRef& getUniformRef(UniformHandle _handle)
+ {
+ return s_ctx->m_uniformRef[_handle.idx];
}
const char* getName(ShaderHandle _handle)
@@ -2241,7 +2260,9 @@ namespace bgfx
for (uint16_t ii = 0, num = _frame->m_freeUniform.getNumQueued(); ii < num; ++ii)
{
- m_uniformHandle.free(_frame->m_freeUniform.get(ii).idx);
+ UniformHandle handle = _frame->m_freeUniform.get(ii);
+ m_uniformCache.invalidate(handle);
+ m_uniformHandle.free(handle.idx);
}
}
@@ -2328,6 +2349,10 @@ namespace bgfx
m_submit->m_perfStats.numViews = 0;
bx::memCopy(m_submit->m_viewRemap, m_viewRemap, sizeof(m_viewRemap) );
+
+ m_uniformCache.frame(m_submit->m_uniformCacheFrame);
+
+ static_assert(bx::isTriviallyCopyable(), "Must be memcopyiable...");
bx::memCopy(m_submit->m_view, m_view, sizeof(m_view) );
if (m_colorPaletteDirty > 0)
@@ -3767,6 +3792,7 @@ namespace bgfx
{
BGFX_CHECK_HANDLE("setUniform", 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(setUniform(uniform.m_type, _handle, _value, UINT16_MAX != _num ? _num : uniform.m_num) );
@@ -5200,7 +5226,12 @@ namespace bgfx
UniformHandle createUniform(const char* _name, UniformType::Enum _type, uint16_t _num)
{
- return s_ctx->createUniform(_name, _type, _num);
+ return s_ctx->createUniform(_name, UniformFreq::Draw, _type, _num);
+ }
+
+ UniformHandle createUniform(const char* _name, UniformFreq::Enum _freq, UniformType::Enum _type, uint16_t _num)
+ {
+ return s_ctx->createUniform(_name, _freq, _type, _num);
}
void getUniformInfo(UniformHandle _handle, UniformInfo& _info)
@@ -5408,6 +5439,17 @@ namespace bgfx
s_ctx->m_encoder0->setUniform(_handle, _value, _num);
}
+ void setViewUniform(ViewId _id, UniformHandle _handle, const void* _value, uint16_t _num)
+ {
+ BX_ASSERT(checkView(_id), "Invalid view id: %d", _id);
+ s_ctx->setViewUniform(_id, _handle, _value, _num);
+ }
+
+ void setFrameUniform(UniformHandle _handle, const void* _value, uint16_t _num)
+ {
+ s_ctx->setViewUniform(UINT16_MAX, _handle, _value, _num);
+ }
+
void setIndexBuffer(IndexBufferHandle _handle)
{
BGFX_CHECK_ENCODER0();
diff --git a/src/bgfx.idl.inl b/src/bgfx.idl.inl
index 9c2f69b92..cab986d62 100644
--- a/src/bgfx.idl.inl
+++ b/src/bgfx.idl.inl
@@ -601,6 +601,13 @@ BGFX_C_API bgfx_uniform_handle_t bgfx_create_uniform(const char* _name, bgfx_uni
return handle_ret.c;
}
+BGFX_C_API bgfx_uniform_handle_t bgfx_create_uniform_with_freq(const char* _name, bgfx_uniform_freq_t _freq, bgfx_uniform_type_t _type, uint16_t _num)
+{
+ union { bgfx_uniform_handle_t c; bgfx::UniformHandle cpp; } handle_ret;
+ handle_ret.cpp = bgfx::createUniform(_name, (bgfx::UniformFreq::Enum)_freq, (bgfx::UniformType::Enum)_type, _num);
+ return handle_ret.c;
+}
+
BGFX_C_API void bgfx_get_uniform_info(bgfx_uniform_handle_t _handle, bgfx_uniform_info_t * _info)
{
union { bgfx_uniform_handle_t c; bgfx::UniformHandle cpp; } handle = { _handle };
@@ -781,6 +788,18 @@ 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_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 };
+ bgfx::setViewUniform((bgfx::ViewId)_id, handle.cpp, _value, _num);
+}
+
+BGFX_C_API void bgfx_set_frame_uniform(bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num)
+{
+ union { bgfx_uniform_handle_t c; bgfx::UniformHandle cpp; } handle = { _handle };
+ bgfx::setFrameUniform(handle.cpp, _value, _num);
+}
+
BGFX_C_API void bgfx_encoder_set_index_buffer(bgfx_encoder_t* _this, bgfx_index_buffer_handle_t _handle, uint32_t _firstIndex, uint32_t _numIndices)
{
bgfx::Encoder* This = (bgfx::Encoder*)_this;
@@ -1392,6 +1411,7 @@ BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version)
bgfx_get_texture,
bgfx_destroy_frame_buffer,
bgfx_create_uniform,
+ bgfx_create_uniform_with_freq,
bgfx_get_uniform_info,
bgfx_destroy_uniform,
bgfx_create_occlusion_query,
@@ -1424,6 +1444,8 @@ 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_set_view_uniform,
+ bgfx_set_frame_uniform,
bgfx_encoder_set_index_buffer,
bgfx_encoder_set_dynamic_index_buffer,
bgfx_encoder_set_transient_index_buffer,
diff --git a/src/bgfx_p.h b/src/bgfx_p.h
index 0cd264f21..f6edb00ed 100644
--- a/src/bgfx_p.h
+++ b/src/bgfx_p.h
@@ -593,6 +593,8 @@ namespace bgfx
const char* getName(ShaderHandle _handle);
const char* getName(Topology::Enum _topology);
+ const struct UniformRef& getUniformRef(UniformHandle _handle);
+
template
inline void release(Ty)
{
@@ -1313,33 +1315,43 @@ namespace bgfx
};
#undef SORT_KEY_RENDER_DRAW
- constexpr uint8_t kBlitKeyViewShift = 32-kSortKeyViewNumBits;
- constexpr uint32_t kBlitKeyViewMask = uint32_t(BGFX_CONFIG_MAX_VIEWS-1)<> kBlitKeyItemShift);
- m_view = ViewId( (_key & kBlitKeyViewMask) >> kBlitKeyViewShift);
+ m_item = uint16_t( (_key & kItemMask) >> kItemShift);
+ m_view = ViewId( (_key & kViewMask) >> kViewShift);
}
- static uint32_t remapView(uint32_t _key, ViewId _viewRemap[BGFX_CONFIG_MAX_VIEWS])
+ static KeyT remapView(KeyT _key, ViewId _viewRemap[BGFX_CONFIG_MAX_VIEWS])
{
- const ViewId oldView = ViewId( (_key & kBlitKeyViewMask) >> kBlitKeyViewShift);
- const uint32_t view = uint32_t( (_viewRemap[oldView] << kBlitKeyViewShift) & kBlitKeyViewMask);
- const uint32_t key = (_key & ~kBlitKeyViewMask) | view;
+ const ViewId oldView = ViewId( (_key & kViewMask) >> kViewShift);
+ const KeyT view = uint32_t( (_viewRemap[oldView] << kViewShift) & kViewMask);
+ const KeyT key = (_key & ~kViewMask) | view;
return key;
}
@@ -1764,7 +1776,7 @@ namespace bgfx
m_startIndirect = 0;
m_numIndirect = UINT32_MAX;
- m_numIndirectIndex = 0;
+ m_numIndirectIndex = 0;
m_indirectBuffer = BGFX_INVALID_HANDLE;
m_numIndirectBuffer = BGFX_INVALID_HANDLE;
m_occlusionQuery = BGFX_INVALID_HANDLE;
@@ -1953,6 +1965,7 @@ namespace bgfx
struct UniformRef
{
bx::FixedString64 m_name;
+ UniformFreq::Enum m_freq;
UniformType::Enum m_type;
uint16_t m_num;
int16_t m_refCount;
@@ -2099,6 +2112,11 @@ namespace bgfx
m_shadingRate = uint8_t(_shadingRate);
}
+ void setUniform(UniformHandle _handle, const void* _value, uint16_t _num)
+ {
+ BX_UNUSED(_handle, _value, _num);
+ }
+
void setFrameBuffer(FrameBufferHandle _handle)
{
m_fbh = _handle;
@@ -2135,6 +2153,149 @@ namespace bgfx
uint8_t m_shadingRate;
};
+ struct UniformCacheKey
+ {
+ using KeyT = uint64_t;
+
+ static constexpr uint8_t kViewShift = sizeof(KeyT)*8-kSortKeyViewNumBits;
+ static constexpr KeyT kViewMask = KeyT(BGFX_CONFIG_MAX_VIEWS-1)<>12)<>4)<>kSizeShift ) + 1)<<4;
+ constexpr uint32_t kMaxOffset = ( (kOffsetMask>>kOffsetShift) + 1)<<4;
+
+ BX_ASSERT(true
+ && m_size < kMaxSize
+ && m_offset < kMaxOffset
+ , "UniformCacheKey couldn't fit size or offest (size %d max %d, offset %d max %d)!"
+ , m_size
+ , kMaxSize
+ , m_offset
+ , kMaxOffset
+ );
+
+ const KeyT view = (KeyT(m_view) << kViewShift) & kViewMask;
+ const KeyT handle = (KeyT(m_handle) << kHandleShift) & kHandleMask;
+ const KeyT offset = (KeyT(m_offset>>4) << kOffsetShift) & kOffsetMask;
+ const KeyT size = (KeyT(m_size>>4) << kSizeShift) & kSizeMask;
+ const KeyT key = view|handle|offset|size;
+
+ return key;
+ }
+
+ void decode(KeyT _key)
+ {
+ m_offset = (uint32_t( (_key & kOffsetMask) >> kOffsetShift) ) << 4;
+ m_handle = {uint16_t( (_key & kHandleMask) >> kHandleShift) };
+ m_size = (uint16_t( (_key & kSizeMask) >> kSizeShift ) ) << 4;
+ m_view = ViewId( (_key & kViewMask) >> kViewShift);
+ }
+
+ static KeyT remapView(KeyT _key, ViewId _viewRemap[BGFX_CONFIG_MAX_VIEWS])
+ {
+ const ViewId oldView = ViewId( (_key & kViewMask) >> kViewShift);
+ const KeyT view = UINT16_MAX != oldView
+ ? (KeyT(_viewRemap[oldView]) << kViewShift) & kViewMask
+ : 0 // frame uniforms go into physical view 0.
+ ;
+ const KeyT key = (_key & ~kViewMask) | view;
+ return key;
+ }
+
+ uint32_t m_offset;
+ uint16_t m_handle;
+ uint16_t m_size;
+ ViewId m_view;
+ };
+
+ struct UniformCacheEntry
+ {
+ uint32_t offset;
+ uint16_t size;
+ int16_t refCount;
+ };
+
+ struct UniformCacheFrame
+ {
+ static constexpr uint32_t kMinKeysCapacity = 256;
+ static constexpr uint32_t kMinDataCapacity = 16<<10;
+
+ UniformCacheFrame()
+ : m_keys(NULL)
+ , m_data(NULL)
+ , m_numItems(0)
+ , m_keysCapacity(kMinKeysCapacity)
+ , m_dataCapacity(kMinDataCapacity)
+ {
+ m_keys = (UniformCacheKey::KeyT*)bx::alloc(g_allocator, m_keysCapacity*sizeof(uint64_t) );
+ m_data = (uint8_t*)bx::alloc(g_allocator, m_dataCapacity);
+ }
+
+ ~UniformCacheFrame()
+ {
+ bx::free(g_allocator, m_keys);
+ bx::free(g_allocator, m_data);
+ }
+
+ void resize(uint32_t _keysCapacity, uint32_t _dataCapacity)
+ {
+ {
+ const uint32_t newKeysCapacity = bx::alignUp(bx::max(_keysCapacity, kMinKeysCapacity), kMinKeysCapacity);
+
+ if (newKeysCapacity != m_keysCapacity)
+ {
+ bx::realloc(g_allocator, m_keys, newKeysCapacity*sizeof(uint64_t) );
+ m_keysCapacity = newKeysCapacity;
+ }
+ }
+
+ {
+ const uint32_t newDataCapacity = bx::alignUp(bx::max(_dataCapacity, kMinDataCapacity), kMinDataCapacity);
+
+ if (newDataCapacity != m_dataCapacity)
+ {
+ bx::realloc(g_allocator, m_keys, newDataCapacity);
+ m_dataCapacity = newDataCapacity;
+ }
+ }
+ }
+
+ void sort(ViewId* _viewRemap, uint64_t* _tempKeys)
+ {
+ for (uint32_t ii = 0, num = m_numItems; ii < num; ++ii)
+ {
+ m_keys[ii] = UniformCacheKey::remapView(m_keys[ii], _viewRemap);
+ }
+
+ bx::radixSort(m_keys, _tempKeys, m_numItems);
+ }
+
+ uint64_t* m_keys;
+ uint8_t* m_data;
+ uint32_t m_numItems;
+ uint32_t m_keysCapacity;
+ uint32_t m_dataCapacity;
+ };
+
struct FrameCache
{
void reset()
@@ -2182,7 +2343,7 @@ namespace bgfx
m_perfStats.viewStats = m_viewStats;
- bx::memSet(&m_renderItemBind[0], 0, sizeof(m_renderItemBind));
+ bx::memSet(&m_renderItemBind[0], 0, sizeof(m_renderItemBind) );
}
~Frame()
@@ -2358,6 +2519,8 @@ namespace bgfx
uint32_t m_blitKeys[BGFX_CONFIG_MAX_BLIT_ITEMS+1];
BlitItem m_blitItem[BGFX_CONFIG_MAX_BLIT_ITEMS+1];
+ UniformCacheFrame m_uniformCacheFrame;
+
FrameCache m_frameCache;
UniformBuffer** m_uniformBuffer;
@@ -2465,7 +2628,7 @@ namespace bgfx
// will leaves bytes uninitialized. This will influence the hashing
// as it reads those bytes too. To make this deterministic, we will
// clear all bytes (inclusively the padding) before we start.
- bx::memSet(&m_bind, 0, sizeof(m_bind));
+ bx::memSet(&m_bind, 0, sizeof(m_bind) );
discard(BGFX_DISCARD_ALL);
}
@@ -2524,7 +2687,13 @@ namespace bgfx
, _handle.idx
, getName(_handle)
);
-// m_uniformSet.insert(_handle.idx);
+ m_uniformSet.insert(_handle.idx);
+
+ const UniformRef& uniform = getUniformRef(_handle);
+ BX_ASSERT(UniformFreq::Draw == uniform.m_freq
+ , "Setting uniform for draw call, but uniform frequency is different (frequency: %d)!"
+ , uniform.m_freq
+ );
}
UniformBuffer::update(&m_frame->m_uniformBuffer[m_uniformIdx]);
@@ -2960,6 +3129,7 @@ namespace bgfx
static const uint64_t kInvalidBlock = UINT64_MAX;
NonLocalAllocator()
+ : m_total(0)
{
}
@@ -2971,6 +3141,7 @@ namespace bgfx
{
m_free.clear();
m_used.clear();
+ m_total = 0;
}
void add(uint64_t _ptr, uint32_t _size)
@@ -3003,6 +3174,7 @@ namespace bgfx
uint64_t ptr = it->m_ptr;
m_used.insert(stl::make_pair(ptr, _size) );
+ m_total += _size;
if (it->m_size != _size)
{
@@ -3027,6 +3199,8 @@ namespace bgfx
UsedList::iterator it = m_used.find(_block);
if (it != m_used.end() )
{
+ m_total -= it->second;
+
m_free.push_front(Free(it->first, it->second) );
m_used.erase(it);
}
@@ -3053,6 +3227,11 @@ namespace bgfx
return 0 == m_used.size();
}
+ uint32_t getTotal() const
+ {
+ return m_total;
+ }
+
private:
struct Free
{
@@ -3076,6 +3255,248 @@ namespace bgfx
typedef stl::unordered_map UsedList;
UsedList m_used;
+
+ uint32_t m_total;
+ };
+
+ struct UniformCache
+ {
+ UniformCache()
+ {
+ const uint32_t size = 1<<20;
+ m_data = (uint8_t*)bx::alloc(g_allocator, size);
+ m_uniformStoreAlloc.add(0, size);
+ }
+
+ ~UniformCache()
+ {
+ BX_ASSERT(true
+ && 0 == m_uniformKeyHashMap.size()
+ && 0 == m_uniformEntryMap.size()
+ && 0 == m_uniformStoreAlloc.getTotal()
+ , "UniformCache leak (keys %d, entries %d, %d bytes)!"
+ , m_uniformKeyHashMap.size()
+ , m_uniformEntryMap.size()
+ , m_uniformStoreAlloc.getTotal()
+ );
+
+ bx::free(g_allocator, m_data);
+ m_uniformKeyHashMap.clear();
+ m_uniformEntryMap.clear();
+ }
+
+ void setViewUniform(ViewId _id, UniformHandle _handle, const void* _value, uint16_t _num)
+ {
+ const UniformRef& uniform = getUniformRef(_handle);
+
+ UniformCacheKey key =
+ {
+ .m_offset = 0,
+ .m_handle = _handle.idx,
+ .m_size = 0,
+ .m_view = _id,
+ };
+
+ constexpr UniformCacheKey::KeyT kViewHandleMask = UniformCacheKey::kViewMask|UniformCacheKey::kHandleMask;
+ static_assert( ( (kViewHandleMask>>32)<<32) == kViewHandleMask, "View + handle must be in top 32 bits of 64-bit key.");
+ const uint32_t uniformKey = uint32_t(key.encode() >> 32);
+
+ setUniform(uniformKey, uniform.m_type, _value, _num);
+ }
+
+ void setUniform(uint32_t _uniformKey, UniformType::Enum _type, const void* _value, uint16_t _num)
+ {
+ const uint32_t typeSize = g_uniformTypeSize[_type];
+ const uint32_t dataSize = _num * typeSize;
+
+ bx::HashMurmur3 murmur;
+ murmur.begin();
+ murmur.add(_type);
+ murmur.add(_num);
+ murmur.add(_value, dataSize);
+ const uint32_t hash = murmur.end();
+
+ UniformKeyHashMap::iterator itKey = m_uniformKeyHashMap.find(_uniformKey);
+ if (itKey != m_uniformKeyHashMap.end() )
+ {
+ if (itKey->second == hash)
+ {
+ return;
+ }
+
+ UniformEntryMap::iterator itOldEntry = m_uniformEntryMap.find(itKey->second);
+ if (itOldEntry != m_uniformEntryMap.end())
+ {
+ if (release(itOldEntry->second) )
+ {
+ m_uniformEntryMap.erase(itOldEntry);
+ }
+ }
+
+ itKey->second = hash;
+
+ UniformEntryMap::iterator itEntry = m_uniformEntryMap.find(hash);
+ if (itEntry != m_uniformEntryMap.end())
+ {
+ ++itEntry->second.refCount;
+
+ return;
+ }
+ }
+ else
+ {
+ m_uniformKeyHashMap.insert(stl::make_pair(_uniformKey, hash) );
+ }
+
+ UniformEntryMap::iterator itEntry = m_uniformEntryMap.find(hash);
+ if (itEntry != m_uniformEntryMap.end())
+ {
+ ++itEntry->second.refCount;
+ }
+ else
+ {
+ const uint64_t offset = m_uniformStoreAlloc.alloc(dataSize);
+ BX_ASSERT(NonLocalAllocator::kInvalidBlock != offset, "UniformCache: Failed to allocate data!");
+
+ m_uniformEntryMap.insert(stl::make_pair(hash, UniformCacheEntry
+ {
+ .offset = bx::narrowCast(offset),
+ .size = bx::narrowCast(dataSize),
+ .refCount = 1
+ }) );
+
+ bx::memCopy(&m_data[offset], _value, dataSize);
+ }
+ }
+
+ void frame(UniformCacheFrame& _outUniformCacheFrame)
+ {
+ m_uniformStoreAlloc.compact();
+
+ _outUniformCacheFrame.resize(
+ uint32_t(m_uniformKeyHashMap.size() )
+ , m_uniformStoreAlloc.getTotal()
+ );
+
+ using OffsetRemap = stl::unordered_map;
+ OffsetRemap offsetRemap;
+
+ uint32_t linearOffset = 0;
+ uint32_t num = 0;
+ for (UniformKeyHashMap::const_iterator itKey = m_uniformKeyHashMap.begin(), itEnd = m_uniformKeyHashMap.end(); itKey != itEnd; ++itKey)
+ {
+ UniformEntryMap::iterator itEntry = m_uniformEntryMap.find(itKey->second);
+ BX_ASSERT(itEntry != m_uniformEntryMap.end()
+ , "Couldn't find uniform cache entry for key 0x%d, hash 0x%x!"
+ , itKey->first
+ , itKey->second
+ );
+
+ const uint32_t offset = itEntry->second.offset;
+ const uint16_t size = itEntry->second.size;
+
+ UniformCacheKey key;
+ key.decode(uint64_t(itKey->first)<<32);
+ key.m_size = size;
+
+ OffsetRemap::const_iterator itOffset = offsetRemap.find(offset);
+ if (itOffset != offsetRemap.end())
+ {
+ key.m_offset = itOffset->second;
+ }
+ else
+ {
+ key.m_offset = linearOffset;
+
+ offsetRemap.insert(stl::make_pair(offset, linearOffset) );
+ bx::memCopy(&_outUniformCacheFrame.m_data[linearOffset], &m_data[offset], size);
+
+ linearOffset += size;
+ }
+
+ _outUniformCacheFrame.m_keys[num++] = key.encode();
+ }
+
+ _outUniformCacheFrame.m_numItems = num;
+ }
+
+ void invalidate(ViewId _viewId)
+ {
+ for (UniformKeyHashMap::iterator itKey = m_uniformKeyHashMap.begin(), itEnd = m_uniformKeyHashMap.end(); itKey != itEnd; ++itKey)
+ {
+ UniformCacheKey key;
+ key.decode(uint64_t(itKey->first) << 32);
+
+ if (key.m_view == _viewId)
+ {
+ release(itKey->second);
+
+ UniformKeyHashMap::iterator itErase = itKey;
+ ++itKey;
+
+ m_uniformKeyHashMap.erase(itErase);
+ }
+ }
+ }
+
+ void invalidate(UniformHandle _handle)
+ {
+ for (UniformKeyHashMap::iterator itKey = m_uniformKeyHashMap.begin(), itEnd = m_uniformKeyHashMap.end(); itKey != itEnd;)
+ {
+ UniformCacheKey key;
+ key.decode(uint64_t(itKey->first) << 32);
+
+ if (key.m_handle == _handle.idx)
+ {
+ release(itKey->second);
+
+ UniformKeyHashMap::iterator itErase = itKey;
+ ++itKey;
+
+ m_uniformKeyHashMap.erase(itErase);
+ }
+ else
+ {
+ ++itKey;
+ }
+ }
+ }
+
+ bool release(UniformCacheEntry& _entry)
+ {
+ --_entry.refCount;
+
+ if (0 == _entry.refCount)
+ {
+ const uint64_t offset = _entry.offset;
+
+ m_uniformStoreAlloc.free(offset);
+ return true;
+ }
+
+ return false;
+ }
+
+ void release(uint32_t _hash)
+ {
+ UniformEntryMap::iterator itEntry = m_uniformEntryMap.find(_hash);
+ if (itEntry != m_uniformEntryMap.end())
+ {
+ if (release(itEntry->second) )
+ {
+ m_uniformEntryMap.erase(itEntry);
+ }
+ }
+ }
+
+ using UniformKeyHashMap = stl::unordered_map;
+ using UniformEntryMap = stl::unordered_map;
+
+ UniformKeyHashMap m_uniformKeyHashMap;
+ UniformEntryMap m_uniformEntryMap;
+
+ NonLocalAllocator m_uniformStoreAlloc;
+ uint8_t* m_data;
};
struct BX_NO_VTABLE RendererContextI
@@ -4248,7 +4669,7 @@ namespace bgfx
PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);
if (PredefinedUniform::Count == predefined && UniformType::End != UniformType::Enum(type) )
{
- uniforms[sr.m_num] = createUniform(name, UniformType::Enum(type), num);
+ uniforms[sr.m_num] = createUniform(name, UniformFreq::Draw, UniformType::Enum(type), num);
sr.m_num++;
}
}
@@ -4903,7 +5324,7 @@ namespace bgfx
}
}
- BGFX_API_FUNC(UniformHandle createUniform(const char* _name, UniformType::Enum _type, uint16_t _num) )
+ BGFX_API_FUNC(UniformHandle createUniform(const char* _name, UniformFreq::Enum _freq, UniformType::Enum _type, uint16_t _num) )
{
BGFX_MUTEX_SCOPE(m_resourceApiLock);
@@ -4930,8 +5351,10 @@ namespace bgfx
, uniform.m_type
);
- uint32_t oldsize = g_uniformTypeSize[uniform.m_type];
- uint32_t newsize = g_uniformTypeSize[_type];
+ const uint32_t oldsize = g_uniformTypeSize[uniform.m_type];
+ const uint32_t newsize = g_uniformTypeSize[_type];
+
+ uniform.m_freq = _freq; // Ignore shader created uniforms, and use UniformFreq when user creates uniform.
if (oldsize < newsize
|| uniform.m_num < _num)
@@ -4967,6 +5390,7 @@ namespace bgfx
UniformRef& uniform = m_uniformRef[handle.idx];
uniform.m_name.set(_name);
uniform.m_refCount = 1;
+ uniform.m_freq = _freq;
uniform.m_type = _type;
uniform.m_num = _num;
@@ -5191,9 +5615,15 @@ namespace bgfx
m_view[_id].setShadingRate(_shadingRate);
}
+ BGFX_API_FUNC(void setViewUniform(ViewId _id, UniformHandle _handle, const void* _value, uint16_t _num) )
+ {
+ m_uniformCache.setViewUniform(_id, _handle, _value, _num);
+ }
+
BGFX_API_FUNC(void resetView(ViewId _id) )
{
m_view[_id].reset();
+ m_uniformCache.invalidate(_id);
}
BGFX_API_FUNC(Encoder* begin(bool _forThread) );
@@ -5387,6 +5817,8 @@ namespace bgfx
uint32_t m_seq[BGFX_CONFIG_MAX_VIEWS];
View m_view[BGFX_CONFIG_MAX_VIEWS];
+ UniformCache m_uniformCache;
+
float m_clearColor[BGFX_CONFIG_MAX_COLOR_PALETTE][4];
uint8_t m_colorPaletteDirty;
diff --git a/src/renderer.h b/src/renderer.h
index c8971fa82..743e90d44 100644
--- a/src/renderer.h
+++ b/src/renderer.h
@@ -58,6 +58,49 @@ namespace bgfx
uint16_t m_item;
};
+ struct UniformCacheItem
+ {
+ uint32_t m_offset;
+ uint16_t m_size;
+ uint16_t m_handle;
+ };
+
+ struct UniformCacheState
+ {
+ UniformCacheState(const Frame* _frame)
+ : m_frame(_frame)
+ , m_item(0)
+ {
+ m_key.decode(_frame->m_uniformCacheFrame.m_keys[0]);
+ }
+
+ bool hasItem(uint16_t _view) const
+ {
+ return m_item < m_frame->m_uniformCacheFrame.m_numItems
+ && m_key.m_view <= _view
+ ;
+ }
+
+ const UniformCacheItem advance()
+ {
+ UniformCacheItem item =
+ {
+ .m_offset = m_key.m_offset,
+ .m_size = m_key.m_size,
+ .m_handle = m_key.m_handle,
+ };
+
+ ++m_item;
+ m_key.decode(m_frame->m_uniformCacheFrame.m_keys[m_item]);
+
+ return item;
+ }
+
+ const Frame* m_frame;
+ UniformCacheKey m_key;
+ uint16_t m_item;
+ };
+
struct ViewState
{
ViewState()
diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp
index 1e58a310f..661161a4d 100644
--- a/src/renderer_d3d11.cpp
+++ b/src/renderer_d3d11.cpp
@@ -2123,6 +2123,8 @@ namespace bgfx { namespace d3d11
void submitBlit(BlitState& _bs, uint16_t _view);
+ void submitUniformCache(UniformCacheState& _ucs, uint16_t _view);
+
void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) override;
void blitSetup(TextVideoMemBlitter& _blitter) override
@@ -5589,6 +5591,16 @@ namespace bgfx { namespace d3d11
}
}
+ void RendererContextD3D11::submitUniformCache(UniformCacheState& _ucs, uint16_t _view)
+ {
+ while (_ucs.hasItem(_view) )
+ {
+ const UniformCacheItem& uci = _ucs.advance();
+
+ bx::memCopy(m_uniforms[uci.m_handle], &_ucs.m_frame->m_uniformCacheFrame.m_data[uci.m_offset], uci.m_size);
+ }
+ }
+
void RendererContextD3D11::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter)
{
if (m_lost)
@@ -5659,6 +5671,7 @@ namespace bgfx { namespace d3d11
uint16_t view = UINT16_MAX;
FrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS };
+ UniformCacheState ucs(_render);
BlitState bs(_render);
const uint64_t primType = _render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0;
@@ -5759,6 +5772,7 @@ namespace bgfx { namespace d3d11
prim = s_primInfo[Topology::Count]; // Force primitive type update after clear quad.
}
+ submitUniformCache(ucs, view);
submitBlit(bs, view);
}
diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp
index db8738a8c..a4f0166be 100644
--- a/src/renderer_d3d12.cpp
+++ b/src/renderer_d3d12.cpp
@@ -2269,6 +2269,8 @@ namespace bgfx { namespace d3d12
void submitBlit(BlitState& _bs, uint16_t _view);
+ void submitUniformCache(UniformCacheState& _ucs, uint16_t _view);
+
void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) override;
void blitSetup(TextVideoMemBlitter& _blitter) override
@@ -6466,6 +6468,16 @@ namespace bgfx { namespace d3d12
}
}
+ void RendererContextD3D12::submitUniformCache(UniformCacheState& _ucs, uint16_t _view)
+ {
+ while (_ucs.hasItem(_view) )
+ {
+ const UniformCacheItem& uci = _ucs.advance();
+
+ bx::memCopy(m_uniforms[uci.m_handle], &_ucs.m_frame->m_uniformCacheFrame.m_data[uci.m_offset], uci.m_size);
+ }
+ }
+
void RendererContextD3D12::submit(Frame* _render, ClearQuad& /*_clearQuad*/, TextVideoMemBlitter& _textVideoMemBlitter)
{
if (m_lost
@@ -6526,6 +6538,7 @@ namespace bgfx { namespace d3d12
uint16_t view = UINT16_MAX;
FrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS };
+ UniformCacheState ucs(_render);
BlitState bs(_render);
uint32_t blendFactor = 0;
@@ -6690,6 +6703,7 @@ namespace bgfx { namespace d3d12
prim = s_primInfo[Topology::Count]; // Force primitive type update.
+ submitUniformCache(ucs, view);
submitBlit(bs, view);
if (m_variableRateShadingSupport)
diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp
index 029952bd7..d52269f51 100644
--- a/src/renderer_gl.cpp
+++ b/src/renderer_gl.cpp
@@ -3674,6 +3674,8 @@ namespace bgfx { namespace gl
void submitBlit(BlitState& _bs, uint16_t _view);
+ void submitUniformCache(UniformCacheState& _ucs, uint16_t _view);
+
void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) override;
void blitSetup(TextVideoMemBlitter& _blitter) override
@@ -7463,6 +7465,16 @@ namespace bgfx { namespace gl
}
}
+ void RendererContextGL::submitUniformCache(UniformCacheState& _ucs, uint16_t _view)
+ {
+ while (_ucs.hasItem(_view) )
+ {
+ const UniformCacheItem& uci = _ucs.advance();
+
+ bx::memCopy(m_uniforms[uci.m_handle], &_ucs.m_frame->m_uniformCacheFrame.m_data[uci.m_offset], uci.m_size);
+ }
+ }
+
void RendererContextGL::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter)
{
if (_render->m_capture)
@@ -7527,6 +7539,7 @@ namespace bgfx { namespace gl
uint16_t view = UINT16_MAX;
FrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS };
+ UniformCacheState ucs(_render);
BlitState bs(_render);
int32_t resolutionHeight = _render->m_resolution.height;
@@ -7649,6 +7662,7 @@ namespace bgfx { namespace gl
GL_CHECK(glEnable(GL_CULL_FACE) );
GL_CHECK(glDisable(GL_BLEND) );
+ submitUniformCache(ucs, view);
submitBlit(bs, view);
}
diff --git a/src/renderer_mtl.mm b/src/renderer_mtl.mm
index be5eb1312..c7f472b39 100644
--- a/src/renderer_mtl.mm
+++ b/src/renderer_mtl.mm
@@ -1338,6 +1338,8 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
void submitBlit(BlitState& _bs, uint16_t _view);
+ void submitUniformCache(UniformCacheState& _ucs, uint16_t _view);
+
void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) override;
void blitSetup(TextVideoMemBlitter& _blitter) override
@@ -4137,6 +4139,16 @@ BX_PRAGMA_DIAGNOSTIC_POP();
}
}
+ void RendererContextMtl::submitUniformCache(UniformCacheState& _ucs, uint16_t _view)
+ {
+ while (_ucs.hasItem(_view) )
+ {
+ const UniformCacheItem& uci = _ucs.advance();
+
+ bx::memCopy(m_uniforms[uci.m_handle], &_ucs.m_frame->m_uniformCacheFrame.m_data[uci.m_offset], uci.m_size);
+ }
+ }
+
void RendererContextMtl::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter)
{
m_cmd.finish(false);
@@ -4265,6 +4277,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
uint16_t view = UINT16_MAX;
FrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS };
+ UniformCacheState ucs(_render);
BlitState bs(_render);
const uint64_t primType = 0;
@@ -4336,6 +4349,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
viewState.m_rect = _render->m_view[view].m_rect;
+ submitUniformCache(ucs, view);
submitBlit(bs, view);
if (!isCompute)
diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp
index 99ecd9bc6..e90745c88 100644
--- a/src/renderer_vk.cpp
+++ b/src/renderer_vk.cpp
@@ -2679,6 +2679,8 @@ VK_IMPORT_DEVICE
void submitBlit(BlitState& _bs, uint16_t _view);
+ void submitUniformCache(UniformCacheState& _ucs, uint16_t _view);
+
void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) override;
void blitSetup(TextVideoMemBlitter& _blitter) override
@@ -8738,6 +8740,16 @@ VK_DESTROY
}
}
+ void RendererContextVK::submitUniformCache(UniformCacheState& _ucs, uint16_t _view)
+ {
+ while (_ucs.hasItem(_view) )
+ {
+ const UniformCacheItem& uci = _ucs.advance();
+
+ bx::memCopy(m_uniforms[uci.m_handle], &_ucs.m_frame->m_uniformCacheFrame.m_data[uci.m_offset], uci.m_size);
+ }
+ }
+
void RendererContextVK::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter)
{
BX_UNUSED(_clearQuad);
@@ -8804,6 +8816,7 @@ VK_DESTROY
uint16_t view = UINT16_MAX;
FrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS };
+ UniformCacheState ucs(_render);
BlitState bs(_render);
uint64_t blendFactor = UINT64_MAX;
@@ -8928,6 +8941,7 @@ VK_DESTROY
beginRenderPass = false;
}
+ submitUniformCache(ucs, view);
submitBlit(bs, view);
BGFX_VK_PROFILER_END();