mirror of
https://github.com/intel/compute-runtime.git
synced 2025-09-15 13:01:45 +08:00
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:
@ -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);
|
||||
|
@ -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)();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user