Skip to content

Commit

Permalink
gh-7: add deferred pipeline setup & common code
Browse files Browse the repository at this point in the history
  • Loading branch information
EgorOrachyov committed Oct 28, 2023
1 parent d202487 commit b45782d
Show file tree
Hide file tree
Showing 74 changed files with 2,481 additions and 143 deletions.
6 changes: 6 additions & 0 deletions engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ add_library(wmoge STATIC
render/aux_draw_manager.hpp
render/canvas.cpp
render/canvas.hpp
render/deferred_pipeline.cpp
render/deferred_pipeline.hpp
render/graphics_pipeline.cpp
render/graphics_pipeline.hpp
render/render_camera.cpp
Expand Down Expand Up @@ -295,6 +297,10 @@ add_library(wmoge STATIC
render/vertex_factory.hpp
render/visibility.cpp
render/visibility.hpp
render/geometry/pass_gbuffer.cpp
render/geometry/pass_gbuffer.hpp
render/post_process/pass_tonemap.cpp
render/post_process/pass_tonemap.hpp
resource/audio_stream.cpp
resource/audio_stream.hpp
resource/audio_stream_wav.cpp
Expand Down
19 changes: 18 additions & 1 deletion engine/gfx/gfx_dynamic_buffers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "gfx/gfx_driver.hpp"
#include "math/math_utils.hpp"

#include "gfx_dynamic_buffers.hpp"
#include <cassert>
#include <cstring>

Expand Down Expand Up @@ -81,7 +82,23 @@ namespace wmoge {

return setup;
}
void GfxUniformPool::recycle() {

void GfxUniformPool::configure(GfxUniformBufferSetup& setup, int constants_size, const void* mem) {
if (!setup.buffer) {
setup = allocate(constants_size, mem);
return;
}

auto* engine = Engine::instance();
auto* gfx_ctx = engine->gfx_ctx();

auto buffer = Ref<GfxUniformBuffer>(setup.buffer);
void* host_ptr = gfx_ctx->map_uniform_buffer(buffer);
std::memcpy(host_ptr, mem, constants_size);
gfx_ctx->unmap_uniform_buffer(buffer);
}

void GfxUniformPool::resycle_allocations() {
std::lock_guard guard(m_mutex);

for (Bucket& bucket : m_buckets) {
Expand Down
8 changes: 7 additions & 1 deletion engine/gfx/gfx_dynamic_buffers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,19 @@ namespace wmoge {
~GfxUniformPool() override = default;

virtual GfxUniformBufferSetup allocate(int constants_size, const void* mem);
virtual void recycle();
virtual void configure(GfxUniformBufferSetup& setup, int constants_size, const void* mem);
virtual void resycle_allocations();

template<typename ConstantsStructure>
GfxUniformBufferSetup allocate(const ConstantsStructure& constants) {
return allocate(int(sizeof(ConstantsStructure)), &constants);
}

template<typename ConstantsStructure>
GfxUniformBufferSetup configure(GfxUniformBufferSetup& setup, const ConstantsStructure& constants) {
return configure(setup, int(sizeof(ConstantsStructure)), &constants);
}

private:
struct Bucket {
std::vector<Ref<GfxUniformBuffer>> buffers;
Expand Down
28 changes: 25 additions & 3 deletions engine/gfx/gfx_vert_format.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,28 +82,50 @@ namespace wmoge {
virtual const GfxVertElements& elements() const = 0;
};

/**
* @brief Vert Format: [pos2, uv2, col3,]
*/
struct GfxVF_Pos2Uv2Col3 {
Vec2f pos;
Vec2f uv;
Vec3f col;
};

/**
* @brief Vert Format: [pos3, col3,]
*/
struct GfxVF_Pos3Col3 {
Vec3f pos;
Vec3f col;
};
struct GfxVF_Pos2Uv2Col4 {

/**
* @brief Vert Format: []
*/
struct GfxVF_Pos2Uv2 {
Vec2f pos;
Vec2f uv;
Vec4f col;
};

/**
* @brief Vert Format: []
*/
struct GfxVF_Pos2Col3 {
Vec2f pos;
Vec3f col;
};

/**
* @brief Vert Format: []
*/
struct GfxVF_Pos3Col4 {
Vec3f pos;
Vec4f col;
};

/**
* @brief Vert Format: []
*/
struct GfxVF_Pos3Col4Uv2 {
Vec3f pos;
Vec4f col;
Expand All @@ -112,7 +134,7 @@ namespace wmoge {

static_assert(sizeof(GfxVF_Pos2Uv2Col3) == 7 * sizeof(float), "unexpected size");
static_assert(sizeof(GfxVF_Pos3Col3) == 6 * sizeof(float), "unexpected size");
static_assert(sizeof(GfxVF_Pos2Uv2Col4) == 8 * sizeof(float), "unexpected size");
static_assert(sizeof(GfxVF_Pos2Uv2) == 4 * sizeof(float), "unexpected size");
static_assert(sizeof(GfxVF_Pos2Col3) == 5 * sizeof(float), "unexpected size");
static_assert(sizeof(GfxVF_Pos3Col4) == 7 * sizeof(float), "unexpected size");
static_assert(sizeof(GfxVF_Pos3Col4Uv2) == 9 * sizeof(float), "unexpected size");
Expand Down
9 changes: 5 additions & 4 deletions engine/gfx/vulkan/vk_ctx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ namespace wmoge {
assert(pass_desc == GfxRenderPassDesc{});// not supported pass desc yet

m_render_pass_binder->start(name);
m_in_render_pass = true;
m_in_render_pass = true;
m_render_pass_name = name;
}
void VKCtx::bind_target(const Ref<Window>& window) {
WG_AUTO_PROFILE_VULKAN("VKCtx::bind_target");
Expand Down Expand Up @@ -374,7 +375,7 @@ namespace wmoge {
WG_VK_END_LABEL(cmd_current());
vkCmdEndRenderPass(cmd_current());

m_render_pass_binder->finish();
m_render_pass_binder->finish(cmd_current());
m_current_pass.reset();
m_current_pipeline.reset();
m_current_shader.reset();
Expand Down Expand Up @@ -431,7 +432,7 @@ namespace wmoge {

if (!m_render_pass_started) {
// Potentially recreate make pass and framebuffer
m_render_pass_binder->validate();
m_render_pass_binder->validate(cmd_current());
m_current_pass = m_render_pass_binder->render_pass();

std::array<VkClearValue, GfxLimits::MAX_COLOR_TARGETS + 1> clear_values{};
Expand Down Expand Up @@ -467,7 +468,7 @@ namespace wmoge {
render_pass_info.pClearValues = clear_values.data();

vkCmdBeginRenderPass(cmd_current(), &render_pass_info, VK_SUBPASS_CONTENTS_INLINE);
WG_VK_BEGIN_LABEL(cmd_current(), m_current_pass->name());
WG_VK_BEGIN_LABEL(cmd_current(), m_render_pass_name);

VkViewport viewport;
viewport.x = static_cast<float>(m_viewport.x());
Expand Down
9 changes: 5 additions & 4 deletions engine/gfx/vulkan/vk_ctx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,11 @@ namespace wmoge {
int m_clear_stencil = 0;
Rect2i m_viewport;

bool m_in_render_pass = false;
bool m_render_pass_started = false;
bool m_pipeline_bound = false;
bool m_target_bound = false;
bool m_in_render_pass = false;
bool m_render_pass_started = false;
bool m_pipeline_bound = false;
bool m_target_bound = false;
StringId m_render_pass_name;

GfxCtxType m_ctx_type = GfxCtxType::Immediate;
Mat4x4f m_clip_matrix;
Expand Down
5 changes: 4 additions & 1 deletion engine/gfx/vulkan/vk_defs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ namespace wmoge {
static VkImageLayout rt_layout_from_fmt(GfxFormat fmt) {
switch (fmt) {
case GfxFormat::DEPTH32F:
return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
case GfxFormat::DEPTH24_STENCIL8:
case GfxFormat::DEPTH32F_STENCIL8:
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
Expand Down Expand Up @@ -419,6 +418,10 @@ namespace wmoge {
case GfxFormat::RG32F:
case GfxFormat::RGB32F:
case GfxFormat::RGBA32F:
case GfxFormat::R32I:
case GfxFormat::RG32I:
case GfxFormat::RGB32I:
case GfxFormat::RGBA32I:
case GfxFormat::BC1_RGB:
case GfxFormat::BC1_RGB_SRGB:
case GfxFormat::BC1_RGBA:
Expand Down
2 changes: 1 addition & 1 deletion engine/gfx/vulkan/vk_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ namespace wmoge {
m_ctx_async->begin_frame();
}

m_uniform_pool->recycle();
m_uniform_pool->resycle_allocations();
}
void VKDriver::end_frame() {
WG_AUTO_PROFILE_VULKAN("VKDriver::end_frame");
Expand Down
26 changes: 24 additions & 2 deletions engine/gfx/vulkan/vk_render_pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,15 +165,37 @@ namespace wmoge {

m_current_name = name;
}
void VKRenderPassBinder::validate() {
void VKRenderPassBinder::validate(VkCommandBuffer cmd) {
WG_AUTO_PROFILE_VULKAN("VKRenderPassBinder::validate");

prepare_render_pass();
prepare_framebuffer();

for (auto& target : m_color_targets) {
if (target.texture) {
target.texture->transition_layout(cmd, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
}
}

if (m_depth_stencil_target.texture) {
m_depth_stencil_target.texture->transition_layout(cmd, VKDefs::rt_layout_from_fmt(m_depth_stencil_target.texture->format()));
}
}
void VKRenderPassBinder::finish() {
void VKRenderPassBinder::finish(VkCommandBuffer cmd) {
WG_AUTO_PROFILE_VULKAN("VKRenderPassBinder::finish");

for (auto& target : m_color_targets) {
if (target.texture) {
target.texture->transition_layout(cmd, target.texture->primary_layout());
target = VKTargetInfo();
}
}

if (m_depth_stencil_target.texture) {
m_depth_stencil_target.texture->transition_layout(cmd, m_depth_stencil_target.texture->primary_layout());
m_depth_stencil_target = VKTargetInfo();
}

m_current_render_pass.reset();
m_current_framebuffer.reset();
m_current_size = {0, 0};
Expand Down
4 changes: 2 additions & 2 deletions engine/gfx/vulkan/vk_render_pass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ namespace wmoge {
void clear_stencil();

void start(const StringId& name);
void validate();
void finish();
void validate(VkCommandBuffer cmd);
void finish(VkCommandBuffer cmd);

[[nodiscard]] const Ref<VKRenderPass>& render_pass() const { return m_current_render_pass; }
[[nodiscard]] const Ref<VKFramebufferObject>& framebuffer() const { return m_current_framebuffer; }
Expand Down
4 changes: 2 additions & 2 deletions engine/gfx/vulkan/vk_texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,11 @@ namespace wmoge {
get_dst_layout_settings(destination, barrier.dstAccessMask, dst_stage_flags);
} else if (m_current_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL) {
barrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
src_stage_flags = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
src_stage_flags = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
get_dst_layout_settings(destination, barrier.dstAccessMask, dst_stage_flags);
} else if (m_current_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
barrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
src_stage_flags = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
src_stage_flags = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
get_dst_layout_settings(destination, barrier.dstAccessMask, dst_stage_flags);
} else if (m_current_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
Expand Down
48 changes: 25 additions & 23 deletions engine/hgfx/hgfx_pass_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,29 +42,31 @@ namespace wmoge {
ShaderManager* shader_manager = engine->shader_manager();
GfxDriver* gfx_driver = engine->gfx_driver();

fast_vector<std::string> defines;
if (out_srgb) defines.push_back("OUT_SRGB");
if (no_alpha) defines.push_back("NO_ALPHA");

assert(attribs_req.get(GfxVertAttrib::Pos3f));
assert(attribs_full.get(GfxVertAttrib::Pos3f));

GfxVertElements elements;
elements.add_vert_attribs(attribs_req, attribs_full, 0, false);

GfxPipelineState pipeline_state{};
pipeline_state.shader = shader_manager->get_shader(SID("base"), attribs_req, defines);
pipeline_state.vert_format = gfx_driver->make_vert_format(elements, name);
pipeline_state.prim_type = prim_type;
pipeline_state.poly_mode = poly_mode;
pipeline_state.cull_mode = cull_mode;
pipeline_state.front_face = front_face;
pipeline_state.depth_enable = depth_enable;
pipeline_state.depth_write = depth_write;
pipeline_state.depth_func = depth_func;
pipeline_state.blending = !no_alpha;

m_pipeline = gfx_driver->make_pipeline(pipeline_state, name);
if (!m_pipeline) {
fast_vector<std::string> defines;
if (out_srgb) defines.push_back("OUT_SRGB");
if (no_alpha) defines.push_back("NO_ALPHA");

assert(attribs_req.get(GfxVertAttrib::Pos3f));
assert(attribs_full.get(GfxVertAttrib::Pos3f));

GfxVertElements elements;
elements.add_vert_attribs(attribs_req, attribs_full, 0, false);

GfxPipelineState pipeline_state{};
pipeline_state.shader = shader_manager->get_shader(SID("base"), attribs_req, defines);
pipeline_state.vert_format = gfx_driver->make_vert_format(elements, name);
pipeline_state.prim_type = prim_type;
pipeline_state.poly_mode = poly_mode;
pipeline_state.cull_mode = cull_mode;
pipeline_state.front_face = front_face;
pipeline_state.depth_enable = depth_enable;
pipeline_state.depth_write = depth_write;
pipeline_state.depth_func = depth_func;
pipeline_state.blending = !no_alpha;

m_pipeline = gfx_driver->make_pipeline(pipeline_state, name);
}

ShaderBase::Params params;
params.mat_clip_proj_view = (gfx_driver->clip_matrix() * mat_proj_view).transpose();
Expand Down
22 changes: 12 additions & 10 deletions engine/hgfx/hgfx_pass_text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,22 @@ namespace wmoge {
ShaderManager* shader_manager = engine->shader_manager();
GfxDriver* gfx_driver = engine->gfx_driver();

fast_vector<std::string> defines;
if (out_srgb) defines.push_back("OUT_SRGB");
if (!m_pipeline) {
fast_vector<std::string> defines;
if (out_srgb) defines.push_back("OUT_SRGB");

GfxVertAttribs attribs = {GfxVertAttrib::Pos3f, GfxVertAttrib::Col04f, GfxVertAttrib::Uv02f};
GfxVertAttribs attribs = {GfxVertAttrib::Pos3f, GfxVertAttrib::Col04f, GfxVertAttrib::Uv02f};

GfxVertElements elements;
elements.add_vert_attribs(attribs, attribs, 0, false);
GfxVertElements elements;
elements.add_vert_attribs(attribs, attribs, 0, false);

GfxPipelineState pipeline_state{};
pipeline_state.shader = shader_manager->get_shader(SID("text"), attribs, defines);
pipeline_state.vert_format = gfx_driver->make_vert_format(elements, name);
pipeline_state.blending = true;
GfxPipelineState pipeline_state{};
pipeline_state.shader = shader_manager->get_shader(SID("text"), attribs, defines);
pipeline_state.vert_format = gfx_driver->make_vert_format(elements, name);
pipeline_state.blending = true;

m_pipeline = gfx_driver->make_pipeline(pipeline_state, name);
m_pipeline = gfx_driver->make_pipeline(pipeline_state, name);
}

ShaderText::Params params;
params.mat_clip_proj_screen = (gfx_driver->clip_matrix() * Math3d::orthographic(0.0f, screen_size.x(), 0, screen_size.y(), -1000.0f, 1000.0f)).transpose();
Expand Down
12 changes: 12 additions & 0 deletions engine/math/math_utils3d.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,18 @@ namespace wmoge {
0.0f, 0.0f, 0.0f, 1.0f);
}

static Vec3f project(const Mat4x4f& mat, const Vec3f& point) {
const Vec4f world_space = mat * Vec4f(point, 1.0f);
const Vec4f ndc = world_space / world_space.w();
return Vec3f(ndc);
}

static Vec2f to_viewport(const Vec4f& viewport, const Vec2f& point) {
const Vec2f pos = Vec2f(viewport.x(), viewport.y());
const Vec2f size = Vec2f(viewport.z(), viewport.w()) - pos;
return pos + size * (point * 0.5f + Vec2f(0.5f, 0.5f));
}

static Vec2f project_to_screen(const Mat4x4f& mat, const Vec2f& area, const Vec3f& point) {
const Vec4f world_space = mat * Vec4f(point, 1.0f);
const Vec4f ndc = world_space / world_space.w();
Expand Down
2 changes: 1 addition & 1 deletion engine/mesh/mesh_processors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ namespace wmoge {

fast_vector<std::string> defines;
{
defines.push_back("PASS_GBUFFER");
defines.push_back("MESH_PASS_GBUFFER");
}

GfxVertAttribs attribs;
Expand Down
Loading

0 comments on commit b45782d

Please sign in to comment.