1/* 2 * Copyright (C) 2020-2021 Intel Corporation 3 * 4 * SPDX-License-Identifier: MIT 5 * 6 */ 7 8#pragma once 9 10#include "shared/source/gmm_helper/gmm.h" 11#include "shared/source/gmm_helper/resource_info.h" 12#include "shared/source/helpers/string.h" 13#include "shared/source/helpers/surface_format_info.h" 14#include "shared/source/image/image_surface_state.h" 15#include "shared/source/memory_manager/allocation_properties.h" 16#include "shared/source/memory_manager/memory_manager.h" 17 18#include "level_zero/core/source/helpers/properties_parser.h" 19#include "level_zero/core/source/hw_helpers/l0_hw_helper.h" 20#include "level_zero/core/source/image/image_formats.h" 21#include "level_zero/core/source/image/image_hw.h" 22 23namespace L0 { 24 25template <GFXCORE_FAMILY gfxCoreFamily> 26ze_result_t ImageCoreFamily<gfxCoreFamily>::initialize(Device *device, const ze_image_desc_t *desc) { 27 using RENDER_SURFACE_STATE = typename GfxFamily::RENDER_SURFACE_STATE; 28 29 StructuresLookupTable lookupTable = {}; 30 31 lookupTable.areImageProperties = true; 32 lookupTable.imageProperties.imageDescriptor = convertDescriptor(*desc); 33 34 auto parseResult = prepareL0StructuresLookupTable(lookupTable, desc->pNext); 35 36 if (parseResult != ZE_RESULT_SUCCESS) { 37 return parseResult; 38 } 39 40 bool isMediaFormatLayout = isMediaFormat(desc->format.layout); 41 42 imgInfo.imgDesc = lookupTable.imageProperties.imageDescriptor; 43 44 imgInfo.surfaceFormat = &ImageFormats::formats[desc->format.layout][desc->format.type]; 45 imageFormatDesc = *const_cast<ze_image_desc_t *>(desc); 46 47 UNRECOVERABLE_IF(device == nullptr); 48 this->device = device; 49 50 if (imgInfo.surfaceFormat->GMMSurfaceFormat == GMM_FORMAT_INVALID) { 51 return ZE_RESULT_ERROR_UNSUPPORTED_IMAGE_FORMAT; 52 } 53 54 typename RENDER_SURFACE_STATE::SURFACE_TYPE surfaceType; 55 switch (desc->type) { 56 case ZE_IMAGE_TYPE_1D: 57 case ZE_IMAGE_TYPE_1DARRAY: 58 surfaceType = RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_1D; 59 break; 60 case ZE_IMAGE_TYPE_2D: 61 case ZE_IMAGE_TYPE_2DARRAY: 62 surfaceType = RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_2D; 63 break; 64 case ZE_IMAGE_TYPE_3D: 65 surfaceType = RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_3D; 66 break; 67 default: 68 return ZE_RESULT_ERROR_INVALID_ARGUMENT; 69 } 70 71 imgInfo.linearStorage = surfaceType == RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_1D; 72 imgInfo.plane = lookupTable.imageProperties.isPlanarExtension ? static_cast<GMM_YUV_PLANE>(lookupTable.imageProperties.planeIndex + 1u) : GMM_NO_PLANE; 73 imgInfo.useLocalMemory = false; 74 75 if (!isImageView) { 76 if (lookupTable.isSharedHandle) { 77 if (!lookupTable.sharedHandleType.isSupportedHandle) { 78 return ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION; 79 } 80 if (lookupTable.sharedHandleType.isDMABUFHandle) { 81 NEO::AllocationProperties properties(device->getRootDeviceIndex(), true, imgInfo, NEO::GraphicsAllocation::AllocationType::SHARED_IMAGE, device->getNEODevice()->getDeviceBitfield()); 82 allocation = device->getNEODevice()->getMemoryManager()->createGraphicsAllocationFromSharedHandle(lookupTable.sharedHandleType.fd, properties, false, false); 83 device->getNEODevice()->getMemoryManager()->closeSharedHandle(allocation); 84 } else if (lookupTable.sharedHandleType.isNTHandle) { 85 auto verifyResult = device->getNEODevice()->getMemoryManager()->verifyHandle(NEO::toOsHandle(lookupTable.sharedHandleType.ntHnadle), device->getNEODevice()->getRootDeviceIndex(), true); 86 if (!verifyResult) { 87 return ZE_RESULT_ERROR_INVALID_ARGUMENT; 88 } 89 allocation = device->getNEODevice()->getMemoryManager()->createGraphicsAllocationFromNTHandle(lookupTable.sharedHandleType.ntHnadle, device->getNEODevice()->getRootDeviceIndex(), NEO::GraphicsAllocation::AllocationType::SHARED_IMAGE); 90 } 91 } else { 92 NEO::AllocationProperties properties(device->getRootDeviceIndex(), true, imgInfo, NEO::GraphicsAllocation::AllocationType::IMAGE, device->getNEODevice()->getDeviceBitfield()); 93 94 properties.flags.preferCompressed = isSuitableForCompression(lookupTable, imgInfo); 95 96 allocation = device->getNEODevice()->getMemoryManager()->allocateGraphicsMemoryWithProperties(properties); 97 } 98 if (allocation == nullptr) { 99 return ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY; 100 } 101 } 102 103 auto gmm = this->allocation->getDefaultGmm(); 104 auto gmmHelper = static_cast<const NEO::RootDeviceEnvironment &>(device->getNEODevice()->getRootDeviceEnvironment()).getGmmHelper(); 105 106 if (gmm != nullptr) { 107 gmm->updateImgInfoAndDesc(imgInfo, 0u); 108 } 109 NEO::SurfaceOffsets surfaceOffsets = {imgInfo.offset, imgInfo.xOffset, imgInfo.yOffset, imgInfo.yOffsetForUVPlane}; 110 111 { 112 surfaceState = GfxFamily::cmdInitRenderSurfaceState; 113 114 NEO::setImageSurfaceState<GfxFamily>(&surfaceState, imgInfo, gmm, *gmmHelper, __GMM_NO_CUBE_MAP, 115 this->allocation->getGpuAddress(), surfaceOffsets, 116 isMediaFormatLayout); 117 118 NEO::setImageSurfaceStateDimensions<GfxFamily>(&surfaceState, imgInfo, __GMM_NO_CUBE_MAP, surfaceType); 119 surfaceState.setSurfaceMinLod(0u); 120 surfaceState.setMipCountLod(0u); 121 NEO::setMipTailStartLod<GfxFamily>(&surfaceState, gmm); 122 123 if (!isMediaFormatLayout) { 124 surfaceState.setShaderChannelSelectRed( 125 static_cast<const typename RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT>( 126 shaderChannelSelect[desc->format.x])); 127 surfaceState.setShaderChannelSelectGreen( 128 static_cast<const typename RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT>( 129 shaderChannelSelect[desc->format.y])); 130 surfaceState.setShaderChannelSelectBlue( 131 static_cast<const typename RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT>( 132 shaderChannelSelect[desc->format.z])); 133 surfaceState.setShaderChannelSelectAlpha( 134 static_cast<const typename RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT>( 135 shaderChannelSelect[desc->format.w])); 136 } else { 137 surfaceState.setShaderChannelSelectRed(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_RED); 138 surfaceState.setShaderChannelSelectGreen(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_GREEN); 139 surfaceState.setShaderChannelSelectBlue(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_BLUE); 140 surfaceState.setShaderChannelSelectAlpha(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_ZERO); 141 } 142 143 surfaceState.setNumberOfMultisamples(RENDER_SURFACE_STATE::NUMBER_OF_MULTISAMPLES::NUMBER_OF_MULTISAMPLES_MULTISAMPLECOUNT_1); 144 145 if (allocation->isCompressionEnabled()) { 146 NEO::EncodeSurfaceState<GfxFamily>::setImageAuxParamsForCCS(&surfaceState, gmm); 147 } 148 } 149 { 150 const uint32_t exponent = Math::log2(imgInfo.surfaceFormat->ImageElementSizeInBytes); 151 DEBUG_BREAK_IF(exponent >= 5u); 152 153 NEO::ImageInfo imgInfoRedescirebed; 154 imgInfoRedescirebed.surfaceFormat = &ImageFormats::surfaceFormatsForRedescribe[exponent % 5]; 155 imgInfoRedescirebed.imgDesc = imgInfo.imgDesc; 156 imgInfoRedescirebed.qPitch = imgInfo.qPitch; 157 redescribedSurfaceState = GfxFamily::cmdInitRenderSurfaceState; 158 159 NEO::setImageSurfaceState<GfxFamily>(&redescribedSurfaceState, imgInfoRedescirebed, gmm, *gmmHelper, 160 __GMM_NO_CUBE_MAP, this->allocation->getGpuAddress(), surfaceOffsets, 161 desc->format.layout == ZE_IMAGE_FORMAT_LAYOUT_NV12); 162 163 NEO::setImageSurfaceStateDimensions<GfxFamily>(&redescribedSurfaceState, imgInfoRedescirebed, __GMM_NO_CUBE_MAP, surfaceType); 164 redescribedSurfaceState.setSurfaceMinLod(0u); 165 redescribedSurfaceState.setMipCountLod(0u); 166 NEO::setMipTailStartLod<GfxFamily>(&redescribedSurfaceState, gmm); 167 168 if (imgInfoRedescirebed.surfaceFormat->GMMSurfaceFormat == GMM_FORMAT_R8_UINT_TYPE || 169 imgInfoRedescirebed.surfaceFormat->GMMSurfaceFormat == GMM_FORMAT_R16_UINT_TYPE || 170 imgInfoRedescirebed.surfaceFormat->GMMSurfaceFormat == GMM_FORMAT_R32_UINT_TYPE) { 171 redescribedSurfaceState.setShaderChannelSelectRed(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_RED); 172 redescribedSurfaceState.setShaderChannelSelectGreen(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_ZERO); 173 redescribedSurfaceState.setShaderChannelSelectBlue(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_ZERO); 174 } else if (imgInfoRedescirebed.surfaceFormat->GMMSurfaceFormat == GMM_FORMAT_R32G32_UINT_TYPE) { 175 redescribedSurfaceState.setShaderChannelSelectRed(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_RED); 176 redescribedSurfaceState.setShaderChannelSelectGreen(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_GREEN); 177 redescribedSurfaceState.setShaderChannelSelectBlue(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_ZERO); 178 } else { 179 redescribedSurfaceState.setShaderChannelSelectRed(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_RED); 180 redescribedSurfaceState.setShaderChannelSelectGreen(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_GREEN); 181 redescribedSurfaceState.setShaderChannelSelectBlue(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_BLUE); 182 } 183 184 redescribedSurfaceState.setNumberOfMultisamples(RENDER_SURFACE_STATE::NUMBER_OF_MULTISAMPLES::NUMBER_OF_MULTISAMPLES_MULTISAMPLECOUNT_1); 185 186 if (allocation->isCompressionEnabled()) { 187 NEO::EncodeSurfaceState<GfxFamily>::setImageAuxParamsForCCS(&redescribedSurfaceState, gmm); 188 } 189 } 190 191 return ZE_RESULT_SUCCESS; 192} 193 194template <GFXCORE_FAMILY gfxCoreFamily> 195void ImageCoreFamily<gfxCoreFamily>::copySurfaceStateToSSH(void *surfaceStateHeap, 196 const uint32_t surfaceStateOffset, 197 bool isMediaBlockArg) { 198 using GfxFamily = typename NEO::GfxFamilyMapper<gfxCoreFamily>::GfxFamily; 199 using RENDER_SURFACE_STATE = typename GfxFamily::RENDER_SURFACE_STATE; 200 201 // Copy the image's surface state into position in the provided surface state heap 202 auto destSurfaceState = ptrOffset(surfaceStateHeap, surfaceStateOffset); 203 memcpy_s(destSurfaceState, sizeof(RENDER_SURFACE_STATE), 204 &surfaceState, sizeof(RENDER_SURFACE_STATE)); 205 if (isMediaBlockArg) { 206 RENDER_SURFACE_STATE *dstRss = static_cast<RENDER_SURFACE_STATE *>(destSurfaceState); 207 uint32_t elSize = static_cast<uint32_t>(imgInfo.surfaceFormat->ImageElementSizeInBytes); 208 dstRss->setWidth(static_cast<uint32_t>((imgInfo.imgDesc.imageWidth * elSize) / sizeof(uint32_t))); 209 } 210} 211 212template <GFXCORE_FAMILY gfxCoreFamily> 213void ImageCoreFamily<gfxCoreFamily>::copyRedescribedSurfaceStateToSSH(void *surfaceStateHeap, 214 const uint32_t surfaceStateOffset) { 215 using GfxFamily = typename NEO::GfxFamilyMapper<gfxCoreFamily>::GfxFamily; 216 using RENDER_SURFACE_STATE = typename GfxFamily::RENDER_SURFACE_STATE; 217 218 // Copy the image's surface state into position in the provided surface state heap 219 auto destSurfaceState = ptrOffset(surfaceStateHeap, surfaceStateOffset); 220 memcpy_s(destSurfaceState, sizeof(RENDER_SURFACE_STATE), 221 &redescribedSurfaceState, sizeof(RENDER_SURFACE_STATE)); 222} 223 224template <GFXCORE_FAMILY gfxCoreFamily> 225bool ImageCoreFamily<gfxCoreFamily>::isSuitableForCompression(const StructuresLookupTable &structuresLookupTable, const NEO::ImageInfo &imgInfo) { 226 auto &hwInfo = device->getHwInfo(); 227 auto &l0HwHelper = L0HwHelper::get(hwInfo.platform.eRenderCoreFamily); 228 229 if (structuresLookupTable.uncompressedHint) { 230 return false; 231 } 232 233 return (l0HwHelper.imageCompressionSupported(hwInfo) && !imgInfo.linearStorage); 234} 235 236} // namespace L0 237