Skip to content

Commit

Permalink
Zephyr: Renderer: implement the poor girl's frustum cull check
Browse files Browse the repository at this point in the history
  • Loading branch information
fleroviux committed May 10, 2024
1 parent f75cf76 commit 392509f
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 15 deletions.
39 changes: 25 additions & 14 deletions zephyr/renderer/src/backend/opengl/render_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ namespace zephyr {
if(render_geometry->GetNumberOfIndices() == 0u) {
continue;
}
render_bundles[render_geometry->GetLayout().key].emplace_back(render_object.local_to_world, (u32)render_geometry->GetDrawCommandID());
render_bundles[render_geometry->GetLayout().key].emplace_back(render_object.local_to_world, (u32) render_geometry->GetGeometryID());
}

// TODO(fleroviux): apply Z-sorting on the render bundles here
Expand All @@ -97,26 +97,27 @@ namespace zephyr {

// TODO(fleroviux): attempt to keep buffers bound throughout the entire rendering process for minimal number of OpenGL calls.

glBindBufferBase(GL_UNIFORM_BUFFER, 0u, m_gl_camera_ubo);

for(const auto& [key, render_bundle] : render_bundles) {
const size_t render_bundle_size = render_bundle.size();

for(size_t base_draw = 0u; base_draw < render_bundle_size; base_draw += k_max_draws_per_draw_call) {
const u32 number_of_draws = std::min<size_t>(render_bundle_size - base_draw, k_max_draws_per_draw_call);

// TODO(fleroviux): use persistently mapped buffers (PMBs) for this and see if they are faster?
// 1. upload render bundle items into the render bundle buffer
// 1. Upload render bundle items into the render bundle buffer
glNamedBufferSubData(m_gl_render_bundle_ssbo, 0u, (GLsizeiptr)(number_of_draws * sizeof(RenderBundleItem)), &render_bundle[base_draw]);
glNamedBufferSubData(m_gl_draw_count_ubo, 0u, sizeof(u32), &number_of_draws);

// 2. generate multi-draw indirect command buffer from the render bundle buffer and geometry descriptor buffer
// 2. Generate multi-draw indirect command buffer from the render bundle buffer and geometry descriptor buffer
{
// TODO(fleroviux): adjust local work group size
glUseProgram(m_gl_draw_list_builder_program);

glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0u, m_render_geometry_manager->GetDrawCommandBuffer());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1u, m_gl_render_bundle_ssbo);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2u, m_gl_draw_list_ssbo);
glBindBufferBase(GL_UNIFORM_BUFFER, 0u, m_gl_draw_count_ubo);
glBindBufferBase(GL_UNIFORM_BUFFER, 1u, m_gl_draw_count_ubo);
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0u, m_gl_draw_count_out_ac);

const GLuint workgroup_size = 32u;
Expand All @@ -126,32 +127,31 @@ namespace zephyr {
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0u, 0u);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1u, 0u);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2u, 0u);
glBindBufferBase(GL_UNIFORM_BUFFER, 0u, 0u);
glBindBufferBase(GL_UNIFORM_BUFFER, 1u, 0u);
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0u, 0u);
}

// 3. draw everything written to the Draw List SSBO
// 3. Draw everything written to the Draw List SSBO
{
glUseProgram(m_gl_draw_program);

glBindVertexArray(m_render_geometry_manager->GetVAOFromLayout(RenderGeometryLayout{key}));
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_gl_draw_list_ssbo);
glBindBuffer(GL_PARAMETER_BUFFER, m_gl_draw_count_out_ac);
glBindBufferBase(GL_UNIFORM_BUFFER, 0u, m_gl_camera_ubo);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0u, m_gl_render_bundle_ssbo);

glMemoryBarrier(GL_COMMAND_BARRIER_BIT | GL_ATOMIC_COUNTER_BARRIER_BIT);
//glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, nullptr, (GLsizei)number_of_draws, sizeof(OpenGLDrawElementsIndirectCommand));
glMultiDrawElementsIndirectCount(GL_TRIANGLES, GL_UNSIGNED_INT, nullptr, 0u, (GLsizei)number_of_draws, sizeof(OpenGLDrawElementsIndirectCommand));

glBindVertexArray(0u);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0u);
glBindBuffer(GL_PARAMETER_BUFFER, 0u);
glBindBufferBase(GL_UNIFORM_BUFFER, 0u, 0u);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0u, 0u);
}
}
}

glBindBufferBase(GL_UNIFORM_BUFFER, 0u, 0u);
}

void OpenGLRenderBackend::SwapBuffers() {
Expand Down Expand Up @@ -213,12 +213,13 @@ namespace zephyr {
#version 460 core
layout(local_size_x = 32) in;
struct DrawIndirectCommand {
uint data[5];
};
struct RenderGeometryRenderData {
// TODO(fleroviux): evaluate whether the packing can be tighter or not.
vec4 aabb_min;
vec4 aabb_max;
DrawIndirectCommand draw_command;
Expand All @@ -241,7 +242,11 @@ namespace zephyr {
DrawIndirectCommand b_command_buffer[];
};
layout(std140, binding = 0) uniform DrawCount {
layout(std140, binding = 0) uniform Transform {
mat4 u_projection;
};
layout(std140, binding = 1) uniform DrawCount {
uint u_draw_count;
};
Expand All @@ -256,8 +261,14 @@ namespace zephyr {
barrier();
if(draw_index < u_draw_count) {
b_command_buffer[draw_index] = rb_render_geometry_render_data[rb_render_bundle_items[draw_index].geometry_id].draw_command;
atomicCounterIncrement(u_draw_count_out);
RenderBundleItem render_bundle_item = rb_render_bundle_items[draw_index];
RenderGeometryRenderData render_data = rb_render_geometry_render_data[render_bundle_item.geometry_id];
vec4 clip_aabb_center = u_projection * render_bundle_item.local_to_world * vec4((render_data.aabb_min.xyz + render_data.aabb_max.xyz) * 0.5, 1.0);
if(abs(clip_aabb_center.x) < clip_aabb_center.w && abs(clip_aabb_center.y) < clip_aabb_center.w && abs(clip_aabb_center.z) < clip_aabb_center.w) {
b_command_buffer[draw_index] = render_data.draw_command;
atomicCounterIncrement(u_draw_count_out);
}
}
}
)", GL_COMPUTE_SHADER);
Expand Down
2 changes: 1 addition & 1 deletion zephyr/renderer/src/backend/opengl/render_geometry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ namespace zephyr {
return m_layout;
}

[[nodiscard]] size_t GetDrawCommandID() const {
[[nodiscard]] size_t GetGeometryID() const {
return m_geometry_render_data_allocation.base_element;
}

Expand Down

0 comments on commit 392509f

Please sign in to comment.