1 /* 2 * Copyright (c) 2017, 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 //! \file cm_mov_inst.h 24 //! \brief Contains Class MovInst_RT definitions 25 //! 26 27 #ifndef MEDIADRIVER_AGNOSTIC_COMMON_CM_CMMOVINST_H_ 28 #define MEDIADRIVER_AGNOSTIC_COMMON_CM_CMMOVINST_H_ 29 30 #include "cm_array.h" 31 #include "cm_mem.h" 32 33 // A simple implementation that encodes a mov instruction in align1 mode. 34 // Both operands must be direct GRF with no modifiers. 35 // predication is disabled, and all instruction control fields have default value. 36 // The format of the mov instruction should be identical for SNB/IVB/HSW 37 class MovInst_RT 38 { 39 40 #define GENX_GRF_BYTE_SIZE 32 41 42 uint32_t m_instructions[4]; //4 DWORDS per inst 43 bool m_isBdw; 44 public: 45 GetBinary()46 void* GetBinary() { return m_instructions; } EnableDebug()47 void EnableDebug(){SetBits( 30, 30, 0x1);} // DbgCtrl; ClearDebug()48 void ClearDebug(){SetBits( 30, 30, 0x0);} // DbgCtrl; 49 50 typedef enum { 51 REG_ARF = 0x0, 52 REG_GRF = 0x1, 53 REG_MRF = 0x2, 54 REG_IMM = 0x3 55 } Genx_Reg_File; 56 57 typedef enum { 58 EXEC_SIZE_1 = 0x0, 59 EXEC_SIZE_2 = 0x1, 60 EXEC_SIZE_4 = 0x2, 61 EXEC_SIZE_8 = 0x3, 62 EXEC_SIZE_16 = 0x4, 63 EXEC_SIZE_32 = 0x5, 64 EXEC_SIZE_ILLEGAL = 0x6 65 } Genx_Exec_Size; 66 67 typedef enum { 68 REG_TYPE_UD = 0x0, 69 REG_TYPE_D = 0x1, 70 REG_TYPE_UW = 0x2, 71 REG_TYPE_W = 0x3, 72 REG_TYPE_UB = 0x4, 73 REG_TYPE_B = 0x5, 74 REG_TYPE_DF = 0x6, 75 REG_TYPE_F = 0x7, 76 } Genx_Reg_Type; 77 78 typedef enum { 79 VS_0 = 0x0, 80 VS_1 = 0x1, 81 VS_2 = 0x2, 82 VS_4 = 0x3, 83 VS_8 = 0x4, 84 VS_16 = 0x5, 85 VS_32 = 0x6 86 } Genx_VStride; 87 88 typedef enum { 89 W_1 = 0x0, 90 W_2 = 0x1, 91 W_4 = 0x2, 92 W_8 = 0x3, 93 W_16 = 0x4 94 } Genx_Width; 95 96 typedef enum { 97 HS_0 = 0x0, 98 HS_1 = 0x1, 99 HS_2 = 0x2, 100 HS_4 = 0x3 101 } Genx_HStride; 102 MovInst_RT(bool isBdw,bool isHwDebug)103 MovInst_RT(bool isBdw, bool isHwDebug) { 104 // initialize the instruction to 105 // mov (8) r0.0<1>:ud r0.0<8;8,1>:ud {Align1} 106 for( int i = 0; i < 4; i++ ) { 107 m_instructions[i] = 0; 108 } 109 m_isBdw = isBdw; 110 SetBits( 0, 6, 0x1); //opcode = move 111 if(isHwDebug) { 112 EnableDebug(); 113 } // DbgCtrl 114 SetBits( 8, 8, 0); //align mode = align1 115 SetExecSize( EXEC_SIZE_8 ); //exec size = 8 116 SetDstRegFile( REG_GRF ); //dst reg file = GRF 117 SetDstType( REG_TYPE_UD ); //dst type = UD 118 SetSrcRegFile( REG_GRF ); //src0 reg file = GRF 119 SetSrcType( REG_TYPE_UD ); //src0 type = UD 120 SetDstRegNum( 0 ); //dst reg = 0 121 SetDstSubregNum( 0 ); //dst subreg = 0 122 SetDstRegion( HS_1 ); //dst region = <1> 123 SetSrcRegNum( 0 ); //src reg = 0 124 SetSrcSubregNum( 0 ); //src subreg = 0 125 SetSrcRegion( VS_8, W_8, HS_1 ); //src region = <8;8,1> 126 } 127 GetTypeSize(Genx_Reg_Type type)128 static uint32_t GetTypeSize( Genx_Reg_Type type ) { 129 switch( type ) { 130 case REG_TYPE_UD: 131 case REG_TYPE_D: 132 case REG_TYPE_F: 133 case REG_TYPE_DF: 134 return 4; 135 case REG_TYPE_UW: 136 case REG_TYPE_W: 137 return 2; 138 case REG_TYPE_UB: 139 case REG_TYPE_B: 140 return 1; 141 default: 142 CM_ASSERTMESSAGE("Error: Invalid register data type."); 143 return 1; 144 } 145 } 146 147 // Create a sequence of Gen move instructions to copy <size> byte data 148 // from srcOffset to dstOffset. The move instructions are appended 149 // to the <movInsts> vector starting at the given <index>. The 150 // function returns the total number of move instructions created CreateMoves(uint32_t dstOffset,uint32_t srcOffset,uint32_t size,CMRT_UMD::CmDynamicArray & movInsts,uint32_t index,bool isBdw,bool isHwDebug)151 static uint32_t CreateMoves( uint32_t dstOffset, uint32_t srcOffset, uint32_t size, 152 CMRT_UMD::CmDynamicArray &movInsts, uint32_t index, bool isBdw, bool isHwDebug ) { 153 154 uint32_t dstEnd = dstOffset + size; 155 uint32_t moveSize = GENX_GRF_BYTE_SIZE; 156 uint32_t remainder = dstOffset % GENX_GRF_BYTE_SIZE; 157 uint32_t numMoves = 0; 158 159 if( remainder != 0 ) { 160 // dst address is not GRF-aligned, handle this portion first 161 // until we get a GRF-aligned dst address 162 uint32_t dstGRFEnd = dstOffset + GENX_GRF_BYTE_SIZE - remainder; 163 if( dstGRFEnd > dstEnd ) { 164 dstGRFEnd = dstEnd; 165 } 166 while( dstGRFEnd != dstOffset ) { 167 while( (dstGRFEnd - dstOffset) >= moveSize ) { 168 MovInst_RT* inst = MovInst_RT::CreateSingleMove( 169 dstOffset, srcOffset, moveSize, isBdw, isHwDebug); 170 if( !movInsts.SetElement( index + numMoves, inst )) { 171 CmSafeDelete(inst); 172 CM_ASSERTMESSAGE("Error: SetElement failure."); 173 } 174 numMoves++; 175 uint32_t srcEndGRFNum = (srcOffset + moveSize - 1) / GENX_GRF_BYTE_SIZE; 176 if( srcEndGRFNum != srcOffset / GENX_GRF_BYTE_SIZE ) 177 { 178 // src straddles two GRFs, we have to insert compensation moves 179 // for the elements in the 2nd GRF 180 uint32_t compSrcStart = srcEndGRFNum * GENX_GRF_BYTE_SIZE; 181 uint32_t compSize = srcOffset + moveSize - compSrcStart; 182 uint32_t compDstStart = dstOffset + (moveSize - compSize); 183 numMoves += CreateMoves( compDstStart, compSrcStart, compSize, movInsts, index + numMoves, isBdw, isHwDebug); 184 } 185 dstOffset += moveSize; 186 srcOffset += moveSize; 187 } 188 moveSize >>= 1; 189 } 190 } 191 192 moveSize = GENX_GRF_BYTE_SIZE; 193 while( dstEnd != dstOffset ) { 194 while( (dstEnd - dstOffset) >= moveSize ) { 195 MovInst_RT* inst = MovInst_RT::CreateSingleMove( 196 dstOffset, srcOffset, moveSize, isBdw, isHwDebug); 197 if( !movInsts.SetElement( index + numMoves, inst )) { 198 CM_ASSERTMESSAGE("Error: SetElement failure."); 199 CmSafeDelete(inst); 200 } 201 numMoves++; 202 203 uint32_t srcEndGRFNum = (srcOffset + moveSize - 1) / GENX_GRF_BYTE_SIZE; 204 if( srcEndGRFNum != srcOffset / GENX_GRF_BYTE_SIZE ) 205 { 206 // src straddles two GRFs, we have to insert compensation moves 207 // for the elements in the 2nd GRF 208 uint32_t compSrcStart = srcEndGRFNum * GENX_GRF_BYTE_SIZE; 209 uint32_t compSize = srcOffset + moveSize - compSrcStart; 210 uint32_t compDstStart = dstOffset + (moveSize - compSize); 211 numMoves += CreateMoves( compDstStart, compSrcStart, compSize, movInsts, index + numMoves, isBdw, isHwDebug); 212 } 213 214 dstOffset += moveSize; 215 srcOffset += moveSize; 216 } 217 moveSize >>= 1; 218 } 219 return numMoves; 220 } 221 222 // Create a single move instruction for the given dst/src offset and size, 223 // all in unit of bytes. The size must be a legal Gen execution size, 224 // i.e., power-of-twos from 1 to 32. CreateSingleMove(uint32_t dstOffset,uint32_t srcOffset,uint32_t size,bool isBdw,bool isHwDebug)225 static MovInst_RT *CreateSingleMove( uint32_t dstOffset, uint32_t srcOffset, uint32_t size, bool isBdw, bool isHwDebug ) 226 { 227 Genx_Exec_Size exeSize; 228 Genx_Reg_Type type; 229 Genx_VStride vStride; 230 Genx_Width width; 231 Genx_HStride hStride; 232 233 switch( size ) { 234 case 32: 235 //type = UD, esize = 8 236 exeSize = MovInst_RT::EXEC_SIZE_8; 237 type = MovInst_RT::REG_TYPE_UD; 238 vStride = MovInst_RT::VS_8; 239 width = MovInst_RT::W_8; 240 hStride = MovInst_RT::HS_1; 241 break; 242 case 16: 243 //type = UD, esize = 4 244 exeSize = MovInst_RT::EXEC_SIZE_4; 245 type = MovInst_RT::REG_TYPE_UD; 246 vStride = MovInst_RT::VS_4; 247 width = MovInst_RT::W_4; 248 hStride = MovInst_RT::HS_1; 249 break; 250 case 8: 251 //type = UD, esize = 2; 252 exeSize = MovInst_RT::EXEC_SIZE_2; 253 type = MovInst_RT::REG_TYPE_UD; 254 vStride = MovInst_RT::VS_2; 255 width = MovInst_RT::W_2; 256 hStride = MovInst_RT::HS_1; 257 break; 258 case 4: 259 //type = UD, esize = 1; 260 exeSize = MovInst_RT::EXEC_SIZE_1; 261 type = MovInst_RT::REG_TYPE_UD; 262 vStride = MovInst_RT::VS_0; 263 width = MovInst_RT::W_1; 264 hStride = MovInst_RT::HS_0; 265 break; 266 case 2: 267 //type = UW, esize = 1; 268 exeSize = MovInst_RT::EXEC_SIZE_1; 269 type = MovInst_RT::REG_TYPE_UW; 270 vStride = MovInst_RT::VS_0; 271 width = MovInst_RT::W_1; 272 hStride = MovInst_RT::HS_0; 273 break; 274 case 1: 275 //type = UB, esize = 1; 276 exeSize = MovInst_RT::EXEC_SIZE_1; 277 type = MovInst_RT::REG_TYPE_UB; 278 vStride = MovInst_RT::VS_0; 279 width = MovInst_RT::W_1; 280 hStride = MovInst_RT::HS_0; 281 break; 282 default: 283 // below assignment is to avoid variables being used uninitialized in this function 284 exeSize = MovInst_RT::EXEC_SIZE_1; 285 type = MovInst_RT::REG_TYPE_UD; 286 vStride = MovInst_RT::VS_0; 287 width = MovInst_RT::W_1; 288 hStride = MovInst_RT::HS_0; 289 CM_ASSERTMESSAGE("Error: Invalid Gen execution size."); 290 } 291 292 MovInst_RT *inst = new (std::nothrow) MovInst_RT(isBdw, isHwDebug); 293 if(!inst) 294 { 295 CM_ASSERTMESSAGE("Error: Out of system memory."); 296 return nullptr; 297 } 298 299 uint32_t dstSubRegNum = dstOffset % GENX_GRF_BYTE_SIZE; 300 uint32_t srcSubRegNum = srcOffset % GENX_GRF_BYTE_SIZE; 301 302 inst->SetDstRegNum( dstOffset / GENX_GRF_BYTE_SIZE ); 303 inst->SetDstSubregNum( dstSubRegNum ); 304 inst->SetSrcRegNum( srcOffset / GENX_GRF_BYTE_SIZE ); 305 inst->SetSrcSubregNum( srcSubRegNum ); 306 inst->SetExecSize( exeSize ); 307 inst->SetDstType( type ); 308 inst->SetSrcType( type ); 309 inst->SetDstRegion( MovInst_RT::HS_1 ); 310 inst->SetSrcRegion( vStride, width, hStride ); 311 return inst; 312 } 313 SetBits(const unsigned char lowBit,const unsigned char highBit,const uint32_t value)314 void SetBits(const unsigned char lowBit, const unsigned char highBit, const uint32_t value) { 315 CM_ASSERT(highBit <= 127); 316 CM_ASSERT((highBit - lowBit) <= 31); 317 CM_ASSERT(highBit >= lowBit); 318 CM_ASSERT((highBit/32) == (lowBit/32)); 319 uint32_t maxvalue = ((1 << (highBit - lowBit)) - 1) | (1 << (highBit - lowBit)); 320 uint32_t newvalue = value; 321 newvalue &= maxvalue; 322 uint32_t dword = highBit/32; 323 324 uint32_t mask = (unsigned long)(0xffffffff >> (32 - (highBit - lowBit + 1))); 325 uint32_t shift = lowBit - (dword*32); 326 mask <<= shift; 327 m_instructions[dword] &= ~mask; 328 m_instructions[dword] |= (newvalue << shift); 329 } 330 GetBits(const int lowBit,const int highBit)331 uint32_t GetBits(const int lowBit, const int highBit) { 332 CM_ASSERT(highBit <= 127); 333 CM_ASSERT((highBit - lowBit) <= 31); 334 CM_ASSERT(highBit >= lowBit); 335 CM_ASSERT((highBit/32) == (lowBit/32)); 336 337 uint32_t retValue; 338 uint32_t dword = highBit/32; 339 uint32_t mask = (uint32_t)(0xffffffff >> (32 - (highBit - lowBit + 1))); 340 uint32_t shift = lowBit - (dword*32); 341 342 retValue = m_instructions[dword] & (mask << shift); 343 retValue >>= shift; 344 retValue &= mask; 345 346 return retValue; 347 } 348 SetExecSize(const Genx_Exec_Size size)349 void SetExecSize( const Genx_Exec_Size size ) { 350 SetBits( 21, 23, size ); 351 } 352 GetExecSize(void)353 Genx_Exec_Size GetExecSize( void ) { 354 return (Genx_Exec_Size) GetBits( 21, 23 ); 355 } 356 SetDstType(const Genx_Reg_Type type)357 void SetDstType( const Genx_Reg_Type type ) { 358 if( m_isBdw ) 359 { 360 SetBits( 37, 40, type ); 361 } 362 else 363 { 364 SetBits( 34, 36, type ); 365 } 366 } 367 GetDstType(void)368 Genx_Reg_Type GetDstType( void ) { 369 if( m_isBdw ) 370 { 371 return (Genx_Reg_Type) GetBits( 37, 40 ); 372 } 373 else 374 { 375 return (Genx_Reg_Type) GetBits( 34, 36 ); 376 } 377 } 378 SetDstRegFile(Genx_Reg_File regFile)379 void SetDstRegFile( Genx_Reg_File regFile ) { 380 if( m_isBdw ) 381 { 382 SetBits( 35, 36, regFile ); 383 } 384 else 385 { 386 SetBits( 32, 33, regFile ); 387 } 388 } 389 SetSrcType(const Genx_Reg_Type type)390 void SetSrcType( const Genx_Reg_Type type ) { 391 if( m_isBdw ) 392 { 393 SetBits( 43, 46, type ); 394 } 395 else 396 { 397 SetBits( 39, 41, type ); 398 } 399 } 400 GetSrcType(void)401 Genx_Reg_Type GetSrcType( void ) { 402 if( m_isBdw ) 403 { 404 return (Genx_Reg_Type) GetBits( 43, 46 ); 405 } 406 else 407 { 408 return (Genx_Reg_Type) GetBits( 39, 41 ); 409 } 410 } 411 SetSrcRegFile(Genx_Reg_File regFile)412 void SetSrcRegFile( Genx_Reg_File regFile ) { 413 if( m_isBdw ) 414 { 415 SetBits( 41, 42, regFile ); 416 } 417 else 418 { 419 SetBits( 37, 38, REG_GRF ); 420 } 421 } 422 SetDstRegNum(const unsigned long reg)423 void SetDstRegNum( const unsigned long reg ) { 424 CM_ASSERT( reg < 128 ); 425 SetBits( 53, 60, reg ); 426 } 427 GetDstRegNum(void)428 uint32_t GetDstRegNum( void ) { 429 return GetBits( 53, 60 ); 430 } 431 SetDstSubregNum(const unsigned long subreg)432 void SetDstSubregNum( const unsigned long subreg ) { 433 CM_ASSERT( subreg < 32 ); 434 SetBits( 48, 52, subreg ); 435 } 436 GetDstSubregNum(void)437 uint32_t GetDstSubregNum( void ) { 438 return GetBits( 48, 52 ); 439 } 440 SetDstRegion(const Genx_HStride hstride)441 void SetDstRegion( const Genx_HStride hstride ) { 442 SetBits( 61, 62, hstride ); 443 } 444 GetDstRegion(void)445 Genx_HStride GetDstRegion( void ) { 446 return (Genx_HStride) GetBits( 61, 62 ); 447 } 448 SetSrcRegNum(const unsigned long reg)449 void SetSrcRegNum( const unsigned long reg ) { 450 CM_ASSERT( reg < 128 ); 451 SetBits( 69, 76, reg ); 452 } 453 GetSrcRegNum(void)454 uint32_t GetSrcRegNum( void ) { 455 return GetBits( 69, 76 ); 456 } 457 SetSrcSubregNum(const unsigned long subreg)458 void SetSrcSubregNum( const unsigned long subreg ) { 459 CM_ASSERT( subreg < 32 ); 460 SetBits( 64, 68, subreg ); 461 } 462 GetSrcSubregNum(void)463 uint32_t GetSrcSubregNum( void ) { 464 return GetBits( 64, 68 ); 465 } 466 SetSrcRegion(const Genx_VStride vstride,const Genx_Width width,const Genx_HStride hstride)467 void SetSrcRegion( const Genx_VStride vstride, const Genx_Width width, const Genx_HStride hstride ) { 468 SetBits( 85, 88, vstride ); 469 SetBits( 82, 84, width ); 470 SetBits( 80, 81, hstride ); 471 } 472 GetSrcVStride(void)473 Genx_VStride GetSrcVStride( void ) { 474 return (Genx_VStride) GetBits( 85, 88 ); 475 } 476 GetSrcWidth(void)477 Genx_Width GetSrcWidth( void ) { 478 return (Genx_Width) GetBits( 82, 84 ); 479 } 480 GetSrcHStride(void)481 Genx_HStride GetSrcHStride( void ) { 482 return (Genx_HStride) GetBits( 80, 81 ); 483 } 484 GetExecSizeValue(Genx_Exec_Size size)485 uint32_t GetExecSizeValue( Genx_Exec_Size size ) { 486 switch( size ) { 487 case EXEC_SIZE_1: 488 return 1; 489 case EXEC_SIZE_2: 490 return 2; 491 case EXEC_SIZE_4: 492 return 4; 493 case EXEC_SIZE_8: 494 return 8; 495 case EXEC_SIZE_16: 496 return 16; 497 case EXEC_SIZE_32: 498 return 32; 499 default: 500 CM_ASSERTMESSAGE("Error: Invalid Gen execution operand size."); 501 return 0; 502 } 503 } 504 GetTypeStr(Genx_Reg_Type type)505 const char* GetTypeStr( Genx_Reg_Type type ) { 506 switch( type ) { 507 case REG_TYPE_UD: 508 return "ud"; 509 case REG_TYPE_D: 510 return "d"; 511 case REG_TYPE_UW: 512 return "uw"; 513 case REG_TYPE_W: 514 return "w"; 515 case REG_TYPE_UB: 516 return "ub"; 517 case REG_TYPE_B: 518 return "b"; 519 case REG_TYPE_DF: 520 return "df"; 521 case REG_TYPE_F: 522 return "f"; 523 default: 524 CM_ASSERTMESSAGE("Error: Invalid register data type."); 525 return ""; 526 } 527 } 528 GetVStrideValue(Genx_VStride vstride)529 uint32_t GetVStrideValue( Genx_VStride vstride ) { 530 switch( vstride ) { 531 case VS_0: 532 return 0; 533 case VS_1: 534 return 1; 535 case VS_2: 536 return 2; 537 case VS_4: 538 return 4; 539 case VS_8: 540 return 8; 541 case VS_16: 542 return 16; 543 case VS_32: 544 return 32; 545 default: 546 CM_ASSERTMESSAGE("Error: Invalid value of vertical stride."); 547 return 0; 548 } 549 } 550 GetWidthValue(Genx_Width width)551 uint32_t GetWidthValue( Genx_Width width ) { 552 switch( width ) { 553 case W_1: 554 return 1; 555 case W_2: 556 return 2; 557 case W_4: 558 return 4; 559 case W_8: 560 return 8; 561 case W_16: 562 return 16; 563 default: 564 CM_ASSERTMESSAGE("Error: Invalid genx width value."); 565 return 0; 566 } 567 } 568 GetHStrideValue(Genx_HStride hstride)569 uint32_t GetHStrideValue( Genx_HStride hstride ) { 570 switch (hstride ) { 571 case HS_0: 572 return 0; 573 case HS_1: 574 return 1; 575 case HS_2: 576 return 2; 577 case HS_4: 578 return 4; 579 default: 580 CM_ASSERTMESSAGE("Error: Invalid value of horizontal stride."); 581 return 0; 582 } 583 } 584 emit()585 void emit() { 586 uint32_t execSize, dstHStride, srcVStride, srcWidth, srcHStride, dstSubregNum, srcSubregNum; 587 const char *dstType, *srcType; 588 execSize = GetExecSizeValue( GetExecSize() ); 589 dstHStride = GetHStrideValue( GetDstRegion() ); 590 dstType = GetTypeStr( GetDstType() ); 591 srcType = GetTypeStr( GetSrcType() ); 592 srcVStride = GetVStrideValue( GetSrcVStride() ); 593 srcWidth = GetWidthValue( GetSrcWidth() ); 594 srcHStride = GetHStrideValue( GetSrcHStride() ); 595 dstSubregNum = GetDstSubregNum() / GetTypeSize( GetDstType() ); 596 srcSubregNum = GetSrcSubregNum() / GetTypeSize( GetSrcType() ); 597 598 CM_NORMALMESSAGE("mov (%d) r%d.%d<%d>:%s r%d.%d<%d;%d,%d>:%s.", 599 execSize, GetDstRegNum(), dstSubregNum, dstHStride, dstType, 600 GetSrcRegNum(), srcSubregNum, srcVStride, srcWidth, srcHStride, srcType ); 601 } 602 }; 603 604 #endif // #ifndef MEDIADRIVER_AGNOSTIC_COMMON_CM_CMMOVINST_H_ 605