SWDEV-299127 - Support External Mipmap
Support hipExternalMemoryGetMappedMipmappedArray(). Add ImageExternalBuffer to differiate ImageBuffer. Currently we only support tiling_optimal mode as vulkan driver doesn't provide tiling information. Change-Id: I7e3524cdde53e4df9f728894bcebf4bd3f58d4d9
This commit is contained in:
@@ -1719,9 +1719,9 @@ pal::Memory* Device::createImage(amd::Memory& owner, bool directAccess) const {
|
||||
params.owner_ = &owner;
|
||||
params.resource_ = buffer;
|
||||
params.memory_ = buffer;
|
||||
|
||||
// Create memory object
|
||||
result = gpuImage->create(Resource::ImageBuffer, ¶ms);
|
||||
result = gpuImage->create(amd::IS_HIP && owner.parent()->isInterop() ?
|
||||
Resource::ImageExternalBuffer : Resource::ImageBuffer, ¶ms);
|
||||
} else if (directAccess && (owner.getMemFlags() & CL_MEM_ALLOC_HOST_PTR)) {
|
||||
Resource::PinnedParams params;
|
||||
params.owner_ = &owner;
|
||||
|
||||
@@ -181,6 +181,7 @@ bool Memory::create(Resource::MemoryType memType, Resource::CreateParams* params
|
||||
flags_ |= SubMemoryObject | (parent_->flags_ & HostMemoryDirectAccess);
|
||||
break;
|
||||
}
|
||||
case Resource::ImageExternalBuffer:
|
||||
case Resource::ImageBuffer: {
|
||||
Resource::ImageBufferParams* view = reinterpret_cast<Resource::ImageBufferParams*>(params);
|
||||
parent_ = reinterpret_cast<const Memory*>(view->memory_);
|
||||
|
||||
@@ -613,7 +613,7 @@ bool Resource::CreateImage(CreateParams* params, bool forceLinear) {
|
||||
ImgSubresRange.startSubres.arraySlice = imageView->layer_;
|
||||
viewOwner_ = imageView->resource_;
|
||||
image_ = viewOwner_->image_;
|
||||
} else if (memoryType() == ImageBuffer) {
|
||||
} else if (memoryType() == ImageBuffer || memoryType() == ImageExternalBuffer) {
|
||||
ImageBufferParams* imageBuffer = reinterpret_cast<ImageBufferParams*>(params);
|
||||
viewOwner_ = imageBuffer->resource_;
|
||||
}
|
||||
@@ -639,6 +639,14 @@ bool Resource::CreateImage(CreateParams* params, bool forceLinear) {
|
||||
if (((memoryType() == Persistent) && dev().settings().linearPersistentImage_) ||
|
||||
(memoryType() == ImageBuffer)) {
|
||||
tiling = Pal::ImageTiling::Linear;
|
||||
} else if (memoryType() == ImageExternalBuffer) {
|
||||
// We cannot get tiling info from vulkan/d3d driver now. So assume it to be optimal.
|
||||
// When we get tiling info, we can easily update here
|
||||
tiling = Pal::ImageTiling::Optimal;
|
||||
// Pal will infer row pitch. If rowPitch != 0 and Pal inferred row picth isn't equal to
|
||||
// rowPitch, assert(false) will be called
|
||||
rowPitch = 0;
|
||||
offset_ += params->owner_->getOrigin();
|
||||
} else if (memoryType() == ImageView) {
|
||||
tiling = viewOwner_->image_->GetImageCreateInfo().tiling;
|
||||
// Find the new pitch in pixels for the new format
|
||||
@@ -677,7 +685,8 @@ bool Resource::CreateImage(CreateParams* params, bool forceLinear) {
|
||||
// createInfo.priority;
|
||||
}
|
||||
|
||||
if ((memoryType() != ImageView) && (memoryType() != ImageBuffer)) {
|
||||
if ((memoryType() != ImageView) && (memoryType() != ImageBuffer) &&
|
||||
(memoryType() != ImageExternalBuffer)) {
|
||||
Pal::GpuMemoryCreateInfo createInfo = {};
|
||||
createInfo.size = amd::alignUp(req.size, MaxGpuAlignment);
|
||||
createInfo.alignment = std::max(req.alignment, MaxGpuAlignment);
|
||||
@@ -710,7 +719,13 @@ bool Resource::CreateImage(CreateParams* params, bool forceLinear) {
|
||||
mapCount_++;
|
||||
}
|
||||
result = image_->BindGpuMemory(memRef_->gpuMem_, offset_);
|
||||
|
||||
if (result != Pal::Result::Success) {
|
||||
LogPrintfError(
|
||||
"BindGpuMemory return %d, offset_=%zu, req.size=%zu, "
|
||||
"viewOwner_->iMem()->Desc().size=%zu\n",
|
||||
result, offset_, req.size,
|
||||
viewOwner_ && viewOwner_->iMem() ? viewOwner_->iMem()->Desc().size : 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1345,8 +1360,8 @@ void Resource::free() {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool wait =
|
||||
(memoryType() != ImageView) && (memoryType() != ImageBuffer) && (memoryType() != View);
|
||||
const bool wait = (memoryType() != ImageView) && (memoryType() != ImageBuffer) &&
|
||||
(memoryType() != ImageExternalBuffer) && (memoryType() != View);
|
||||
|
||||
// OCL has to wait, even if resource is placed in the cache, since reallocation can occur
|
||||
// and resource can be reused on another async queue without a wait on a busy operation
|
||||
|
||||
@@ -178,7 +178,8 @@ class Resource : public amd::HeapObject {
|
||||
P2PAccess, //!< resource is a shared resource for P2P access
|
||||
VkInterop, //!< resource is a Vulkan memory object
|
||||
VaRange, //!< reousrce is a virtual address range
|
||||
IpcMemory //!< reousrce is a IPC memory object
|
||||
IpcMemory, //!< reousrce is a IPC memory object
|
||||
ImageExternalBuffer //!< resource is an image view of an external buffer
|
||||
};
|
||||
|
||||
//! Resource map flags
|
||||
|
||||
@@ -71,25 +71,4 @@ namespace amd
|
||||
|
||||
virtual ~ExternalBuffer() {}
|
||||
};
|
||||
|
||||
// to be modified once image requirments are known, for now, implement like buffer
|
||||
class ExternalImage final : public Buffer, public ExternalMemory
|
||||
{
|
||||
protected:
|
||||
// Initializes device memory array, which is located after ExternalImage object in memory
|
||||
void initDeviceMemory() {
|
||||
deviceMemories_ =
|
||||
reinterpret_cast<DeviceMemory*>(reinterpret_cast<char*>(this) + sizeof(ExternalImage));
|
||||
memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory));
|
||||
}
|
||||
|
||||
public:
|
||||
ExternalImage(Context& amdContext, size_t size_in_bytes, amd::Os::FileDesc handle,
|
||||
ExternalMemory::HandleType handle_type)
|
||||
: Buffer(amdContext, 0, size_in_bytes), ExternalMemory(handle, handle_type) {
|
||||
setInteropObj(this);
|
||||
}
|
||||
|
||||
virtual ~ExternalImage() {}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ Memory::Memory(Memory& parent, Flags flags, size_t origin, size_t size, Type typ
|
||||
flags_(flags),
|
||||
version_(parent.getVersion()),
|
||||
lastWriter_(parent.getLastWriter()),
|
||||
interopObj_(parent.getInteropObj()),
|
||||
interopObj_(nullptr),
|
||||
vDev_(NULL),
|
||||
mapCount_(0),
|
||||
svmHostAddress_(parent.getSvmPtr()),
|
||||
@@ -606,10 +606,11 @@ Image::Image(Context& context, Type type, Flags flags, const Format& format, siz
|
||||
}
|
||||
|
||||
Image::Image(Buffer& buffer, Type type, Flags flags, const Format& format, size_t width,
|
||||
size_t height, size_t depth, size_t rowPitch, size_t slicePitch)
|
||||
: Memory(buffer, flags, 0, buffer.getSize(), type),
|
||||
size_t height, size_t depth, size_t rowPitch, size_t slicePitch, uint mipLevels,
|
||||
size_t offset)
|
||||
: Memory(buffer, flags, offset, buffer.getSize(), type),
|
||||
impl_(format, Coord3D(width, height, depth), rowPitch, slicePitch),
|
||||
mipLevels_(1),
|
||||
mipLevels_(mipLevels),
|
||||
baseMipLevel_(0) {
|
||||
initDimension();
|
||||
}
|
||||
|
||||
@@ -566,7 +566,7 @@ class Image : public Memory {
|
||||
size_t depth, size_t rowPitch, size_t slicePitch, uint mipLevels = 1);
|
||||
|
||||
Image(Buffer& buffer, Type type, Flags flags, const Format& format, size_t width, size_t height,
|
||||
size_t depth, size_t rowPitch, size_t slicePitch);
|
||||
size_t depth, size_t rowPitch, size_t slicePitch, uint mipLevels = 1, size_t offset = 0);
|
||||
|
||||
//! Validate image dimensions with supported sizes
|
||||
static bool validateDimensions(
|
||||
|
||||
Reference in New Issue
Block a user