diff --git a/graphics/openshadinglanguage/files/patch-src_testrender_rapidobj_rapidobj.hpp b/graphics/openshadinglanguage/files/patch-src_testrender_rapidobj_rapidobj.hpp new file mode 100644 index 000000000000..1aaf04ef7a09 --- /dev/null +++ b/graphics/openshadinglanguage/files/patch-src_testrender_rapidobj_rapidobj.hpp @@ -0,0 +1,127 @@ +--- src/testrender/rapidobj/rapidobj.hpp.orig 2025-12-28 12:45:06 UTC ++++ src/testrender/rapidobj/rapidobj.hpp +@@ -61,6 +61,12 @@ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH + #include + #include + ++#elif __FreeBSD__ ++ ++#include ++#include ++#include ++ + #endif + + #define RAPIDOBJ_VERSION_MAJOR 1 +@@ -5200,6 +5206,111 @@ struct FileReader : Reader { + private: + int m_fd = -1; + off_t m_offset{}; ++ size_t m_size{}; ++ char* m_buffer{}; ++}; ++ ++#elif __FreeBSD__ ++ ++inline auto AlignedAllocate(size_t size, size_t alignment) ++{ ++ return static_cast(aligned_alloc(alignment, size)); ++} ++ ++struct AlignedDeleter final { ++ void operator()(void* ptr) const { free(ptr); } ++}; ++ ++class File final { ++ public: ++ File(const std::filesystem::path& filepath) ++ { ++ auto filepath_string = filepath.string(); ++ ++ if (-1 == stat(filepath_string.c_str(), &m_info)) { ++ m_error = std::error_code(errno, std::system_category()); ++ return; ++ } ++ ++ m_fd = open(filepath_string.c_str(), O_RDONLY); ++ ++ if (-1 == m_fd) { ++ m_error = std::error_code(errno, std::system_category()); ++ } ++ } ++ File(const File&) = delete; ++ File& operator=(const File&) = delete; ++ File(File&&) = delete; ++ File& operator=(File&&) = delete; ++ ~File() noexcept ++ { ++ if (m_fd != -1) { ++ close(m_fd); ++ } ++ } ++ ++ explicit operator bool() const noexcept { return m_fd != -1; } ++ auto handle() const noexcept { return m_fd; } ++ auto size() const noexcept { return static_cast(m_info.st_size); } ++ auto error() const noexcept { return m_error; } ++ ++ private: ++ int m_fd = -1; ++ struct stat m_info {}; ++ std::error_code m_error{}; ++}; ++ ++struct FileReader : Reader { ++ FileReader(const File& file) noexcept : m_fd{ file.handle() } {} ++ ++ std::error_code ReadBlock(size_t offset, size_t size, char* buffer) override ++ { ++ assert(buffer); ++ assert(m_fd != -1); ++ assert(std::uintptr_t(buffer) % 4096 == 0); ++ ++ ++m_num_requests; ++ ++ auto t1 = std::chrono::steady_clock::now(); ++ ++ m_offset = offset; ++ m_size = size; ++ m_buffer = buffer; ++ ++ posix_fadvise(m_fd, offset, size, POSIX_FADV_WILLNEED); ++ ++ auto t2 = std::chrono::steady_clock::now(); ++ ++ m_submit_time += t2 - t1; ++ ++ return {}; ++ } ++ ++ ReadResult WaitForResult() override ++ { ++ auto t1 = std::chrono::steady_clock::now(); ++ ++ auto result = pread(m_fd, m_buffer, m_size, m_offset); ++ ++ auto t2 = std::chrono::steady_clock::now(); ++ ++ m_wait_time += t2 - t1; ++ ++ if (result < 0) { ++ auto error = std::error_code(errno, std::system_category()); ++ return ReadResult{ 0, error }; ++ } ++ ++ auto bytes_read = static_cast(result); ++ ++ m_bytes_read += bytes_read; ++ ++ return ReadResult{ bytes_read, std::error_code() }; ++ } ++ ++ private: ++ int m_fd = -1; ++ size_t m_offset{}; + size_t m_size{}; + char* m_buffer{}; + };