s3d_device.c (4356B)
1 /* Copyright (C) 2015-2023, 2026 |Méso|Star> (contact@meso-star.com) 2 * 3 * This file is part of Star-3D. 4 * 5 * Star-3D is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * Star-3D is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with Star-3D. If not, see <http://www.gnu.org/licenses/>. */ 17 18 #include "s3d.h" 19 #include "s3d_c.h" 20 21 #include "s3d_backend.h" 22 #include "s3d_device_c.h" 23 24 #include <rsys/logger.h> 25 #include <rsys/mem_allocator.h> 26 27 /******************************************************************************* 28 * Helper functions 29 ******************************************************************************/ 30 static INLINE void 31 rtc_error_func(void* context, enum RTCError err, const char* str) 32 { 33 (void)str, (void)context; 34 VFATAL("Embree:error: %s\n", ARG1(rtc_error_string(err))); 35 } 36 37 static INLINE void 38 log_msg 39 (struct s3d_device* dev, 40 const enum log_type stream, 41 const char* msg, 42 va_list vargs) 43 { 44 ASSERT(dev && msg); 45 if(dev->verbose) { 46 res_T res; (void)res; 47 res = logger_vprint(dev->logger, stream, msg, vargs); 48 ASSERT(res == RES_OK); 49 } 50 } 51 52 static void 53 device_release(ref_T* ref) 54 { 55 struct s3d_device* dev; 56 ASSERT(ref); 57 dev = CONTAINER_OF(ref, struct s3d_device, ref); 58 ASSERT(flist_name_is_empty(&dev->names) == 1); 59 flist_name_release(&dev->names); 60 rtcReleaseDevice(dev->rtc); 61 MEM_RM(dev->allocator, dev); 62 } 63 64 /******************************************************************************* 65 * Exported s3d_device functions 66 ******************************************************************************/ 67 res_T 68 s3d_device_create 69 (struct logger* logger, 70 struct mem_allocator* mem_allocator, 71 const int verbose, 72 struct s3d_device** out_dev) 73 { 74 char embree_opts[512]; 75 struct s3d_device* dev = NULL; 76 struct mem_allocator* allocator; 77 const int verbosity = MMAX(MMIN(verbose, 3), 0); 78 int sz; 79 res_T res = RES_OK; 80 81 if(!out_dev) { 82 res = RES_BAD_ARG; 83 goto error; 84 } 85 86 allocator = mem_allocator ? mem_allocator : &mem_default_allocator; 87 dev = (struct s3d_device*)MEM_CALLOC(allocator, 1, sizeof(struct s3d_device)); 88 if(!dev) { 89 res = RES_MEM_ERR; 90 goto error; 91 } 92 dev->logger = logger ? logger : LOGGER_DEFAULT; 93 dev->allocator = allocator; 94 dev->verbose = verbose; 95 flist_name_init(allocator, &dev->names); 96 ref_init(&dev->ref); 97 98 sz = snprintf(embree_opts, sizeof(embree_opts), "verbose=%d", verbosity); 99 if((size_t)sz >= sizeof(embree_opts)) { 100 log_error(dev, "Could not setup the Embree option string.\n"); 101 res = RES_MEM_ERR; 102 goto error; 103 } 104 105 dev->rtc = rtcNewDevice(embree_opts); 106 if(dev->rtc == NULL) { 107 const enum RTCError err = rtcGetDeviceError(NULL); 108 log_error(dev, "Could not create the embree device -- %s.\n", 109 rtc_error_string(err)); 110 res = rtc_error_to_res_T(err); 111 goto error; 112 } 113 114 #ifndef NDEBUG 115 rtcSetDeviceErrorFunction(dev->rtc, rtc_error_func, dev); 116 #endif 117 118 exit: 119 if(out_dev) *out_dev = dev; 120 return res; 121 error: 122 if(dev) { 123 S3D(device_ref_put(dev)); 124 dev = NULL; 125 } 126 goto exit; 127 } 128 129 res_T 130 s3d_device_ref_get(struct s3d_device* dev) 131 { 132 if(!dev) return RES_BAD_ARG; 133 ref_get(&dev->ref); 134 return RES_OK; 135 } 136 137 res_T 138 s3d_device_ref_put(struct s3d_device* dev) 139 { 140 if(!dev) return RES_BAD_ARG; 141 ref_put(&dev->ref, device_release); 142 return RES_OK; 143 } 144 145 /******************************************************************************* 146 * Local functions 147 ******************************************************************************/ 148 void 149 log_error(struct s3d_device* dev, const char* msg, ...) 150 { 151 va_list vargs_list; 152 ASSERT(dev && msg); 153 154 va_start(vargs_list, msg); 155 log_msg(dev, LOG_ERROR, msg, vargs_list); 156 va_end(vargs_list); 157 } 158 159 void 160 log_warning(struct s3d_device* dev, const char* msg, ...) 161 { 162 va_list vargs_list; 163 ASSERT(dev && msg); 164 165 va_start(vargs_list, msg); 166 log_msg(dev, LOG_WARNING, msg, vargs_list); 167 va_end(vargs_list); 168 } 169