Skip to content

Commit

Permalink
[RendererVK] Better window resize
Browse files Browse the repository at this point in the history
  • Loading branch information
native-m committed Oct 25, 2024
1 parent def39f5 commit 1dffcfb
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 32 deletions.
8 changes: 3 additions & 5 deletions src/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ static void handle_events(SDL_Event& event) {
if (event.window.windowID == main_window_id) {
switch (event.window.event) {
case SDL_WINDOWEVENT_RESIZED:
g_renderer->refresh_window();
//g_renderer->resize_viewport();
break;
case SDL_WINDOWEVENT_CLOSE:
is_running = false;
Expand Down Expand Up @@ -192,10 +192,7 @@ static void register_events() {
static void imgui_renderer_create_window(ImGuiViewport* viewport) {
SDL_Window* window = SDL_GetWindowFromID((uint32_t)(uint64_t)viewport->PlatformHandle);
uint32_t flags = SDL_GetWindowFlags(window);
if (!has_bit(flags, SDL_WINDOW_BORDERLESS)) {
setup_dark_mode(window);
make_child_window(window);
}
make_child_window(window);
g_renderer->add_viewport(viewport);
}

Expand All @@ -205,6 +202,7 @@ static void imgui_renderer_destroy_window(ImGuiViewport* viewport) {
}

static void imgui_renderer_set_window_size(ImGuiViewport* viewport, ImVec2 size) {
g_renderer->resize_viewport(viewport, size);
}

static void imgui_renderer_render_window(ImGuiViewport* viewport, void* userdata) {
Expand Down
9 changes: 7 additions & 2 deletions src/core/algorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@

namespace wb {

template <typename T>
constexpr const T* ptr_of(const T&& v) noexcept {
return __builtin_addressof(v);
}

template <typename T, typename Tcmp, typename... Args>
inline bool any_of(T value, Tcmp cmp, Args... cmp_args) {
inline bool any_of(T value, Tcmp cmp, Args... cmp_args) noexcept {
return value == cmp || ((value == cmp_args) || ...);
}

template <typename T, typename ValT, typename CompareFn>
inline T find_lower_bound(T begin, T end, ValT value, CompareFn comp_fn) {
inline T find_lower_bound(T begin, T end, ValT value, CompareFn comp_fn) noexcept {
using DiffType = typename std::iterator_traits<T>::difference_type;
DiffType left = 0;
DiffType right = (end - begin) - 1;
Expand Down
2 changes: 1 addition & 1 deletion src/core/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
#define WB_UNREACHABLE() __assume(false)
#else
#define WB_UNREACHABLE() __builtin_unreachable()
#endif
#endif
2 changes: 1 addition & 1 deletion src/gfx/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ struct Renderer {
virtual ~Renderer() {}
virtual std::shared_ptr<Framebuffer> create_framebuffer(uint32_t width, uint32_t height) = 0;
virtual std::shared_ptr<SamplePeaks> create_sample_peaks(const Sample& sample, SamplePeaksPrecision precision) = 0;
virtual void refresh_window() = 0;
virtual void new_frame() = 0;
virtual void end_frame() = 0;
virtual void set_framebuffer(const std::shared_ptr<Framebuffer>& framebuffer) = 0;
Expand All @@ -83,6 +82,7 @@ struct Renderer {
virtual void draw_waveforms(const ImVector<ClipContentDrawCmd>& clips) = 0;
virtual void render_draw_command_list(DrawCommandList* command_list) = 0;
virtual void render_imgui_draw_data(ImDrawData* draw_data) = 0;
virtual void resize_viewport(ImGuiViewport* viewport, ImVec2 vec) = 0;
virtual bool add_viewport(ImGuiViewport* viewport) { return false; }
virtual bool remove_viewport(ImGuiViewport* viewport) { return false; }
virtual void present() = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/gfx/renderer_d3d11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ RendererD3D11::RendererD3D11(IDXGISwapChain2* swapchain, ID3D11Device* device, I
swapchain_(swapchain), device_(device), ctx_(ctx) {
swapchain_->SetMaximumFrameLatency(1);
frame_latency_waitable_handle_ = swapchain->GetFrameLatencyWaitableObject();
refresh_window();
resize_viewport(nullptr, {});
}

RendererD3D11::~RendererD3D11() {
Expand Down Expand Up @@ -305,7 +305,7 @@ void RendererD3D11::new_frame() {
void RendererD3D11::end_frame() {
}

void RendererD3D11::refresh_window() {
void RendererD3D11::resize_viewport(ImGuiViewport* viewport, ImVec2 vec) {
constexpr UINT swapchain_flags =
DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH | DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;

Expand Down
2 changes: 1 addition & 1 deletion src/gfx/renderer_d3d11.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ struct RendererD3D11 : public Renderer {
bool init();
std::shared_ptr<Framebuffer> create_framebuffer(uint32_t width, uint32_t height) override;
std::shared_ptr<SamplePeaks> create_sample_peaks(const Sample& sample, SamplePeaksPrecision precision) override;
void resize_viewport(ImGuiViewport* viewport, ImVec2 vec) override;
void new_frame() override;
void end_frame() override;
void refresh_window() override;
void set_framebuffer(const std::shared_ptr<Framebuffer>& framebuffer) override;
void begin_draw(Framebuffer* framebuffer, const ImVec4& clear_color) override;
void finish_draw() override;
Expand Down
76 changes: 57 additions & 19 deletions src/gfx/renderer_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -907,11 +907,6 @@ std::shared_ptr<SamplePeaks> RendererVK::create_sample_peaks(const Sample& sampl
return ret;
}

void RendererVK::refresh_window() {
// vkDeviceWaitIdle(device_);
// init_swapchain_();
}

void RendererVK::new_frame() {
FrameSync& frame_sync = frame_sync_[sync_id_];
CommandBufferVK& cmd_buf = cmd_buf_[frame_id_];
Expand All @@ -920,6 +915,10 @@ void RendererVK::new_frame() {
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
};

for (auto swapchain : swapchains) {
swapchain->acquire(device_);
}

vkWaitForFences(device_, 1, &fences_[frame_id_], VK_TRUE, UINT64_MAX);
resource_disposal_.flush(device_, instance_, allocator_, frame_id_);
descriptor_stream_.reset(device_, frame_id_);
Expand All @@ -943,8 +942,12 @@ void RendererVK::new_frame() {
void RendererVK::end_frame() {
vkEndCommandBuffer(current_cb_);

for (auto swapchain : swapchains) {
for (auto swapchain : added_swapchains) {
swapchain->acquire(device_);
swapchains.push_back(swapchain);
}

for (auto swapchain : swapchains) {
uint32_t sync_id = swapchain->sync_id;
image_acquired_semaphore.push_back(swapchain->image_acquire_semaphore[swapchain->sync_id]);
swapchain_image_wait_stage.push_back(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
Expand All @@ -969,6 +972,7 @@ void RendererVK::end_frame() {
sync_id_ = (sync_id_ + 1) % sync_count_;
image_acquired_semaphore.resize(0);
swapchain_image_wait_stage.resize(0);
added_swapchains.resize(0);
}

void RendererVK::set_framebuffer(const std::shared_ptr<Framebuffer>& framebuffer) {
Expand Down Expand Up @@ -1237,6 +1241,7 @@ void RendererVK::draw_waveforms(const ImVector<ClipContentDrawCmd>& clips) {
if (current_buffer != buffer) {
VkDescriptorSet descriptor_set =
descriptor_stream_.allocate_descriptor_set(device_, waveform_layout.set_layout[0], 0, 1, 0, 0);

VkDescriptorBufferInfo buffer_descriptor {buffer, 0, VK_WHOLE_SIZE};

VkWriteDescriptorSet write_descriptor {
Expand Down Expand Up @@ -1572,8 +1577,7 @@ bool RendererVK::add_viewport(ImGuiViewport* viewport) {
viewport->RendererUserData = &swapchain->fb;
swapchain->surface = surface;
swapchain->viewport = viewport;
swapchains.push_back(swapchain);
swapchain_results.resize(swapchains.size());
added_swapchains.push_back(swapchain);
vkDeviceWaitIdle(device_);
return create_or_recreate_swapchain(swapchain);
}
Expand All @@ -1599,6 +1603,14 @@ bool RendererVK::remove_viewport(ImGuiViewport* viewport) {
return true;
}

void RendererVK::resize_viewport(ImGuiViewport* viewport, ImVec2 vec) {
FramebufferVK* framebuffer = (FramebufferVK*)viewport->RendererUserData;
vkDeviceWaitIdle(device_);
create_or_recreate_swapchain(framebuffer->parent_swapchain);
framebuffer->parent_swapchain->acquire(device_);
// init_swapchain_();
}

void RendererVK::present() {
using namespace std::chrono_literals;
for (auto swapchain : swapchains) {
Expand Down Expand Up @@ -1875,17 +1887,17 @@ vk_create_pipeline_layout(VkDevice device, uint32_t push_constant_size,
VK_CHECK(vkCreateDescriptorSetLayout(device, &set_layout_info, nullptr, &ret.set_layout[1]));
}

VkPushConstantRange constant_range {
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
.size = push_constant_size,
};
VkPipelineLayoutCreateInfo pipeline_layout {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = ds_bindings1.size() > 0 ? 2u : 1u,
.pSetLayouts = ret.set_layout,
.pushConstantRangeCount = 1,
.pPushConstantRanges = &constant_range,
.pPushConstantRanges = ptr_of(VkPushConstantRange {
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
.size = push_constant_size,
}),
};

VK_CHECK(vkCreatePipelineLayout(device, &pipeline_layout, nullptr, &ret.layout));
return ret;
}
Expand Down Expand Up @@ -2059,14 +2071,40 @@ VkPipeline RendererVK::create_pipeline(const char* vs, const char* fs, VkPipelin
.stageCount = 2,
.pStages = shader_stages,
.pVertexInputState = vertex_input ? vertex_input : &empty_vertex_input,
.pInputAssemblyState = &input_assembly,
.pInputAssemblyState = ptr_of<VkPipelineInputAssemblyStateCreateInfo>({
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
.topology = primitive_topology,
}),
.pTessellationState = {},
.pViewportState = &viewport,
.pRasterizationState = &rasterization,
.pMultisampleState = &multisample,
.pViewportState = ptr_of<VkPipelineViewportStateCreateInfo>({
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.viewportCount = 1,
.scissorCount = 1,
}),
.pRasterizationState = ptr_of<VkPipelineRasterizationStateCreateInfo>({
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.depthClampEnable = VK_FALSE,
.rasterizerDiscardEnable = VK_FALSE,
.polygonMode = VK_POLYGON_MODE_FILL,
.cullMode = VK_CULL_MODE_NONE,
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
.lineWidth = 1.0f,
}),
.pMultisampleState = ptr_of<VkPipelineMultisampleStateCreateInfo>({
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
}),
.pDepthStencilState = {},
.pColorBlendState = &blend,
.pDynamicState = &dynamic_state,
.pColorBlendState = ptr_of<VkPipelineColorBlendStateCreateInfo>({
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
.attachmentCount = 1,
.pAttachments = &color_attachment,
}),
.pDynamicState = ptr_of<VkPipelineDynamicStateCreateInfo>({
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.dynamicStateCount = IM_ARRAYSIZE(dynamic_states),
.pDynamicStates = dynamic_states,
}),
.layout = layout,
.renderPass = fb_render_pass_,
.subpass = 0,
Expand Down
3 changes: 2 additions & 1 deletion src/gfx/renderer_vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ struct RendererVK : public Renderer {
VkQueue graphics_queue_;
VkQueue present_queue_;
Vector<SwapchainVK*> swapchains;
Vector<SwapchainVK*> added_swapchains;
SwapchainVK* main_swapchain_ {};

VkRenderPass fb_render_pass_ {};
Expand Down Expand Up @@ -287,7 +288,7 @@ struct RendererVK : public Renderer {

std::shared_ptr<SamplePeaks> create_sample_peaks(const Sample& sample, SamplePeaksPrecision precision) override;

void refresh_window() override;
void resize_viewport(ImGuiViewport* viewport, ImVec2 vec) override;

void new_frame() override;

Expand Down

0 comments on commit 1dffcfb

Please sign in to comment.