2017-12-21 07:45:38 +08:00
|
|
|
/*
|
2018-03-27 20:30:05 +08:00
|
|
|
* Copyright (c) 2017 - 2018, Intel Corporation
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included
|
|
|
|
* in all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
|
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
|
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "runtime/context/context.h"
|
|
|
|
#include "runtime/device/device.h"
|
|
|
|
#include "runtime/sampler/sampler.h"
|
|
|
|
#include "runtime/helpers/get_info.h"
|
|
|
|
#include "runtime/helpers/hw_info.h"
|
|
|
|
#include "patch_list.h"
|
|
|
|
|
2018-04-10 23:36:34 +08:00
|
|
|
#include <limits>
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
namespace OCLRT {
|
|
|
|
|
|
|
|
SamplerCreateFunc samplerFactory[IGFX_MAX_CORE] = {};
|
|
|
|
getSamplerStateSizeHwFunc getSamplerStateSizeHw[IGFX_MAX_CORE] = {};
|
|
|
|
|
|
|
|
Sampler::Sampler(Context *context, cl_bool normalizedCoordinates,
|
2018-04-10 23:36:34 +08:00
|
|
|
cl_addressing_mode addressingMode, cl_filter_mode filterMode,
|
|
|
|
cl_filter_mode mipFilterMode, float lodMin, float lodMax)
|
2017-12-21 07:45:38 +08:00
|
|
|
: context(context), normalizedCoordinates(normalizedCoordinates),
|
2018-04-10 23:36:34 +08:00
|
|
|
addressingMode(addressingMode), filterMode(filterMode),
|
|
|
|
mipFilterMode(mipFilterMode), lodMin(lodMin), lodMax(lodMax) {
|
|
|
|
}
|
|
|
|
|
|
|
|
Sampler::Sampler(Context *context,
|
|
|
|
cl_bool normalizedCoordinates,
|
|
|
|
cl_addressing_mode addressingMode,
|
|
|
|
cl_filter_mode filterMode)
|
|
|
|
: Sampler(context, normalizedCoordinates, addressingMode, filterMode,
|
|
|
|
CL_FILTER_NEAREST, 0.0f, std::numeric_limits<float>::max()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Sampler *Sampler::create(Context *context, cl_bool normalizedCoordinates,
|
2018-04-10 23:36:34 +08:00
|
|
|
cl_addressing_mode addressingMode, cl_filter_mode filterMode,
|
|
|
|
cl_filter_mode mipFilterMode, float lodMin, float lodMax,
|
|
|
|
cl_int &errcodeRet) {
|
2017-12-21 07:45:38 +08:00
|
|
|
errcodeRet = CL_SUCCESS;
|
|
|
|
Sampler *sampler = nullptr;
|
|
|
|
|
|
|
|
DEBUG_BREAK_IF(nullptr == context);
|
|
|
|
const auto device = context->getDevice(0);
|
|
|
|
const auto &hwInfo = device->getHardwareInfo();
|
|
|
|
|
|
|
|
auto funcCreate = samplerFactory[hwInfo.pPlatform->eRenderCoreFamily];
|
|
|
|
DEBUG_BREAK_IF(nullptr == funcCreate);
|
2018-04-10 23:36:34 +08:00
|
|
|
sampler = funcCreate(context, normalizedCoordinates, addressingMode, filterMode, mipFilterMode, lodMin, lodMax);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
if (sampler == nullptr) {
|
|
|
|
errcodeRet = CL_OUT_OF_HOST_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
return sampler;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t Sampler::getSamplerStateSize(const HardwareInfo &hwInfo) {
|
|
|
|
return getSamplerStateSizeHw[hwInfo.pPlatform->eRenderCoreFamily]();
|
|
|
|
}
|
|
|
|
|
2018-04-10 23:36:34 +08:00
|
|
|
template <typename ParameterType>
|
2017-12-21 07:45:38 +08:00
|
|
|
struct SetOnce {
|
2018-04-10 23:36:34 +08:00
|
|
|
SetOnce(ParameterType defaultValue, ParameterType min, ParameterType max)
|
|
|
|
: value(defaultValue), min(min), max(max) {
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-04-10 23:36:34 +08:00
|
|
|
cl_int setValue(ParameterType property) {
|
|
|
|
if (alreadySet) {
|
|
|
|
return CL_INVALID_VALUE;
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-04-10 23:36:34 +08:00
|
|
|
if ((property < min) || (property > max)) {
|
|
|
|
return CL_INVALID_VALUE;
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-04-10 23:36:34 +08:00
|
|
|
this->value = property;
|
|
|
|
alreadySet = true;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-04-10 23:36:34 +08:00
|
|
|
return CL_SUCCESS;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-04-10 23:36:34 +08:00
|
|
|
bool alreadySet = false;
|
|
|
|
ParameterType value;
|
|
|
|
ParameterType min;
|
|
|
|
ParameterType max;
|
2017-12-21 07:45:38 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
Sampler *Sampler::create(Context *context,
|
|
|
|
const cl_sampler_properties *samplerProperties,
|
|
|
|
cl_int &errcodeRet) {
|
2018-04-10 23:36:34 +08:00
|
|
|
SetOnce<uint32_t> normalizedCoords(CL_TRUE, CL_FALSE, CL_TRUE);
|
|
|
|
SetOnce<uint32_t> filterMode(CL_FILTER_NEAREST, CL_FILTER_NEAREST, CL_FILTER_LINEAR);
|
|
|
|
SetOnce<uint32_t> addressingMode(CL_ADDRESS_CLAMP, CL_ADDRESS_NONE, CL_ADDRESS_MIRRORED_REPEAT);
|
|
|
|
SetOnce<uint32_t> mipFilterMode(CL_FILTER_NEAREST, CL_FILTER_NEAREST, CL_FILTER_LINEAR);
|
|
|
|
SetOnce<float> lodMin(0.0f, 0.0f, std::numeric_limits<float>::max());
|
|
|
|
SetOnce<float> lodMax(std::numeric_limits<float>::max(), 0.0f, std::numeric_limits<float>::max());
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
errcodeRet = CL_SUCCESS;
|
|
|
|
if (samplerProperties) {
|
|
|
|
cl_ulong samType;
|
|
|
|
|
|
|
|
while ((samType = *samplerProperties) != 0) {
|
|
|
|
++samplerProperties;
|
|
|
|
auto samValue = *samplerProperties;
|
|
|
|
switch (samType) {
|
|
|
|
case CL_SAMPLER_NORMALIZED_COORDS:
|
2018-04-10 23:36:34 +08:00
|
|
|
errcodeRet = normalizedCoords.setValue(static_cast<uint32_t>(samValue));
|
2017-12-21 07:45:38 +08:00
|
|
|
break;
|
|
|
|
case CL_SAMPLER_ADDRESSING_MODE:
|
2018-04-10 23:36:34 +08:00
|
|
|
errcodeRet = addressingMode.setValue(static_cast<uint32_t>(samValue));
|
2017-12-21 07:45:38 +08:00
|
|
|
break;
|
|
|
|
case CL_SAMPLER_FILTER_MODE:
|
2018-04-10 23:36:34 +08:00
|
|
|
errcodeRet = filterMode.setValue(static_cast<uint32_t>(samValue));
|
|
|
|
break;
|
|
|
|
case CL_SAMPLER_MIP_FILTER_MODE:
|
|
|
|
errcodeRet = mipFilterMode.setValue(static_cast<uint32_t>(samValue));
|
2017-12-21 07:45:38 +08:00
|
|
|
break;
|
2018-04-10 23:36:34 +08:00
|
|
|
case CL_SAMPLER_LOD_MIN: {
|
|
|
|
SamplerLodProperty lodData;
|
|
|
|
lodData.data = samValue;
|
|
|
|
errcodeRet = lodMin.setValue(lodData.lod);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CL_SAMPLER_LOD_MAX: {
|
|
|
|
SamplerLodProperty lodData;
|
|
|
|
lodData.data = samValue;
|
|
|
|
errcodeRet = lodMax.setValue(lodData.lod);
|
|
|
|
break;
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
default:
|
|
|
|
errcodeRet = CL_INVALID_VALUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++samplerProperties;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Sampler *sampler = nullptr;
|
|
|
|
if (errcodeRet == CL_SUCCESS) {
|
2018-04-10 23:36:34 +08:00
|
|
|
sampler = create(context, normalizedCoords.value, addressingMode.value, filterMode.value,
|
|
|
|
mipFilterMode.value, lodMin.value, lodMax.value,
|
|
|
|
errcodeRet);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return sampler;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int Sampler::getSnapWaValue() const {
|
|
|
|
if (filterMode == CL_FILTER_NEAREST && addressingMode == CL_ADDRESS_CLAMP) {
|
|
|
|
return iOpenCL::CONSTANT_REGISTER_BOOLEAN_TRUE;
|
|
|
|
} else {
|
|
|
|
return iOpenCL::CONSTANT_REGISTER_BOOLEAN_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cl_int Sampler::getInfo(cl_sampler_info paramName, size_t paramValueSize,
|
|
|
|
void *paramValue, size_t *paramValueSizeRet) {
|
|
|
|
cl_int retVal;
|
|
|
|
size_t valueSize = 0;
|
|
|
|
const void *pValue = nullptr;
|
|
|
|
cl_uint refCount = 0;
|
|
|
|
|
|
|
|
switch (paramName) {
|
|
|
|
case CL_SAMPLER_CONTEXT:
|
|
|
|
valueSize = sizeof(cl_device_id);
|
|
|
|
pValue = &this->context;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_SAMPLER_NORMALIZED_COORDS:
|
|
|
|
valueSize = sizeof(cl_bool);
|
|
|
|
pValue = &this->normalizedCoordinates;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_SAMPLER_ADDRESSING_MODE:
|
|
|
|
valueSize = sizeof(cl_addressing_mode);
|
|
|
|
pValue = &this->addressingMode;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_SAMPLER_FILTER_MODE:
|
|
|
|
valueSize = sizeof(cl_filter_mode);
|
|
|
|
pValue = &this->filterMode;
|
|
|
|
break;
|
|
|
|
|
2018-04-10 23:36:34 +08:00
|
|
|
case CL_SAMPLER_MIP_FILTER_MODE:
|
|
|
|
valueSize = sizeof(cl_filter_mode);
|
|
|
|
pValue = &this->mipFilterMode;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_SAMPLER_LOD_MIN:
|
|
|
|
valueSize = sizeof(float);
|
|
|
|
pValue = &this->lodMin;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_SAMPLER_LOD_MAX:
|
|
|
|
valueSize = sizeof(float);
|
|
|
|
pValue = &this->lodMax;
|
|
|
|
break;
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
case CL_SAMPLER_REFERENCE_COUNT:
|
|
|
|
refCount = static_cast<cl_uint>(this->getReference());
|
|
|
|
valueSize = sizeof(refCount);
|
|
|
|
pValue = &refCount;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
retVal = ::getInfo(paramValue, paramValueSize, pValue, valueSize);
|
|
|
|
|
|
|
|
if (paramValueSizeRet) {
|
|
|
|
*paramValueSizeRet = valueSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
return retVal;
|
|
|
|
}
|
2018-03-27 20:30:05 +08:00
|
|
|
|
|
|
|
bool Sampler::isTransformable() const {
|
|
|
|
return addressingMode == CL_ADDRESS_CLAMP_TO_EDGE &&
|
|
|
|
filterMode == CL_FILTER_NEAREST &&
|
|
|
|
normalizedCoordinates == CL_FALSE;
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
} // namespace OCLRT
|