2017-12-21 00:45:38 +01:00
/*
2019-02-07 11:04:22 -08:00
* Copyright ( C ) 2017 - 2019 Intel Corporation
2017-12-21 00:45:38 +01:00
*
2018-09-18 09:11:08 +02:00
* SPDX - License - Identifier : MIT
2017-12-21 00:45:38 +01:00
*
*/
2019-02-27 11:39:32 +01:00
# include "runtime/os_interface/linux/drm_buffer_object.h"
2019-08-02 13:25:45 -07:00
# include "core/helpers/aligned_memory.h"
2017-12-21 00:45:38 +01:00
# include "runtime/helpers/debug_helpers.h"
# include "runtime/os_interface/linux/drm_memory_manager.h"
# include "runtime/os_interface/linux/drm_neo.h"
2018-05-22 15:55:06 +02:00
# include "runtime/os_interface/linux/os_time_linux.h"
2018-02-28 12:09:48 +01:00
# include "runtime/utilities/stackvec.h"
2017-12-21 00:45:38 +01:00
2019-02-27 11:39:32 +01:00
# include "drm/i915_drm.h"
2017-12-21 00:45:38 +01:00
# include <errno.h>
# include <fcntl.h>
2019-02-27 11:39:32 +01:00
# include <map>
# include <stdarg.h>
2017-12-21 00:45:38 +01:00
# include <string.h>
2019-02-27 11:39:32 +01:00
# include <sys/ioctl.h>
# include <sys/mman.h>
# include <sys/syscall.h>
# include <sys/types.h>
2017-12-21 00:45:38 +01:00
# include <unistd.h>
2019-03-26 11:59:46 +01:00
namespace NEO {
2017-12-21 00:45:38 +01:00
2019-08-05 13:34:29 +02:00
BufferObject : : BufferObject ( Drm * drm , int handle ) : drm ( drm ) , refCount ( 1 ) , handle ( handle ) , isReused ( false ) {
2017-12-21 00:45:38 +01:00
this - > tiling_mode = I915_TILING_NONE ;
this - > stride = 0 ;
this - > size = 0 ;
2018-02-26 23:23:43 +01:00
this - > lockedAddress = nullptr ;
2017-12-21 00:45:38 +01:00
}
uint32_t BufferObject : : getRefCount ( ) const {
return this - > refCount . load ( ) ;
}
bool BufferObject : : close ( ) {
2018-03-20 10:49:09 +01:00
drm_gem_close close = { } ;
2017-12-21 00:45:38 +01: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 14:28:42 +01:00
DEBUG_BREAK_IF ( true ) ;
2017-12-21 00:45:38 +01:00
return false ;
}
this - > handle = - 1 ;
return true ;
}
int BufferObject : : wait ( int64_t timeoutNs ) {
2018-03-20 10:49:09 +01:00
drm_i915_gem_wait wait = { } ;
2017-12-21 00:45:38 +01: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 10:49:09 +01:00
drm_i915_gem_set_tiling set_tiling = { } ;
2017-12-21 00:45:38 +01:00
set_tiling . handle = this - > handle ;
set_tiling . tiling_mode = mode ;
set_tiling . stride = stride ;
2018-03-20 10:49:09 +01:00
if ( this - > drm - > ioctl ( DRM_IOCTL_I915_GEM_SET_TILING , & set_tiling ) ! = 0 ) {
2017-12-21 00:45:38 +01:00
return false ;
}
this - > tiling_mode = set_tiling . tiling_mode ;
this - > stride = set_tiling . stride ;
return set_tiling . tiling_mode = = mode ;
2018-02-26 23:23:43 +01:00
}
2017-12-21 00:45:38 +01:00
2018-12-11 08:21:56 +01:00
void BufferObject : : fillExecObject ( drm_i915_gem_exec_object2 & execObject , uint32_t drmContextId ) {
2017-12-21 00:45:38 +01:00
execObject . handle = this - > handle ;
2018-03-09 13:03:48 +01:00
execObject . relocation_count = 0 ; //No relocations, we are SoftPinning
2017-12-21 00:45:38 +01:00
execObject . relocs_ptr = 0ul ;
execObject . alignment = 0 ;
2019-02-20 15:08:03 +01:00
execObject . offset = this - > gpuAddress ;
execObject . flags = EXEC_OBJECT_PINNED ;
2017-12-21 00:45:38 +01:00
# ifdef __x86_64__
2019-02-07 11:04:22 -08:00
// set EXEC_OBJECT_SUPPORTS_48B_ADDRESS flag if whole object resides in 32BIT address space boundary
2019-02-20 15:08:03 +01:00
execObject . flags | = ( this - > gpuAddress + this - > size ) & MemoryConstants : : zoneHigh ? EXEC_OBJECT_SUPPORTS_48B_ADDRESS : 0 ;
2017-12-21 00:45:38 +01:00
# endif
2018-12-11 08:21:56 +01:00
execObject . rsvd1 = drmContextId ;
2017-12-21 00:45:38 +01:00
execObject . rsvd2 = 0 ;
}
2019-07-17 15:38:14 +02: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 ) ;
2017-12-21 00:45:38 +01:00
}
2019-07-17 15:38:14 +02:00
this - > fillExecObject ( execObjectsStorage [ residencyCount ] , drmContextId ) ;
2017-12-21 00:45:38 +01:00
2019-07-17 15:38:14 +02:00
drm_i915_gem_execbuffer2 execbuf { } ;
2017-12-21 00:45:38 +01:00
execbuf . buffers_ptr = reinterpret_cast < uintptr_t > ( execObjectsStorage ) ;
2019-07-17 15:38:14 +02:00
execbuf . buffer_count = static_cast < uint32_t > ( residencyCount + 1u ) ;
2017-12-21 00:45:38 +01:00
execbuf . batch_start_offset = static_cast < uint32_t > ( startOffset ) ;
execbuf . batch_len = alignUp ( used , 8 ) ;
execbuf . flags = flags ;
2018-12-11 08:21:56 +01:00
execbuf . rsvd1 = drmContextId ;
2017-12-21 00:45:38 +01:00
int ret = this - > drm - > ioctl ( DRM_IOCTL_I915_GEM_EXECBUFFER2 , & execbuf ) ;
2019-07-17 15:38:14 +02:00
if ( ret = = 0 ) {
return 0 ;
2017-12-21 00:45:38 +01:00
}
2019-07-17 15:38:14 +02:00
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 ;
2017-12-21 00:45:38 +01:00
}
2019-02-25 14:11:34 +01:00
int BufferObject : : pin ( BufferObject * const boToPin [ ] , size_t numberOfBos , uint32_t drmContextId ) {
2019-02-20 15:08:03 +01:00
reinterpret_cast < uint32_t * > ( this - > gpuAddress ) [ 0 ] = 0x05000000 ;
reinterpret_cast < uint32_t * > ( this - > gpuAddress ) [ 1 ] = 0x00000000 ;
2019-07-17 15:38:14 +02: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 00:45:38 +01:00
}
2018-02-28 12:09:48 +01:00
2019-03-26 11:59:46 +01:00
} // namespace NEO