Added uniform frequency. (#3485)

* Added uniform frequency.

* Cleanup.

* Cleanup.
This commit is contained in:
Branimir Karadžić
2025-11-10 15:41:33 -08:00
committed by GitHub
parent 8a9bc3ed65
commit 35911ac2d9
25 changed files with 1294 additions and 117 deletions

View File

@@ -1847,6 +1847,27 @@ public static class bgfx
Count
}
[AllowDuplicates]
public enum UniformFreq : uint32
{
/// <summary>
/// Changing per draw call.
/// </summary>
Draw,
/// <summary>
/// Changing per view.
/// </summary>
View,
/// <summary>
/// Changing per frame.
/// </summary>
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);
/// <summary>
/// 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.
/// </summary>
///
/// <param name="_name">Uniform name in shader.</param>
/// <param name="_freq">Uniform change frequency (See: `bgfx::UniformFreq`).</param>
/// <param name="_type">Type of uniform (See: `bgfx::UniformType`).</param>
/// <param name="_num">Number of elements in array.</param>
///
[LinkName("bgfx_create_uniform_with_freq")]
public static extern UniformHandle create_uniform_with_freq(char8* _name, UniformFreq _freq, UniformType _type, uint16 _num);
/// <summary>
/// Retrieve uniform info.
/// </summary>
@@ -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);
/// <summary>
/// Set shader uniform parameter for view.
/// @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
/// </summary>
///
/// <param name="_id">View id.</param>
/// <param name="_handle">Uniform.</param>
/// <param name="_value">Pointer to uniform data.</param>
/// <param name="_num">Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.</param>
///
[LinkName("bgfx_set_view_uniform")]
public static extern void set_view_uniform(ViewId _id, UniformHandle _handle, void* _value, uint16 _num);
/// <summary>
/// Set shader uniform parameter for frame.
/// @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
/// </summary>
///
/// <param name="_handle">Uniform.</param>
/// <param name="_value">Pointer to uniform data.</param>
/// <param name="_num">Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.</param>
///
[LinkName("bgfx_set_frame_uniform")]
public static extern void set_frame_uniform(UniformHandle _handle, void* _value, uint16 _num);
/// <summary>
/// Set index buffer for draw primitive.
/// </summary>

View File

@@ -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.`

View File

@@ -1839,6 +1839,26 @@ public static partial class bgfx
Count
}
public enum UniformFreq
{
/// <summary>
/// Changing per draw call.
/// </summary>
Draw,
/// <summary>
/// Changing per view.
/// </summary>
View,
/// <summary>
/// Changing per frame.
/// </summary>
Frame,
Count
}
public enum BackbufferRatio
{
/// <summary>
@@ -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);
/// <summary>
/// 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.
/// </summary>
///
/// <param name="_name">Uniform name in shader.</param>
/// <param name="_freq">Uniform change frequency (See: `bgfx::UniformFreq`).</param>
/// <param name="_type">Type of uniform (See: `bgfx::UniformType`).</param>
/// <param name="_num">Number of elements in array.</param>
///
[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);
/// <summary>
/// Retrieve uniform info.
/// </summary>
@@ -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);
/// <summary>
/// Set shader uniform parameter for view.
/// @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
/// </summary>
///
/// <param name="_id">View id.</param>
/// <param name="_handle">Uniform.</param>
/// <param name="_value">Pointer to uniform data.</param>
/// <param name="_num">Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.</param>
///
[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);
/// <summary>
/// Set shader uniform parameter for frame.
/// @attention Uniform must be created with `bgfx::UniformFreq::View` argument.
/// </summary>
///
/// <param name="_handle">Uniform.</param>
/// <param name="_value">Pointer to uniform data.</param>
/// <param name="_num">Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.</param>
///
[DllImport(DllName, EntryPoint="bgfx_set_frame_uniform", CallingConvention = CallingConvention.Cdecl)]
public static extern unsafe void set_frame_uniform(UniformHandle _handle, void* _value, ushort _num);
/// <summary>
/// Set index buffer for draw primitive.
/// </summary>

View File

@@ -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

View File

@@ -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:

View File

@@ -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.
/// <param name="_name">Uniform name in shader.</param>
/// <param name="_freq">Uniform change frequency (See: `bgfx::UniformFreq`).</param>
/// <param name="_type">Type of uniform (See: `bgfx::UniformType`).</param>
/// <param name="_num">Number of elements in array.</param>
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.
/// <param name="_handle">Handle to uniform object.</param>
/// <param name="_info">Uniform info.</param>
@@ -3040,6 +3086,27 @@ extern fn bgfx_encoder_alloc_transform(self: ?*Encoder, _transform: [*c]Transfor
/// <param name="_num">Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.</param>
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.
/// <param name="_id">View id.</param>
/// <param name="_handle">Uniform.</param>
/// <param name="_value">Pointer to uniform data.</param>
/// <param name="_num">Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.</param>
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.
/// <param name="_handle">Uniform.</param>
/// <param name="_value">Pointer to uniform data.</param>
/// <param name="_num">Number of elements. Passing `UINT16_MAX` will use the _num passed on uniform creation.</param>
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.
/// <param name="_handle">Index buffer.</param>
/// <param name="_firstIndex">First index to render.</param>

View File

@@ -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 };

View File

@@ -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<BX_COUNTOF( m_textureCube ); ++ii)
{
@@ -592,7 +592,7 @@ public:
int64_t now = bx::getHPCounter();
float time = (float)( (now - m_timeOffset)/double(bx::getHPFrequency() ) );
bgfx::setUniform(u_time, &time);
bgfx::setFrameUniform(u_time, &time);
if (now > m_updateTime)
{

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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);

View File

@@ -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.

View File

@@ -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"

View File

@@ -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<View>(), "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();

View File

@@ -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,

View File

@@ -593,6 +593,8 @@ namespace bgfx
const char* getName(ShaderHandle _handle);
const char* getName(Topology::Enum _topology);
const struct UniformRef& getUniformRef(UniformHandle _handle);
template<typename Ty>
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)<<kBlitKeyViewShift;
constexpr uint8_t kBlitKeyItemShift = 0;
constexpr uint32_t kBlitKeyItemMask = UINT16_MAX;
struct BlitKey
{
uint32_t encode()
using KeyT = uint32_t;
static constexpr uint8_t kViewShift = 32-kSortKeyViewNumBits;
static constexpr uint32_t kViewMask = uint32_t(BGFX_CONFIG_MAX_VIEWS-1)<<kViewShift;
static constexpr uint8_t kItemShift = 0;
static constexpr uint32_t kItemMask = UINT16_MAX;
static_assert( (0
| kViewMask
| kItemMask
) == (0
^ kViewMask
^ kItemMask
), "BlitKey: Key mask shouldn't overlap!");
KeyT encode()
{
const uint32_t view = (uint32_t(m_view) << kBlitKeyViewShift) & kBlitKeyViewMask;
const uint32_t item = (uint32_t(m_item) << kBlitKeyItemShift) & kBlitKeyItemMask;
const uint32_t key = view|item;
const KeyT view = (KeyT(m_view) << kViewShift) & kViewMask;
const KeyT item = (KeyT(m_item) << kItemShift) & kItemMask;
const KeyT key = view|item;
return key;
}
void decode(uint32_t _key)
void decode(KeyT _key)
{
m_item = uint16_t( (_key & kBlitKeyItemMask) >> 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)<<kViewShift;
static constexpr uint8_t kHandleShift = kViewShift - 16;
static constexpr KeyT kHandleMask = KeyT(UINT16_MAX)<<kHandleShift;
static constexpr uint8_t kOffsetShift = kHandleShift-20;
static constexpr KeyT kOffsetMask = KeyT(UINT32_MAX>>12)<<kOffsetShift;
static constexpr uint8_t kSizeShift = kOffsetShift-12;
static constexpr KeyT kSizeMask = KeyT(UINT16_MAX>>4)<<kSizeShift;
static_assert( (0
| kViewMask
| kHandleMask
| kOffsetMask
| kSizeMask
) == (0
^ kViewMask
^ kHandleMask
^ kOffsetMask
^ kSizeMask
), "UniformCacheKey: Key mask shouldn't overlap!");
KeyT encode()
{
constexpr uint32_t kMaxSize = ( (kSizeMask >>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<uint64_t, uint32_t> 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<uint32_t>(offset),
.size = bx::narrowCast<uint16_t>(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<uint32_t, uint32_t>;
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<uint32_t, uint32_t>;
using UniformEntryMap = stl::unordered_map<uint32_t, UniformCacheEntry>;
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;

View File

@@ -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()

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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();