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