diff --git a/source/nvidia/cuda/nvidia-cuda-context.cpp b/source/nvidia/cuda/nvidia-cuda-context.cpp index e738c93c..2cb250c3 100644 --- a/source/nvidia/cuda/nvidia-cuda-context.cpp +++ b/source/nvidia/cuda/nvidia-cuda-context.cpp @@ -31,13 +31,7 @@ #endif #endif -nvidia::cuda::context::context(std::shared_ptr<::nvidia::cuda::cuda> cuda) - : _cuda(cuda), _ctx(), _has_device(false), _device() -{ - if (!cuda) - throw std::invalid_argument("cuda"); -} - +nvidia::cuda::context::context() : _cuda(::nvidia::cuda::cuda::get()), _ctx(), _has_device(false), _device() {} nvidia::cuda::context::~context() { if (_has_device) { @@ -47,7 +41,7 @@ nvidia::cuda::context::~context() } #ifdef WIN32 -nvidia::cuda::context::context(std::shared_ptr<::nvidia::cuda::cuda> cuda, ID3D11Device* device) : context(cuda) +nvidia::cuda::context::context(ID3D11Device* device) : context() { using namespace nvidia::cuda; diff --git a/source/nvidia/cuda/nvidia-cuda-context.hpp b/source/nvidia/cuda/nvidia-cuda-context.hpp index 1ae042df..de9b42db 100644 --- a/source/nvidia/cuda/nvidia-cuda-context.hpp +++ b/source/nvidia/cuda/nvidia-cuda-context.hpp @@ -31,13 +31,13 @@ namespace nvidia::cuda { ::nvidia::cuda::device_t _device; private: - context(std::shared_ptr<::nvidia::cuda::cuda> cuda); + context(); public: ~context(); #ifdef WIN32 - context(std::shared_ptr<::nvidia::cuda::cuda> cuda, ID3D11Device* device); + context(ID3D11Device* device); #endif ::nvidia::cuda::context_t get(); diff --git a/source/nvidia/cuda/nvidia-cuda-gs-texture.cpp b/source/nvidia/cuda/nvidia-cuda-gs-texture.cpp index a9aa0f74..19e51c22 100644 --- a/source/nvidia/cuda/nvidia-cuda-gs-texture.cpp +++ b/source/nvidia/cuda/nvidia-cuda-gs-texture.cpp @@ -20,13 +20,11 @@ #include "nvidia-cuda-gs-texture.hpp" #include "obs/gs/gs-helper.hpp" -nvidia::cuda::gstexture::gstexture(std::shared_ptr cuda, std::shared_ptr texture) - : _cuda(cuda), _texture(texture), _resource(), _is_mapped(false), _pointer() +nvidia::cuda::gstexture::gstexture(std::shared_ptr texture) + : _cuda(::nvidia::cuda::cuda::get()), _texture(texture), _resource(), _is_mapped(false), _pointer() { if (!texture) throw std::invalid_argument("texture"); - if (!cuda) - throw std::invalid_argument("cuda"); gs::context gctx; int dev_type = gs_get_device_type(); diff --git a/source/nvidia/cuda/nvidia-cuda-gs-texture.hpp b/source/nvidia/cuda/nvidia-cuda-gs-texture.hpp index 26e8f90c..3e63bad1 100644 --- a/source/nvidia/cuda/nvidia-cuda-gs-texture.hpp +++ b/source/nvidia/cuda/nvidia-cuda-gs-texture.hpp @@ -35,7 +35,7 @@ namespace nvidia::cuda { std::shared_ptr _stream; public: - gstexture(std::shared_ptr cuda, std::shared_ptr texture); + gstexture(std::shared_ptr texture); ~gstexture(); array_t map(std::shared_ptr stream); diff --git a/source/nvidia/cuda/nvidia-cuda-memory.cpp b/source/nvidia/cuda/nvidia-cuda-memory.cpp index 76036e6a..dfe9f344 100644 --- a/source/nvidia/cuda/nvidia-cuda-memory.cpp +++ b/source/nvidia/cuda/nvidia-cuda-memory.cpp @@ -20,10 +20,9 @@ #include "nvidia-cuda-memory.hpp" #include -nvidia::cuda::memory::memory(std::shared_ptr<::nvidia::cuda::cuda> cuda, std::size_t size) - : _cuda(cuda), _pointer(), _size(size) +nvidia::cuda::memory::memory(size_t size) : _cuda(::nvidia::cuda::cuda::get()), _pointer(), _size(size) { - ::nvidia::cuda::result res = _cuda->cuMemAlloc(&_pointer, size); + ::nvidia::cuda::result res = _cuda->cuMemAlloc(&_pointer, _size); switch (res) { case ::nvidia::cuda::result::SUCCESS: break; @@ -36,7 +35,6 @@ nvidia::cuda::memory::~memory() { _cuda->cuMemFree(_pointer); } - nvidia::cuda::device_ptr_t nvidia::cuda::memory::get() { return _pointer; diff --git a/source/nvidia/cuda/nvidia-cuda-memory.hpp b/source/nvidia/cuda/nvidia-cuda-memory.hpp index 315aefba..ee40ee4f 100644 --- a/source/nvidia/cuda/nvidia-cuda-memory.hpp +++ b/source/nvidia/cuda/nvidia-cuda-memory.hpp @@ -26,10 +26,10 @@ namespace nvidia::cuda { class memory { std::shared_ptr<::nvidia::cuda::cuda> _cuda; device_ptr_t _pointer; - std::size_t _size; + size_t _size; public: - memory(std::shared_ptr<::nvidia::cuda::cuda> cuda, std::size_t size); + memory(size_t size); ~memory(); device_ptr_t get(); diff --git a/source/nvidia/cuda/nvidia-cuda-stream.cpp b/source/nvidia/cuda/nvidia-cuda-stream.cpp index 455758b0..b86f40c8 100644 --- a/source/nvidia/cuda/nvidia-cuda-stream.cpp +++ b/source/nvidia/cuda/nvidia-cuda-stream.cpp @@ -20,9 +20,7 @@ #include "nvidia-cuda-stream.hpp" #include -nvidia::cuda::stream::stream(std::shared_ptr<::nvidia::cuda::cuda> cuda, ::nvidia::cuda::stream_flags flags, - int32_t priority) - : _cuda(cuda) +nvidia::cuda::stream::stream(::nvidia::cuda::stream_flags flags, int32_t priority) : _cuda(::nvidia::cuda::cuda::get()) { nvidia::cuda::result res; if (priority == 0) { diff --git a/source/nvidia/cuda/nvidia-cuda-stream.hpp b/source/nvidia/cuda/nvidia-cuda-stream.hpp index a17bbd53..ecbb8599 100644 --- a/source/nvidia/cuda/nvidia-cuda-stream.hpp +++ b/source/nvidia/cuda/nvidia-cuda-stream.hpp @@ -27,9 +27,8 @@ namespace nvidia::cuda { ::nvidia::cuda::stream_t _stream; public: - stream(std::shared_ptr<::nvidia::cuda::cuda> cuda, - ::nvidia::cuda::stream_flags flags = ::nvidia::cuda::stream_flags::DEFAULT, int32_t priority = 0); ~stream(); + stream(::nvidia::cuda::stream_flags flags = ::nvidia::cuda::stream_flags::DEFAULT, int32_t priority = 0); ::nvidia::cuda::stream_t get(); }; diff --git a/source/nvidia/cuda/nvidia-cuda.cpp b/source/nvidia/cuda/nvidia-cuda.cpp index 80aa07ce..a0edd92f 100644 --- a/source/nvidia/cuda/nvidia-cuda.cpp +++ b/source/nvidia/cuda/nvidia-cuda.cpp @@ -18,8 +18,22 @@ */ #include "nvidia-cuda.hpp" -#include "common.hpp" #include +#include "util/util-logging.hpp" + +#ifdef _DEBUG +#define ST_PREFIX "<%s> " +#define D_LOG_ERROR(x, ...) P_LOG_ERROR(ST_PREFIX##x, __FUNCTION_SIG__, __VA_ARGS__) +#define D_LOG_WARNING(x, ...) P_LOG_WARN(ST_PREFIX##x, __FUNCTION_SIG__, __VA_ARGS__) +#define D_LOG_INFO(x, ...) P_LOG_INFO(ST_PREFIX##x, __FUNCTION_SIG__, __VA_ARGS__) +#define D_LOG_DEBUG(x, ...) P_LOG_DEBUG(ST_PREFIX##x, __FUNCTION_SIG__, __VA_ARGS__) +#else +#define ST_PREFIX " " +#define D_LOG_ERROR(...) P_LOG_ERROR(ST_PREFIX __VA_ARGS__) +#define D_LOG_WARNING(...) P_LOG_WARN(ST_PREFIX __VA_ARGS__) +#define D_LOG_INFO(...) P_LOG_INFO(ST_PREFIX __VA_ARGS__) +#define D_LOG_DEBUG(...) P_LOG_DEBUG(ST_PREFIX __VA_ARGS__) +#endif #if defined(_WIN32) || defined(_WIN64) #define CUDA_NAME "nvcuda.dll" @@ -29,28 +43,33 @@ #define CUDA_LOAD_SYMBOL(NAME) \ { \ - NAME = reinterpret_cast(os_dlsym(_library, #NAME)); \ + NAME = reinterpret_cast(_library->load_symbol(#NAME)); \ if (!NAME) \ throw std::runtime_error("Failed to load '" #NAME "' from '" CUDA_NAME "'."); \ } #define CUDA_LOAD_SYMBOL_V2(NAME) \ { \ - NAME = reinterpret_cast(os_dlsym(_library, #NAME "_v2")); \ + NAME = reinterpret_cast(_library->load_symbol(#NAME "_v2")); \ if (!NAME) \ throw std::runtime_error("Failed to load '" #NAME "' from '" CUDA_NAME "'."); \ } #define CUDA_LOAD_SYMBOL_EX(NAME, OVERRIDE) \ { \ - NAME = reinterpret_cast(os_dlsym(_library, #OVERRIDE)); \ + NAME = reinterpret_cast(_library->load_symbol(#OVERRIDE)); \ if (!NAME) \ throw std::runtime_error("Failed to load '" #NAME "' from '" CUDA_NAME "'."); \ } -nvidia::cuda::cuda::cuda() +nvidia::cuda::cuda::~cuda() { - _library = os_dlopen(CUDA_NAME); - if (!_library) - throw std::runtime_error("Failed to load '" CUDA_NAME "'."); + D_LOG_DEBUG("Finalizing... (Addr: 0x%" PRIuPTR ")", this); +} + +nvidia::cuda::cuda::cuda() : _library() +{ + D_LOG_DEBUG("Initialization... (Addr: 0x%" PRIuPTR ")", this); + + _library = util::library::load(std::string_view(CUDA_NAME)); // Initialization CUDA_LOAD_SYMBOL(cuInit); @@ -117,19 +136,16 @@ nvidia::cuda::cuda::cuda() cuInit(0); } -nvidia::cuda::cuda::~cuda() -{ - os_dlclose(_library); -} - std::shared_ptr nvidia::cuda::cuda::get() { - static std::shared_ptr instance; - static std::mutex lock; + static std::weak_ptr instance; + static std::mutex lock; std::unique_lock ul(lock); - if (!instance) { - instance = std::make_shared(); + if (instance.expired()) { + auto hard_instance = std::make_shared(); + instance = hard_instance; + return hard_instance; } - return instance; + return instance.lock(); } diff --git a/source/nvidia/cuda/nvidia-cuda.hpp b/source/nvidia/cuda/nvidia-cuda.hpp index 45e9eb73..90b9da31 100644 --- a/source/nvidia/cuda/nvidia-cuda.hpp +++ b/source/nvidia/cuda/nvidia-cuda.hpp @@ -18,10 +18,9 @@ */ #pragma once -#include "common.hpp" #include -#include -#include +#include "util/util-bitmask.hpp" +#include "util/util-library.hpp" #ifdef WIN32 #pragma warning(push) @@ -128,8 +127,7 @@ namespace nvidia::cuda { }; class cuda { - private: - void* _library; + std::shared_ptr _library; public: cuda(); @@ -395,7 +393,7 @@ namespace nvidia::cuda { ID3D11Resource* d3dresource, uint32_t flags); #endif public: - static std::shared_ptr get(); + static std::shared_ptr<::nvidia::cuda::cuda> get(); }; } // namespace nvidia::cuda