-
Notifications
You must be signed in to change notification settings - Fork 0
Error check #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Error check #32
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
c073dc4
feat: include std:excepted
WSQS 755acba
fix:finish compile
WSQS 701a26a
fix:change init check logic
WSQS 216056b
refactor: refactor whole code
WSQS d901457
doc: change comment
WSQS 085c4d9
fix:add check for sdl init video
WSQS 13172f9
fix:early return for pipeline submit
WSQS 4e0dd99
style: format code with ClangFormat
deepsource-autofix[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,82 +1,137 @@ | ||
| // | ||
| // sdl_wrapper.buffer.cpp | ||
| // Created by sophomore on 11/12/25. | ||
| // | ||
| module; | ||
| #include <cstdint> | ||
| #include <expected> | ||
| #include <memory> | ||
| #include <variant> | ||
|
|
||
| #include "SDL3/SDL_gpu.h" | ||
| #include "SDL3/SDL_log.h" | ||
| #include "SDL3/SDL_stdinc.h" | ||
| module sdl_wrapper; | ||
| import :buffer; | ||
| import :gpu; | ||
|
|
||
| namespace sopho | ||
| { | ||
| /** | ||
| * @brief Releases GPU resources owned by this BufferWrapper. | ||
| * | ||
| * Releases the GPU vertex buffer and, if present, the transfer (staging) buffer, | ||
| * then clears the corresponding handles and resets the transfer buffer size. | ||
| * | ||
| * @note If the associated GPU has already been destroyed, releasing these resources | ||
| * may have no effect or may be too late to perform a proper cleanup. | ||
| */ | ||
|
|
||
| BufferWrapper::~BufferWrapper() | ||
| BufferWrapper::~BufferWrapper() noexcept | ||
| { | ||
| SDL_ReleaseGPUBuffer(m_gpu->data(), m_vertex_buffer); | ||
| m_vertex_buffer = nullptr; | ||
| if (!m_gpu) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| // Release vertex buffer | ||
| if (m_vertex_buffer) | ||
| { | ||
| m_gpu->release_buffer(m_vertex_buffer); | ||
| m_vertex_buffer = nullptr; | ||
| } | ||
|
|
||
| // Release transfer buffer | ||
| if (m_transfer_buffer) | ||
| { | ||
| SDL_ReleaseGPUTransferBuffer(m_gpu->data(), m_transfer_buffer); | ||
| SDL_ReleaseGPUTransferBuffer(m_gpu->device(), m_transfer_buffer); | ||
| m_transfer_buffer = nullptr; | ||
| m_transfer_buffer_size = 0; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * @brief Uploads a block of data into the wrapped GPU vertex buffer at the specified byte offset. | ||
| * | ||
| * Reallocates the internal staging (transfer) buffer if its capacity is less than the requested size, | ||
| * copies p_size bytes from p_data into the staging buffer, and enqueues a GPU copy pass that writes the data | ||
| * into the vertex buffer at p_offset. The GPU command buffer is submitted immediately. | ||
| * | ||
| * @param p_data Pointer to the source data to upload. | ||
| * @param p_size Size in bytes of the data to upload. | ||
| * @param p_offset Byte offset within the vertex buffer where the data will be written. | ||
| */ | ||
| void BufferWrapper::upload(void* p_data, uint32_t p_size, uint32_t p_offset) | ||
| [[nodiscard]] std::expected<std::monostate, GpuError> | ||
| BufferWrapper::upload(const void* src_data, std::uint32_t size, std::uint32_t offset) | ||
| { | ||
| if (p_size > m_transfer_buffer_size) | ||
| // Bounds check to avoid writing past the end of the GPU buffer. | ||
| if (offset + size > m_vertex_buffer_size) | ||
| { | ||
| SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d buffer overflow: size=%u, offset=%u, buffer_size=%u", __FILE__, | ||
| __LINE__, size, offset, m_vertex_buffer_size); | ||
|
|
||
| return std::unexpected(GpuError::BUFFER_OVERFLOW); | ||
| } | ||
|
|
||
| auto* device = m_gpu->device(); | ||
|
|
||
| // 1. Ensure the transfer buffer capacity is sufficient. | ||
| if (size > m_transfer_buffer_size) | ||
| { | ||
| if (m_transfer_buffer != nullptr) | ||
| { | ||
| SDL_ReleaseGPUTransferBuffer(m_gpu->data(), m_transfer_buffer); | ||
| SDL_ReleaseGPUTransferBuffer(device, m_transfer_buffer); | ||
| m_transfer_buffer = nullptr; | ||
| m_transfer_buffer_size = 0; | ||
| } | ||
|
|
||
| SDL_GPUTransferBufferCreateInfo transfer_info{}; | ||
| transfer_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD; | ||
| transfer_info.size = size; | ||
| transfer_info.props = 0; | ||
|
|
||
| m_transfer_buffer = SDL_CreateGPUTransferBuffer(device, &transfer_info); | ||
| if (!m_transfer_buffer) | ||
| { | ||
| SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d failed to create transfer buffer: %s", __FILE__, __LINE__, | ||
| SDL_GetError()); | ||
|
|
||
| return std::unexpected(GpuError::CREATE_TRANSFER_BUFFER_FAILED); | ||
| } | ||
| SDL_GPUTransferBufferCreateInfo transfer_info{SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD, p_size, 0}; | ||
| m_transfer_buffer = SDL_CreateGPUTransferBuffer(m_gpu->data(), &transfer_info); | ||
|
|
||
| m_transfer_buffer_size = transfer_info.size; | ||
| } | ||
|
|
||
| auto data = SDL_MapGPUTransferBuffer(m_gpu->data(), m_transfer_buffer, false); | ||
| SDL_memcpy(data, p_data, p_size); | ||
| SDL_UnmapGPUTransferBuffer(m_gpu->data(), m_transfer_buffer); | ||
| // 2. Map the transfer buffer and copy data into it. | ||
| void* dst = SDL_MapGPUTransferBuffer(device, m_transfer_buffer, false); | ||
| if (!dst) | ||
| { | ||
| SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d failed to map transfer buffer: %s", __FILE__, __LINE__, | ||
| SDL_GetError()); | ||
|
|
||
| return std::unexpected(GpuError::MAP_TRANSFER_BUFFER_FAILED); | ||
| } | ||
|
|
||
| // TODO: Delay submit command in collect | ||
| auto command_buffer = SDL_AcquireGPUCommandBuffer(m_gpu->data()); | ||
| auto copy_pass = SDL_BeginGPUCopyPass(command_buffer); | ||
| SDL_memcpy(dst, src_data, size); | ||
| SDL_UnmapGPUTransferBuffer(device, m_transfer_buffer); | ||
|
|
||
| // 3. Acquire a command buffer and enqueue the copy pass. | ||
| auto* command_buffer = SDL_AcquireGPUCommandBuffer(device); | ||
| if (!command_buffer) | ||
| { | ||
| SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d failed to acquire GPU command buffer: %s", __FILE__, __LINE__, | ||
| SDL_GetError()); | ||
|
|
||
| return std::unexpected(GpuError::ACQUIRE_COMMAND_BUFFER_FAILED); | ||
| } | ||
|
|
||
| auto* copy_pass = SDL_BeginGPUCopyPass(command_buffer); | ||
|
|
||
| if (!copy_pass) | ||
| { | ||
| SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d failed to begin GPU copy pass: %s", __FILE__, __LINE__, | ||
| SDL_GetError()); | ||
| SDL_SubmitGPUCommandBuffer(command_buffer); | ||
| return std::unexpected(GpuError::BEGIN_COPY_PASS_FAILED); | ||
| } | ||
|
|
||
| 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; | ||
| region.size = size; | ||
| region.offset = offset; | ||
|
|
||
| SDL_UploadToGPUBuffer(copy_pass, &location, ®ion, false); | ||
|
|
||
| SDL_EndGPUCopyPass(copy_pass); | ||
| SDL_SubmitGPUCommandBuffer(command_buffer); | ||
| if (!SDL_SubmitGPUCommandBuffer(command_buffer)) | ||
| { | ||
| SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d %s", __FILE__, __LINE__, SDL_GetError()); | ||
| return std::unexpected(GpuError::SUBMIT_COMMAND_FAILED); | ||
| } | ||
|
|
||
| return std::monostate{}; | ||
| } | ||
|
|
||
| } // namespace sopho |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,32 +1,57 @@ | ||
| // | ||
| // sdl_wrapper.buffer.ixx | ||
| // Created by sophomore on 11/8/25. | ||
| // | ||
|
|
||
| module; | ||
|
|
||
| #include <expected> | ||
| #include <memory> | ||
| #include <variant> | ||
|
|
||
| #include "SDL3/SDL_gpu.h" | ||
|
|
||
| export module sdl_wrapper:buffer; | ||
| import :decl; | ||
|
|
||
| export namespace sopho | ||
| { | ||
| class BufferWrapper | ||
| { | ||
| std::shared_ptr<GpuWrapper> m_gpu{}; | ||
| SDL_GPUBuffer* m_vertex_buffer{}; | ||
| SDL_GPUTransferBuffer* m_transfer_buffer{}; | ||
| uint32_t m_transfer_buffer_size{}; | ||
| std::shared_ptr<GpuWrapper> m_gpu{}; // Owns the device lifetime | ||
| SDL_GPUBuffer* m_vertex_buffer{}; // Target GPU buffer | ||
| SDL_GPUTransferBuffer* m_transfer_buffer{}; // Staging/transfer buffer | ||
| std::uint32_t m_vertex_buffer_size{}; // Total size of the GPU buffer | ||
| std::uint32_t m_transfer_buffer_size{}; // Current capacity of the transfer buffer | ||
|
|
||
| BufferWrapper(std::shared_ptr<::sopho::GpuWrapper> p_gpu, SDL_GPUBuffer* p_buffer) : | ||
| m_gpu(p_gpu), m_vertex_buffer(p_buffer) | ||
| // Only GpuWrapper is allowed to construct this type. | ||
| BufferWrapper(std::shared_ptr<GpuWrapper> gpu, SDL_GPUBuffer* buffer, std::uint32_t size) noexcept : | ||
| m_gpu(std::move(gpu)), m_vertex_buffer(buffer), m_vertex_buffer_size(size) | ||
| { | ||
| } | ||
|
|
||
| public: | ||
| void upload(void* p_data, uint32_t p_size, uint32_t p_offset); | ||
| BufferWrapper(const BufferWrapper&) = delete; | ||
| BufferWrapper& operator=(const BufferWrapper&) = delete; | ||
| BufferWrapper(BufferWrapper&&) = default; | ||
| BufferWrapper& operator=(BufferWrapper&&) = default; | ||
|
|
||
| /// Upload a block of data into the GPU buffer at the given byte offset. | ||
| /// | ||
| /// This function may fail in several ways: | ||
| /// - The requested upload range exceeds the buffer size. | ||
| /// - The transfer buffer cannot be created or resized. | ||
| /// - Mapping the transfer buffer fails. | ||
| /// - Acquiring a GPU command buffer fails. | ||
| /// | ||
| /// All such failures are reported via the returned std::expected. | ||
| [[nodiscard]] std::expected<std::monostate, GpuError> upload(const void* data, std::uint32_t size, | ||
| std::uint32_t offset); | ||
|
|
||
| /// Returns the underlying SDL_GPUBuffer pointer. | ||
| [[nodiscard]] SDL_GPUBuffer* data() const noexcept { return m_vertex_buffer; } | ||
|
|
||
| auto data() { return m_vertex_buffer; } | ||
| ~BufferWrapper() noexcept; | ||
|
|
||
| ~BufferWrapper(); | ||
| friend GpuWrapper; | ||
| friend class GpuWrapper; | ||
| }; | ||
| } // namespace sopho |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,19 +1,30 @@ | ||
| // | ||
| // sdl_wrapper.gpu.cpp | ||
| // Created by wsqsy on 11/14/2025. | ||
| // | ||
| module; | ||
| #include <SDL3/SDL_gpu.h> | ||
| #include <expected> | ||
| #include "SDL3/SDL_gpu.h" | ||
| #include "SDL3/SDL_log.h" | ||
| module sdl_wrapper; | ||
| import :gpu; | ||
| import :pipeline; | ||
| namespace sopho | ||
| { | ||
| BufferWrapper GpuWrapper::create_buffer(SDL_GPUBufferUsageFlags flag, uint32_t size) | ||
| std::expected<BufferWrapper, GpuError> GpuWrapper::create_buffer(SDL_GPUBufferUsageFlags flag, uint32_t size) | ||
| { | ||
| SDL_GPUBufferCreateInfo create_info{flag, size}; | ||
| auto buffer = SDL_CreateGPUBuffer(m_device, &create_info); | ||
| BufferWrapper result(shared_from_this(), buffer); | ||
| return result; | ||
| SDL_GPUBufferCreateInfo create_info{.usage = flag, .size = size}; | ||
| auto buffer = SDL_CreateGPUBuffer(device(), &create_info); | ||
| if (!buffer) | ||
| { | ||
| SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d %s", __FILE__, __LINE__, SDL_GetError()); | ||
| return std::unexpected(GpuError::CREATE_BUFFER_FAILED); | ||
| } | ||
| return BufferWrapper{shared_from_this(), buffer, size}; | ||
| } | ||
| std::expected<PipelineWrapper, GpuError> GpuWrapper::create_pipeline_wrapper() | ||
| { | ||
| // Query texture format, then construct PipelineWrapper | ||
| return get_texture_format().transform([self = shared_from_this()](SDL_GPUTextureFormat format) | ||
| { return PipelineWrapper{self, format}; }); | ||
| } | ||
| PipelineWrapper GpuWrapper::create_pipeline() { return PipelineWrapper{shared_from_this()}; } | ||
| } // namespace sopho |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.