2017-12-21 00:45:38 +01:00
|
|
|
/*
|
2020-01-21 15:24:52 +01:00
|
|
|
* Copyright (C) 2017-2020 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
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
2020-02-23 22:44:01 +01:00
|
|
|
#include "shared/source/os_interface/linux/drm_buffer_object.h"
|
2019-02-27 11:39:32 +01:00
|
|
|
|
2020-02-23 22:44:01 +01:00
|
|
|
#include "shared/source/helpers/debug_helpers.h"
|
|
|
|
|
#include "shared/source/os_interface/linux/drm_memory_manager.h"
|
|
|
|
|
#include "shared/source/os_interface/linux/os_time_linux.h"
|
|
|
|
|
#include "shared/source/utilities/stackvec.h"
|
2017-12-21 00:45:38 +01:00
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <fcntl.h>
|
2019-02-27 11:39:32 +01:00
|
|
|
#include <stdarg.h>
|
|
|
|
|
#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
|
|
|
|
2020-03-19 10:41:35 +01:00
|
|
|
BufferObject::BufferObject(Drm *drm, int handle, size_t size) : drm(drm), refCount(1), handle(handle), size(size), isReused(false) {
|
2017-12-21 00:45:38 +01:00
|
|
|
this->tiling_mode = I915_TILING_NONE;
|
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;
|
|
|
|
|
|
|
|
|
|
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;
|
2019-09-03 09:26:49 +02:00
|
|
|
execObject.flags = EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
|
2018-12-11 08:21:56 +01:00
|
|
|
execObject.rsvd1 = drmContextId;
|
2017-12-21 00:45:38 +01:00
|
|
|
execObject.rsvd2 = 0;
|
|
|
|
|
}
|
|
|
|
|
|
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
|