diff --git a/opencl/source/helpers/cl_hw_helper.h b/opencl/source/helpers/cl_hw_helper.h index e9a36e124b..1439e8ab3f 100644 --- a/opencl/source/helpers/cl_hw_helper.h +++ b/opencl/source/helpers/cl_hw_helper.h @@ -39,6 +39,8 @@ class ClHwHelper { virtual std::vector getSupportedThreadArbitrationPolicies() const = 0; virtual cl_version getDeviceIpVersion(const HardwareInfo &hwInfo) const = 0; virtual cl_device_feature_capabilities_intel getSupportedDeviceFeatureCapabilities() const = 0; + virtual bool allowImageCompression(cl_image_format format) const = 0; + virtual bool isFormatRedescribable(cl_image_format format) const = 0; protected: virtual bool hasStatelessAccessToBuffer(const KernelInfo &kernelInfo) const = 0; @@ -68,6 +70,8 @@ class ClHwHelperHw : public ClHwHelper { std::vector getSupportedThreadArbitrationPolicies() const override; cl_version getDeviceIpVersion(const HardwareInfo &hwInfo) const override; cl_device_feature_capabilities_intel getSupportedDeviceFeatureCapabilities() const override; + bool allowImageCompression(cl_image_format format) const override; + bool isFormatRedescribable(cl_image_format format) const override; protected: bool hasStatelessAccessToBuffer(const KernelInfo &kernelInfo) const override; diff --git a/opencl/source/helpers/cl_hw_helper_base.inl b/opencl/source/helpers/cl_hw_helper_base.inl index beb874c32c..3a141ec3a9 100644 --- a/opencl/source/helpers/cl_hw_helper_base.inl +++ b/opencl/source/helpers/cl_hw_helper_base.inl @@ -55,4 +55,9 @@ std::vector ClHwHelperHw::getSupportedThreadArbitrationPoli return std::vector{CL_KERNEL_EXEC_INFO_THREAD_ARBITRATION_POLICY_OLDEST_FIRST_INTEL, CL_KERNEL_EXEC_INFO_THREAD_ARBITRATION_POLICY_ROUND_ROBIN_INTEL, CL_KERNEL_EXEC_INFO_THREAD_ARBITRATION_POLICY_AFTER_DEPENDENCY_ROUND_ROBIN_INTEL}; } +template +bool ClHwHelperHw::allowImageCompression(cl_image_format format) const { + return true; +} + } // namespace NEO diff --git a/opencl/source/helpers/cl_hw_helper_bdw_and_later.inl b/opencl/source/helpers/cl_hw_helper_bdw_and_later.inl index 282bc195b8..3d7deaf659 100644 --- a/opencl/source/helpers/cl_hw_helper_bdw_and_later.inl +++ b/opencl/source/helpers/cl_hw_helper_bdw_and_later.inl @@ -6,6 +6,7 @@ */ #include "opencl/source/helpers/cl_hw_helper.h" +#include "opencl/source/helpers/surface_formats.h" namespace NEO { @@ -27,4 +28,22 @@ cl_device_feature_capabilities_intel ClHwHelperHw::getSupportedDevice return 0; } +static const std::vector redescribeFormats = { + {CL_R, CL_UNSIGNED_INT8}, + {CL_R, CL_UNSIGNED_INT16}, + {CL_R, CL_UNSIGNED_INT32}, + {CL_RG, CL_UNSIGNED_INT32}, + {CL_RGBA, CL_UNSIGNED_INT32}}; + +template +bool ClHwHelperHw::isFormatRedescribable(cl_image_format format) const { + for (const auto &referenceFormat : redescribeFormats) { + if (referenceFormat.image_channel_data_type == format.image_channel_data_type && + referenceFormat.image_channel_order == format.image_channel_order) { + return false; + } + } + + return true; +} } // namespace NEO diff --git a/opencl/source/helpers/cl_hw_helper_xehp_and_later.inl b/opencl/source/helpers/cl_hw_helper_xehp_and_later.inl index e382cc2d25..85f116d703 100644 --- a/opencl/source/helpers/cl_hw_helper_xehp_and_later.inl +++ b/opencl/source/helpers/cl_hw_helper_xehp_and_later.inl @@ -26,4 +26,8 @@ cl_device_feature_capabilities_intel ClHwHelperHw::getSupportedDevice return ClDeviceHelper::getExtraCapabilities(); } +template +bool ClHwHelperHw::isFormatRedescribable(cl_image_format format) const { + return false; +} } // namespace NEO diff --git a/opencl/source/helpers/surface_formats.cpp b/opencl/source/helpers/surface_formats.cpp index 66f80e1404..941d7c33a1 100644 --- a/opencl/source/helpers/surface_formats.cpp +++ b/opencl/source/helpers/surface_formats.cpp @@ -75,12 +75,12 @@ namespace NEO { {{CL_sBGRA, CL_UNORM_INT8}, {GMM_FORMAT_B8G8R8A8_UNORM_SRGB_TYPE, GFX3DSTATE_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB , 0, 4, 1, 4}} #define DEPTHFORMATS \ - {{ CL_DEPTH, CL_FLOAT}, {GMM_FORMAT_R32_FLOAT_TYPE, GFX3DSTATE_SURFACEFORMAT_R32_FLOAT , 0, 1, 4, 4}}, \ - {{ CL_DEPTH, CL_UNORM_INT16}, {GMM_FORMAT_R16_UNORM_TYPE, GFX3DSTATE_SURFACEFORMAT_R16_UNORM , 0, 1, 2, 2}} + {{ CL_DEPTH, CL_FLOAT}, {GMM_FORMAT_R32_FLOAT_TYPE, GFX3DSTATE_SURFACEFORMAT_R32_FLOAT , 0, 1, 4, 4}}, \ + {{ CL_DEPTH, CL_UNORM_INT16}, {GMM_FORMAT_R16_UNORM_TYPE, GFX3DSTATE_SURFACEFORMAT_R16_UNORM , 0, 1, 2, 2}} #define DEPTHSTENCILFORMATS \ - {{ CL_DEPTH_STENCIL, CL_UNORM_INT24}, {GMM_FORMAT_GENERIC_32BIT, GFX3DSTATE_SURFACEFORMAT_R24_UNORM_X8_TYPELESS , 0, 1, 4, 4}}, \ - {{ CL_DEPTH_STENCIL, CL_FLOAT}, {GMM_FORMAT_R32G32_FLOAT_TYPE, GFX3DSTATE_SURFACEFORMAT_R32_FLOAT_X8X24_TYPELESS, 0, 2, 4, 8}} + {{ CL_DEPTH_STENCIL, CL_UNORM_INT24}, {GMM_FORMAT_GENERIC_32BIT, GFX3DSTATE_SURFACEFORMAT_R24_UNORM_X8_TYPELESS , 0, 1, 4, 4}}, \ + {{ CL_DEPTH_STENCIL, CL_FLOAT}, {GMM_FORMAT_R32G32_FLOAT_TYPE, GFX3DSTATE_SURFACEFORMAT_R32_FLOAT_X8X24_TYPELESS, 0, 2, 4, 8}} //Initialize this with the required formats first. //Append the optional one later @@ -100,12 +100,12 @@ const ClSurfaceFormatInfo SurfaceFormats::packedYuvSurfaceFormats[] = { }; const ClSurfaceFormatInfo SurfaceFormats::planarYuvSurfaceFormats[] = { - {{CL_NV12_INTEL, CL_UNORM_INT8}, {GMM_FORMAT_NV12, GFX3DSTATE_SURFACEFORMAT_PLANAR_420_8 , 0, 1, 1, 1}} + {{CL_NV12_INTEL, CL_UNORM_INT8}, {GMM_FORMAT_NV12, GFX3DSTATE_SURFACEFORMAT_PLANAR_420_8 , 0, 1, 1, 1}} }; const ClSurfaceFormatInfo SurfaceFormats::packedSurfaceFormats[] = { - {{CL_RGBA, CL_UNORM_INT16}, {GMM_FORMAT_Y210, GFX3DSTATE_SURFACEFORMAT_R16G16B16A16_UNORM , 0, 4, 2, 8}}, - {{CL_RG, CL_UNORM_INT16}, {GMM_FORMAT_YUY2_2x1, GFX3DSTATE_SURFACEFORMAT_R10G10B10A2_UNORM , 0, 2, 2, 4}} + {{CL_RGBA, CL_UNORM_INT16}, {GMM_FORMAT_Y210, GFX3DSTATE_SURFACEFORMAT_R16G16B16A16_UNORM , 0, 4, 2, 8}}, + {{CL_RG, CL_UNORM_INT16}, {GMM_FORMAT_YUY2_2x1, GFX3DSTATE_SURFACEFORMAT_R10G10B10A2_UNORM , 0, 2, 2, 4}} }; const ClSurfaceFormatInfo SurfaceFormats::readOnlyDepthSurfaceFormats[] = { DEPTHFORMATS, DEPTHSTENCILFORMATS }; diff --git a/opencl/source/mem_obj/image.cpp b/opencl/source/mem_obj/image.cpp index 556c1b7fa2..611fc1695c 100644 --- a/opencl/source/mem_obj/image.cpp +++ b/opencl/source/mem_obj/image.cpp @@ -23,6 +23,7 @@ #include "opencl/source/cl_device/cl_device_get_cap.inl" #include "opencl/source/command_queue/command_queue.h" #include "opencl/source/context/context.h" +#include "opencl/source/helpers/cl_hw_helper.h" #include "opencl/source/helpers/cl_memory_properties_helpers.h" #include "opencl/source/helpers/get_info_status_mapper.h" #include "opencl/source/helpers/gmm_types_converter.h" @@ -196,11 +197,13 @@ Image *Image::create(Context *context, auto hostPtrRowPitch = imageDesc->image_row_pitch ? imageDesc->image_row_pitch : imageWidth * surfaceFormat->surfaceFormat.ImageElementSizeInBytes; auto hostPtrSlicePitch = imageDesc->image_slice_pitch ? imageDesc->image_slice_pitch : hostPtrRowPitch * imageHeight; + auto &clHwHelper = ClHwHelper::get(context->getDevice(0)->getHardwareInfo().platform.eRenderCoreFamily); imgInfo.linearStorage = !defaultHwHelper.tilingAllowed(context->isSharedContext, Image::isImage1d(*imageDesc), memoryProperties.flags.forceLinearStorage); imgInfo.preferRenderCompression = MemObjHelper::isSuitableForRenderCompression(!imgInfo.linearStorage, memoryProperties, *context, true); - imgInfo.preferRenderCompression &= !Image::isFormatRedescribable(surfaceFormat->OCLImageFormat); + imgInfo.preferRenderCompression &= clHwHelper.allowImageCompression(surfaceFormat->OCLImageFormat); + imgInfo.preferRenderCompression &= !clHwHelper.isFormatRedescribable(surfaceFormat->OCLImageFormat); if (!context->getDevice(0)->getSharedDeviceInfo().imageSupport && !imgInfo.linearStorage) { errcodeRet = CL_INVALID_OPERATION; @@ -1001,19 +1004,6 @@ static const uint32_t redescribeTableBytes[] = { 7 // {CL_RGBA, CL_UNSIGNED_INT32} 16 byte }; -bool Image::isFormatRedescribable(cl_image_format format) { - const ArrayRef readWriteSurfaceFormats = SurfaceFormats::readWrite(); - for (auto indexInRedescribeTable = 0u; indexInRedescribeTable < sizeof(redescribeTableBytes) / sizeof(uint32_t); indexInRedescribeTable++) { - const uint32_t formatIndex = redescribeTableBytes[indexInRedescribeTable]; - const cl_image_format nonRedescribableFormat = readWriteSurfaceFormats[formatIndex].OCLImageFormat; - if (nonRedescribableFormat.image_channel_data_type == format.image_channel_data_type && - nonRedescribableFormat.image_channel_order == format.image_channel_order) { - return false; - } - } - return true; -} - Image *Image::redescribe() { const uint32_t bytesPerPixel = this->surfaceFormatInfo.surfaceFormat.NumChannels * surfaceFormatInfo.surfaceFormat.PerChannelSizeInBytes; const uint32_t exponent = Math::log2(bytesPerPixel); diff --git a/opencl/source/mem_obj/image.h b/opencl/source/mem_obj/image.h index ce1a875f6c..f183a3d445 100644 --- a/opencl/source/mem_obj/image.h +++ b/opencl/source/mem_obj/image.h @@ -147,7 +147,6 @@ class Image : public MemObj { void transferDataToHostPtr(MemObjSizeArray ©Size, MemObjOffsetArray ©Offset) override; void transferDataFromHostPtr(MemObjSizeArray ©Size, MemObjOffsetArray ©Offset) override; - static bool isFormatRedescribable(cl_image_format format); Image *redescribe(); Image *redescribeFillImage(); ImageCreatFunc createFunction; diff --git a/opencl/test/unit_test/helpers/hw_helper_tests.cpp b/opencl/test/unit_test/helpers/hw_helper_tests.cpp index ed6d1d94c2..7caa3b8a18 100644 --- a/opencl/test/unit_test/helpers/hw_helper_tests.cpp +++ b/opencl/test/unit_test/helpers/hw_helper_tests.cpp @@ -1320,3 +1320,25 @@ HWTEST_F(HwHelperTest, givenGetRenderSurfaceStateBaseAddressCalledThenCorrectVal const auto &hwHelper = HwHelper::get(renderCoreFamily); EXPECT_EQ(expectedBaseAddress, hwHelper.getRenderSurfaceStateBaseAddress(&renderSurfaceState)); } + +HWCMDTEST_F(IGFX_GEN8_CORE, HwHelperTest, givenCLImageFormatsWhenCallingIsFormatRedescribableThenCorrectValueReturned) { + static const cl_image_format redescribeFormats[] = { + {CL_R, CL_UNSIGNED_INT8}, + {CL_R, CL_UNSIGNED_INT16}, + {CL_R, CL_UNSIGNED_INT32}, + {CL_RG, CL_UNSIGNED_INT32}, + {CL_RGBA, CL_UNSIGNED_INT32}, + }; + MockContext context; + auto &clHwHelper = ClHwHelper::get(context.getDevice(0)->getHardwareInfo().platform.eRenderCoreFamily); + + const ArrayRef formats = SurfaceFormats::readWrite(); + for (const auto &format : formats) { + const cl_image_format oclFormat = format.OCLImageFormat; + bool expectedResult = true; + for (const auto &nonRedescribableFormat : redescribeFormats) { + expectedResult &= (memcmp(&oclFormat, &nonRedescribableFormat, sizeof(cl_image_format)) != 0); + } + EXPECT_EQ(expectedResult, clHwHelper.isFormatRedescribable(oclFormat)); + } +} diff --git a/opencl/test/unit_test/helpers/hw_helper_tests_xehp_and_later.cpp b/opencl/test/unit_test/helpers/hw_helper_tests_xehp_and_later.cpp index 5a8f58fe79..99dabf3367 100644 --- a/opencl/test/unit_test/helpers/hw_helper_tests_xehp_and_later.cpp +++ b/opencl/test/unit_test/helpers/hw_helper_tests_xehp_and_later.cpp @@ -16,8 +16,10 @@ #include "shared/test/common/helpers/unit_test_helper.h" #include "opencl/source/command_queue/gpgpu_walker.h" +#include "opencl/source/helpers/cl_hw_helper.h" #include "opencl/source/helpers/hardware_commands_helper.h" #include "opencl/test/unit_test/fixtures/cl_device_fixture.h" +#include "opencl/test/unit_test/mocks/mock_context.h" #include "engine_node.h" #include "pipe_control_args.h" @@ -448,3 +450,19 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, HwInfoConfigTestXeHpAndLater, givenXeHPAndLaterPlat EXPECT_FALSE(hwInfoConfig.isTile64With3DSurfaceOnBCSSupported(hwInfo)); } + +HWCMDTEST_F(IGFX_XE_HP_CORE, HwInfoConfigTestXeHpAndLater, givenCLImageFormatsWhenCallingIsFormatRedescribableThenFalseIsReturned) { + static const cl_image_format redescribeFormats[] = { + {CL_R, CL_UNSIGNED_INT8}, + {CL_R, CL_UNSIGNED_INT16}, + {CL_R, CL_UNSIGNED_INT32}, + {CL_RG, CL_UNSIGNED_INT32}, + {CL_RGBA, CL_UNSIGNED_INT32}, + }; + MockContext context; + auto &clHwHelper = ClHwHelper::get(context.getDevice(0)->getHardwareInfo().platform.eRenderCoreFamily); + + for (const auto &format : redescribeFormats) { + EXPECT_EQ(false, clHwHelper.isFormatRedescribable(format)); + } +} diff --git a/opencl/test/unit_test/mem_obj/image_tests.cpp b/opencl/test/unit_test/mem_obj/image_tests.cpp index 90b035e6d5..98e3d49c56 100644 --- a/opencl/test/unit_test/mem_obj/image_tests.cpp +++ b/opencl/test/unit_test/mem_obj/image_tests.cpp @@ -657,26 +657,6 @@ TEST(TestCreateImageUseHostPtr, givenZeroCopyImageValuesWhenUsingHostPtrThenZero alignedFree(hostPtr); } -TEST(TestRedescribableFormatCheck, givenVariousOclFormatsWhenCheckingIfRedescribableThenReturnCorrectResults) { - static const cl_image_format redescribeFormats[] = { - {CL_R, CL_UNSIGNED_INT8}, - {CL_R, CL_UNSIGNED_INT16}, - {CL_R, CL_UNSIGNED_INT32}, - {CL_RG, CL_UNSIGNED_INT32}, - {CL_RGBA, CL_UNSIGNED_INT32}, - }; - - const ArrayRef formats = SurfaceFormats::readWrite(); - for (const auto &format : formats) { - const cl_image_format oclFormat = format.OCLImageFormat; - bool expectedResult = true; - for (const auto &nonRedescribableFormat : redescribeFormats) { - expectedResult &= (memcmp(&oclFormat, &nonRedescribableFormat, sizeof(cl_image_format)) != 0); - } - EXPECT_EQ(expectedResult, Image::isFormatRedescribable(oclFormat)); - } -} - TEST_P(CreateImageNoHostPtr, GivenMissingPitchWhenImageIsCreatedThenConstructorFillsMissingData) { auto image = createImageWithFlags(flags); diff --git a/opencl/test/unit_test/mem_obj/image_tests_xehp_and_later.cpp b/opencl/test/unit_test/mem_obj/image_tests_xehp_and_later.cpp index 9f285ec253..31338541ce 100644 --- a/opencl/test/unit_test/mem_obj/image_tests_xehp_and_later.cpp +++ b/opencl/test/unit_test/mem_obj/image_tests_xehp_and_later.cpp @@ -17,6 +17,7 @@ #include "shared/test/common/mocks/mock_gmm_client_context.h" #include "opencl/test/unit_test/fixtures/image_fixture.h" +#include "opencl/test/unit_test/mem_obj/image_compression_fixture.h" #include "opencl/test/unit_test/mocks/mock_context.h" #include "opencl/test/unit_test/mocks/mock_platform.h" #include "test.h" @@ -684,3 +685,27 @@ HWTEST2_F(XeHPAndLaterImageHelperTests, givenAuxModeMcsLceWhenAppendingSurfaceSt EXPECT_EQ(expectedGetSurfaceStateCompressionFormatCalled, gmmClientContext->getSurfaceStateCompressionFormatCalled); EXPECT_EQ(expectedGetMediaSurfaceStateCompressionFormatCalled, gmmClientContext->getMediaSurfaceStateCompressionFormatCalled); } + +HWTEST2_F(ImageCompressionTests, givenXeHpCoreAndRedescribableFormatWhenCreatingAllocationThenDoNotPreferRenderCompression, IsXeHpCore) { + MockContext context{}; + imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D; + imageDesc.image_width = 5; + imageDesc.image_height = 5; + + auto surfaceFormat = Image::getSurfaceFormatFromTable( + flags, &imageFormat, context.getDevice(0)->getHardwareInfo().capabilityTable.supportsOcl21Features); + auto image = std::unique_ptr(Image::create( + mockContext.get(), ClMemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context.getDevice(0)->getDevice()), + flags, 0, surfaceFormat, &imageDesc, nullptr, retVal)); + ASSERT_NE(nullptr, image); + EXPECT_EQ(UnitTestHelper::tiledImagesSupported, myMemoryManager->capturedImgInfo.preferRenderCompression); + + imageFormat.image_channel_order = CL_RG; + surfaceFormat = Image::getSurfaceFormatFromTable( + flags, &imageFormat, context.getDevice(0)->getHardwareInfo().capabilityTable.supportsOcl21Features); + image = std::unique_ptr(Image::create( + mockContext.get(), ClMemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context.getDevice(0)->getDevice()), + flags, 0, surfaceFormat, &imageDesc, nullptr, retVal)); + ASSERT_NE(nullptr, image); + EXPECT_TRUE(myMemoryManager->capturedImgInfo.preferRenderCompression); +}