1 /*============================================================================== 2 Copyright(c) 2019 Intel Corporation 3 4 Permission is hereby granted, free of charge, to any person obtaining a 5 copy of this software and associated documentation files(the "Software"), 6 to deal in the Software without restriction, including without limitation 7 the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 and / or sell copies of the Software, and to permit persons to whom the 9 Software is furnished to do so, subject to the following conditions: 10 11 The above copyright notice and this permission notice shall be included 12 in all copies or substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 OTHER DEALINGS IN THE SOFTWARE. 21 ============================================================================*/ 22 23 #pragma once 24 25 #if defined (__linux__) && !defined(__i386__) 26 27 #ifndef _ISOC11_SOURCE 28 #define _ISOC11_SOURCE 1 29 #endif 30 31 #include "GmmGen10ResourceULT.h" 32 #include <stdlib.h> 33 #include <malloc.h> 34 35 #ifndef ALIGN 36 #define ALIGN(v, a) (((v) + ((a)-1)) & ~((a)-1)) 37 #endif 38 39 class CTestAuxTable : public CTestGen10Resource 40 { 41 42 public: 43 static void SetUpTestCase(); 44 static void TearDownTestCase(); 45 46 CTestAuxTable(); 47 ~CTestAuxTable(); 48 49 static int allocCB(void *bufMgr, size_t size, size_t alignment, void **bo, void **cpuAddr, uint64_t *gpuAddr); 50 static void freeCB(void *bo); 51 static void waitFromCpuCB(void *bo); 52 53 class Surface 54 { 55 public: 56 Surface(unsigned int width, unsigned int height, bool mmc = true) mWidth(width)57 : mWidth(width), mHeight(height), mMMC(mmc), mResInfo(0), mBuf(0) 58 { 59 } 60 ~Surface()61 ~Surface() 62 { 63 deinit(); 64 } 65 init()66 bool init() 67 { 68 size_t size; 69 size_t alignment; 70 71 GMM_RESCREATE_PARAMS gmmParams = {}; 72 gmmParams.Type = RESOURCE_2D; 73 gmmParams.Format = GMM_FORMAT_NV12; 74 gmmParams.BaseWidth = mWidth; 75 gmmParams.BaseHeight = mHeight; 76 gmmParams.Depth = 0x1; 77 gmmParams.ArraySize = 1; 78 gmmParams.Flags.Info.TiledY = 1; 79 gmmParams.Flags.Info.MediaCompressed = mMMC ? 1 : 0; 80 //gmmParams.Flags.Gpu.CCS = mmc ? 1 : 0; 81 gmmParams.Flags.Gpu.MMC = mMMC ? 1 : 0; 82 gmmParams.Flags.Gpu.Texture = 1; 83 gmmParams.Flags.Gpu.RenderTarget = 1; 84 gmmParams.Flags.Gpu.UnifiedAuxSurface = mMMC ? 1 : 0; 85 //gmmParams.Flags.Gpu.Depth = 1; 86 gmmParams.Flags.Gpu.Video = true; 87 88 mResInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams); 89 90 size = mResInfo->GetSizeSurface(); 91 92 alignment = mResInfo->GetResFlags().Info.TiledYf ? GMM_KBYTE(16) : GMM_KBYTE(64); 93 94 mBuf = aligned_alloc(alignment, ALIGN(size, alignment)); 95 96 if(!mResInfo || !mBuf) 97 return false; 98 99 mYBase = (GMM_GFX_ADDRESS)mBuf; 100 mUVBase = 0; 101 mAuxYBase = mYBase + mResInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_CCS); 102 mAuxUVBase = 0; 103 mYPlaneSize = mResInfo->GetSizeMainSurface(); 104 105 if(pGmmULTClientContext->IsPlanar(mResInfo->GetResourceFormat())) 106 { 107 GMM_REQ_OFFSET_INFO ReqInfo = {0}; 108 ReqInfo.Plane = GMM_PLANE_U; 109 ReqInfo.ReqRender = 1; 110 111 mResInfo->GetOffset(ReqInfo); 112 mYPlaneSize = ReqInfo.Render.Offset64; 113 114 mUVBase = mYBase + mYPlaneSize; 115 mAuxUVBase = mYBase + mResInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_UV_CCS); 116 } 117 118 mUVPlaneSize = mResInfo->GetSizeMainSurface() - mYPlaneSize; 119 120 return true; 121 } 122 deinit()123 void deinit() 124 { 125 if(mBuf) 126 { 127 free(mBuf); 128 mBuf = NULL; 129 } 130 131 if(mResInfo) 132 { 133 pGmmULTClientContext->DestroyResInfoObject(mResInfo); 134 mResInfo = NULL; 135 } 136 } 137 getGfxAddress(GMM_YUV_PLANE plane)138 GMM_GFX_ADDRESS getGfxAddress(GMM_YUV_PLANE plane) 139 { 140 switch(plane) 141 { 142 case GMM_PLANE_Y: 143 return mYBase; 144 case GMM_PLANE_U: 145 case GMM_PLANE_V: 146 return mUVBase; 147 default: 148 throw; 149 } 150 } 151 getAuxGfxAddress(GMM_UNIFIED_AUX_TYPE auxType)152 GMM_GFX_ADDRESS getAuxGfxAddress(GMM_UNIFIED_AUX_TYPE auxType) 153 { 154 switch(auxType) 155 { 156 case GMM_AUX_CCS: 157 case GMM_AUX_Y_CCS: 158 return mAuxYBase; 159 case GMM_AUX_UV_CCS: 160 return mAuxUVBase; 161 default: 162 throw; 163 } 164 } 165 getGMMResourceInfo()166 GMM_RESOURCE_INFO *getGMMResourceInfo() 167 { 168 return mResInfo; 169 } 170 getSurfaceSize(GMM_YUV_PLANE plane)171 size_t getSurfaceSize(GMM_YUV_PLANE plane) 172 { 173 switch(plane) 174 { 175 case GMM_PLANE_Y: 176 return mYPlaneSize; 177 case GMM_PLANE_U: 178 case GMM_PLANE_V: 179 return mUVPlaneSize; 180 default: 181 throw; 182 } 183 } 184 185 private: 186 unsigned int mWidth; 187 unsigned int mHeight; 188 bool mMMC; 189 GMM_RESOURCE_INFO *mResInfo; 190 void * mBuf; 191 GMM_GFX_ADDRESS mYBase; 192 GMM_GFX_ADDRESS mUVBase; 193 GMM_GFX_ADDRESS mAuxYBase; 194 GMM_GFX_ADDRESS mAuxUVBase; 195 size_t mYPlaneSize; 196 size_t mUVPlaneSize; 197 }; 198 199 class Walker 200 { 201 public: Walker(GMM_GFX_ADDRESS mainBase,GMM_GFX_ADDRESS auxBase,GMM_GFX_ADDRESS l3Base)202 Walker(GMM_GFX_ADDRESS mainBase, GMM_GFX_ADDRESS auxBase, 203 GMM_GFX_ADDRESS l3Base) 204 { 205 mMainBase = mainBase; 206 mAuxBase = (auxBase >> 6) << 6; 207 mL3Base = (uint64_t *)l3Base; 208 } 209 expected(GMM_GFX_ADDRESS addr)210 GMM_GFX_ADDRESS expected(GMM_GFX_ADDRESS addr) 211 { 212 uint8_t Is64KChunk = (const_cast<WA_TABLE &>(pGfxAdapterInfo->WaTable).WaAuxTable16KGranular) ? 0 : 1; 213 uint32_t count = (addr - mMainBase) / (Is64KChunk ? GMM_KBYTE(64) : GMM_KBYTE(16)); 214 return mAuxBase + (Is64KChunk ? 256 : 64) * count; 215 } 216 walk(GMM_GFX_ADDRESS addr)217 GMM_GFX_ADDRESS walk(GMM_GFX_ADDRESS addr) 218 { 219 uint64_t mask = (const_cast<WA_TABLE &>(pGfxAdapterInfo->WaTable).WaAuxTable16KGranular) ? 0x0000ffffffffffc0 : 0x0000ffffffffff00; 220 uint32_t idx = l3Index(addr); 221 uint64_t *l2Base = (uint64_t *)((mL3Base[idx] >> 15) << 15); 222 idx = l2Index(addr); 223 uint64_t *l1Base = (uint64_t *)((l2Base[idx] >> 13) << 13); 224 idx = l1Index(addr); 225 uint64_t auxAddr = (uint64_t)(l1Base[idx] & mask); 226 return auxAddr; 227 } 228 229 public: l3Index(GMM_GFX_ADDRESS addr)230 static inline uint32_t l3Index(GMM_GFX_ADDRESS addr) 231 { 232 return GMM_AUX_L3_ENTRY_IDX(addr); 233 } 234 l2Index(GMM_GFX_ADDRESS addr)235 static inline uint32_t l2Index(GMM_GFX_ADDRESS addr) 236 { 237 return GMM_AUX_L2_ENTRY_IDX(addr); 238 } 239 l1Index(GMM_GFX_ADDRESS addr)240 static inline uint32_t l1Index(GMM_GFX_ADDRESS addr) 241 { 242 return GMM_AUX_L1_ENTRY_IDX_EXPORTED_2(addr, (const_cast<WA_TABLE &>(pGfxAdapterInfo->WaTable).WaAuxTable64KGranular), (const_cast<WA_TABLE &>(pGfxAdapterInfo->WaTable).WaAuxTable16KGranular)); 243 } 244 245 private: 246 GMM_GFX_ADDRESS mMainBase; 247 GMM_GFX_ADDRESS mAuxBase; 248 uint64_t * mL3Base; 249 }; 250 }; 251 252 #endif /* __linux__ */ 253