// cuda-helper-functions.h #pragma once #include "../../../source/core/slang-list.h" #include "cuda-base.h" #include "slang-gfx.h" namespace gfx { using namespace Slang; #ifdef GFX_ENABLE_CUDA namespace cuda { SLANG_FORCE_INLINE bool _isError(CUresult result) { return result != 0; } // A enum used to control if errors are reported on failure of CUDA call. enum class CUDAReportStyle { Normal, Silent, }; struct CUDAErrorInfo { CUDAErrorInfo( const char* filePath, int lineNo, const char* errorName = nullptr, const char* errorString = nullptr) : m_filePath(filePath), m_lineNo(lineNo), m_errorName(errorName), m_errorString(errorString) { } SlangResult handle() const; const char* m_filePath; int m_lineNo; const char* m_errorName; const char* m_errorString; }; // If this code path is enabled, CUDA errors will be reported directly to StdWriter::out stream. SlangResult _handleCUDAError(CUresult cuResult, const char* file, int line); #define SLANG_CUDA_HANDLE_ERROR(x) _handleCUDAError(x, __FILE__, __LINE__) #define SLANG_CUDA_RETURN_ON_FAIL(x) \ { \ auto _res = x; \ if (_isError(_res)) \ return SLANG_CUDA_HANDLE_ERROR(_res); \ } #define SLANG_CUDA_RETURN_WITH_REPORT_ON_FAIL(x, r) \ { \ auto _res = x; \ if (_isError(_res)) \ { \ return (r == CUDAReportStyle::Normal) ? SLANG_CUDA_HANDLE_ERROR(_res) : SLANG_FAIL; \ } \ } #define SLANG_CUDA_ASSERT_ON_FAIL(x) \ { \ auto _res = x; \ if (_isError(_res)) \ { \ SLANG_ASSERT(!"Failed CUDA call"); \ }; \ } #ifdef RENDER_TEST_OPTIX bool _isError(OptixResult result); #if 1 SlangResult _handleOptixError(OptixResult result, char const* file, int line); #define SLANG_OPTIX_HANDLE_ERROR(RESULT) _handleOptixError(RESULT, __FILE__, __LINE__) #else #define SLANG_OPTIX_HANDLE_ERROR(RESULT) SLANG_FAIL #endif #define SLANG_OPTIX_RETURN_ON_FAIL(EXPR) \ do \ { \ auto _res = EXPR; \ if (_isError(_res)) \ return SLANG_OPTIX_HANDLE_ERROR(_res); \ } while (0) void _optixLogCallback(unsigned int level, const char* tag, const char* message, void* userData); #endif AdapterLUID getAdapterLUID(int deviceIndex); // Version-aware cuCtxCreate wrapper that works with both CUDA 12 and CUDA 13 inline CUresult createCudaContext(CUcontext* pctx, unsigned int flags, CUdevice dev) { #if CUDA_VERSION >= 13000 // CUDA 13+ requires CUctxCreateParams CUctxCreateParams ctxCreateParams = {}; return cuCtxCreate(pctx, &ctxCreateParams, flags, dev); #else // CUDA 12 and earlier use the old signature return cuCtxCreate(pctx, flags, dev); #endif } } // namespace cuda #endif Result SLANG_MCALL getCUDAAdapters(List& outAdapters); Result SLANG_MCALL createCUDADevice(const IDevice::Desc* desc, IDevice** outDevice); } // namespace gfx