2017-12-21 07:45:38 +08:00
/*
2020-01-21 22:24:52 +08:00
* Copyright ( C ) 2017 - 2020 Intel Corporation
2017-12-21 07:45:38 +08:00
*
2018-09-18 15:11:08 +08:00
* SPDX - License - Identifier : MIT
2017-12-21 07:45:38 +08:00
*
*/
2020-02-24 05:44:01 +08:00
# include "shared/source/os_interface/linux/drm_buffer_object.h"
2019-02-27 18:39:32 +08:00
2020-05-06 18:37:15 +08:00
# include "shared/source/helpers/aligned_memory.h"
2020-02-24 05:44:01 +08:00
# include "shared/source/helpers/debug_helpers.h"
# include "shared/source/os_interface/linux/drm_memory_manager.h"
2020-05-06 18:37:15 +08:00
# include "shared/source/os_interface/linux/drm_neo.h"
2020-02-24 05:44:01 +08:00
# include "shared/source/os_interface/linux/os_time_linux.h"
# include "shared/source/utilities/stackvec.h"
2017-12-21 07:45:38 +08:00
2020-05-06 18:37:15 +08:00
# include "drm/i915_drm.h"
2017-12-21 07:45:38 +08:00
# include <errno.h>
# include <fcntl.h>
2020-05-06 18:37:15 +08:00
# include <map>
2019-02-27 18:39:32 +08:00
# include <stdarg.h>
2020-05-06 18:37:15 +08:00
# include <string.h>
2019-02-27 18:39:32 +08:00
# include <sys/ioctl.h>
# include <sys/mman.h>
# include <sys/syscall.h>
# include <sys/types.h>
2017-12-21 07:45:38 +08:00
# include <unistd.h>
2019-03-26 18:59:46 +08:00
namespace NEO {
2017-12-21 07:45:38 +08:00
2020-03-19 17:41:35 +08:00
BufferObject : : BufferObject ( Drm * drm , int handle , size_t size ) : drm ( drm ) , refCount ( 1 ) , handle ( handle ) , size ( size ) , isReused ( false ) {
2017-12-21 07:45:38 +08:00
this - > tiling_mode = I915_TILING_NONE ;
2018-02-27 06:23:43 +08:00
this - > lockedAddress = nullptr ;
2017-12-21 07:45:38 +08:00
}
uint32_t BufferObject : : getRefCount ( ) const {
return this - > refCount . load ( ) ;
}
bool BufferObject : : close ( ) {
2018-03-20 17:49:09 +08:00
drm_gem_close close = { } ;
2017-12-21 07:45:38 +08:00
close . handle = this - > handle ;
int ret = this - > drm - > ioctl ( DRM_IOCTL_GEM_CLOSE , & close ) ;
if ( ret ! = 0 ) {
int err = errno ;
printDebugString ( DebugManager . flags . PrintDebugMessages . get ( ) , stderr , " ioctl(GEM_CLOSE) failed with %d. errno=%d(%s) \n " , ret , err , strerror ( err ) ) ;
2017-12-20 21:28:42 +08:00
DEBUG_BREAK_IF ( true ) ;
2017-12-21 07:45:38 +08:00
return false ;
}
this - > handle = - 1 ;
return true ;
}
int BufferObject : : wait ( int64_t timeoutNs ) {
2018-03-20 17:49:09 +08:00
drm_i915_gem_wait wait = { } ;
2017-12-21 07:45:38 +08:00
wait . bo_handle = this - > handle ;
wait . timeout_ns = - 1 ;
int ret = this - > drm - > ioctl ( DRM_IOCTL_I915_GEM_WAIT , & wait ) ;
if ( ret ! = 0 ) {
int err = errno ;
printDebugString ( DebugManager . flags . PrintDebugMessages . get ( ) , stderr , " ioctl(I915_GEM_WAIT) failed with %d. errno=%d(%s) \n " , ret , err , strerror ( err ) ) ;
}
UNRECOVERABLE_IF ( ret ! = 0 ) ;
return ret ;
}
bool BufferObject : : setTiling ( uint32_t mode , uint32_t stride ) {
if ( this - > tiling_mode = = mode ) {
return true ;
}
2018-03-20 17:49:09 +08:00
drm_i915_gem_set_tiling set_tiling = { } ;
2017-12-21 07:45:38 +08:00
set_tiling . handle = this - > handle ;
set_tiling . tiling_mode = mode ;
set_tiling . stride = stride ;
2018-03-20 17:49:09 +08:00
if ( this - > drm - > ioctl ( DRM_IOCTL_I915_GEM_SET_TILING , & set_tiling ) ! = 0 ) {
2017-12-21 07:45:38 +08:00
return false ;
}
this - > tiling_mode = set_tiling . tiling_mode ;
return set_tiling . tiling_mode = = mode ;
2018-02-27 06:23:43 +08:00
}
2017-12-21 07:45:38 +08:00
2018-12-11 15:21:56 +08:00
void BufferObject : : fillExecObject ( drm_i915_gem_exec_object2 & execObject , uint32_t drmContextId ) {
2017-12-21 07:45:38 +08:00
execObject . handle = this - > handle ;
2018-03-09 20:03:48 +08:00
execObject . relocation_count = 0 ; //No relocations, we are SoftPinning
2017-12-21 07:45:38 +08:00
execObject . relocs_ptr = 0ul ;
execObject . alignment = 0 ;
2019-02-20 22:08:03 +08:00
execObject . offset = this - > gpuAddress ;
2019-09-03 15:26:49 +08:00
execObject . flags = EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS ;
2018-12-11 15:21:56 +08:00
execObject . rsvd1 = drmContextId ;
2017-12-21 07:45:38 +08:00
execObject . rsvd2 = 0 ;
}
2020-05-06 18:37:15 +08:00
int BufferObject : : exec ( uint32_t used , size_t startOffset , unsigned int flags , bool requiresCoherency , uint32_t drmContextId , BufferObject * const residency [ ] , size_t residencyCount , drm_i915_gem_exec_object2 * execObjectsStorage ) {
for ( size_t i = 0 ; i < residencyCount ; i + + ) {
residency [ i ] - > fillExecObject ( execObjectsStorage [ i ] , drmContextId ) ;
}
this - > fillExecObject ( execObjectsStorage [ residencyCount ] , drmContextId ) ;
drm_i915_gem_execbuffer2 execbuf { } ;
execbuf . buffers_ptr = reinterpret_cast < uintptr_t > ( execObjectsStorage ) ;
execbuf . buffer_count = static_cast < uint32_t > ( residencyCount + 1u ) ;
execbuf . batch_start_offset = static_cast < uint32_t > ( startOffset ) ;
execbuf . batch_len = alignUp ( used , 8 ) ;
execbuf . flags = flags ;
execbuf . rsvd1 = drmContextId ;
2020-06-09 16:00:59 +08:00
if ( DebugManager . flags . PrintExecutionBuffer . get ( ) ) {
printExecutionBuffer ( execbuf , residencyCount , execObjectsStorage ) ;
}
2020-05-06 18:37:15 +08:00
int ret = this - > drm - > ioctl ( DRM_IOCTL_I915_GEM_EXECBUFFER2 , & execbuf ) ;
if ( ret = = 0 ) {
return 0 ;
}
int err = this - > drm - > getErrno ( ) ;
printDebugString ( DebugManager . flags . PrintDebugMessages . get ( ) , stderr , " ioctl(I915_GEM_EXECBUFFER2) failed with %d. errno=%d(%s) \n " , ret , err , strerror ( err ) ) ;
return err ;
}
2020-06-09 16:00:59 +08:00
void BufferObject : : printExecutionBuffer ( drm_i915_gem_execbuffer2 & execbuf , const size_t & residencyCount , drm_i915_gem_exec_object2 * execObjectsStorage ) {
std : : string logger = " drm_i915_gem_execbuffer2 { \n " ;
logger + = " buffers_ptr: " + std : : to_string ( execbuf . buffers_ptr ) + " , \n " ;
logger + = " buffer_count: " + std : : to_string ( execbuf . buffer_count ) + " , \n " ;
logger + = " batch_start_offset: " + std : : to_string ( execbuf . batch_start_offset ) + " , \n " ;
logger + = " batch_len: " + std : : to_string ( execbuf . batch_len ) + " , \n " ;
logger + = " flags: " + std : : to_string ( execbuf . flags ) + " , \n " ;
logger + = " rsvd1: " + std : : to_string ( execbuf . rsvd1 ) + " , \n " ;
logger + = " } \n " ;
for ( size_t i = 0 ; i < residencyCount + 1 ; i + + ) {
std : : string temp = " drm_i915_gem_exec_object2 { \n " ;
temp + = " handle: " + std : : to_string ( execObjectsStorage [ i ] . handle ) + " , \n " ;
temp + = " relocation_count: " + std : : to_string ( execObjectsStorage [ i ] . relocation_count ) + " , \n " ;
temp + = " relocs_ptr: " + std : : to_string ( execObjectsStorage [ i ] . relocs_ptr ) + " , \n " ;
temp + = " alignment: " + std : : to_string ( execObjectsStorage [ i ] . alignment ) + " , \n " ;
temp + = " offset: " + std : : to_string ( execObjectsStorage [ i ] . offset ) + " , \n " ;
temp + = " flags: " + std : : to_string ( execObjectsStorage [ i ] . flags ) + " , \n " ;
temp + = " rsvd1: " + std : : to_string ( execObjectsStorage [ i ] . rsvd1 ) + " , \n " ;
temp + = " rsvd2: " + std : : to_string ( execObjectsStorage [ i ] . rsvd2 ) + " , \n " ;
temp + = " pad_to_size: " + std : : to_string ( execObjectsStorage [ i ] . pad_to_size ) + " , \n " ;
temp + = " } \n " ;
logger + = temp ;
}
std : : cout < < logger < < std : : endl ;
}
2019-02-25 21:11:34 +08:00
int BufferObject : : pin ( BufferObject * const boToPin [ ] , size_t numberOfBos , uint32_t drmContextId ) {
2019-07-17 21:38:14 +08:00
StackVec < drm_i915_gem_exec_object2 , maxFragmentsCount + 1 > execObject ( numberOfBos + 1 ) ;
return this - > exec ( 4u , 0u , 0u , false , drmContextId , boToPin , numberOfBos , & execObject [ 0 ] ) ;
2017-12-21 07:45:38 +08:00
}
2018-02-28 19:09:48 +08:00
2019-03-26 18:59:46 +08:00
} // namespace NEO