Clover Git
OpenCL 1.1 software implementation
|
00001 /* 00002 * Copyright (c) 2011, Denis Steckelmacher <steckdenis@yahoo.fr> 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * * Redistributions of source code must retain the above copyright 00008 * notice, this list of conditions and the following disclaimer. 00009 * * Redistributions in binary form must reproduce the above copyright 00010 * notice, this list of conditions and the following disclaimer in the 00011 * documentation and/or other materials provided with the distribution. 00012 * * Neither the name of the copyright holder nor the 00013 * names of its contributors may be used to endorse or promote products 00014 * derived from this software without specific prior written permission. 00015 * 00016 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00017 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00018 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00019 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY 00020 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00021 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00022 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00023 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00024 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00025 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 */ 00027 00033 #include "sampler.h" 00034 #include "context.h" 00035 #include "deviceinterface.h" 00036 #include "propertylist.h" 00037 00038 #include <cstring> 00039 #include <cstdlib> 00040 00041 using namespace Coal; 00042 00043 Sampler::Sampler(Context *ctx, 00044 cl_bool normalized_coords, 00045 cl_addressing_mode addressing_mode, 00046 cl_filter_mode filter_mode, 00047 cl_int *errcode_ret) 00048 : Object(Object::T_Sampler, ctx), p_bitfield(0) 00049 { 00050 if (normalized_coords) 00051 p_bitfield |= CLK_NORMALIZED_COORDS_TRUE; 00052 else 00053 p_bitfield |= CLK_NORMALIZED_COORDS_FALSE; 00054 00055 switch (addressing_mode) 00056 { 00057 case CL_ADDRESS_NONE: 00058 p_bitfield |= CLK_ADDRESS_NONE; 00059 break; 00060 00061 case CL_ADDRESS_MIRRORED_REPEAT: 00062 p_bitfield |= CLK_ADDRESS_MIRRORED_REPEAT; 00063 break; 00064 00065 case CL_ADDRESS_REPEAT: 00066 p_bitfield |= CLK_ADDRESS_REPEAT; 00067 break; 00068 00069 case CL_ADDRESS_CLAMP_TO_EDGE: 00070 p_bitfield |= CLK_ADDRESS_CLAMP_TO_EDGE; 00071 break; 00072 00073 case CL_ADDRESS_CLAMP: 00074 p_bitfield |= CLK_ADDRESS_CLAMP; 00075 break; 00076 00077 default: 00078 *errcode_ret = CL_INVALID_VALUE; 00079 return; 00080 } 00081 00082 switch (filter_mode) 00083 { 00084 case CL_FILTER_NEAREST: 00085 p_bitfield |= CLK_FILTER_NEAREST; 00086 break; 00087 00088 case CL_FILTER_LINEAR: 00089 p_bitfield |= CLK_FILTER_LINEAR; 00090 break; 00091 00092 default: 00093 *errcode_ret = CL_INVALID_VALUE; 00094 return; 00095 } 00096 00097 // Check that images are available on all the devices 00098 *errcode_ret = checkImageAvailability(); 00099 } 00100 00101 Sampler::Sampler(Context *ctx, unsigned int bitfield) 00102 : Object(Object::T_Sampler, ctx), p_bitfield(bitfield) 00103 { 00104 checkImageAvailability(); 00105 } 00106 00107 cl_int Sampler::checkImageAvailability() const 00108 { 00109 cl_uint num_devices; 00110 DeviceInterface **devices; 00111 cl_int rs; 00112 00113 rs = ((Context *)parent())->info(CL_CONTEXT_NUM_DEVICES, 00114 sizeof(unsigned int), 00115 &num_devices, 0); 00116 00117 if (rs != CL_SUCCESS) 00118 return rs; 00119 00120 devices = (DeviceInterface **)std::malloc(num_devices * 00121 sizeof(DeviceInterface *)); 00122 00123 if (!devices) 00124 { 00125 return CL_OUT_OF_HOST_MEMORY; 00126 } 00127 00128 rs = ((Context *)parent())->info(CL_CONTEXT_DEVICES, 00129 num_devices * sizeof(DeviceInterface *), 00130 devices, 0); 00131 00132 if (rs != CL_SUCCESS) 00133 { 00134 std::free((void *)devices); 00135 return rs; 00136 } 00137 00138 for (unsigned int i=0; i<num_devices; ++i) 00139 { 00140 cl_bool image_support; 00141 00142 rs = devices[i]->info(CL_DEVICE_IMAGE_SUPPORT, sizeof(cl_bool), 00143 &image_support, 0); 00144 00145 if (rs != CL_SUCCESS) 00146 { 00147 std::free((void *)devices); 00148 return rs; 00149 } 00150 00151 if (!image_support) 00152 { 00153 std::free((void *)devices); 00154 return CL_INVALID_OPERATION; 00155 } 00156 } 00157 00158 std::free((void *)devices); 00159 00160 return CL_SUCCESS; 00161 } 00162 00163 unsigned int Sampler::bitfield() const 00164 { 00165 return p_bitfield; 00166 } 00167 00168 cl_int Sampler::info(cl_sampler_info param_name, 00169 size_t param_value_size, 00170 void *param_value, 00171 size_t *param_value_size_ret) const 00172 { 00173 void *value = 0; 00174 size_t value_length = 0; 00175 00176 union { 00177 cl_uint cl_uint_var; 00178 cl_context cl_context_var; 00179 cl_bool cl_bool_var; 00180 cl_addressing_mode cl_addressing_mode_var; 00181 cl_filter_mode cl_filter_mode_var; 00182 }; 00183 00184 switch (param_name) 00185 { 00186 case CL_SAMPLER_REFERENCE_COUNT: 00187 SIMPLE_ASSIGN(cl_uint, references()); 00188 break; 00189 00190 case CL_SAMPLER_CONTEXT: 00191 SIMPLE_ASSIGN(cl_context, parent()); 00192 break; 00193 00194 case CL_SAMPLER_NORMALIZED_COORDS: 00195 if (p_bitfield & CLK_NORMALIZED_COORDS_MASK) 00196 SIMPLE_ASSIGN(cl_bool, true) 00197 else 00198 SIMPLE_ASSIGN(cl_bool, false); 00199 break; 00200 00201 case CL_SAMPLER_ADDRESSING_MODE: 00202 switch (p_bitfield & CLK_ADDRESS_MODE_MASK) 00203 { 00204 case CLK_ADDRESS_CLAMP: 00205 SIMPLE_ASSIGN(cl_addressing_mode, CL_ADDRESS_CLAMP); 00206 break; 00207 case CLK_ADDRESS_CLAMP_TO_EDGE: 00208 SIMPLE_ASSIGN(cl_addressing_mode, CL_ADDRESS_CLAMP_TO_EDGE); 00209 break; 00210 case CLK_ADDRESS_MIRRORED_REPEAT: 00211 SIMPLE_ASSIGN(cl_addressing_mode, CL_ADDRESS_MIRRORED_REPEAT); 00212 break; 00213 case CLK_ADDRESS_REPEAT: 00214 SIMPLE_ASSIGN(cl_addressing_mode, CL_ADDRESS_REPEAT); 00215 break; 00216 case CLK_ADDRESS_NONE: 00217 SIMPLE_ASSIGN(cl_addressing_mode, CL_ADDRESS_NONE); 00218 break; 00219 } 00220 break; 00221 00222 case CL_SAMPLER_FILTER_MODE: 00223 switch (p_bitfield & CLK_FILTER_MASK) 00224 { 00225 case CLK_FILTER_LINEAR: 00226 SIMPLE_ASSIGN(cl_filter_mode, CL_FILTER_LINEAR); 00227 break; 00228 case CLK_FILTER_NEAREST: 00229 SIMPLE_ASSIGN(cl_filter_mode, CL_FILTER_NEAREST); 00230 break; 00231 } 00232 00233 default: 00234 return CL_INVALID_VALUE; 00235 } 00236 00237 if (param_value && param_value_size < value_length) 00238 return CL_INVALID_VALUE; 00239 00240 if (param_value_size_ret) 00241 *param_value_size_ret = value_length; 00242 00243 if (param_value) 00244 std::memcpy(param_value, value, value_length); 00245 00246 return CL_SUCCESS; 00247 }