Adding mipmap support in sampler

* sampler mipmap lod/filtering programming
* sampler queries
* clCreateSamplerWithProperties
* fixed point numeric type (e.g. U4.8)

Change-Id: I6b496e6f067f6232bab464ab3ee74af8b00904d3
This commit is contained in:
Chodor, Jaroslaw
2018-04-10 17:36:34 +02:00
parent c408bb5d8d
commit 1c3ff8a15b
13 changed files with 407 additions and 49 deletions

View File

@ -27,20 +27,33 @@
#include "runtime/helpers/hw_info.h"
#include "patch_list.h"
#include <limits>
namespace OCLRT {
SamplerCreateFunc samplerFactory[IGFX_MAX_CORE] = {};
getSamplerStateSizeHwFunc getSamplerStateSizeHw[IGFX_MAX_CORE] = {};
Sampler::Sampler(Context *context, cl_bool normalizedCoordinates,
cl_addressing_mode addressingMode, cl_filter_mode filterMode)
cl_addressing_mode addressingMode, cl_filter_mode filterMode,
cl_filter_mode mipFilterMode, float lodMin, float lodMax)
: context(context), normalizedCoordinates(normalizedCoordinates),
addressingMode(addressingMode), filterMode(filterMode) {
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()) {
}
Sampler *Sampler::create(Context *context, cl_bool normalizedCoordinates,
cl_addressing_mode addressingMode,
cl_filter_mode filterMode, cl_int &errcodeRet) {
cl_addressing_mode addressingMode, cl_filter_mode filterMode,
cl_filter_mode mipFilterMode, float lodMin, float lodMax,
cl_int &errcodeRet) {
errcodeRet = CL_SUCCESS;
Sampler *sampler = nullptr;
@ -50,7 +63,7 @@ Sampler *Sampler::create(Context *context, cl_bool normalizedCoordinates,
auto funcCreate = samplerFactory[hwInfo.pPlatform->eRenderCoreFamily];
DEBUG_BREAK_IF(nullptr == funcCreate);
sampler = funcCreate(context, normalizedCoordinates, addressingMode, filterMode);
sampler = funcCreate(context, normalizedCoordinates, addressingMode, filterMode, mipFilterMode, lodMin, lodMax);
if (sampler == nullptr) {
errcodeRet = CL_OUT_OF_HOST_MEMORY;
@ -63,42 +76,42 @@ size_t Sampler::getSamplerStateSize(const HardwareInfo &hwInfo) {
return getSamplerStateSizeHw[hwInfo.pPlatform->eRenderCoreFamily]();
}
template <typename ParameterType, ParameterType minValue, ParameterType maxValue>
template <typename ParameterType>
struct SetOnce {
SetOnce(ParameterType defaultValue) : value(defaultValue),
setValueInternal(&SetOnce::setValueValid) {
SetOnce(ParameterType defaultValue, ParameterType min, ParameterType max)
: value(defaultValue), min(min), max(max) {
}
cl_int setValue(cl_ulong property) {
auto result = (this->*setValueInternal)(property);
setValueInternal = &SetOnce::setValueInvalid;
return result;
}
ParameterType value;
protected:
cl_int (SetOnce::*setValueInternal)(cl_ulong property);
cl_int setValueValid(cl_ulong property) {
if (property >= minValue && property <= maxValue) {
value = static_cast<ParameterType>(property);
return CL_SUCCESS;
cl_int setValue(ParameterType property) {
if (alreadySet) {
return CL_INVALID_VALUE;
}
return CL_INVALID_VALUE;
if ((property < min) || (property > max)) {
return CL_INVALID_VALUE;
}
this->value = property;
alreadySet = true;
return CL_SUCCESS;
}
cl_int setValueInvalid(cl_ulong property) {
return CL_INVALID_VALUE;
}
bool alreadySet = false;
ParameterType value;
ParameterType min;
ParameterType max;
};
Sampler *Sampler::create(Context *context,
const cl_sampler_properties *samplerProperties,
cl_int &errcodeRet) {
SetOnce<uint32_t, CL_FALSE, CL_TRUE> normalizedCoords(CL_TRUE);
SetOnce<uint32_t, CL_FILTER_NEAREST, CL_FILTER_LINEAR> filterMode(CL_FILTER_NEAREST);
SetOnce<uint32_t, CL_ADDRESS_NONE, CL_ADDRESS_MIRRORED_REPEAT> addressingMode(CL_ADDRESS_CLAMP);
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());
errcodeRet = CL_SUCCESS;
if (samplerProperties) {
@ -109,14 +122,29 @@ Sampler *Sampler::create(Context *context,
auto samValue = *samplerProperties;
switch (samType) {
case CL_SAMPLER_NORMALIZED_COORDS:
errcodeRet = normalizedCoords.setValue(samValue);
errcodeRet = normalizedCoords.setValue(static_cast<uint32_t>(samValue));
break;
case CL_SAMPLER_ADDRESSING_MODE:
errcodeRet = addressingMode.setValue(samValue);
errcodeRet = addressingMode.setValue(static_cast<uint32_t>(samValue));
break;
case CL_SAMPLER_FILTER_MODE:
errcodeRet = filterMode.setValue(samValue);
errcodeRet = filterMode.setValue(static_cast<uint32_t>(samValue));
break;
case CL_SAMPLER_MIP_FILTER_MODE:
errcodeRet = mipFilterMode.setValue(static_cast<uint32_t>(samValue));
break;
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;
}
default:
errcodeRet = CL_INVALID_VALUE;
break;
@ -127,7 +155,9 @@ Sampler *Sampler::create(Context *context,
Sampler *sampler = nullptr;
if (errcodeRet == CL_SUCCESS) {
sampler = create(context, normalizedCoords.value, addressingMode.value, filterMode.value, errcodeRet);
sampler = create(context, normalizedCoords.value, addressingMode.value, filterMode.value,
mipFilterMode.value, lodMin.value, lodMax.value,
errcodeRet);
}
return sampler;
@ -169,6 +199,21 @@ cl_int Sampler::getInfo(cl_sampler_info paramName, size_t paramValueSize,
pValue = &this->filterMode;
break;
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;
case CL_SAMPLER_REFERENCE_COUNT:
refCount = static_cast<cl_uint>(this->getReference());
valueSize = sizeof(refCount);

View File

@ -33,6 +33,11 @@ struct OpenCLObjectMapper<_cl_sampler> {
typedef class Sampler DerivedType;
};
union SamplerLodProperty {
cl_sampler_properties data;
float lod;
};
class Sampler : public BaseObject<_cl_sampler> {
public:
static const cl_ulong objectMagic = 0x4684913AC213EF00LL;
@ -40,8 +45,17 @@ class Sampler : public BaseObject<_cl_sampler> {
static Sampler *create(Context *context, cl_bool normalizedCoordinates,
cl_addressing_mode addressingMode, cl_filter_mode filterMode,
cl_filter_mode mipFilterMode, float lodMin, float lodMax,
cl_int &errcodeRet);
static Sampler *create(Context *context, cl_bool normalizedCoordinates,
cl_addressing_mode addressingMode, cl_filter_mode filterMode,
cl_int &errcodeRet) {
return Sampler::create(context, normalizedCoordinates, addressingMode, filterMode,
CL_FILTER_NEAREST, 0.0f, std::numeric_limits<float>::max(),
errcodeRet);
}
static Sampler *create(Context *context,
const cl_sampler_properties *samplerProperties,
cl_int &errcodeRet);
@ -54,6 +68,14 @@ class Sampler : public BaseObject<_cl_sampler> {
static size_t getSamplerStateSize(const HardwareInfo &hwInfo);
bool isTransformable() const;
Sampler(Context *context,
cl_bool normalizedCoordinates,
cl_addressing_mode addressingMode,
cl_filter_mode filterMode,
cl_filter_mode mipFilterMode,
float lodMin,
float lodMax);
Sampler(Context *context,
cl_bool normalizedCoordinates,
cl_addressing_mode addressingMode,
@ -65,30 +87,51 @@ class Sampler : public BaseObject<_cl_sampler> {
cl_bool normalizedCoordinates;
cl_addressing_mode addressingMode;
cl_filter_mode filterMode;
cl_filter_mode mipFilterMode;
float lodMin;
float lodMax;
};
template <typename GfxFamily>
struct SamplerHw : public Sampler {
void setArg(void *memory) override;
void appendSamplerStateParams(typename GfxFamily::SAMPLER_STATE *state);
static constexpr float getGenSamplerMaxLod() {
return 14.0f;
}
SamplerHw(Context *context,
cl_bool normalizedCoordinates,
cl_addressing_mode addressingMode,
cl_filter_mode filterMode) : Sampler(context,
normalizedCoordinates,
addressingMode,
filterMode) {
cl_filter_mode filterMode,
cl_filter_mode mipFilterMode,
float lodMin,
float lodMax)
: Sampler(context, normalizedCoordinates, addressingMode, filterMode,
mipFilterMode, lodMin, lodMax) {
}
SamplerHw(Context *context,
cl_bool normalizedCoordinates,
cl_addressing_mode addressingMode,
cl_filter_mode filterMode)
: Sampler(context, normalizedCoordinates, addressingMode, filterMode) {
}
static Sampler *create(Context *context,
cl_bool normalizedCoordinates,
cl_addressing_mode addressingMode,
cl_filter_mode filterMode) {
cl_filter_mode filterMode,
cl_filter_mode mipFilterMode,
float lodMin,
float lodMax) {
return new SamplerHw<GfxFamily>(context,
normalizedCoordinates,
addressingMode,
filterMode);
filterMode,
mipFilterMode,
lodMin,
lodMax);
}
static size_t getSamplerStateSize();
@ -97,7 +140,10 @@ struct SamplerHw : public Sampler {
typedef Sampler *(*SamplerCreateFunc)(Context *context,
cl_bool normalizedCoordinates,
cl_addressing_mode addressingMode,
cl_filter_mode filterMode);
cl_filter_mode filterMode,
cl_filter_mode mipFilterMode,
float lodMin,
float lodMax);
typedef size_t (*getSamplerStateSizeHwFunc)();
}

View File

@ -20,6 +20,10 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "runtime/utilities/numeric.h"
#include <algorithm>
namespace OCLRT {
template <typename GfxFamily>
@ -65,6 +69,9 @@ void SamplerHw<GfxFamily>::setArg(void *memory) {
if (CL_FILTER_LINEAR == filterMode) {
minMode = SAMPLER_STATE::MIN_MODE_FILTER_LINEAR;
magMode = SAMPLER_STATE::MAG_MODE_FILTER_LINEAR;
}
if (CL_FILTER_LINEAR == mipFilterMode) {
mipMode = SAMPLER_STATE::MIP_MODE_FILTER_LINEAR;
}
@ -90,6 +97,12 @@ void SamplerHw<GfxFamily>::setArg(void *memory) {
samplerState->setUAddressMinFilterRoundingEnable(false);
samplerState->setUAddressMagFilterRoundingEnable(false);
}
FixedU4D8 minLodValue = FixedU4D8(std::min(getGenSamplerMaxLod(), this->lodMin));
FixedU4D8 maxLodValue = FixedU4D8(std::min(getGenSamplerMaxLod(), this->lodMax));
samplerState->setMinLod(minLodValue.getRawAccess());
samplerState->setMaxLod(maxLodValue.getRawAccess());
appendSamplerStateParams(samplerState);
}