From 82ec49f89db84d340e21a8a61ff6ef6a2847b364 Mon Sep 17 00:00:00 2001 From: Harrand Date: Wed, 30 Oct 2024 18:23:42 +0000 Subject: [PATCH] [gpu.resource] slight api modifications involving errors --- include/tz/gpu/resource.hpp | 11 ++++++----- src/tz/gpu/rhi_vulkan.cpp | 24 +++++++++++++++++------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/include/tz/gpu/resource.hpp b/include/tz/gpu/resource.hpp index b2d589f86a..81b4cd0dfc 100644 --- a/include/tz/gpu/resource.hpp +++ b/include/tz/gpu/resource.hpp @@ -193,7 +193,7 @@ namespace tz::gpu * @brief Write some new data to a resource. The thread will block until the changes are resident GPU-side. * @param res Resource whose data should be changed. * @param new_data Region containing new memory for the provided resource. - * @pre new_data.size_bytes() < X, where X is the number of bytes comprising the image's underlying data. Otherwise, the behaviour is undefined. + * @return @ref tz::error_code::invalid_value If the write is too large. The size of the new data + offset must be less than or equal to the resource's size. * * If the region of new data is smaller than the total size of the resource's underlying data, then all bytes beyond the new data region will be unchanged and keep their previous state. * @@ -204,7 +204,8 @@ namespace tz::gpu * - If the image was created with @ref image_type::rgba, then each pixel should be 4 bytes - one for each component (0-255). * - If the image was created with @ref image_type::depth or @ref image_type::floats, then each pixel should be 4 bytes - a single signed 32-bit float. */ - void resource_write(resource_handle res, std::span new_data, std::size_t offset = 0); + tz::error_code resource_write(resource_handle res, std::span new_data, std::size_t offset = 0); + std::size_t resource_size(resource_handle res); /** * @ingroup tz_gpu_resource * @brief Retrieves the current data within a resource. @@ -220,21 +221,21 @@ namespace tz::gpu * * This is a helper function which will call @ref resource_write under-the-hood. */ - void index_buffer_write(resource_handle index_buffer, std::span indices); + tz::error_code index_buffer_write(resource_handle index_buffer, std::span indices); /** * @ingroup tz_gpu_resource * @brief Write draw-indirect-count + commands into a buffer resource. * * This is a helper function which will call @ref resource_write under-the-hood. */ - void draw_buffer_write(resource_handle draw_buffer, std::uint32_t count, std::span draws); + tz::error_code draw_buffer_write(resource_handle draw_buffer, std::uint32_t count, std::span draws); /** * @ingroup tz_gpu_resource * @brief Write draw-indirect-count + indexed commands into a buffer resource. * * This is a helper function which will call @ref resource_write under-the-hood. */ - void draw_buffer_indexed_write(resource_handle draw_buffer, std::uint32_t count, std::span draws); + tz::error_code draw_buffer_indexed_write(resource_handle draw_buffer, std::uint32_t count, std::span draws); } #endif // TOPAZ_GPU_RESOURCE_HPP \ No newline at end of file diff --git a/src/tz/gpu/rhi_vulkan.cpp b/src/tz/gpu/rhi_vulkan.cpp index fe9948aff0..ec997988e7 100644 --- a/src/tz/gpu/rhi_vulkan.cpp +++ b/src/tz/gpu/rhi_vulkan.cpp @@ -907,15 +907,25 @@ namespace tz::gpu return tz::error_code::success; } - void resource_write(resource_handle resh, std::span new_data, std::size_t offset) + tz::error_code resource_write(resource_handle resh, std::span new_data, std::size_t offset) { auto& res = resources[resh.peek()]; // update the resource data cpu-side. + if(offset + new_data.size_bytes() > res.data.size()) + { + RETERR(tz::error_code::invalid_value, "resource write at offset {} of size {} (total {}) is too large - the resource data is only of size {}", offset, new_data.size_bytes(), (offset + new_data.size_bytes()), res.data.size()); + } tz_assert(offset + new_data.size_bytes() <= res.data.size(), "resource write data span is of wrong size."); std::copy(new_data.begin(), new_data.end(), res.data.begin() + offset); // make sure the change is resident GPU-side. // definitely could cause gpu sync issues if commands are currently in-flight that are reading from it. impl_write_single_resource(resh); + return tz::error_code::success; + } + + std::size_t resource_size(resource_handle resh) + { + return resources[resh.peek()].data.size(); } std::span resource_read(resource_handle resh) @@ -938,27 +948,27 @@ namespace tz::gpu tz_error("image resize NYI"); } - void index_buffer_write(resource_handle index_buffer, std::span indices) + tz::error_code index_buffer_write(resource_handle index_buffer, std::span indices) { - resource_write(index_buffer, std::as_bytes(indices)); + return resource_write(index_buffer, std::as_bytes(indices)); } - void draw_buffer_write(resource_handle draw_buffer, std::uint32_t count, std::span draws) + tz::error_code draw_buffer_write(resource_handle draw_buffer, std::uint32_t count, std::span draws) { std::vector mem(sizeof(std::uint32_t) + draws.size_bytes()); auto cursor = mem.data(); *reinterpret_cast(cursor) = count; std::memcpy(cursor + sizeof(std::uint32_t), draws.data(), draws.size_bytes()); - resource_write(draw_buffer, mem); + return resource_write(draw_buffer, mem); } - void draw_buffer_indexed_write(resource_handle draw_buffer, std::uint32_t count, std::span draws) + tz::error_code draw_buffer_indexed_write(resource_handle draw_buffer, std::uint32_t count, std::span draws) { std::vector mem(sizeof(std::uint32_t) + draws.size_bytes()); auto cursor = mem.data(); *reinterpret_cast(cursor) = count; std::memcpy(cursor + sizeof(std::uint32_t), draws.data(), draws.size_bytes()); - resource_write(draw_buffer, mem); + return resource_write(draw_buffer, mem); } std::expected create_graphics_shader(std::string_view vertex_source, std::string_view fragment_source)