Start using SSBOs for lights
This commit is contained in:
parent
a41e4b64d3
commit
f92283d152
@ -27,9 +27,9 @@ layout(std140, binding = 0) uniform Matrices {
|
|||||||
mat4 view;
|
mat4 view;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(std140, binding = 1) uniform Lights {
|
layout(std430, binding = 1) readonly buffer Lights {
|
||||||
Light lights[MAX_POINT_LIGHTS];
|
|
||||||
uint lights_count;
|
uint lights_count;
|
||||||
|
Light lights[];
|
||||||
};
|
};
|
||||||
|
|
||||||
int getShadowMapIndex(int lightIdx) {
|
int getShadowMapIndex(int lightIdx) {
|
||||||
|
@ -40,13 +40,14 @@ tripple_buffer_index: usize = MAX_FRAMES_QUEUED - 1,
|
|||||||
gl_fences: [MAX_FRAMES_QUEUED]?gl.GLsync = [_]?gl.GLsync{null} ** MAX_FRAMES_QUEUED,
|
gl_fences: [MAX_FRAMES_QUEUED]?gl.GLsync = [_]?gl.GLsync{null} ** MAX_FRAMES_QUEUED,
|
||||||
camera_ubo: gl.GLuint = 0,
|
camera_ubo: gl.GLuint = 0,
|
||||||
camera_matrices: []u8 = &.{},
|
camera_matrices: []u8 = &.{},
|
||||||
point_lights_ubo: gl.GLuint = 0,
|
point_lights_ssbo: gl.GLuint = 0,
|
||||||
point_lights: []u8 = &.{}, // TODO: remove
|
point_lights: []u8 = &.{}, // TODO: remove
|
||||||
lights: [MAX_LIGHT_COMMANDS]LightCommand = undefined,
|
lights: [MAX_LIGHT_COMMANDS]LightCommand = undefined,
|
||||||
light_count: usize = 0,
|
light_count: usize = 0,
|
||||||
command_buffer: [MAX_DRAW_COMMANDS]DrawCommand = undefined,
|
command_buffer: [MAX_DRAW_COMMANDS]DrawCommand = undefined,
|
||||||
command_count: usize = 0,
|
command_count: usize = 0,
|
||||||
ubo_align: usize = 0,
|
ubo_align: usize = 0,
|
||||||
|
ssbo_align: usize = 0,
|
||||||
shadow_vao: gl.GLuint = 0,
|
shadow_vao: gl.GLuint = 0,
|
||||||
shadow_texture_array: gl.GLuint = 0,
|
shadow_texture_array: gl.GLuint = 0,
|
||||||
shadow_texture_handle: gl.GLuint64 = 0,
|
shadow_texture_handle: gl.GLuint64 = 0,
|
||||||
@ -84,12 +85,19 @@ pub fn init(allocator: std.mem.Allocator, frame_arena: std.mem.Allocator, assetm
|
|||||||
|
|
||||||
gl.clipControl(gl.LOWER_LEFT, gl.ZERO_TO_ONE); // use [0, 1] depth in NDC
|
gl.clipControl(gl.LOWER_LEFT, gl.ZERO_TO_ONE); // use [0, 1] depth in NDC
|
||||||
|
|
||||||
|
{
|
||||||
var buffer_align_int: gl.GLint = 0;
|
var buffer_align_int: gl.GLint = 0;
|
||||||
gl.getIntegerv(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT, &buffer_align_int);
|
gl.getIntegerv(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT, &buffer_align_int);
|
||||||
|
|
||||||
if (buffer_align_int == 0) @panic("Failed to query GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT");
|
if (buffer_align_int == 0) @panic("Failed to query GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT");
|
||||||
|
|
||||||
render.ubo_align = @intCast(buffer_align_int);
|
render.ubo_align = @intCast(buffer_align_int);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var buffer_align_int: gl.GLint = 0;
|
||||||
|
gl.getIntegerv(gl.SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &buffer_align_int);
|
||||||
|
if (buffer_align_int == 0) @panic("Failed to query GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT");
|
||||||
|
render.ssbo_align = @intCast(buffer_align_int);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// MESH VAO
|
// MESH VAO
|
||||||
@ -148,24 +156,24 @@ pub fn init(allocator: std.mem.Allocator, frame_arena: std.mem.Allocator, assetm
|
|||||||
|
|
||||||
// Point lights ubo
|
// Point lights ubo
|
||||||
{
|
{
|
||||||
gl.createBuffers(1, &render.point_lights_ubo);
|
gl.createBuffers(1, &render.point_lights_ssbo);
|
||||||
std.debug.assert(render.camera_ubo != 0);
|
std.debug.assert(render.camera_ubo != 0);
|
||||||
|
|
||||||
const buf_size = render.uboAlignedSizeOf(LightArray) * MAX_FRAMES_QUEUED;
|
const buf_size = render.ssboAlign(@sizeOf(LightArraySSBO) + Light.sizeOfStd430() * MAX_LIGHTS) * MAX_FRAMES_QUEUED;
|
||||||
gl.namedBufferStorage(
|
gl.namedBufferStorage(
|
||||||
render.point_lights_ubo,
|
render.point_lights_ssbo,
|
||||||
@intCast(buf_size),
|
@intCast(buf_size),
|
||||||
null,
|
null,
|
||||||
PERSISTENT_BUFFER_FLAGS,
|
PERSISTENT_BUFFER_FLAGS,
|
||||||
);
|
);
|
||||||
const point_lights_c: [*]u8 = @ptrCast(gl.mapNamedBufferRange(
|
const point_lights_c: [*]u8 = @ptrCast(gl.mapNamedBufferRange(
|
||||||
render.point_lights_ubo,
|
render.point_lights_ssbo,
|
||||||
0,
|
0,
|
||||||
@intCast(buf_size),
|
@intCast(buf_size),
|
||||||
PERSISTENT_BUFFER_FLAGS,
|
PERSISTENT_BUFFER_FLAGS,
|
||||||
) orelse {
|
) orelse {
|
||||||
checkGLError();
|
checkGLError();
|
||||||
@panic("bind point_lights_ubo");
|
@panic("bind point_lights_ssbo");
|
||||||
});
|
});
|
||||||
render.point_lights = point_lights_c[0..buf_size];
|
render.point_lights = point_lights_c[0..buf_size];
|
||||||
}
|
}
|
||||||
@ -391,21 +399,22 @@ pub fn begin(self: *Render) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getLightBuffer(self: *Render) *LightArray {
|
fn getLightBuffer(self: *Render) *LightArraySSBO {
|
||||||
return @alignCast(@ptrCast(self.point_lights[self.tripple_buffer_index * self.uboAlignedSizeOf(LightArray) ..].ptr));
|
return @alignCast(@ptrCast(self.point_lights[self.tripple_buffer_index * self.ssboAlign(@sizeOf(LightArraySSBO) + Light.sizeOfStd430() * MAX_LIGHTS) ..].ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: get rid of this
|
// TODO: get rid of this
|
||||||
pub fn flushUBOs(self: *Render) void {
|
pub fn flushUBOs(self: *Render) void {
|
||||||
const idx = self.tripple_buffer_index;
|
const idx = self.tripple_buffer_index;
|
||||||
|
|
||||||
// gl.flushMappedNamedBufferRange(self.point_lights_ubo, idx * @sizeOf(PointLightArray), @sizeOf(PointLightArray));
|
const light_array_size = self.ssboAlign(@sizeOf(LightArraySSBO) + Light.sizeOfStd430() * MAX_LIGHTS);
|
||||||
|
// gl.flushMappedNamedBufferRange(self.point_lights_ssbo, idx * @sizeOf(PointLightArray), @sizeOf(PointLightArray));
|
||||||
gl.bindBufferRange(
|
gl.bindBufferRange(
|
||||||
gl.UNIFORM_BUFFER,
|
gl.SHADER_STORAGE_BUFFER,
|
||||||
UBO.PointLights.value(),
|
SSBO.PointLights.value(),
|
||||||
self.point_lights_ubo,
|
self.point_lights_ssbo,
|
||||||
idx * self.uboAlignedSizeOf(LightArray),
|
idx * light_array_size,
|
||||||
@intCast(self.uboAlignedSizeOf(LightArray)),
|
@intCast(light_array_size),
|
||||||
);
|
);
|
||||||
checkGLError();
|
checkGLError();
|
||||||
}
|
}
|
||||||
@ -497,6 +506,7 @@ pub fn finish(self: *Render) void {
|
|||||||
|
|
||||||
const lights_buf = self.getLightBuffer();
|
const lights_buf = self.getLightBuffer();
|
||||||
lights_buf.count = 0;
|
lights_buf.count = 0;
|
||||||
|
const lights_buf_lights = lights_buf.getLights();
|
||||||
|
|
||||||
var dir_view_proj_mat: [CSM_SPLITS]Mat4 = undefined;
|
var dir_view_proj_mat: [CSM_SPLITS]Mat4 = undefined;
|
||||||
|
|
||||||
@ -513,9 +523,9 @@ pub fn finish(self: *Render) void {
|
|||||||
|
|
||||||
for (lights) |light_cmd| {
|
for (lights) |light_cmd| {
|
||||||
const i = lights_buf.count;
|
const i = lights_buf.count;
|
||||||
if (i == lights_buf.lights.len) break;
|
if (i == lights_buf_lights.len) break;
|
||||||
|
|
||||||
const light = &lights_buf.lights[i];
|
const light = &lights_buf_lights[i];
|
||||||
lights_buf.count += 1;
|
lights_buf.count += 1;
|
||||||
|
|
||||||
switch (light_cmd) {
|
switch (light_cmd) {
|
||||||
@ -697,7 +707,7 @@ pub fn finish(self: *Render) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Light world space to view space
|
// Light world space to view space
|
||||||
for (lights_buf.lights[0..lights_buf.count]) |*light| {
|
for (lights_buf_lights[0..lights_buf.count]) |*light| {
|
||||||
light.pos = self.camera.view_mat.mulByVec4(light.pos);
|
light.pos = self.camera.view_mat.mulByVec4(light.pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1093,12 +1103,18 @@ pub const Attrib = enum(gl.GLuint) {
|
|||||||
};
|
};
|
||||||
pub const UBO = enum(gl.GLuint) {
|
pub const UBO = enum(gl.GLuint) {
|
||||||
CameraMatrices = 0,
|
CameraMatrices = 0,
|
||||||
PointLights = 1,
|
|
||||||
|
|
||||||
pub inline fn value(self: UBO) gl.GLuint {
|
pub inline fn value(self: UBO) gl.GLuint {
|
||||||
return @intFromEnum(self);
|
return @intFromEnum(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
pub const SSBO = enum(gl.GLuint) {
|
||||||
|
PointLights = 1,
|
||||||
|
|
||||||
|
pub inline fn value(self: SSBO) gl.GLuint {
|
||||||
|
return @intFromEnum(self);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub const Uniform = enum(gl.GLint) {
|
pub const Uniform = enum(gl.GLint) {
|
||||||
ModelMatrix = 1,
|
ModelMatrix = 1,
|
||||||
@ -1169,14 +1185,38 @@ pub const Light = extern struct {
|
|||||||
csm_split_count: f32,
|
csm_split_count: f32,
|
||||||
},
|
},
|
||||||
csm_split_points: [4]f32 = undefined,
|
csm_split_points: [4]f32 = undefined,
|
||||||
|
|
||||||
|
/// Alignment of this struct if it was in a std430 array
|
||||||
|
pub fn alignStd430() usize {
|
||||||
|
return 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Aligned size of this struct if it was in a std430 array
|
||||||
|
pub fn sizeOfStd430() usize {
|
||||||
|
return std.mem.alignForward(usize, @sizeOf(Light), Light.alignStd430());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: rename
|
// TODO: rename
|
||||||
pub const LightArray = extern struct {
|
pub const LightArraySSBO = extern struct {
|
||||||
lights: [MAX_LIGHTS]Light align(16),
|
|
||||||
count: c_uint,
|
count: c_uint,
|
||||||
|
// Zero sized field that just has the right alignment
|
||||||
|
_lights_start: [0]Light align(Light.alignStd430()),
|
||||||
|
|
||||||
|
pub fn getLights(self: *LightArraySSBO) []align(Light.alignStd430()) Light {
|
||||||
|
var lights_c: [*]align(Light.alignStd430()) Light = @ptrFromInt(@intFromPtr(self) + @offsetOf(LightArraySSBO, "_lights_start"));
|
||||||
|
return lights_c[0..MAX_LIGHTS];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn uboAlignedSizeOf(self: *const Render, comptime T: type) usize {
|
fn uboAlignedSizeOf(self: *const Render, comptime T: type) usize {
|
||||||
return std.mem.alignForward(usize, @sizeOf(T), self.ubo_align);
|
return std.mem.alignForward(usize, @sizeOf(T), self.ubo_align);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn ssboAlign(self: *const Render, size: usize) usize {
|
||||||
|
return std.mem.alignForward(usize, size, self.ssbo_align);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ssboAlignedSizeOf(self: *const Render, comptime T: type) usize {
|
||||||
|
return self.ssboAlign(@sizeOf(T));
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user