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:
taosang2
2023-08-10 11:49:48 -04:00
committed by Tao Sang
parent e63c280d4d
commit 6398f604b0
12 changed files with 136 additions and 41 deletions
+28 -1
View File
@@ -376,7 +376,8 @@ enum hip_api_id_t {
HIP_API_ID_hipArrayGetDescriptor = 361,
HIP_API_ID_hipArrayGetInfo = 362,
HIP_API_ID_hipStreamGetDevice = 363,
HIP_API_ID_LAST = 363,
HIP_API_ID_hipExternalMemoryGetMappedMipmappedArray = 364,
HIP_API_ID_LAST = 364,
HIP_API_ID_hipBindTexture = HIP_API_ID_NONE,
HIP_API_ID_hipBindTexture2D = HIP_API_ID_NONE,
@@ -779,6 +780,7 @@ static inline const char* hip_api_name(const uint32_t id) {
case HIP_API_ID_hipUserObjectRelease: return "hipUserObjectRelease";
case HIP_API_ID_hipUserObjectRetain: return "hipUserObjectRetain";
case HIP_API_ID_hipWaitExternalSemaphoresAsync: return "hipWaitExternalSemaphoresAsync";
case HIP_API_ID_hipExternalMemoryGetMappedMipmappedArray: return "hipExternalMemoryGetMappedMipmappedArray";
};
return "unknown";
};
@@ -1145,6 +1147,7 @@ static inline uint32_t hipApiIdByName(const char* name) {
if (strcmp("hipUserObjectRelease", name) == 0) return HIP_API_ID_hipUserObjectRelease;
if (strcmp("hipUserObjectRetain", name) == 0) return HIP_API_ID_hipUserObjectRetain;
if (strcmp("hipWaitExternalSemaphoresAsync", name) == 0) return HIP_API_ID_hipWaitExternalSemaphoresAsync;
if (strcmp("hipExternalMemoryGetMappedMipmappedArray", name) == 0) return HIP_API_ID_hipExternalMemoryGetMappedMipmappedArray;
return HIP_API_ID_NONE;
}
@@ -3266,6 +3269,12 @@ typedef struct hip_api_data_s {
unsigned int numExtSems;
hipStream_t stream;
} hipWaitExternalSemaphoresAsync;
struct {
hipMipmappedArray_t* mipmap;
hipExternalMemory_t extMem;
const hipExternalMemoryMipmappedArrayDesc* mipmapDesc;
hipExternalMemoryMipmappedArrayDesc mipmapDesc__val;
} hipExternalMemoryGetMappedMipmappedArray;
} args;
uint64_t *phase_data;
} hip_api_data_t;
@@ -3692,6 +3701,12 @@ typedef struct hip_api_data_s {
cb_data.args.hipExternalMemoryGetMappedBuffer.extMem = (hipExternalMemory_t)extMem; \
cb_data.args.hipExternalMemoryGetMappedBuffer.bufferDesc = (const hipExternalMemoryBufferDesc*)bufferDesc; \
};
// hipExternalMemoryGetMappedMipmappedArray[('hipMipmappedArray_t*', 'mipmap'), ('hipExternalMemory_t', 'extMem'), ('const hipExternalMemoryMipmappedArrayDesc*', 'mipmapDesc')]
#define INIT_hipExternalMemoryGetMappedMipmappedArray_CB_ARGS_DATA(cb_data) { \
cb_data.args.hipExternalMemoryGetMappedMipmappedArray.mipmap = (hipMipmappedArray_t*)mipmap; \
cb_data.args.hipExternalMemoryGetMappedMipmappedArray.extMem = (hipExternalMemory_t)extMem; \
cb_data.args.hipExternalMemoryGetMappedMipmappedArray.mipmapDesc = (const hipExternalMemoryMipmappedArrayDesc*)mipmapDesc; \
};
// hipFree[('void*', 'ptr')]
#define INIT_hipFree_CB_ARGS_DATA(cb_data) { \
cb_data.args.hipFree.ptr = (void*)ptr; \
@@ -5835,6 +5850,10 @@ static inline void hipApiArgsInit(hip_api_id_t id, hip_api_data_t* data) {
if (data->args.hipExternalMemoryGetMappedBuffer.devPtr) data->args.hipExternalMemoryGetMappedBuffer.devPtr__val = *(data->args.hipExternalMemoryGetMappedBuffer.devPtr);
if (data->args.hipExternalMemoryGetMappedBuffer.bufferDesc) data->args.hipExternalMemoryGetMappedBuffer.bufferDesc__val = *(data->args.hipExternalMemoryGetMappedBuffer.bufferDesc);
break;
// hipExternalMemoryGetMappedMipmappedArray[('hipMipmappedArray_t*', 'mipmap'), ('hipExternalMemory_t', 'extMem'), ('const hipExternalMemoryMipmappedArrayDesc*', 'mipmapDesc')]
case HIP_API_ID_hipExternalMemoryGetMappedMipmappedArray:
if (data->args.hipExternalMemoryGetMappedMipmappedArray.mipmapDesc) data->args.hipExternalMemoryGetMappedMipmappedArray.mipmapDesc__val = *(data->args.hipExternalMemoryGetMappedMipmappedArray.mipmapDesc);
break;
// hipFree[('void*', 'ptr')]
case HIP_API_ID_hipFree:
break;
@@ -7503,6 +7522,14 @@ static inline const char* hipApiString(hip_api_id_t id, const hip_api_data_t* da
else { oss << ", bufferDesc="; roctracer::hip_support::detail::operator<<(oss, data->args.hipExternalMemoryGetMappedBuffer.bufferDesc__val); }
oss << ")";
break;
case HIP_API_ID_hipExternalMemoryGetMappedMipmappedArray:
oss << "hipExternalMemoryGetMappedMipmappedArray(";
oss << "mipmap="; roctracer::hip_support::detail::operator<<(oss, data->args.hipExternalMemoryGetMappedMipmappedArray.mipmap);
oss << ", extMem="; roctracer::hip_support::detail::operator<<(oss, data->args.hipExternalMemoryGetMappedMipmappedArray.extMem);
if (data->args.hipExternalMemoryGetMappedMipmappedArray.mipmapDesc == NULL) oss << ", mipmapDesc=NULL";
else { oss << ", mipmapDesc="; roctracer::hip_support::detail::operator<<(oss, data->args.hipExternalMemoryGetMappedMipmappedArray.mipmapDesc__val); }
oss << ")";
break;
case HIP_API_ID_hipFree:
oss << "hipFree(";
oss << "ptr="; roctracer::hip_support::detail::operator<<(oss, data->args.hipFree.ptr);
@@ -1284,6 +1284,7 @@ typedef enum cudaExternalMemoryHandleType hipExternalMemoryHandleType;
typedef struct cudaExternalMemoryHandleDesc hipExternalMemoryHandleDesc;
typedef struct cudaExternalMemoryBufferDesc hipExternalMemoryBufferDesc;
typedef cudaExternalMemory_t hipExternalMemory_t;
typedef cudaExternalMemoryMipmappedArrayDesc hipExternalMemoryMipmappedArrayDesc;
typedef enum cudaExternalSemaphoreHandleType hipExternalSemaphoreHandleType;
#define hipExternalSemaphoreHandleTypeOpaqueFd cudaExternalSemaphoreHandleTypeOpaqueFd
@@ -2944,6 +2945,14 @@ inline static hipError_t hipExternalMemoryGetMappedBuffer(void **devPtr, hipExte
return hipCUDAErrorTohipError(cudaExternalMemoryGetMappedBuffer(devPtr, extMem, (const struct cudaExternalMemoryBufferDesc*)bufferDesc));
}
inline static hipError_t hipExternalMemoryGetMappedMipmappedArray(
hipMipmappedArray_t* mipmap, hipExternalMemory_t extMem,
const hipExternalMemoryMipmappedArrayDesc* mipmapDesc) {
return hipCUDAErrorTohipError(cudaExternalMemoryGetMappedMipmappedArray(
(cudaMipmappedArray_t*)mipmap, (cudaExternalMemory_t)extMem,
(const struct cudaExternalMemoryMipmappedArrayDesc*)mipmapDesc));
}
inline static hipError_t hipDestroyExternalMemory(hipExternalMemory_t extMem) {
return hipCUDAErrorTohipError(cudaDestroyExternalMemory(extMem));
}
+1
View File
@@ -31,6 +31,7 @@ hipDeviceGetUuid
hipDeviceGetPCIBusId
hipDeviceGetSharedMemConfig
hipDeviceGetP2PAttribute
hipExternalMemoryGetMappedMipmappedArray
hipDevicePrimaryCtxGetState
hipDevicePrimaryCtxRelease
hipDevicePrimaryCtxReset
+65 -7
View File
@@ -875,6 +875,7 @@ amd::Image* ihipImageCreate(const cl_channel_order channelOrder,
const size_t imageRowPitch,
const size_t imageSlicePitch,
const uint32_t numMipLevels,
const size_t offset,
amd::Memory* buffer,
hipError_t& status) {
status = hipSuccess;
@@ -925,9 +926,34 @@ amd::Image* ihipImageCreate(const cl_channel_order channelOrder,
}
// TODO validate the image descriptor.
bool isExternalBuffer = buffer != nullptr ? buffer->isInterop() : false;
amd::Image* image = nullptr;
if (buffer != nullptr) {
if (isExternalBuffer) {
// We will create mipmap image view on top of external buffer which is from Vulkan or D3D
// image. The buffer contains subchunks of tiled image, or it's just a linear image. Lower
// level PAL will infer memory layout (offset, pitch, slice pitch, size) for each level
// array in terms of tiling mode(linear or optimal), extent, format and mipmap levels.
// Note that RocR will support mipmap in the future.
switch (imageType) {
case CL_MEM_OBJECT_IMAGE1D:
case CL_MEM_OBJECT_IMAGE2D:
case CL_MEM_OBJECT_IMAGE3D:
image = new (context) amd::Image(*buffer->asBuffer(),
imageType,
CL_MEM_READ_WRITE,
imageFormat,
imageWidth,
(imageHeight == 0) ? 1 : imageHeight,
(imageDepth == 0) ? 1 : imageDepth,
imageRowPitch,
imageSlicePitch,
numMipLevels,
offset);
break;
default:
LogPrintfError("Cannot create image of imageType: 0x%x for external buffer\n", imageType);
}
} else if (buffer != nullptr) {
switch (imageType) {
case CL_MEM_OBJECT_IMAGE1D_BUFFER:
case CL_MEM_OBJECT_IMAGE2D:
@@ -939,7 +965,9 @@ amd::Image* ihipImageCreate(const cl_channel_order channelOrder,
(imageHeight == 0) ? 1 : imageHeight,
(imageDepth == 0) ? 1 : imageDepth,
imageRowPitch,
imageSlicePitch);
imageSlicePitch,
numMipLevels,
offset);
break;
default:
LogPrintfError("Cannot create image of imageType: 0x%x \n", imageType);
@@ -1040,7 +1068,7 @@ hipError_t ihipArrayCreate(hipArray** array,
pAllocateArray->Depth, /* array size */
0, /* row pitch */
0, /* slice pitch */
numMipmapLevels,
numMipmapLevels, 0,
nullptr, /* buffer */
status);
@@ -3933,7 +3961,8 @@ hipError_t hipDrvMemcpy2DUnaligned(const hip_Memcpy2D* pCopy) {
hipError_t ihipMipmapArrayCreate(hipMipmappedArray_t* mipmapped_array_pptr,
HIP_ARRAY3D_DESCRIPTOR* mipmapped_array_desc_ptr,
unsigned int num_mipmap_levels) {
unsigned int num_mipmap_levels,
size_t offset = 0, amd::Memory* buffer = nullptr) {
bool mipMapSupport = true;
amd::Context& context = *hip::getCurrentDevice()->asContext();
const std::vector<amd::Device*>& devices = context.devices();
@@ -3966,7 +3995,8 @@ hipError_t ihipMipmapArrayCreate(hipMipmappedArray_t* mipmapped_array_pptr,
0 /* row pitch */,
0 /* slice pitch */,
num_mipmap_levels,
nullptr, /* buffer */
offset,
buffer,
status);
if (image == nullptr) {
@@ -3985,7 +4015,7 @@ hipError_t ihipMipmapArrayCreate(hipMipmappedArray_t* mipmapped_array_pptr,
(*mipmapped_array_pptr)->height = mipmapped_array_desc_ptr->Height;
(*mipmapped_array_pptr)->depth = mipmapped_array_desc_ptr->Depth;
(*mipmapped_array_pptr)->min_mipmap_level = 0;
(*mipmapped_array_pptr)->max_mipmap_level = num_mipmap_levels;
(*mipmapped_array_pptr)->max_mipmap_level = num_mipmap_levels - 1;
(*mipmapped_array_pptr)->flags = mipmapped_array_desc_ptr->Flags;
(*mipmapped_array_pptr)->format = mipmapped_array_desc_ptr->Format;
(*mipmapped_array_pptr)->num_channels = mipmapped_array_desc_ptr->NumChannels;
@@ -4127,3 +4157,31 @@ hipError_t hipGetMipmappedArrayLevel(hipArray_t *levelArray,
const_cast<hipMipmappedArray_t>(mipmappedArray),
level));
}
// ================================================================================================
hipError_t hipExternalMemoryGetMappedMipmappedArray(
hipMipmappedArray_t* mipmap, hipExternalMemory_t extMem,
const hipExternalMemoryMipmappedArrayDesc* mipmapDesc) {
HIP_INIT_API(hipExternalMemoryGetMappedMipmappedArray, mipmap, extMem, mipmapDesc);
if (mipmap == nullptr || extMem == nullptr || mipmapDesc == nullptr ||
mipmapDesc->flags != hipArrayDefault) {
HIP_RETURN(hipErrorInvalidValue);
}
CHECK_STREAM_CAPTURE_SUPPORTED();
auto buf = reinterpret_cast<amd::ExternalBuffer*>(extMem);
const device::Memory* devMem = buf->getDeviceMemory(*hip::getCurrentDevice()->devices()[0]);
HIP_ARRAY3D_DESCRIPTOR allocateArray = {mipmapDesc->extent.width,
mipmapDesc->extent.height,
mipmapDesc->extent.depth,
hip::getArrayFormat(mipmapDesc->formatDesc),
hip::getNumChannels(mipmapDesc->formatDesc),
mipmapDesc->flags};
if (!hip::CheckArrayFormat(mipmapDesc->formatDesc)) {
return HIP_RETURN(hipErrorInvalidValue);
}
HIP_RETURN(ihipMipmapArrayCreate(mipmap, &allocateArray, mipmapDesc->numLevels,
(size_t)mipmapDesc->offset, buf));
}
+3
View File
@@ -67,6 +67,7 @@ amd::Image* ihipImageCreate(const cl_channel_order channelOrder,
const size_t imageRowPitch,
const size_t imageSlicePitch,
const uint32_t numMipLevels,
const size_t offset,
amd::Memory* buffer,
hipError_t& status);
@@ -301,6 +302,7 @@ hipError_t ihipCreateTextureObject(hipTextureObject_t* pTexObject,
0, /* imageRowPitch */
0, /* imageSlicePitch */
0, /* numMipLevels */
0, /* offset */
buffer,
status);
buffer->release();
@@ -328,6 +330,7 @@ hipError_t ihipCreateTextureObject(hipTextureObject_t* pTexObject,
pResDesc->res.pitch2D.pitchInBytes, /* imageRowPitch */
0, /* imageSlicePitch */
0, /* numMipLevels */
0, /* offset */
buffer,
status);
if (buffer != nullptr) {