SWDEV-479958 - Support different address mode

Support different address modes in X, Y, Z directions

Change-Id: If1db5a8af33c92dd14b48968c3e8eceb97daea6c


[ROCm/clr commit: d82d6a78cf]
This commit is contained in:
taosang2
2024-11-15 17:47:37 -05:00
committed by Tao Sang
parent 56ccdaf1dc
commit da613fbbeb
7 changed files with 94 additions and 125 deletions
+11 -8
View File
@@ -173,17 +173,20 @@ hipError_t ihipCreateTextureObject(hipTextureObject_t* pTexObject,
}
// TODO ROCclr assumes all dimensions have the same addressing mode.
cl_addressing_mode addressMode = CL_ADDRESS_NONE;
cl_addressing_mode addressMode[3] = { CL_ADDRESS_NONE, CL_ADDRESS_NONE, CL_ADDRESS_NONE};
// If hipTextureDesc::normalizedCoords is set to zero,
// hipAddressModeWrap and hipAddressModeMirror won't be supported
// and will be switched to hipAddressModeClamp.
if ((pTexDesc->normalizedCoords == 0) &&
((pTexDesc->addressMode[0] == hipAddressModeWrap) || (pTexDesc->addressMode[0] == hipAddressModeMirror))) {
addressMode = hip::getCLAddressingMode(hipAddressModeClamp);
}
// hipTextureDesc::addressMode is ignored if hipResourceDesc::resType is hipResourceTypeLinear
else if (pResDesc->resType != hipResourceTypeLinear) {
addressMode = hip::getCLAddressingMode(pTexDesc->addressMode[0]);
for (int i = 0; i < 3; i++) {
if ((pTexDesc->normalizedCoords == 0) &&
((pTexDesc->addressMode[i] == hipAddressModeWrap) ||
(pTexDesc->addressMode[i] == hipAddressModeMirror))) {
addressMode[i] = hip::getCLAddressingMode(hipAddressModeClamp);
}
// hipTextureDesc::addressMode is ignored if hipResourceDesc::resType is hipResourceTypeLinear
else if (pResDesc->resType != hipResourceTypeLinear) {
addressMode[i] = hip::getCLAddressingMode(pTexDesc->addressMode[i]);
}
}
#ifndef CL_FILTER_NONE
+26 -34
View File
@@ -2347,10 +2347,10 @@ void Device::destroyScratchBuffers() {
}
}
void Device::fillHwSampler(uint32_t state, void* hwState, uint32_t hwStateSize, uint32_t mipFilter,
float minLod, float maxLod) const {
void Device::fillHwSampler(uint32_t state, void* hwState, uint32_t hwStateSize,
const uint* addressMode, uint32_t mipFilter, float minLod, float maxLod) const {
Pal::SamplerInfo samplerInfo = {};
assert(addressMode != nullptr);
samplerInfo.borderColorType = Pal::BorderColorType::TransparentBlack;
samplerInfo.filter.zFilter = Pal::XyFilterPoint;
@@ -2360,33 +2360,6 @@ void Device::fillHwSampler(uint32_t state, void* hwState, uint32_t hwStateSize,
state &= ~amd::Sampler::StateNormalizedCoordsMask;
// Program the sampler address mode
switch (state & amd::Sampler::StateAddressMask) {
case amd::Sampler::StateAddressRepeat:
samplerInfo.addressU = Pal::TexAddressMode::Wrap;
samplerInfo.addressV = Pal::TexAddressMode::Wrap;
samplerInfo.addressW = Pal::TexAddressMode::Wrap;
break;
case amd::Sampler::StateAddressClampToEdge:
samplerInfo.addressU = Pal::TexAddressMode::Clamp;
samplerInfo.addressV = Pal::TexAddressMode::Clamp;
samplerInfo.addressW = Pal::TexAddressMode::Clamp;
break;
case amd::Sampler::StateAddressMirroredRepeat:
samplerInfo.addressU = Pal::TexAddressMode::Mirror;
samplerInfo.addressV = Pal::TexAddressMode::Mirror;
samplerInfo.addressW = Pal::TexAddressMode::Mirror;
break;
case amd::Sampler::StateAddressClamp:
case amd::Sampler::StateAddressNone:
samplerInfo.addressU = Pal::TexAddressMode::ClampBorder;
samplerInfo.addressV = Pal::TexAddressMode::ClampBorder;
samplerInfo.addressW = Pal::TexAddressMode::ClampBorder;
default:
break;
}
state &= ~amd::Sampler::StateAddressMask;
// Program texture filter mode
if (state == amd::Sampler::StateFilterLinear) {
samplerInfo.filter.magnification = Pal::XyFilterLinear;
@@ -2400,6 +2373,25 @@ void Device::fillHwSampler(uint32_t state, void* hwState, uint32_t hwStateSize,
samplerInfo.filter.mipFilter = Pal::MipFilterLinear;
}
auto addessModeMap = [] (const uint addreMode)
{
switch(addreMode) {
case CL_ADDRESS_CLAMP_TO_EDGE:
return Pal::TexAddressMode::Clamp;
case CL_ADDRESS_REPEAT:
return Pal::TexAddressMode::Wrap;
case CL_ADDRESS_MIRRORED_REPEAT:
return Pal::TexAddressMode::Mirror;
case CL_ADDRESS_CLAMP:
case CL_ADDRESS_NONE:
default:
return Pal::TexAddressMode::ClampBorder;
}
};
samplerInfo.addressU = addessModeMap(addressMode[0]);
samplerInfo.addressV = addessModeMap(addressMode[1]);
samplerInfo.addressW = addessModeMap(addressMode[2]);
iDev()->CreateSamplerSrds(1, &samplerInfo, hwState);
}
@@ -2656,12 +2648,12 @@ Device::SrdManager::~SrdManager() {
}
}
bool Sampler::create(uint32_t oclSamplerState) {
bool Sampler::create(uint32_t oclSamplerState, const uint addressMode[3]) {
hwSrd_ = dev_.srds().allocSrdSlot(&hwState_);
if (0 == hwSrd_) {
return false;
}
dev_.fillHwSampler(oclSamplerState, hwState_, HsaSamplerObjectSize);
dev_.fillHwSampler(oclSamplerState, hwState_, HsaSamplerObjectSize, addressMode);
return true;
}
@@ -2670,8 +2662,8 @@ bool Sampler::create(const amd::Sampler& owner) {
if (0 == hwSrd_) {
return false;
}
dev_.fillHwSampler(owner.state(), hwState_, HsaSamplerObjectSize, owner.mipFilter(),
owner.minLod(), owner.maxLod());
dev_.fillHwSampler(owner.state(), hwState_, HsaSamplerObjectSize, owner.addessMode(),
owner.mipFilter(), owner.minLod(), owner.maxLod());
return true;
}
+3 -1
View File
@@ -232,7 +232,8 @@ class Sampler : public device::Sampler {
virtual ~Sampler();
//! Creates a device sampler from the OCL sampler state
bool create(uint32_t oclSamplerState //!< OCL sampler state
bool create(uint32_t oclSamplerState, //!< OCL sampler state
const uint addressMode[3] //!< Address modes in X, Y and Z
);
//! Creates a device sampler from the OCL sampler state
@@ -539,6 +540,7 @@ class Device : public NullDevice {
void fillHwSampler(uint32_t state, //!< Sampler's OpenCL state
void* hwState, //!< Sampler's HW state
uint32_t hwStateSize, //!< Size of sampler's HW state
const uint* addressMode, //!< Address modes in X, Y and Z
uint32_t mipFilter = CL_FILTER_NONE, //!< Mip filter
float minLod = 0.f, //!< Min level of detail
float maxLod = CL_MAXFLOAT //!< Max level of detail
+11 -7
View File
@@ -655,28 +655,32 @@ hsa_status_t PALHSALoaderContext::SamplerCreate(
assert(false);
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
}
// This path works in OCL only, so address_mode is the same in X, Y and Z.
uint addressMode[3];
switch (sampler_descriptor->address_mode) {
case HSA_EXT_SAMPLER_ADDRESSING_MODE_CLAMP_TO_EDGE:
state |= amd::Sampler::StateAddressClampToEdge;
addressMode[0] = CL_ADDRESS_CLAMP_TO_EDGE;
break;
case HSA_EXT_SAMPLER_ADDRESSING_MODE_CLAMP_TO_BORDER:
state |= amd::Sampler::StateAddressClamp;
addressMode[0] = CL_ADDRESS_CLAMP;
break;
case HSA_EXT_SAMPLER_ADDRESSING_MODE_REPEAT:
state |= amd::Sampler::StateAddressRepeat;
addressMode[0] = CL_ADDRESS_REPEAT;
break;
case HSA_EXT_SAMPLER_ADDRESSING_MODE_MIRRORED_REPEAT:
state |= amd::Sampler::StateAddressMirroredRepeat;
addressMode[0] = CL_ADDRESS_MIRRORED_REPEAT;
break;
case HSA_EXT_SAMPLER_ADDRESSING_MODE_UNDEFINED:
state |= amd::Sampler::StateAddressNone;
addressMode[0] = CL_ADDRESS_NONE;
break;
default:
assert(false);
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
}
addressMode[1] = addressMode[2] = addressMode[0];
std::unique_ptr<pal::Sampler> sampler(new pal::Sampler(program_->palDevice()));
if (!sampler || !sampler->create(state)) {
if (!sampler || !sampler->create(state, addressMode)) {
return HSA_STATUS_ERROR;
}
sampler_handle->handle = sampler->hwSrd();
+23 -21
View File
@@ -1087,7 +1087,7 @@ bool Device::createSampler(const amd::Sampler& owner, device::Sampler** sampler)
return true;
}
void Sampler::fillSampleDescriptor(hsa_ext_sampler_descriptor_t& samplerDescriptor,
void Sampler::fillSampleDescriptor(hsa_ext_sampler_descriptor_v2_t& samplerDescriptor,
const amd::Sampler& sampler) const {
samplerDescriptor.filter_mode = sampler.filterMode() == CL_FILTER_NEAREST
? HSA_EXT_SAMPLER_FILTER_MODE_NEAREST
@@ -1095,32 +1095,34 @@ void Sampler::fillSampleDescriptor(hsa_ext_sampler_descriptor_t& samplerDescript
samplerDescriptor.coordinate_mode = sampler.normalizedCoords()
? HSA_EXT_SAMPLER_COORDINATE_MODE_NORMALIZED
: HSA_EXT_SAMPLER_COORDINATE_MODE_UNNORMALIZED;
switch (sampler.addressingMode()) {
case CL_ADDRESS_CLAMP_TO_EDGE:
samplerDescriptor.address_mode = HSA_EXT_SAMPLER_ADDRESSING_MODE_CLAMP_TO_EDGE;
break;
case CL_ADDRESS_REPEAT:
samplerDescriptor.address_mode = HSA_EXT_SAMPLER_ADDRESSING_MODE_REPEAT;
break;
case CL_ADDRESS_CLAMP:
samplerDescriptor.address_mode = HSA_EXT_SAMPLER_ADDRESSING_MODE_CLAMP_TO_BORDER;
break;
case CL_ADDRESS_MIRRORED_REPEAT:
samplerDescriptor.address_mode = HSA_EXT_SAMPLER_ADDRESSING_MODE_MIRRORED_REPEAT;
break;
case CL_ADDRESS_NONE:
samplerDescriptor.address_mode = HSA_EXT_SAMPLER_ADDRESSING_MODE_UNDEFINED;
break;
default:
return;
for (int i = 0; i < 3; i++) {
switch (sampler.addressingMode(i)) {
case CL_ADDRESS_CLAMP_TO_EDGE:
samplerDescriptor.address_modes[i] = HSA_EXT_SAMPLER_ADDRESSING_MODE_CLAMP_TO_EDGE;
break;
case CL_ADDRESS_REPEAT:
samplerDescriptor.address_modes[i] = HSA_EXT_SAMPLER_ADDRESSING_MODE_REPEAT;
break;
case CL_ADDRESS_CLAMP:
samplerDescriptor.address_modes[i] = HSA_EXT_SAMPLER_ADDRESSING_MODE_CLAMP_TO_BORDER;
break;
case CL_ADDRESS_MIRRORED_REPEAT:
samplerDescriptor.address_modes[i] = HSA_EXT_SAMPLER_ADDRESSING_MODE_MIRRORED_REPEAT;
break;
case CL_ADDRESS_NONE:
samplerDescriptor.address_modes[i] = HSA_EXT_SAMPLER_ADDRESSING_MODE_UNDEFINED;
break;
default:
return;
}
}
}
bool Sampler::create(const amd::Sampler& owner) {
hsa_ext_sampler_descriptor_t samplerDescriptor;
hsa_ext_sampler_descriptor_v2_t samplerDescriptor;
fillSampleDescriptor(samplerDescriptor, owner);
hsa_status_t status = hsa_ext_sampler_create(dev_.getBackendDevice(), &samplerDescriptor, &hsa_sampler);
hsa_status_t status = hsa_ext_sampler_create_v2(dev_.getBackendDevice(), &samplerDescriptor, &hsa_sampler);
if (HSA_STATUS_SUCCESS != status) {
DevLogPrintfError("Sampler creation failed with status: %d \n", status);
@@ -124,7 +124,7 @@ class Sampler : public device::Sampler {
);
private:
void fillSampleDescriptor(hsa_ext_sampler_descriptor_t& samplerDescriptor,
void fillSampleDescriptor(hsa_ext_sampler_descriptor_v2_t& samplerDescriptor,
const amd::Sampler& sampler) const;
Sampler& operator=(const Sampler&);
+19 -53
View File
@@ -38,13 +38,6 @@ class Sampler : public RuntimeObject {
StateNormalizedCoordsFalse = 0x00,
StateNormalizedCoordsTrue = 0x01,
StateNormalizedCoordsMask = (StateNormalizedCoordsFalse | StateNormalizedCoordsTrue),
StateAddressNone = 0x00,
StateAddressRepeat = 0x02,
StateAddressClampToEdge = 0x04,
StateAddressClamp = 0x06,
StateAddressMirroredRepeat = 0x08,
StateAddressMask = (StateAddressNone | StateAddressRepeat | StateAddressMirroredRepeat |
StateAddressClampToEdge | StateAddressClamp),
StateFilterNearest = 0x10,
StateFilterLinear = 0x20,
StateFilterMask = (StateFilterNearest | StateFilterLinear)
@@ -57,9 +50,10 @@ class Sampler : public RuntimeObject {
float minLod_; //!< min level of detail
float maxLod_; //!< max level of detail
DeviceSamplers deviceSamplers_; //!< Container for the device samplers
uint addressMode_[3]; //!< address modes in X, Y and Z
public:
Sampler(Context& context, //!< OpenCL context
Sampler(Context& context, //!< context for OCL
bool normCoords, //!< normalized coordinates
uint addrMode, //!< adressing mode
uint filterMode, //!< filter mode
@@ -72,6 +66,7 @@ class Sampler : public RuntimeObject {
minLod_(minLod),
maxLod_(maxLod) { // Packs the sampler state into uint32_t for kernel execution
state_ = 0;
for (int i = 0; i < 3; i++) addressMode_[i] = addrMode;
// Set normalized state
if (normCoords) {
@@ -86,27 +81,20 @@ class Sampler : public RuntimeObject {
} else {
state_ |= StateFilterNearest;
}
}
// Program the sampler address mode
switch (addrMode) {
case CL_ADDRESS_CLAMP_TO_EDGE:
state_ |= StateAddressClampToEdge;
break;
case CL_ADDRESS_REPEAT:
state_ |= StateAddressRepeat;
break;
case CL_ADDRESS_CLAMP:
state_ |= StateAddressClamp;
break;
case CL_ADDRESS_MIRRORED_REPEAT:
state_ |= StateAddressMirroredRepeat;
break;
case CL_ADDRESS_NONE:
state_ |= StateAddressNone;
break;
default:
break;
}
Sampler(Context& context, //!< context for Hip
bool normCoords, //!< normalized coordinates
const uint addrMode[3], //!< adressing modes in X, Y and Z directions
uint filterMode, //!< filter mode
uint mipFilterMode, //!< mip filter mode
float minLod, //!< min level of detail
float maxLod //!< max level of detail
)
: Sampler(context, normCoords, addrMode[0], filterMode,
mipFilterMode, minLod, maxLod) {
addressMode_[1] = addrMode[1];
addressMode_[2] = addrMode[2];
}
virtual ~Sampler() {
@@ -142,33 +130,11 @@ class Sampler : public RuntimeObject {
uint mipFilter() const { return mipFilter_; }
float minLod() const { return minLod_; }
float maxLod() const { return maxLod_; }
const uint* addessMode() const { return addressMode_; }
bool normalizedCoords() const { return (state_ & StateNormalizedCoordsTrue) ? true : false; }
uint addressingMode() const {
uint adressing = 0;
// Program the sampler address mode
switch (state_ & StateAddressMask) {
case StateAddressRepeat:
adressing = CL_ADDRESS_REPEAT;
break;
case StateAddressClampToEdge:
adressing = CL_ADDRESS_CLAMP_TO_EDGE;
break;
case StateAddressClamp:
adressing = CL_ADDRESS_CLAMP;
break;
case StateAddressMirroredRepeat:
adressing = CL_ADDRESS_MIRRORED_REPEAT;
break;
case StateAddressNone:
adressing = CL_ADDRESS_NONE;
break;
default:
break;
}
return adressing;
uint inline addressingMode(const int index = 0) const {
return addressMode_[index];
}
uint filterMode() const {