Clover Git
OpenCL 1.1 software implementation

sampler.cpp

Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines