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:
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user