rocr: Add support for Mipmapped Array (#1847)

SWDEV-539526 - Add support for Mipmapped Array in Rocr

Add support for Mipmapped Array functionality in Rocr Runtimeenabling GPU applications to work with multi-level texture mipmaps. The implementation introduces new public APIs for creating, querying, and managing mipmapped arrays across different GPU architectures.

Signed-off-by: Apurv Mishra <Apurv.Mishra@amd.com>
Co-authored-by: Shweta Khatri <shweta.khatri@amd.com>
Co-authored-by: taosang2 <tao.sang@amd.com>
This commit is contained in:
authored and GitHub committed 2026-01-08 17:14:39 -06:00
1 parent 8b529e7b29
commit be375c2dbf
21 files changed
+2918 -101

No files matched your search

@@ -369,6 +369,48 @@ hsa_status_t hsa_ext_image_create_with_layout(
CATCH;
}
hsa_status_t hsa_ext_image_data_get_info_with_layout_v2(
hsa_agent_t agent, const hsa_ext_image_descriptor_v2_t* image_descriptor,
hsa_access_permission_t access_permission, hsa_ext_image_data_layout_t image_data_layout,
size_t image_data_row_pitch, size_t image_data_slice_pitch,
hsa_ext_image_data_info_t* image_data_info) {
TRY;
if (agent.handle == 0) {
return HSA_STATUS_ERROR_INVALID_AGENT;
}
if ((image_descriptor == NULL) || (image_data_info == NULL) ||
(access_permission < HSA_ACCESS_PERMISSION_RO) ||
(access_permission > HSA_ACCESS_PERMISSION_RW) ||
(image_data_layout != HSA_EXT_IMAGE_DATA_LAYOUT_LINEAR)) {
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
}
// V2 descriptor: only single-level images supported with LINEAR layout
// Mipmap levels must be 0 or 1 for LINEAR layout
uint32_t mipmap_levels =
(image_descriptor->mipmap_levels == 0) ? 1 : image_descriptor->mipmap_levels;
if (mipmap_levels > 1) {
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
}
// Convert V2 descriptor to V1 for internal use
hsa_ext_image_descriptor_t desc_v1 = {};
desc_v1.geometry = image_descriptor->geometry;
desc_v1.width = image_descriptor->width;
desc_v1.height = image_descriptor->height;
desc_v1.depth = image_descriptor->depth;
desc_v1.array_size = image_descriptor->array_size;
desc_v1.format = image_descriptor->format;
enforceDefaultPitch(agent, &desc_v1, image_data_row_pitch, image_data_slice_pitch);
return ImageRuntime::instance()->GetImageSizeAndAlignment(
agent, desc_v1, image_data_layout, image_data_row_pitch, image_data_slice_pitch,
*image_data_info);
CATCH;
}
hsa_status_t hsa_amd_image_create(hsa_agent_t agent,
const hsa_ext_image_descriptor_t* image_descriptor,
const hsa_amd_image_descriptor_t* image_layout,
@@ -388,6 +430,153 @@ hsa_status_t hsa_amd_image_create(hsa_agent_t agent,
CATCH;
}
hsa_status_t hsa_amd_image_create_v2(hsa_agent_t agent,
const hsa_ext_image_descriptor_v2_t* image_descriptor,
const hsa_amd_image_descriptor_t* image_layout,
const void* image_data,
hsa_access_permission_t access_permission,
hsa_ext_image_t* image) {
TRY;
if (agent.handle == 0) {
return HSA_STATUS_ERROR_INVALID_AGENT;
}
if (image_descriptor == NULL || image_data == NULL || image == NULL) {
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
}
// Convert V2 descriptor to V1 for internal use
hsa_ext_image_descriptor_t desc_v1 = {};
desc_v1.geometry = image_descriptor->geometry;
desc_v1.width = image_descriptor->width;
desc_v1.height = image_descriptor->height;
desc_v1.depth = image_descriptor->depth;
desc_v1.array_size = image_descriptor->array_size;
desc_v1.format = image_descriptor->format;
uint32_t mipmap_levels =
(image_descriptor->mipmap_levels == 0) ? 1 : image_descriptor->mipmap_levels;
if (mipmap_levels > 1) {
// Mipmapped array path with AMD layout
return ImageRuntime::instance()->CreateMipmapArrayHandleWithLayout(
agent, desc_v1, image_layout, image_data, access_permission, mipmap_levels, *image);
} else {
// Regular single-level image path with AMD layout
return ImageRuntime::instance()->CreateImageHandleWithLayout(
agent, desc_v1, image_layout, image_data, access_permission, *image);
}
CATCH;
}
//---------------------------------------------------------------------------//
// V2 API Implementations (Unified Mipmap Support)
//---------------------------------------------------------------------------//
hsa_status_t hsa_ext_image_data_get_info_v2(hsa_agent_t agent,
const hsa_ext_image_descriptor_v2_t* image_descriptor,
hsa_access_permission_t access_permission,
hsa_ext_image_data_info_t* image_data_info) {
TRY;
if (agent.handle == 0) {
return HSA_STATUS_ERROR_INVALID_AGENT;
}
if (image_descriptor == NULL || image_data_info == NULL) {
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
}
// Check if this is a mipmap request
uint32_t mipmap_levels =
(image_descriptor->mipmap_levels == 0) ? 1 : image_descriptor->mipmap_levels;
// Convert V2 descriptor to V1 for internal use
hsa_ext_image_descriptor_t desc_v1 = {};
desc_v1.geometry = image_descriptor->geometry;
desc_v1.width = image_descriptor->width;
desc_v1.height = image_descriptor->height;
desc_v1.depth = image_descriptor->depth;
desc_v1.array_size = image_descriptor->array_size;
desc_v1.format = image_descriptor->format;
if (mipmap_levels > 1) {
return ImageRuntime::instance()->GetMipmapArraySizeAndAlignment(
agent, desc_v1, mipmap_levels, HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE, 0, 0,
image_data_info->size, image_data_info->alignment);
} else {
// Regular image path (single level)
return ImageRuntime::instance()->GetImageSizeAndAlignment(
agent, desc_v1, HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE, 0, 0, *image_data_info);
}
CATCH;
}
hsa_status_t hsa_ext_image_create_v2(hsa_agent_t agent,
const hsa_ext_image_descriptor_v2_t* image_descriptor,
const void* image_data,
hsa_access_permission_t access_permission,
hsa_ext_image_t* image) {
TRY;
if (agent.handle == 0) {
return HSA_STATUS_ERROR_INVALID_AGENT;
}
if (image_descriptor == NULL || image_data == NULL || image == NULL) {
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
}
// Check if this is a mipmap request
uint32_t mipmap_levels =
(image_descriptor->mipmap_levels == 0) ? 1 : image_descriptor->mipmap_levels;
// Convert V2 descriptor to V1 for internal use
hsa_ext_image_descriptor_t desc_v1 = {};
desc_v1.geometry = image_descriptor->geometry;
desc_v1.width = image_descriptor->width;
desc_v1.height = image_descriptor->height;
desc_v1.depth = image_descriptor->depth;
desc_v1.array_size = image_descriptor->array_size;
desc_v1.format = image_descriptor->format;
if (mipmap_levels > 1) {
// Mipmapped array path
return ImageRuntime::instance()->CreateMipmapArrayHandle(
agent, desc_v1, image_data, access_permission, mipmap_levels,
HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE, 0, 0, *image);
} else {
// Regular image path (single level)
return ImageRuntime::instance()->CreateImageHandle(
agent, desc_v1, image_data, access_permission,
HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE, 0, 0, *image);
}
CATCH;
}
hsa_status_t hsa_ext_image_destroy_v2(hsa_agent_t agent, hsa_ext_image_t image) {
TRY;
if (agent.handle == 0) {
return HSA_STATUS_ERROR_INVALID_AGENT;
}
// The destroy operation is the same for both regular images and mipmaps
// The runtime internally determines the correct cleanup path
return ImageRuntime::instance()->DestroyImageHandle(image);
CATCH;
}
// per-level view retrieval implementation
hsa_status_t HSA_API hsa_ext_image_mipmap_array_get_level(hsa_agent_t agent,
const hsa_ext_image_t* mipmapped_array,
uint32_t mip_level,
hsa_ext_image_t* level_image_out) {
TRY;
if (!mipmapped_array || !level_image_out) { return HSA_STATUS_ERROR_INVALID_ARGUMENT; }
return ImageRuntime::instance()->GetMipmapArrayLevelHandle(agent, *mipmapped_array, mip_level, *level_image_out);
CATCH;
}
void LoadImage(core::ImageExtTableInternal* image_api,
decltype(::hsa_amd_image_create)** interface_api) {
image_api->hsa_ext_image_get_capability_fn = hsa_ext_image_get_capability;
@@ -420,6 +609,12 @@ void LoadImage(core::ImageExtTableInternal* image_api,
image_api->hsa_ext_sampler_create_v2_fn = hsa_ext_sampler_create_v2;
// V2 unified APIs for images and mipmaps
image_api->hsa_ext_image_data_get_info_v2_fn = hsa_ext_image_data_get_info_v2;
image_api->hsa_ext_image_create_v2_fn = hsa_ext_image_create_v2;
image_api->hsa_ext_image_destroy_v2_fn = hsa_ext_image_destroy_v2;
image_api->hsa_ext_image_mipmap_array_get_level_fn = hsa_ext_image_mipmap_array_get_level;
*interface_api = hsa_amd_image_create;
}