Skip to content

Commit

Permalink
stop constantly reallocating memory on loader thread, wait on the gpu…
Browse files Browse the repository at this point in the history
… a lot less, fix unicode support
  • Loading branch information
khang06 committed Jul 16, 2020
1 parent 7557aaf commit 3883043
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 40 deletions.
19 changes: 12 additions & 7 deletions Chikara/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

Renderer r;
Midi* midi;
Utils u;

Vertex instanced_quad[] {
{ {0,1}, {0,1} },
Expand All @@ -41,9 +40,10 @@ void Main::run(int argc, wchar_t** argv)
auto config_path = Config::GetConfigPath();
Config::GetConfig().Load(config_path);
KDMAPI::Init();
std::cout << "Loading " << u.GetFileName(argv[1]) << std::endl;
SetConsoleOutputCP(65001);
fmt::print("Loading {}\n", Utils::wstringToUtf8(Utils::GetFileName(argv[1])));
std::cout << "RPC Enabled: " << Config::GetConfig().discord_rpc << std::endl;
if(Config::GetConfig().discord_rpc) u.InitDiscord();
if(Config::GetConfig().discord_rpc) Utils::InitDiscord();
midi = new Midi(argv[1]);
r.note_event_buffer = midi->note_event_buffer;
r.midi_renderer_time = &midi->renderer_time;
Expand All @@ -66,7 +66,8 @@ void Main::initWindow(wchar_t** argv)
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); //Set the glfw api to GLFW_NO_API because we are using Vulkan
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); //Change the ability to resize the window
//glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); //Window Transparancy
r.window = glfwCreateWindow(default_width, default_height, std::string("Chikara | " + u.GetFileName(argv[1])).c_str(), nullptr, nullptr); //Now we create the window
auto filename = Utils::wstringToUtf8(Utils::GetFileName(argv[1]));
r.window = glfwCreateWindow(default_width, default_height, std::string("Chikara | " + filename).c_str(), nullptr, nullptr); //Now we create the window
glfwSetWindowUserPointer(r.window, &r);
glfwSetFramebufferSizeCallback(r.window, r.framebufferResizeCallback);
}
Expand Down Expand Up @@ -121,10 +122,14 @@ void Main::mainLoop(wchar_t** argv)
long long start = (std::chrono::system_clock::now().time_since_epoch() + std::chrono::seconds(1)) / std::chrono::milliseconds(1);
long long end_time = (std::chrono::system_clock::now().time_since_epoch() + std::chrono::seconds(1) + std::chrono::seconds((long long)midi->song_len)) / std::chrono::milliseconds(1);
midi->SpawnPlaybackThread(start_time);
/*
char buffer[256];
sprintf(buffer, "Note Count: %s", fmt::format(std::locale("en_US.UTF-8"), "{:n}", midi->note_count));
if(Config::GetConfig().discord_rpc)
u.UpdatePresence(buffer, "Playing: ", u.GetFileName(argv[1]), (uint64_t)start, (uint64_t)end_time);
*/
if (Config::GetConfig().discord_rpc) {
auto rpc_text = fmt::format(std::locale("en_US.UTF-8"), "Note Count: {:n}", midi->note_count);
Utils::UpdatePresence(rpc_text.c_str(), "Playing: ", Utils::wstringToUtf8(Utils::GetFileName(argv[1])), (uint64_t)start, (uint64_t)end_time);
}
while(!glfwWindowShouldClose(r.window))
{
r.pre_time = Config::GetConfig().note_speed;
Expand Down Expand Up @@ -264,7 +269,7 @@ void Main::cleanup()
glfwDestroyWindow(r.window);

glfwTerminate(); //Now we terminate
u.destroyDiscord();
Utils::DestroyDiscord();
}

#pragma endregion
Expand Down
4 changes: 2 additions & 2 deletions Chikara/Midi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,8 @@ void Midi::LoaderThread()
double seconds = -1;
uint64_t time = 0;
bool all_ended = false;
bool* tracks_ended = new bool[track_count];
while (true) {
bool* tracks_ended = new bool[track_count];
memset(tracks_ended, 0, track_count);
while (seconds < renderer_time.load() + 10.0f)
{
Expand Down Expand Up @@ -333,10 +333,10 @@ void Midi::LoaderThread()
if (all_ended)
break;
}
delete[] tracks_ended;
if (all_ended)
break;
}
delete[] tracks_ended;
misc_events.enqueue({ static_cast<float>(seconds), PLAYBACK_TERMINATE_EVENT });
printf("\nloader thread exiting\n");
}
Expand Down
84 changes: 59 additions & 25 deletions Chikara/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1487,27 +1487,6 @@ void Renderer::drawFrame(float time)
//vkWaitForFences(device, 1, &in_flight_fences[current_frame], VK_TRUE, UINT64_MAX);
//vkResetFences(device, 1, &in_flight_fences[current_frame]);

uint32_t img_index;
VkResult result = vkAcquireNextImageKHR(device, swap_chain, UINT64_MAX, img_available_semaphore[current_frame], VK_NULL_HANDLE, &img_index);

if(result == VK_ERROR_OUT_OF_DATE_KHR)
{
m.recreateSwapChain();
return;
} else if(result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
throw std::runtime_error("VKERR: Failed to acquire swap chain image!");
}

//Check if a previous frame is using this image (i.e. there is its fence to wait on)
if(imgs_in_flight[img_index] != VK_NULL_HANDLE)
vkWaitForFences(device, 1, &imgs_in_flight[img_index], VK_TRUE, UINT64_MAX);

//Mark the image as now being in use by this frame
imgs_in_flight[img_index] = imgs_in_flight[current_frame];

//Update the Uniform Buffer
updateUniformBuffer(img_index, time);

size_t key_indices[256] = {};
size_t cur_offset = 0;
// yep, this iterates over the keys twice...
Expand Down Expand Up @@ -1590,10 +1569,35 @@ void Renderer::drawFrame(float time)
else {
last_notes_shown_count = notes_shown_size;
}

uint32_t img_index;
VkResult result = vkAcquireNextImageKHR(device, swap_chain, UINT64_MAX, img_available_semaphore[current_frame], VK_NULL_HANDLE, &img_index);

if (result == VK_ERROR_OUT_OF_DATE_KHR)
{
m.recreateSwapChain();
return;
}
else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
throw std::runtime_error("VKERR: Failed to acquire swap chain image!");
}

//Check if a previous frame is using this image (i.e. there is its fence to wait on)
if (imgs_in_flight[img_index] != VK_NULL_HANDLE)
vkWaitForFences(device, 1, &imgs_in_flight[img_index], VK_TRUE, UINT64_MAX);

//Mark the image as now being in use by this frame
imgs_in_flight[img_index] = imgs_in_flight[current_frame];

//Update the Uniform Buffer
updateUniformBuffer(img_index, time);

vkWaitForFences(device, 1, &in_flight_fences[current_frame], VK_TRUE, UINT64_MAX);

VkCommandBuffer last_note_cmdbuf = nullptr; // used to submit a single note draw command buffer at the same time as the imgui one
size_t instances_left = notes_shown_size;
if (notes_shown_size == 0)
submitSingleCommandBuffer(cmd_buffers[img_index * MAX_NOTES_MULT]);
last_note_cmdbuf = cmd_buffers[img_index * MAX_NOTES_MULT];
for (size_t i = 0; i < notes_shown_size; i += MAX_NOTES) {
size_t instances_processed = min(instances_left, MAX_NOTES);
vkMapMemory(device, note_instance_buffer_mem, 0, sizeof(InstanceData) * instances_processed, 0, &data);
Expand All @@ -1611,12 +1615,17 @@ void Renderer::drawFrame(float time)
}
}

submitSingleCommandBuffer(cmd_buffers[(i == 0 ? 0 : swap_chain_framebuffers.size() * MAX_NOTES_MULT) + note_cmd_buf + img_index * MAX_NOTES_MULT]);
instances_left -= instances_processed;
last_instances_processed = instances_processed;
auto cmd_buf = cmd_buffers[(i == 0 ? 0 : swap_chain_framebuffers.size() * MAX_NOTES_MULT) + note_cmd_buf + img_index * MAX_NOTES_MULT];
if (instances_left == 0)
last_note_cmdbuf = cmd_buf;
else
submitSingleCommandBuffer(cmd_buf);
}

// render imgui command buffers
// TODO: this can be done at the same time as the above block, but how can that be done efficiently?
ImGui_ImplVulkan_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
Expand Down Expand Up @@ -1650,13 +1659,38 @@ void Renderer::drawFrame(float time)
}
}

submitSingleCommandBuffer(imgui_cmd_buffers[img_index]);
//Submit to the command buffer
VkSubmitInfo submit_info = {};
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;

std::array<VkCommandBuffer, 2> command_buffers = { last_note_cmdbuf, imgui_cmd_buffers[img_index] };

VkSemaphore wait_semaphores[] = { img_available_semaphore[current_frame] }; //The semaphores we are waiting for
VkPipelineStageFlags wait_stages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; //Wait with writing colors until the image is available
submit_info.waitSemaphoreCount = 1;
submit_info.pWaitSemaphores = wait_semaphores;
submit_info.pWaitDstStageMask = wait_stages;
submit_info.commandBufferCount = static_cast<uint32_t>(command_buffers.size());
submit_info.pCommandBuffers = command_buffers.data();

submit_info.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores = &render_fin_semaphore[current_frame];

//vkWaitForFences(device, 1, &in_flight_fences[current_frame], VK_TRUE, UINT64_MAX);
vkResetFences(device, 1, &in_flight_fences[current_frame]);

auto submit_res = vkQueueSubmit(graphics_queue, 1, &submit_info, in_flight_fences[current_frame]);
if (submit_res != VK_SUCCESS)
{
printf("%d\n", submit_res);
throw std::runtime_error("VKERR: Failed to submit draw to command buffer!");
}

//Presentation
VkPresentInfoKHR present_info = {};
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
present_info.waitSemaphoreCount = 1;
present_info.pWaitSemaphores = &img_available_semaphore[current_frame];
present_info.pWaitSemaphores = &render_fin_semaphore[current_frame];

VkSwapchainKHR swap_chains[] = { swap_chain }; //An array of all our swap chains
present_info.swapchainCount = 1;
Expand Down
11 changes: 8 additions & 3 deletions Chikara/Utils.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "Utils.h"

std::string Utils::GetFileName(std::filesystem::path file_path)
std::wstring Utils::GetFileName(std::filesystem::path file_path)
{
return std::filesystem::path(file_path).filename().string();
return std::filesystem::path(file_path).filename().wstring();
}

static void handleDiscordReady(const DiscordUser* connectedUser)
Expand Down Expand Up @@ -48,7 +48,12 @@ void Utils::UpdatePresence(const char* state, const char* details, std::string f
Discord_UpdatePresence(&discordPresence);
}

void Utils::destroyDiscord()
void Utils::DestroyDiscord()
{
Discord_Shutdown();
}

std::string Utils::wstringToUtf8(std::wstring str) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
return conv.to_bytes(str);
}
8 changes: 5 additions & 3 deletions Chikara/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

#include <iostream>
#include <filesystem>
#include <codecvt>
#include <discord_rpc.h>

class Utils
{
public:
std::string GetFileName(std::filesystem::path file_path);
void InitDiscord();
static std::wstring GetFileName(std::filesystem::path file_path);
static void InitDiscord();
static void UpdatePresence(const char* state, const char* details, std::string file_name, uint64_t start_time, uint64_t end_time);
void destroyDiscord();
static void DestroyDiscord();
static std::string wstringToUtf8(std::wstring str);
};

0 comments on commit 3883043

Please sign in to comment.