diff --git a/projects/clr/rocclr/device/pal/palvirtual.hpp b/projects/clr/rocclr/device/pal/palvirtual.hpp index 4e83bffc47..204b6720f9 100644 --- a/projects/clr/rocclr/device/pal/palvirtual.hpp +++ b/projects/clr/rocclr/device/pal/palvirtual.hpp @@ -628,7 +628,7 @@ class VirtualGPU : public device::VirtualDevice { ) { amd::Memory* mem = new (amdImage.getContext()) amd::Buffer(amdImage, 0, 0, amdImage.getSize()); mem->setVirtualDevice(this); - if ((mem != nullptr) && !mem->create()) { + if (!mem->create()) { mem->release(); } return mem; diff --git a/projects/clr/rocclr/device/rocm/rocdevice.cpp b/projects/clr/rocclr/device/rocm/rocdevice.cpp index 10745a944f..32ce8c4703 100644 --- a/projects/clr/rocclr/device/rocm/rocdevice.cpp +++ b/projects/clr/rocclr/device/rocm/rocdevice.cpp @@ -915,6 +915,16 @@ void Sampler::fillSampleDescriptor(hsa_ext_sampler_descriptor_v2_t& samplerDescr samplerDescriptor.filter_mode = sampler.filterMode() == CL_FILTER_NEAREST ? HSA_EXT_SAMPLER_FILTER_MODE_NEAREST : HSA_EXT_SAMPLER_FILTER_MODE_LINEAR; + switch (sampler.mipFilter()) { + case CL_FILTER_NEAREST: + samplerDescriptor.mipmap_filter_mode = HSA_EXT_SAMPLER_FILTER_MODE_NEAREST; + break; + case CL_FILTER_LINEAR: + samplerDescriptor.mipmap_filter_mode = HSA_EXT_SAMPLER_FILTER_MODE_LINEAR; + break; + default: + samplerDescriptor.mipmap_filter_mode = HSA_EXT_SAMPLER_FILTER_MODE_NONE; + } samplerDescriptor.coordinate_mode = sampler.normalizedCoords() ? HSA_EXT_SAMPLER_COORDINATE_MODE_NORMALIZED : HSA_EXT_SAMPLER_COORDINATE_MODE_UNNORMALIZED; diff --git a/projects/clr/rocclr/device/rocm/rocmemory.cpp b/projects/clr/rocclr/device/rocm/rocmemory.cpp index 5624f8569d..434c031c18 100644 --- a/projects/clr/rocclr/device/rocm/rocmemory.cpp +++ b/projects/clr/rocclr/device/rocm/rocmemory.cpp @@ -1175,6 +1175,7 @@ void Image::populateImageDescriptor() { imageDescriptor_.height = image->getHeight(); imageDescriptor_.depth = image->getDepth(); imageDescriptor_.array_size = 0; + imageDescriptor_.mipmap_levels = image->getMipLevels() == 0 ? 1 : image->getMipLevels(); switch (image->getType()) { case CL_MEM_OBJECT_IMAGE1D: @@ -1440,8 +1441,31 @@ bool Image::createView(const Memory& parent) { status = Hsa::image_create(dev().getBackendDevice(), &imageDescriptor_, amdImageDesc_, deviceMemory_, permission_, &hsaImageObject_); } else { - status = Hsa::image_create(dev().getBackendDevice(), &imageDescriptor_, deviceMemory_, - permission_, &hsaImageObject_); + if (ancestor->asImage()->getMipLevels() > 1 && imageDescriptor_.mipmap_levels == 1) { + // This is on leveled image of mipmap image ancestor + amd::Memory* parentOwner = parent.owner(); + auto* ancestor_image = static_cast(ancestor->getDeviceMemory(dev())); + if (ancestor == parentOwner) { + // This is leveled image + status = Hsa::image_get_mipmap_level(dev().getBackendDevice(), + &ancestor_image->hsaImageObject_, + owner()->asImage()->getBaseMipLevel(), + nullptr, &hsaImageObject_); + } else if (ancestor == parentOwner->parent()) { + // This is format changed view on leveled image + status = Hsa::image_get_mipmap_level(dev().getBackendDevice(), + &ancestor_image->hsaImageObject_, + parentOwner->asImage()->getBaseMipLevel(), + &imageDescriptor_, &hsaImageObject_); + } else { + // This is an impossible view on leveled image + status = HSA_STATUS_ERROR_INVALID_REGION; + } + } else { + // This is a view on regular image or mipmap image. + status = Hsa::image_create(dev().getBackendDevice(), &imageDescriptor_, deviceMemory_, + permission_, &hsaImageObject_); + } } if (status != HSA_STATUS_SUCCESS) { diff --git a/projects/clr/rocclr/device/rocm/rocmemory.hpp b/projects/clr/rocclr/device/rocm/rocmemory.hpp index d6d2876000..5c9e01897c 100644 --- a/projects/clr/rocclr/device/rocm/rocmemory.hpp +++ b/projects/clr/rocclr/device/rocm/rocmemory.hpp @@ -227,7 +227,7 @@ class Image : public roc::Memory { size_t getDeviceDataAlignment() { return deviceImageInfo_.alignment; } hsa_ext_image_t getHsaImageObject() const { return hsaImageObject_; } - const hsa_ext_image_descriptor_t& getHsaImageDescriptor() const { return imageDescriptor_; } + const hsa_ext_image_descriptor_v2_t& getHsaImageDescriptor() const { return imageDescriptor_; } virtual const address cpuSrd() const { return reinterpret_cast(getHsaImageObject().handle); @@ -263,7 +263,7 @@ class Image : public roc::Memory { void populateImageDescriptor(); - hsa_ext_image_descriptor_t imageDescriptor_; + hsa_ext_image_descriptor_v2_t imageDescriptor_; hsa_access_permission_t permission_; hsa_ext_image_data_info_t deviceImageInfo_; hsa_ext_image_t hsaImageObject_; diff --git a/projects/clr/rocclr/device/rocm/rocrctx.cpp b/projects/clr/rocclr/device/rocm/rocrctx.cpp index 306993a7f7..45fdffa42f 100644 --- a/projects/clr/rocclr/device/rocm/rocrctx.cpp +++ b/projects/clr/rocclr/device/rocm/rocrctx.cpp @@ -130,14 +130,15 @@ bool Hsa::LoadLib() { GET_ROCR_SYMBOL(hsa_amd_ais_file_write) // Image extensions - GET_ROCR_SYMBOL(hsa_ext_image_data_get_info) - GET_ROCR_SYMBOL(hsa_ext_image_create) + GET_ROCR_SYMBOL(hsa_ext_image_data_get_info_v2) + GET_ROCR_SYMBOL(hsa_ext_image_create_v2) GET_ROCR_SYMBOL(hsa_ext_image_import) GET_ROCR_SYMBOL(hsa_ext_image_export) - GET_ROCR_SYMBOL(hsa_ext_image_destroy) + GET_ROCR_SYMBOL(hsa_ext_image_destroy_v2) GET_ROCR_SYMBOL(hsa_ext_sampler_create_v2) GET_ROCR_SYMBOL(hsa_ext_sampler_destroy) GET_ROCR_SYMBOL(hsa_ext_image_create_with_layout) + GET_ROCR_SYMBOL(hsa_ext_image_mipmap_array_get_level) is_ready_ = true; return true; } diff --git a/projects/clr/rocclr/device/rocm/rocrctx.hpp b/projects/clr/rocclr/device/rocm/rocrctx.hpp index e612e4eaa1..b8c5b1bf2c 100644 --- a/projects/clr/rocclr/device/rocm/rocrctx.hpp +++ b/projects/clr/rocclr/device/rocm/rocrctx.hpp @@ -138,14 +138,15 @@ struct RocrEntryPoints { decltype(hsa_amd_ais_file_read)* hsa_amd_ais_file_read_; decltype(hsa_amd_ais_file_write)* hsa_amd_ais_file_write_; // Image extensions - decltype(hsa_ext_image_data_get_info)* hsa_ext_image_data_get_info_; - decltype(hsa_ext_image_create)* hsa_ext_image_create_; + decltype(hsa_ext_image_data_get_info_v2)* hsa_ext_image_data_get_info_v2_; + decltype(hsa_ext_image_create_v2)* hsa_ext_image_create_v2_; decltype(hsa_ext_image_import)* hsa_ext_image_import_; decltype(hsa_ext_image_export)* hsa_ext_image_export_; - decltype(hsa_ext_image_destroy)* hsa_ext_image_destroy_; + decltype(hsa_ext_image_destroy_v2)* hsa_ext_image_destroy_v2_; decltype(hsa_ext_sampler_create_v2)* hsa_ext_sampler_create_v2_; decltype(hsa_ext_sampler_destroy)* hsa_ext_sampler_destroy_; decltype(hsa_ext_image_create_with_layout)* hsa_ext_image_create_with_layout_; + decltype(hsa_ext_image_mipmap_array_get_level)* hsa_ext_image_mipmap_array_get_level_; }; #ifdef ROCR_DYN_DLL @@ -523,25 +524,27 @@ class Hsa : public amd::AllStatic { // Image extensions static hsa_status_t image_create(hsa_agent_t agent, - const hsa_ext_image_descriptor_t* image_descriptor, + 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) { - return ROCR_DYN(hsa_amd_image_create)(agent, image_descriptor, image_layout, image_data, - access_permission, image); + assert(image_descriptor->mipmap_levels == 1); + return ROCR_DYN(hsa_amd_image_create)(agent, + reinterpret_cast(image_descriptor), + image_layout, image_data, access_permission, image); } static hsa_status_t image_data_get_info( - hsa_agent_t agent, const hsa_ext_image_descriptor_t* image_descriptor, + 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) { - return ROCR_DYN(hsa_ext_image_data_get_info)(agent, image_descriptor, access_permission, + return ROCR_DYN(hsa_ext_image_data_get_info_v2)(agent, image_descriptor, access_permission, image_data_info); } static hsa_status_t image_create(hsa_agent_t agent, - const hsa_ext_image_descriptor_t* image_descriptor, + const hsa_ext_image_descriptor_v2_t* image_descriptor, const void* image_data, hsa_access_permission_t access_permission, hsa_ext_image_t* image) { - return ROCR_DYN(hsa_ext_image_create)(agent, image_descriptor, image_data, + return ROCR_DYN(hsa_ext_image_create_v2)(agent, image_descriptor, image_data, access_permission, image); } static hsa_status_t image_import(hsa_agent_t agent, const void* src_memory, @@ -559,7 +562,7 @@ class Hsa : public amd::AllStatic { dst_slice_pitch, image_region); } static hsa_status_t image_destroy(hsa_agent_t agent, hsa_ext_image_t image) { - return ROCR_DYN(hsa_ext_image_destroy)(agent, image); + return ROCR_DYN(hsa_ext_image_destroy_v2)(agent, image); } static hsa_status_t sampler_create(hsa_agent_t agent, const hsa_ext_sampler_descriptor_v2_t* sampler_descriptor, hsa_ext_sampler_t* sampler) { @@ -569,14 +572,20 @@ class Hsa : public amd::AllStatic { return ROCR_DYN(hsa_ext_sampler_destroy)(agent, sampler); } static hsa_status_t image_create_with_layout( - hsa_agent_t agent, const hsa_ext_image_descriptor_t* image_descriptor, const void* image_data, + 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_data_layout_t image_data_layout, size_t image_data_row_pitch, size_t image_data_slice_pitch, hsa_ext_image_t* image) { return ROCR_DYN(hsa_ext_image_create_with_layout)( - agent, image_descriptor, image_data, access_permission, image_data_layout, + agent, reinterpret_cast(image_descriptor), + image_data, access_permission, image_data_layout, image_data_row_pitch, image_data_slice_pitch, image); } - + static hsa_status_t image_get_mipmap_level( + hsa_agent_t agent, const hsa_ext_image_t* mipmapped_array, uint32_t mip_level, + const hsa_ext_image_descriptor_v2_t* image_descriptor, hsa_ext_image_t* level_image_out) { + return ROCR_DYN(hsa_ext_image_mipmap_array_get_level)( + agent, mipmapped_array, mip_level, image_descriptor, level_image_out); + } private: static RocrEntryPoints cep_; static bool is_ready_; diff --git a/projects/clr/rocclr/device/rocm/rocsettings.cpp b/projects/clr/rocclr/device/rocm/rocsettings.cpp index 3899f2cf8b..ad1a231dbe 100644 --- a/projects/clr/rocclr/device/rocm/rocsettings.cpp +++ b/projects/clr/rocclr/device/rocm/rocsettings.cpp @@ -177,6 +177,10 @@ bool Settings::create(bool fullProfile, const amd::Isa& isa, bool enableXNACK, b gwsInitSupported_ = false; } + if (GPU_MIPMAP) { + enableExtension(ClKhrMipMapImage); + enableExtension(ClKhrMipMapImageWrites); + } // Override current device settings override(); diff --git a/projects/clr/rocclr/platform/memory.hpp b/projects/clr/rocclr/platform/memory.hpp index 4bf0d84dcb..0cfdb87b3f 100644 --- a/projects/clr/rocclr/platform/memory.hpp +++ b/projects/clr/rocclr/platform/memory.hpp @@ -660,10 +660,10 @@ class Image : public Memory { //! Returns image's slice pitch in bytes size_t getSlicePitch() const { return impl_.sp_; } - //! Returns image's slice pitch in bytes + //! Returns image's mipmap levels uint getMipLevels() const { return mipLevels_; } - //! Returns image's slice pitch in bytes + //! Returns image's mipmap base level uint getBaseMipLevel() const { return baseMipLevel_; } //! Get the image covered region diff --git a/projects/hip-tests/catch/hipTestMain/main.cc b/projects/hip-tests/catch/hipTestMain/main.cc old mode 100644 new mode 100755 diff --git a/projects/hip-tests/catch/unit/texture/CMakeLists.txt b/projects/hip-tests/catch/unit/texture/CMakeLists.txt index 7fce814ff3..e0fc67e107 100644 --- a/projects/hip-tests/catch/unit/texture/CMakeLists.txt +++ b/projects/hip-tests/catch/unit/texture/CMakeLists.txt @@ -82,6 +82,25 @@ set(NOT_FOR_gfx90a_AND_ABOVE_TEST tex2DLayered.cc tex3D.cc tex3DGrad.cc + hipBindTextureToMipmappedArray.cc + hipMallocMipmappedArray.cc + hipFreeMipmappedArray.cc + hipGetMipmappedArrayLevel.cc + hipMipmappedArrayCreate.cc + hipMipmappedArrayDestroy.cc + hipMipmappedArrayGetLevel.cc + hipTextureMipmapObj1D.cc + hipTextureMipmapObj2D.cc + hipTextureMipmapObj3D.cc + tex1DLod.cc + tex1DLayeredLod.cc + tex2DLod.cc + tex2DLayeredLod.cc + tex3DLod.cc + hipTexRefSetGetMipmapFilterMode.cc + hipTexRefSetGetMipmapLevelBias.cc + hipTexRefSetGetMipmapLevelClamp.cc + hipTexRefSetGetMipmappedArray.cc ) set(gfx90a_AND_ABOVE_TARGETS gfx90a gfx942 gfx950) @@ -125,33 +144,6 @@ else() set(TEST_SRC ${TEST_SRC} ${NOT_FOR_gfx90a_AND_ABOVE_TEST}) endif() -# Mipmap APIs are not supported on Linux -if(0) -set(TEST_SRC - ${TEST_SRC} - hipBindTextureToMipmappedArray.cc - hipMallocMipmappedArray.cc - hipFreeMipmappedArray.cc - hipGetMipmappedArrayLevel.cc - hipMipmappedArrayCreate.cc - hipMipmappedArrayDestroy.cc - hipMipmappedArrayGetLevel.cc - hipTextureMipmapObj1D.cc - hipTextureMipmapObj2D.cc - hipTextureMipmapObj3D.cc - tex1DLod.cc - tex1DLayeredLod.cc - tex2DLod.cc - tex2DLayeredLod.cc - tex3DLod.cc - hipTexRefSetGetMipmapFilterMode.cc - hipTexRefSetGetMipmapLevelBias.cc - hipTexRefSetGetMipmapLevelClamp.cc - hipTexRefSetGetMipmappedArray.cc -) -endif() - - hip_add_exe_to_target(NAME TextureTest TEST_SRC ${TEST_SRC} TEST_TARGET_NAME build_tests) diff --git a/projects/hip-tests/catch/unit/texture/hipFreeMipmappedArray.cc b/projects/hip-tests/catch/unit/texture/hipFreeMipmappedArray.cc index 6c7fc7e948..20ee62f745 100644 --- a/projects/hip-tests/catch/unit/texture/hipFreeMipmappedArray.cc +++ b/projects/hip-tests/catch/unit/texture/hipFreeMipmappedArray.cc @@ -42,11 +42,6 @@ THE SOFTWARE. TEST_CASE("Unit_hipFreeMipmappedArray_Negative_Parameters") { CHECK_IMAGE_SUPPORT; -#ifdef __linux__ - HipTest::HIP_SKIP_TEST("Mipmap APIs are not supported on Linux"); - return; -#endif //__linux__ - SECTION("array is nullptr") { HIP_CHECK_ERROR(hipFreeMipmappedArray(nullptr), hipErrorInvalidValue); } diff --git a/projects/hip-tests/catch/unit/texture/hipGetMipmappedArrayLevel.cc b/projects/hip-tests/catch/unit/texture/hipGetMipmappedArrayLevel.cc index 48a03c5573..2ec207de25 100644 --- a/projects/hip-tests/catch/unit/texture/hipGetMipmappedArrayLevel.cc +++ b/projects/hip-tests/catch/unit/texture/hipGetMipmappedArrayLevel.cc @@ -42,11 +42,6 @@ THE SOFTWARE. TEST_CASE("Unit_hipGetMipmappedArrayLevel_Negative_Parameters") { CHECK_IMAGE_SUPPORT; -#ifdef __linux__ - HipTest::HIP_SKIP_TEST("Mipmap APIs are not supported on Linux"); - return; -#endif //__linux__ - hipMipmappedArray_t array; hipChannelFormatDesc desc = hipCreateChannelDesc(); hipExtent extent = make_hipExtent(4, 4, 6); diff --git a/projects/hip-tests/catch/unit/texture/hipMallocMipmappedArray.cc b/projects/hip-tests/catch/unit/texture/hipMallocMipmappedArray.cc index 6d31afcb89..aaa38ba19a 100644 --- a/projects/hip-tests/catch/unit/texture/hipMallocMipmappedArray.cc +++ b/projects/hip-tests/catch/unit/texture/hipMallocMipmappedArray.cc @@ -42,11 +42,6 @@ THE SOFTWARE. TEST_CASE("Unit_hipMallocMipmappedArray_Negative_Parameters") { CHECK_IMAGE_SUPPORT; -#ifdef __linux__ - HipTest::HIP_SKIP_TEST("Mipmap APIs are not supported on Linux"); - return; -#endif //__linux__ - hipMipmappedArray_t array; hipChannelFormatDesc desc = hipCreateChannelDesc(); hipExtent extent = make_hipExtent(4, 4, 6); diff --git a/projects/hip-tests/catch/unit/texture/hipMipmappedArrayCreate.cc b/projects/hip-tests/catch/unit/texture/hipMipmappedArrayCreate.cc index c772313733..6b237dbaed 100644 --- a/projects/hip-tests/catch/unit/texture/hipMipmappedArrayCreate.cc +++ b/projects/hip-tests/catch/unit/texture/hipMipmappedArrayCreate.cc @@ -43,11 +43,6 @@ THE SOFTWARE. TEST_CASE("Unit_hipMipmappedArrayCreate_Negative_Parameters") { CHECK_IMAGE_SUPPORT; -#ifdef __linux__ - HipTest::HIP_SKIP_TEST("Mipmap APIs are not supported on Linux"); - return; -#endif //__linux__ - hipmipmappedArray array; HIP_ARRAY3D_DESCRIPTOR desc = {}; diff --git a/projects/hip-tests/catch/unit/texture/hipMipmappedArrayDestroy.cc b/projects/hip-tests/catch/unit/texture/hipMipmappedArrayDestroy.cc index 5f51a54d02..5a01095b75 100644 --- a/projects/hip-tests/catch/unit/texture/hipMipmappedArrayDestroy.cc +++ b/projects/hip-tests/catch/unit/texture/hipMipmappedArrayDestroy.cc @@ -43,13 +43,6 @@ THE SOFTWARE. TEST_CASE("Unit_hipMipmappedArrayDestroy_Negative_Parameters") { CHECK_IMAGE_SUPPORT; -#ifdef __linux__ - HipTest::HIP_SKIP_TEST("Mipmap APIs are not supported on Linux"); - return; -#endif //__linux__ - - HIP_CHECK(hipFree(0)); - SECTION("array is nullptr") { HIP_CHECK_ERROR(hipMipmappedArrayDestroy(nullptr), hipErrorInvalidValue); } diff --git a/projects/hip-tests/catch/unit/texture/hipMipmappedArrayGetLevel.cc b/projects/hip-tests/catch/unit/texture/hipMipmappedArrayGetLevel.cc index 01732c60a3..1f12449a1a 100644 --- a/projects/hip-tests/catch/unit/texture/hipMipmappedArrayGetLevel.cc +++ b/projects/hip-tests/catch/unit/texture/hipMipmappedArrayGetLevel.cc @@ -43,11 +43,6 @@ THE SOFTWARE. TEST_CASE("Unit_hipMipmappedArrayGetLevel_Negative_Parameters") { CHECK_IMAGE_SUPPORT; -#ifdef __linux__ - HipTest::HIP_SKIP_TEST("Mipmap APIs are not supported on Linux"); - return; -#endif //__linux__ - hipmipmappedArray array; HIP_ARRAY3D_DESCRIPTOR desc = {}; @@ -79,6 +74,7 @@ TEST_CASE("Unit_hipMipmappedArrayGetLevel_Negative_Parameters") { } HIP_CHECK(hipMipmappedArrayDestroy(array)); + (void)hipGetLastError(); } /** diff --git a/projects/hip-tests/catch/unit/texture/hipTexObjectCreate.cc b/projects/hip-tests/catch/unit/texture/hipTexObjectCreate.cc index 4ca8e5531b..c8271e4f3b 100644 --- a/projects/hip-tests/catch/unit/texture/hipTexObjectCreate.cc +++ b/projects/hip-tests/catch/unit/texture/hipTexObjectCreate.cc @@ -246,10 +246,6 @@ TEST_CASE("Unit_TexObjectCreate_TypeArray_NullptrArray") { #if 0 TEST_CASE("Unit_TexObjectCreate_TypeMipmapped") { -#if __linux__ - HipTest::HIP_SKIP_TEST("Mipmap APIs are not supported on Linux"); - return; -#endif // __linux__ CHECK_IMAGE_SUPPORT hipMipmappedArray_t mipmapped_array; @@ -277,10 +273,6 @@ TEST_CASE("Unit_TexObjectCreate_TypeMipmapped") { } TEST_CASE("Unit_TexObjectCreate_TypeMipmaped_IncompleteInit") { -#if __linux__ - HipTest::HIP_SKIP_TEST("Mipmap APIs are not supported on Linux"); - return; -#endif // __linux__ CHECK_IMAGE_SUPPORT CTX_CREATE(); diff --git a/projects/hip-tests/catch/unit/texture/hipTextureObjectTests.cc b/projects/hip-tests/catch/unit/texture/hipTextureObjectTests.cc index 944fc4f56b..9d4fa748fc 100644 --- a/projects/hip-tests/catch/unit/texture/hipTextureObjectTests.cc +++ b/projects/hip-tests/catch/unit/texture/hipTextureObjectTests.cc @@ -243,8 +243,6 @@ TEST_CASE("Unit_hipGetTextureObjectResourceViewDesc_Negative_Parameters") { hipGetTextureObjectResourceViewDesc(&check_desc, static_cast(0)), hipErrorInvalidValue); } - - HipTest::HIP_SKIP_TEST("Skipping on NVIDIA platform"); } #endif diff --git a/projects/hip-tests/catch/unit/texture/tex2DLayeredLod.cc b/projects/hip-tests/catch/unit/texture/tex2DLayeredLod.cc index 0384405e2b..7482359e65 100644 --- a/projects/hip-tests/catch/unit/texture/tex2DLayeredLod.cc +++ b/projects/hip-tests/catch/unit/texture/tex2DLayeredLod.cc @@ -161,7 +161,7 @@ TEMPLATE_TEST_CASE("Unit_tex2DLayeredLod_Positive_ReadModeNormalizedFloat", "", y = GetCoordinate(y, params.NumItersY(), params.Height(), params.num_subdivisions, params.tex_desc.normalizedCoords); auto ref_val = fixture.tex_h.Tex2DLayered(x, y, layer, params.tex_desc); - if (!fixture.Verify(fixture.out_alloc_h[i], ref_val) { + if (!fixture.Verify(fixture.out_alloc_h[i], ref_val)) { INFO("Layer: " << layer); INFO("Filtering mode: " << FilteringModeToString(params.tex_desc.filterMode)); INFO("Normalized coordinates: " << std::boolalpha << params.tex_desc.normalizedCoords); diff --git a/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/hsa_ext_interface.cpp b/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/hsa_ext_interface.cpp index 494a6307d5..459a4d28f5 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/hsa_ext_interface.cpp +++ b/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/hsa_ext_interface.cpp @@ -503,9 +503,10 @@ hsa_status_t hsa_ext_image_destroy_v2(hsa_agent_t agent, hsa_ext_image_t image) hsa_status_t hsa_ext_image_mipmap_array_get_level(hsa_agent_t agent, const hsa_ext_image_t* mipmap_array, uint32_t mip_level, + const hsa_ext_image_descriptor_v2_t* image_descriptor, hsa_ext_image_t* level_view) { return rocr::core::Runtime::runtime_singleton_->extensions_.image_api - .hsa_ext_image_mipmap_array_get_level_fn(agent, mipmap_array, mip_level, + .hsa_ext_image_mipmap_array_get_level_fn(agent, mipmap_array, mip_level, image_descriptor, level_view); } diff --git a/projects/rocr-runtime/runtime/hsa-runtime/image/hsa_ext_image.cpp b/projects/rocr-runtime/runtime/hsa-runtime/image/hsa_ext_image.cpp index 71e06bc626..433a21002f 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/image/hsa_ext_image.cpp +++ b/projects/rocr-runtime/runtime/hsa-runtime/image/hsa_ext_image.cpp @@ -266,7 +266,7 @@ hsa_status_t hsa_ext_sampler_create(hsa_agent_t agent, } hsa_ext_sampler_descriptor_v2_t sampler_descriptor_v2 = { sampler_descriptor->coordinate_mode, - sampler_descriptor->filter_mode, + sampler_descriptor->filter_mode, HSA_EXT_SAMPLER_FILTER_MODE_NONE, {sampler_descriptor->address_mode, sampler_descriptor->address_mode, sampler_descriptor->address_mode} }; @@ -566,13 +566,15 @@ hsa_status_t hsa_ext_image_destroy_v2(hsa_agent_t agent, hsa_ext_image_t image) // 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) { + const hsa_ext_image_t* mipmapped_array, + uint32_t mip_level, + const hsa_ext_image_descriptor_v2_t* image_descriptor, + 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); + return ImageRuntime::instance()->GetMipmapArrayLevelHandle(agent, *mipmapped_array, mip_level, + image_descriptor, *level_image_out); CATCH; } diff --git a/projects/rocr-runtime/runtime/hsa-runtime/image/image_manager_ai.cpp b/projects/rocr-runtime/runtime/hsa-runtime/image/image_manager_ai.cpp index 4a7a35e9cf..fc41606be0 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/image/image_manager_ai.cpp +++ b/projects/rocr-runtime/runtime/hsa-runtime/image/image_manager_ai.cpp @@ -483,7 +483,17 @@ hsa_status_t ImageManagerAi::PopulateSamplerSrd(Sampler& sampler) const { } word2.bits.XY_MIN_FILTER = word2.bits.XY_MAG_FILTER; word2.bits.Z_FILTER = SQ_TEX_Z_FILTER_NONE; - word2.bits.MIP_FILTER = SQ_TEX_MIP_FILTER_NONE; + + switch (sampler_descriptor.mipmap_filter_mode) { + case HSA_EXT_SAMPLER_FILTER_MODE_NEAREST: + word2.bits.MIP_FILTER = static_cast(SQ_TEX_MIP_FILTER_POINT); + break; + case HSA_EXT_SAMPLER_FILTER_MODE_LINEAR: + word2.bits.MIP_FILTER = static_cast(SQ_TEX_MIP_FILTER_LINEAR); + break; + default: + word2.bits.MIP_FILTER = static_cast(SQ_TEX_MIP_FILTER_NONE); + } word3.u32All = 0; @@ -999,6 +1009,8 @@ hsa_status_t ImageManagerAi::PopulateMipLevelSrd( MipmappedArray& level_view, const MipmappedArray& mipmap_array, uint32_t mip_level) const { + // Copy entire parent structure (srd is a fixed array, so it's deep-copied automatically) + level_view = mipmap_array; // SRD already copied from parent, just modify BASE_LEVEL/LAST_LEVEL fields uint32_t* srd_words = reinterpret_cast(level_view.srd); @@ -1010,7 +1022,9 @@ hsa_status_t ImageManagerAi::PopulateMipLevelSrd( word3->f.base_level = mip_level; word3->f.last_level = mip_level; - debug_print("Set SRD mip selection: BASE_LEVEL=%u, LAST_LEVEL=%u", mip_level, mip_level); + if (core::Runtime::runtime_singleton_->flag().image_print_srd()) { + debug_print("Set SRD mip selection: BASE_LEVEL=%u, LAST_LEVEL=%u", mip_level, mip_level); + } return HSA_STATUS_SUCCESS; } diff --git a/projects/rocr-runtime/runtime/hsa-runtime/image/image_manager_gfx11.cpp b/projects/rocr-runtime/runtime/hsa-runtime/image/image_manager_gfx11.cpp index bf346b40b8..a55d2a981f 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/image/image_manager_gfx11.cpp +++ b/projects/rocr-runtime/runtime/hsa-runtime/image/image_manager_gfx11.cpp @@ -601,7 +601,17 @@ hsa_status_t ImageManagerGfx11::PopulateSamplerSrd(Sampler& sampler) const { } word2.bits.XY_MIN_FILTER = word2.bits.XY_MAG_FILTER; word2.bits.Z_FILTER = SQ_TEX_Z_FILTER_NONE; - word2.bits.MIP_FILTER = SQ_TEX_MIP_FILTER_NONE; + + switch (sampler_descriptor.mipmap_filter_mode) { + case HSA_EXT_SAMPLER_FILTER_MODE_NEAREST: + word2.bits.MIP_FILTER = static_cast(SQ_TEX_MIP_FILTER_POINT); + break; + case HSA_EXT_SAMPLER_FILTER_MODE_LINEAR: + word2.bits.MIP_FILTER = static_cast(SQ_TEX_MIP_FILTER_LINEAR); + break; + default: + word2.bits.MIP_FILTER = static_cast(SQ_TEX_MIP_FILTER_NONE); + } word3.u32All = 0; @@ -924,9 +934,8 @@ hsa_status_t ImageManagerGfx11::PopulateMipmapSrd(MipmappedArray& mipmap) const // For 1d, 2d and 2d-msaa in gfx11 this is pitch-1 if (!mipmap_array && !mipmap_3d) { - word4.f.PITCH = out.pitch - 1; + word4.f.PITCH = 0; // mipmap dosesn't support custom pitch, so set it as 0 } - word5.val = 0; word6.val = 0; word7.val = 0; @@ -1199,6 +1208,8 @@ hsa_status_t ImageManagerGfx11::PopulateMipLevelSrd( MipmappedArray& level_view, const MipmappedArray& mipmap_array, uint32_t mip_level) const { + // Copy entire parent structure (srd is a fixed array, so it's deep-copied automatically) + level_view = mipmap_array; // SRD already copied from parent, just modify BASE_LEVEL/LAST_LEVEL fields uint32_t* srd_words = reinterpret_cast(level_view.srd); @@ -1210,7 +1221,9 @@ hsa_status_t ImageManagerGfx11::PopulateMipLevelSrd( word3->f.BASE_LEVEL = mip_level; word3->f.LAST_LEVEL = mip_level; - debug_print("Set SRD mip selection: BASE_LEVEL=%u, LAST_LEVEL=%u", mip_level, mip_level); + if (core::Runtime::runtime_singleton_->flag().image_print_srd()) { + debug_print("Set SRD mip selection: BASE_LEVEL=%u, LAST_LEVEL=%u", mip_level, mip_level); + } return HSA_STATUS_SUCCESS; } diff --git a/projects/rocr-runtime/runtime/hsa-runtime/image/image_manager_gfx12.cpp b/projects/rocr-runtime/runtime/hsa-runtime/image/image_manager_gfx12.cpp index 7f8480137c..43a34d8e06 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/image/image_manager_gfx12.cpp +++ b/projects/rocr-runtime/runtime/hsa-runtime/image/image_manager_gfx12.cpp @@ -637,7 +637,17 @@ hsa_status_t ImageManagerGfx12::PopulateSamplerSrd(Sampler& sampler) const { } word2.bits.XY_MIN_FILTER = word2.bits.XY_MAG_FILTER; word2.bits.Z_FILTER = SQ_TEX_Z_FILTER_NONE; - word2.bits.MIP_FILTER = SQ_TEX_MIP_FILTER_NONE; + + switch (sampler_descriptor.mipmap_filter_mode) { + case HSA_EXT_SAMPLER_FILTER_MODE_NEAREST: + word2.bits.MIP_FILTER = static_cast(SQ_TEX_MIP_FILTER_POINT); + break; + case HSA_EXT_SAMPLER_FILTER_MODE_LINEAR: + word2.bits.MIP_FILTER = static_cast(SQ_TEX_MIP_FILTER_LINEAR); + break; + default: + word2.bits.MIP_FILTER = static_cast(SQ_TEX_MIP_FILTER_NONE); + } word3.u32All = 0; @@ -1051,7 +1061,7 @@ hsa_status_t ImageManagerGfx12::PopulateMipmapSrd(MipmappedArray& mipmap) const // For 1d, 2d and 2d-msaa, fields DEPTH+PITCH_MSB encode pitch-1 if (!mipmap_array && !mipmap_3d) { - uint32_t encPitch = out.pitch - 1; + uint32_t encPitch = 0; // mipmap dosesn't support custom pitch, so set it as 0 word4.f.DEPTH = encPitch & 0x3fff; // first 14 bits word4.f.PITCH_MSB = (encPitch >> 14) & 0x3; // last 2 bits } else { @@ -1358,6 +1368,8 @@ hsa_status_t ImageManagerGfx12::PopulateMipLevelSrd( MipmappedArray& level_view, const MipmappedArray& mipmap_array, uint32_t mip_level) const { + // Copy entire parent structure (srd is a fixed array, so it's deep-copied automatically) + level_view = mipmap_array; // SRD already copied from parent, just modify BASE_LEVEL/LAST_LEVEL fields uint32_t* srd_words = reinterpret_cast(level_view.srd); @@ -1370,7 +1382,9 @@ hsa_status_t ImageManagerGfx12::PopulateMipLevelSrd( word1->f.BASE_LEVEL = mip_level; word3->f.LAST_LEVEL = mip_level; - debug_print("Set SRD mip selection: BASE_LEVEL=%u, LAST_LEVEL=%u", mip_level, mip_level); + if (core::Runtime::runtime_singleton_->flag().image_print_srd()) { + debug_print("Set SRD mip selection: BASE_LEVEL=%u, LAST_LEVEL=%u", mip_level, mip_level); + } return HSA_STATUS_SUCCESS; } diff --git a/projects/rocr-runtime/runtime/hsa-runtime/image/image_manager_nv.cpp b/projects/rocr-runtime/runtime/hsa-runtime/image/image_manager_nv.cpp index 760657c0ea..7ec2939a62 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/image/image_manager_nv.cpp +++ b/projects/rocr-runtime/runtime/hsa-runtime/image/image_manager_nv.cpp @@ -594,7 +594,17 @@ hsa_status_t ImageManagerNv::PopulateSamplerSrd(Sampler& sampler) const { } word2.bits.XY_MIN_FILTER = word2.bits.XY_MAG_FILTER; word2.bits.Z_FILTER = SQ_TEX_Z_FILTER_NONE; - word2.bits.MIP_FILTER = SQ_TEX_MIP_FILTER_NONE; + + switch (sampler_descriptor.mipmap_filter_mode) { + case HSA_EXT_SAMPLER_FILTER_MODE_NEAREST: + word2.bits.MIP_FILTER = static_cast(SQ_TEX_MIP_FILTER_POINT); + break; + case HSA_EXT_SAMPLER_FILTER_MODE_LINEAR: + word2.bits.MIP_FILTER = static_cast(SQ_TEX_MIP_FILTER_LINEAR); + break; + default: + word2.bits.MIP_FILTER = static_cast(SQ_TEX_MIP_FILTER_NONE); + } word3.u32All = 0; @@ -923,7 +933,7 @@ hsa_status_t ImageManagerNv::PopulateMipmapSrd(MipmappedArray& mipmap) const { uint32_t minor_ver = MinorVerFromDevID(chip_id_); // For 1d, 2d and 2d-msaa in gfx1030 and beyond this is pitch-1 if ((minor_ver >= 3) && !mipmap_array && !mipmap_3d) - word4.f.PITCH = out.pitch - 1; + word4.f.PITCH = 0; // mipmap dosesn't support custom pitch, so set it as 0 word5.val = 0; word5.f.MAX_MIP = mipmap.num_levels - 1; @@ -1119,6 +1129,8 @@ hsa_status_t ImageManagerNv::PopulateMipLevelSrd( MipmappedArray& level_view, const MipmappedArray& mipmap_array, uint32_t mip_level) const { + // Copy entire parent structure (srd is a fixed array, so it's deep-copied automatically) + level_view = mipmap_array; // SRD already copied from parent, just modify BASE_LEVEL/LAST_LEVEL fields uint32_t* srd_words = reinterpret_cast(level_view.srd); @@ -1130,7 +1142,9 @@ hsa_status_t ImageManagerNv::PopulateMipLevelSrd( word3->f.BASE_LEVEL = mip_level; word3->f.LAST_LEVEL = mip_level; - debug_print("Set SRD mip selection: BASE_LEVEL=%u, LAST_LEVEL=%u", mip_level, mip_level); + if (core::Runtime::runtime_singleton_->flag().image_print_srd()) { + debug_print("Set SRD mip selection: BASE_LEVEL=%u, LAST_LEVEL=%u", mip_level, mip_level); + } return HSA_STATUS_SUCCESS; } diff --git a/projects/rocr-runtime/runtime/hsa-runtime/image/image_runtime.cpp b/projects/rocr-runtime/runtime/hsa-runtime/image/image_runtime.cpp index 85e114545d..64f1500991 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/image/image_runtime.cpp +++ b/projects/rocr-runtime/runtime/hsa-runtime/image/image_runtime.cpp @@ -771,8 +771,6 @@ hsa_status_t ImageRuntime::CreateMipmapArrayHandle( mipmap_array->tile_mode = Image::TileMode::TILED; } - debug_print("Tile mode = %u (0: LINEAR, 1: TILED)", mipmap_array->tile_mode); - // Initialize the mipmapped array object mipmap_array->component = component; mipmap_array->data = const_cast(image_data); @@ -782,15 +780,18 @@ hsa_status_t ImageRuntime::CreateMipmapArrayHandle( mipmap_array->flags = 0; manager->PopulateMipmapSrd(*mipmap_array); - debug_print("Populating mipmapped array SRD..."); - if (core::Runtime::runtime_singleton_->flag().image_print_srd()) - mipmap_array->printSRD(); - - manager->printSRDDetailed(mipmap_array->srd); // assert(mipmap_array->size == required_size); image_handle.handle = mipmap_array->Convert(); - debug_print("output handle = %lu", image_handle.handle); + + if (core::Runtime::runtime_singleton_->flag().image_print_srd()) { + debug_print("Tile mode = %u (0: LINEAR, 1: TILED)", mipmap_array->tile_mode); + debug_print("Populating mipmapped array SRD..."); + mipmap_array->printSRD(); + manager->printSRDDetailed(mipmap_array->srd); + debug_print("output handle = %lu", image_handle.handle); + } + return HSA_STATUS_SUCCESS; } @@ -809,7 +810,12 @@ hsa_status_t ImageRuntime::DestroyMipmapArrayHandle( hsa_status_t ImageRuntime::GetMipmapArrayLevelHandle( hsa_agent_t component, const hsa_ext_image_t& mipmapped_array, - uint32_t mip_level, hsa_ext_image_t& level_image_out) { + uint32_t mip_level, const hsa_ext_image_descriptor_v2_t* image_descriptor, + hsa_ext_image_t& level_image_out) { + ImageManager * manager = image_manager(component); + if (!manager) { + return HSA_STATUS_ERROR_OUT_OF_RESOURCES; + } level_image_out.handle = 0; @@ -837,35 +843,42 @@ hsa_status_t ImageRuntime::GetMipmapArrayLevelHandle( return HSA_STATUS_ERROR_INVALID_ARGUMENT; } - debug_print("Creating mip level %u view for %u level mipmap\n", + if (core::Runtime::runtime_singleton_->flag().image_print_srd()) { + debug_print("Creating mip level %u view for %u level mipmap\n", mip_level, array->num_levels); + } // Create a view that references the parent mipmap array MipmappedArray* level_view = MipmappedArray::Create(component); if (!level_view) return HSA_STATUS_ERROR_OUT_OF_RESOURCES; - // Copy entire parent structure (srd is a fixed array, so it's deep-copied automatically) - *level_view = *array; - - // Modify SRD to select only the specific mip level - ImageManager* manager = image_manager(component); - if (!manager) { - MipmappedArray::Destroy(level_view); - return HSA_STATUS_ERROR_OUT_OF_RESOURCES; + auto format = image_descriptor ? &image_descriptor->format : nullptr; + if (format && + (array->desc.format.channel_type != format->channel_type || + array->desc.format.channel_order != format->channel_order)) { + MipmappedArray tempArray = *array; + tempArray.desc.format.channel_type = format->channel_type; + tempArray.desc.format.channel_order = format->channel_order; + status = manager->PopulateMipmapSrd(tempArray); + if (status == HSA_STATUS_SUCCESS) { + status = manager->PopulateMipLevelSrd(*level_view, tempArray, mip_level); + } + else { + debug_print("PopulateMipmapSrd() failed with status %d", status); + } + } + else { + status = manager->PopulateMipLevelSrd(*level_view, *array, mip_level); } - - status = manager->PopulateMipLevelSrd(*level_view, *array, mip_level); if (status != HSA_STATUS_SUCCESS) { MipmappedArray::Destroy(level_view); return status; } - debug_print("Created mip level view using SRD fields"); - if (core::Runtime::runtime_singleton_->flag().image_print_srd()) + if (core::Runtime::runtime_singleton_->flag().image_print_srd()) { level_view->printSRD(); - - manager->printSRDDetailed(level_view->srd); - + manager->printSRDDetailed(level_view->srd); + } // Return handle level_image_out.handle = level_view->Convert(); return HSA_STATUS_SUCCESS; diff --git a/projects/rocr-runtime/runtime/hsa-runtime/image/image_runtime.h b/projects/rocr-runtime/runtime/hsa-runtime/image/image_runtime.h index ba85432629..1deceb26d7 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/image/image_runtime.h +++ b/projects/rocr-runtime/runtime/hsa-runtime/image/image_runtime.h @@ -171,7 +171,8 @@ class ImageRuntime { /// @brief Get the handle for a specific mipmap level in a mipmapped array. hsa_status_t GetMipmapArrayLevelHandle( hsa_agent_t agent, const hsa_ext_image_t& mipmapped_array, - uint32_t mip_level, hsa_ext_image_t& level_image_out); + uint32_t mip_level, const hsa_ext_image_descriptor_v2_t* image_descriptor, + hsa_ext_image_t& level_image_out); ImageManager* image_manager(hsa_agent_t agent) { std::map::iterator it = image_managers_.find(agent.handle); diff --git a/projects/rocr-runtime/runtime/hsa-runtime/image/resource.h b/projects/rocr-runtime/runtime/hsa-runtime/image/resource.h index 3f1893a631..3c83894bfa 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/image/resource.h +++ b/projects/rocr-runtime/runtime/hsa-runtime/image/resource.h @@ -223,9 +223,9 @@ private: tile_mode = LINEAR; } - ~MipmappedArray() {} - public: + ~MipmappedArray() {} + /// @brief Create a MipmappedArray. /// Only internal metadata is allocated; image data must be provided by the user. static MipmappedArray* Create(hsa_agent_t agent); diff --git a/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa_ext_image.h b/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa_ext_image.h index 86b9294437..fe582a1963 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa_ext_image.h +++ b/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa_ext_image.h @@ -1053,6 +1053,7 @@ hsa_status_t HSA_API hsa_ext_image_destroy_v2(hsa_agent_t agent, hsa_ext_image_t 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, + const hsa_ext_image_descriptor_v2_t* image_descriptor, hsa_ext_image_t* level_image_out); /** @@ -1381,7 +1382,12 @@ typedef enum { * square block or 2x2x2 cube block around the specified coordinate. The * elements are combined using linear interpolation. */ - HSA_EXT_SAMPLER_FILTER_MODE_LINEAR = 1 + HSA_EXT_SAMPLER_FILTER_MODE_LINEAR = 1, + + /** + * None filter. Used for mipmap filter mode of non-mipmap images. + */ + HSA_EXT_SAMPLER_FILTER_MODE_NONE = 2 } hsa_ext_sampler_filter_mode_t; @@ -1422,10 +1428,15 @@ typedef struct hsa_ext_sampler_descriptor_v2_s { hsa_ext_sampler_coordinate_mode32_t coordinate_mode; /** - * Sampler filter type describes the type of sampling performed. + * Sampler filter type describes the type of sampling performed on regular image. */ hsa_ext_sampler_filter_mode32_t filter_mode; + /** + * Sampler filter type describes the type of sampling performed on mipmap image. + */ + hsa_ext_sampler_filter_mode32_t mipmap_filter_mode; + /** * Sampler address mode describes the processing of out-of-range image * coordinates.