diff --git a/.coderabbit.yaml b/.coderabbit.yaml index ced5a00..3424534 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -37,7 +37,8 @@ reviews: ignore_title_keywords: [] labels: [] drafts: false - base_branches: [] + base_branches: + - ".*" ignore_usernames: [] finishing_touches: docstrings: diff --git a/main.cpp b/main.cpp index c1b3cad..144d96b 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,6 @@ #include "shaderc/shaderc.hpp" #include +#include #include "imgui.h" #include "imgui_impl_sdl3.h" @@ -49,13 +50,10 @@ void main() })WSQ"; class UserApp : public sopho::App { - - sopho::BufferWrapper BufferWrapper{}; + std::optional vertexBuffer; SDL_Window *window{}; SDL_GPUDevice *device{}; - SDL_GPUBuffer *vertexBuffer{}; - SDL_GPUTransferBuffer *transferBuffer{}; SDL_GPUGraphicsPipeline *graphicsPipeline{}; virtual SDL_AppResult init(int argc, char **argv) override { @@ -177,42 +175,9 @@ class UserApp : public sopho::App { SDL_GPUBufferCreateInfo bufferInfo{}; bufferInfo.size = sizeof(vertices); bufferInfo.usage = SDL_GPU_BUFFERUSAGE_VERTEX; - vertexBuffer = SDL_CreateGPUBuffer(device, &bufferInfo); - - // create a transfer buffer to upload to the vertex buffer - SDL_GPUTransferBufferCreateInfo transferInfo{}; - transferInfo.size = sizeof(vertices); - transferInfo.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD; - transferBuffer = SDL_CreateGPUTransferBuffer(device, &transferInfo); - - // fill the transfer buffer - Vertex *data = (Vertex *) SDL_MapGPUTransferBuffer(device, transferBuffer, false); - - SDL_memcpy(data, (void *) vertices, sizeof(vertices)); - - SDL_UnmapGPUTransferBuffer(device, transferBuffer); - - // start a copy pass - SDL_GPUCommandBuffer *commandBuffer = SDL_AcquireGPUCommandBuffer(device); - SDL_GPUCopyPass *copyPass = SDL_BeginGPUCopyPass(commandBuffer); - - // where is the data - SDL_GPUTransferBufferLocation location{}; - location.transfer_buffer = transferBuffer; - location.offset = 0; - - // where to upload the data - SDL_GPUBufferRegion region{}; - region.buffer = vertexBuffer; - region.size = sizeof(vertices); - region.offset = 0; + vertexBuffer.emplace(device, &bufferInfo); - // upload the data - SDL_UploadToGPUBuffer(copyPass, &location, ®ion, true); - - // end the copy pass - SDL_EndGPUCopyPass(copyPass); - SDL_SubmitGPUCommandBuffer(commandBuffer); + vertexBuffer->upload(vertices, sizeof(vertices), 0); // Setup Dear ImGui context IMGUI_CHECKVERSION(); @@ -262,34 +227,8 @@ class UserApp : public sopho::App { vertices[0].y = node[1]; vertices[0].z = node[2]; - // fill the transfer buffer - Vertex *data = (Vertex *) SDL_MapGPUTransferBuffer(device, transferBuffer, false); - - SDL_memcpy(data, (void *) vertices, sizeof(vertices)); - - SDL_UnmapGPUTransferBuffer(device, transferBuffer); - - // start a copy pass - SDL_GPUCommandBuffer *commandBuffer = SDL_AcquireGPUCommandBuffer(device); - SDL_GPUCopyPass *copyPass = SDL_BeginGPUCopyPass(commandBuffer); + vertexBuffer->upload(vertices, sizeof(vertices), 0); - // where is the data - SDL_GPUTransferBufferLocation location{}; - location.transfer_buffer = transferBuffer; - location.offset = 0; - - // where to upload the data - SDL_GPUBufferRegion region{}; - region.buffer = vertexBuffer; - region.size = sizeof(vertices); - region.offset = 0; - - // upload the data - SDL_UploadToGPUBuffer(copyPass, &location, ®ion, true); - - // end the copy pass - SDL_EndGPUCopyPass(copyPass); - SDL_SubmitGPUCommandBuffer(commandBuffer); ImGui::End(); } @@ -329,7 +268,7 @@ class UserApp : public sopho::App { // bind the vertex buffer SDL_GPUBufferBinding bufferBindings[1]; - bufferBindings[0].buffer = vertexBuffer; // index 0 is slot 0 in this example + bufferBindings[0].buffer = vertexBuffer->data(); // index 0 is slot 0 in this example bufferBindings[0].offset = 0; // start from the first byte SDL_BindGPUVertexBuffers(renderPass, 0, bufferBindings, 1); // bind one buffer starting from slot 0 @@ -361,8 +300,7 @@ class UserApp : public sopho::App { ImGui_ImplSDLGPU3_Shutdown(); ImGui::DestroyContext(); // release buffers - SDL_ReleaseGPUBuffer(device, vertexBuffer); - SDL_ReleaseGPUTransferBuffer(device, transferBuffer); + vertexBuffer = std::nullopt; // release the pipeline SDL_ReleaseGPUGraphicsPipeline(device, graphicsPipeline); diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index 690d78c..796b21f 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -7,11 +7,11 @@ add_library(sdl_wrapper STATIC) target_sources(sdl_wrapper PUBLIC FILE_SET cxx_modules TYPE CXX_MODULES FILES - ${CMAKE_CURRENT_SOURCE_DIR}/sdl_wrapper.ixx - ${CMAKE_CURRENT_SOURCE_DIR}/sdl_wrapper.buffer.ixx - ${CMAKE_CURRENT_SOURCE_DIR}/sdl_wrapper.app.ixx + sdl_wrapper.ixx + sdl_wrapper.buffer.ixx + sdl_wrapper.app.ixx PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/sdl_callback_implement.cpp + sdl_callback_implement.cpp ) target_link_libraries(sdl_wrapper PUBLIC SDL3::SDL3) diff --git a/sdl_wrapper/sdl_callback_implement.cpp b/sdl_wrapper/sdl_callback_implement.cpp index 1c5a460..dedd3f8 100644 --- a/sdl_wrapper/sdl_callback_implement.cpp +++ b/sdl_wrapper/sdl_callback_implement.cpp @@ -11,21 +11,24 @@ extern sopho::App *create_app(); SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) { auto app = create_app(); + if (!app) + return SDL_APP_FAILURE; *appstate = app; return app->init(argc, argv); } SDL_AppResult SDL_AppIterate(void *appstate) { - auto *app = static_cast(appstate); + auto app = static_cast(appstate); return app->iterate(); } SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { - auto *app = static_cast(appstate); + auto app = static_cast(appstate); return app->event(event); } void SDL_AppQuit(void *appstate, SDL_AppResult result) { - auto *app = static_cast(appstate); + auto app = static_cast(appstate); app->quit(result); + delete app; } diff --git a/sdl_wrapper/sdl_wrapper.buffer.ixx b/sdl_wrapper/sdl_wrapper.buffer.ixx index b046374..845436f 100644 --- a/sdl_wrapper/sdl_wrapper.buffer.ixx +++ b/sdl_wrapper/sdl_wrapper.buffer.ixx @@ -7,6 +7,64 @@ export module sdl_wrapper:buffer; namespace sopho { export class BufferWrapper { - SDL_GPUBuffer *vertexBuffer{}; + SDL_GPUDevice *m_gpu{}; + SDL_GPUBuffer *m_vertex_buffer{}; + SDL_GPUTransferBuffer *m_transfer_buffer{}; + uint32_t m_transfer_buffer_size{}; + + public: + BufferWrapper() = default; + + BufferWrapper(SDL_GPUDevice *p_gpu, const SDL_GPUBufferCreateInfo *p_create_info) + : m_gpu(p_gpu), m_vertex_buffer(SDL_CreateGPUBuffer(p_gpu, p_create_info)) { + } + + void upload(void *p_data, uint32_t p_size, uint32_t p_offset) { + if (p_size > m_transfer_buffer_size) { + if (m_transfer_buffer != nullptr) { + SDL_ReleaseGPUTransferBuffer(m_gpu, m_transfer_buffer); + } + SDL_GPUTransferBufferCreateInfo transfer_info{SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD, p_size, 0}; + m_transfer_buffer = SDL_CreateGPUTransferBuffer(m_gpu, &transfer_info); + m_transfer_buffer_size = transfer_info.size; + } + + auto data = SDL_MapGPUTransferBuffer(m_gpu, m_transfer_buffer, false); + SDL_memcpy(data, p_data, p_size); + SDL_UnmapGPUTransferBuffer(m_gpu, m_transfer_buffer); + + // TODO: Delay submit command in collect + auto command_buffer = SDL_AcquireGPUCommandBuffer(m_gpu); + auto copy_pass = SDL_BeginGPUCopyPass(command_buffer); + + SDL_GPUTransferBufferLocation location{}; + location.transfer_buffer = m_transfer_buffer; + location.offset = 0; + + SDL_GPUBufferRegion region{}; + region.buffer = m_vertex_buffer; + region.size = p_size; + region.offset = p_offset; + + SDL_UploadToGPUBuffer(copy_pass, &location, ®ion, false); + + SDL_EndGPUCopyPass(copy_pass); + SDL_SubmitGPUCommandBuffer(command_buffer); + } + + auto data() { + return m_vertex_buffer; + } + + ~BufferWrapper() { + // TODO: It's too late to release gpu buffer, gpu was released + SDL_ReleaseGPUBuffer(m_gpu, m_vertex_buffer); + m_vertex_buffer = nullptr; + if (m_transfer_buffer) { + SDL_ReleaseGPUTransferBuffer(m_gpu, m_transfer_buffer); + m_transfer_buffer = nullptr; + m_transfer_buffer_size = 0; + } + } }; }