mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-14 22:47:12 +00:00
libports: add mesa/lima driver
This commit introduces the Mesa3D lima driver for Mali 400 series GPUs. Issue #4559.
This commit is contained in:
parent
d2c26fd504
commit
da25b288ee
@ -16,7 +16,7 @@
|
||||
#define _INCLUDE__LIBDRM__IOCTL_DISPATCH_H_
|
||||
|
||||
namespace Libdrm {
|
||||
enum Driver { INVALID, ETNAVIV };
|
||||
enum Driver { INVALID, ETNAVIV, LIMA };
|
||||
}; /* namespace Libdrm */
|
||||
|
||||
void drm_init(Libdrm::Driver);
|
||||
|
@ -232,6 +232,7 @@ SRC_C += compiler/glsl/glcpp/pp.c \
|
||||
compiler/nir/nir_lower_drawpixels.c \
|
||||
compiler/nir/nir_lower_flatshade.c \
|
||||
compiler/nir/nir_lower_flrp.c \
|
||||
compiler/nir/nir_lower_fragcoord_wtrans.c \
|
||||
compiler/nir/nir_lower_frexp.c \
|
||||
compiler/nir/nir_lower_global_vars_to_local.c \
|
||||
compiler/nir/nir_lower_goto_ifs.c \
|
||||
@ -253,6 +254,7 @@ SRC_C += compiler/glsl/glcpp/pp.c \
|
||||
compiler/nir/nir_lower_patch_vertices.c \
|
||||
compiler/nir/nir_lower_phis_to_scalar.c \
|
||||
compiler/nir/nir_lower_pntc_ytransform.c \
|
||||
compiler/nir/nir_lower_point_size.c \
|
||||
compiler/nir/nir_lower_point_size_mov.c \
|
||||
compiler/nir/nir_lower_regs_to_ssa.c \
|
||||
compiler/nir/nir_lower_returns.c \
|
||||
@ -268,6 +270,7 @@ SRC_C += compiler/glsl/glcpp/pp.c \
|
||||
compiler/nir/nir_lower_variable_initializers.c \
|
||||
compiler/nir/nir_lower_vars_to_ssa.c \
|
||||
compiler/nir/nir_lower_vec_to_movs.c \
|
||||
compiler/nir/nir_lower_viewport_transform.c \
|
||||
compiler/nir/nir_lower_wpos_ytransform.c \
|
||||
compiler/nir/nir_metadata.c \
|
||||
compiler/nir/nir_move_vec_src_uses_to_dest.c \
|
||||
@ -448,6 +451,7 @@ SRC_C += compiler/glsl/glcpp/pp.c \
|
||||
gallium/auxiliary/util/u_sampler.c \
|
||||
gallium/auxiliary/util/u_screen.c \
|
||||
gallium/auxiliary/util/u_simple_shaders.c \
|
||||
gallium/auxiliary/util/u_split_draw.c \
|
||||
gallium/auxiliary/util/u_surface.c \
|
||||
gallium/auxiliary/util/u_tests.c \
|
||||
gallium/auxiliary/util/u_texture.c \
|
||||
|
@ -3,5 +3,6 @@ include $(REP_DIR)/lib/mk/libdrm.inc
|
||||
LIBS += vfs_gpu
|
||||
|
||||
include $(call select_from_repositories,lib/import/import-libdrm.mk)
|
||||
include $(call select_from_repositories,lib/import/import-mesa_api.mk)
|
||||
|
||||
SRC_CC := ioctl_dispatch.cc ioctl_etnaviv.cc
|
||||
SRC_CC := ioctl_dispatch.cc ioctl_etnaviv.cc ioctl_lima.cc
|
||||
|
64
repos/libports/lib/mk/spec/arm_v8/lima.mk
Normal file
64
repos/libports/lib/mk/spec/arm_v8/lima.mk
Normal file
@ -0,0 +1,64 @@
|
||||
LIBS = libc libdrm
|
||||
|
||||
include $(REP_DIR)/lib/mk/mesa-common.inc
|
||||
|
||||
INC_DIR += $(MESA_SRC_DIR)/src/compiler/nir \
|
||||
$(MESA_SRC_DIR)/src/gallium/auxiliary \
|
||||
$(MESA_SRC_DIR)/src/gallium/drivers \
|
||||
$(MESA_SRC_DIR)/src/gallium/drivers/lima \
|
||||
$(MESA_SRC_DIR)/src/panfrost/shared \
|
||||
$(MESA_SRC_DIR)/src/util \
|
||||
$(MESA_GEN_DIR)/src/compiler/nir \
|
||||
$(MESA_PORT_DIR)/include/drm-uapi
|
||||
|
||||
REP_INC_DIR += include/drm-uapi
|
||||
|
||||
SRC_C := \
|
||||
gallium/drivers/lima/lima_draw.c \
|
||||
gallium/drivers/lima/lima_job.c \
|
||||
gallium/drivers/lima/lima_context.c \
|
||||
gallium/drivers/lima/ir/pp/node_to_instr.c \
|
||||
gallium/drivers/lima/ir/pp/liveness.c \
|
||||
gallium/drivers/lima/ir/pp/codegen.c \
|
||||
gallium/drivers/lima/ir/pp/nir.c \
|
||||
gallium/drivers/lima/ir/pp/disasm.c \
|
||||
gallium/drivers/lima/ir/pp/regalloc.c \
|
||||
gallium/drivers/lima/ir/pp/node.c \
|
||||
gallium/drivers/lima/ir/pp/instr.c \
|
||||
gallium/drivers/lima/ir/pp/lower.c \
|
||||
gallium/drivers/lima/ir/pp/scheduler.c \
|
||||
gallium/drivers/lima/ir/gp/codegen.c \
|
||||
gallium/drivers/lima/ir/gp/nir.c \
|
||||
gallium/drivers/lima/ir/gp/disasm.c \
|
||||
gallium/drivers/lima/ir/gp/regalloc.c \
|
||||
gallium/drivers/lima/ir/gp/optimize.c \
|
||||
gallium/drivers/lima/ir/gp/node.c \
|
||||
gallium/drivers/lima/ir/gp/reduce_scheduler.c \
|
||||
gallium/drivers/lima/ir/gp/instr.c \
|
||||
gallium/drivers/lima/ir/gp/lower.c \
|
||||
gallium/drivers/lima/ir/gp/scheduler.c \
|
||||
gallium/drivers/lima/ir/lima_nir_split_load_input.c \
|
||||
gallium/drivers/lima/ir/lima_nir_duplicate_consts.c \
|
||||
gallium/drivers/lima/ir/lima_nir_duplicate_intrinsic.c \
|
||||
gallium/drivers/lima/ir/lima_nir_lower_uniform_to_scalar.c \
|
||||
gallium/drivers/lima/lima_bo.c \
|
||||
gallium/drivers/lima/lima_context.c \
|
||||
gallium/drivers/lima/lima_draw.c \
|
||||
gallium/drivers/lima/lima_fence.c \
|
||||
gallium/drivers/lima/lima_format.c \
|
||||
gallium/drivers/lima/lima_job.c \
|
||||
gallium/drivers/lima/lima_parser.c \
|
||||
gallium/drivers/lima/lima_program.c \
|
||||
gallium/drivers/lima/lima_query.c \
|
||||
gallium/drivers/lima/lima_resource.c \
|
||||
gallium/drivers/lima/lima_screen.c \
|
||||
gallium/drivers/lima/lima_state.c \
|
||||
gallium/drivers/lima/lima_texture.c \
|
||||
gallium/drivers/lima/lima_util.c \
|
||||
gallium/drivers/lima/lima_nir_algebraic.c \
|
||||
gallium/winsys/lima/drm/lima_drm_winsys.c \
|
||||
panfrost/shared/pan_minmax_cache.c \
|
||||
panfrost/shared/pan_tiling.c
|
||||
|
||||
vpath %.c $(MESA_SRC_DIR)/src
|
||||
vpath %.c $(MESA_SRC_DIR)/../../../generated/src
|
@ -1,10 +1,13 @@
|
||||
SHARED_LIB := yes
|
||||
LIBS += libdrm
|
||||
|
||||
LIBS += etnaviv
|
||||
CC_OPT += -DHAVE_UINT128
|
||||
|
||||
CC_OPT += -DGALLIUM_ETNAVIV \
|
||||
-DHAVE_UINT128
|
||||
LIBS += etnaviv
|
||||
CC_OPT += -DGALLIUM_ETNAVIV
|
||||
|
||||
LIBS += lima
|
||||
CC_OPT += -DGALLIUM_LIMA
|
||||
|
||||
include $(REP_DIR)/lib/mk/mesa.inc
|
||||
|
||||
|
19
repos/libports/lib/mk/spec/arm_v8/mesa_gpu-lima.mk
Normal file
19
repos/libports/lib/mk/spec/arm_v8/mesa_gpu-lima.mk
Normal file
@ -0,0 +1,19 @@
|
||||
SHARED_LIB := yes
|
||||
LIBS := libc egl
|
||||
|
||||
include $(REP_DIR)/lib/mk/mesa-common.inc
|
||||
|
||||
SRC_CC := drm_init.cc
|
||||
SRC_C := platform_lima.c
|
||||
|
||||
CC_OPT += -DHAVE_GENODE_PLATFORM
|
||||
|
||||
INC_DIR += $(MESA_SRC_DIR)/src/egl/drivers/dri2 \
|
||||
$(MESA_SRC_DIR)/src/egl/main \
|
||||
$(MESA_SRC_DIR)/src/mapi \
|
||||
$(MESA_SRC_DIR)/src/mesa
|
||||
|
||||
vpath %.c $(LIB_DIR)/lima
|
||||
vpath %.cc $(LIB_DIR)/lima
|
||||
|
||||
CC_CXX_WARN_STRICT :=
|
@ -1 +1 @@
|
||||
2a8726a52ca7b243fcf40d07da28a52aba4c767f
|
||||
a195203391df18dabe0e9c247301d9f3df1c8192
|
||||
|
@ -23,15 +23,17 @@ PATCHES := src/lib/mesa/patches/bitset_redefined.patch \
|
||||
src/lib/mesa/patches/lseek.patch \
|
||||
src/lib/mesa/patches/mesa.patch \
|
||||
src/lib/mesa/patches/os_mmap.patch \
|
||||
src/lib/mesa/patches/softpipe_cache.patch
|
||||
src/lib/mesa/patches/softpipe_cache.patch \
|
||||
src/lib/mesa/patches/lima.patch \
|
||||
src/lib/mesa/patches/sync_wait.patch
|
||||
|
||||
PATCH_OPT := -p1
|
||||
|
||||
#
|
||||
# Generated Mesa sources
|
||||
#
|
||||
URL(generated) = https://github.com/ssumpf/mesa_generated.git
|
||||
REV(generated) = 396d4b08cbcff941126640e6d3e3d2a5f807d527
|
||||
URL(generated) = https://github.com/cnuke/mesa_generated.git
|
||||
REV(generated) = c3954da3f66d6cb961421f03c09d589faade1784
|
||||
DIR(generated) = generated
|
||||
|
||||
#
|
||||
@ -110,7 +112,8 @@ generated_files = $(GEN_TARGET)/src/compiler/glsl/float64_glsl.h \
|
||||
$(GEN_TARGET)/src/intel/genxml/genX_bits.h \
|
||||
$(GEN_TARGET)/src/intel/genxml/genX_xml.h \
|
||||
$(GEN_TARGET)/src/intel/isl/isl_format_layout.c \
|
||||
$(GEN_TARGET)/src/intel/perf/gen_perf_metrics.h
|
||||
$(GEN_TARGET)/src/intel/perf/gen_perf_metrics.h \
|
||||
$(GEN_TARGET)/src/gallium/drivers/lima/lima_nir_algebraic.c
|
||||
|
||||
#
|
||||
# Print message and create directory
|
||||
@ -345,6 +348,11 @@ $(GEN_TARGET)/src/intel/perf/gen_perf_metrics.h:
|
||||
$(SRC)/src/intel/perf/oa-sklgt4.xml \
|
||||
$(SRC)/src/intel/perf/oa-tgl.xml
|
||||
|
||||
$(GEN_TARGET)/src/gallium/drivers/lima/lima_nir_algebraic.c:
|
||||
$(MSG_DIR)
|
||||
$(VERBOSE)$(PYTHON) $(SRC)/src/gallium/drivers/lima/ir/lima_nir_algebraic.py \
|
||||
-p $(SRC)/src/compiler/nir/ > $@
|
||||
|
||||
CMD(glcpp-lex.c) = glcpp-lex.l
|
||||
CMD(glsl_lexer.cpp) = glsl_lexer.ll
|
||||
CMD(lex.yy.c) = program_lexer.l
|
||||
|
@ -8,7 +8,8 @@ MIRROR_FROM_REP_DIR := lib/mk/libdrm.mk \
|
||||
src/lib/libdrm/ioctl_dummy.cc \
|
||||
src/lib/libdrm/ioctl_iris.cc \
|
||||
src/lib/libdrm/ioctl_etnaviv.cc \
|
||||
src/lib/libdrm/ioctl_dispatch.cc
|
||||
src/lib/libdrm/ioctl_dispatch.cc \
|
||||
src/lib/libdrm/ioctl_lima.cc
|
||||
|
||||
content: $(MIRROR_FROM_REP_DIR) src/lib/libdrm/target.mk
|
||||
|
||||
|
@ -2,3 +2,4 @@ base
|
||||
gpu_session
|
||||
libc
|
||||
vfs_gpu
|
||||
mesa
|
||||
|
@ -12,8 +12,10 @@ MIRROR_FROM_REP_DIR := \
|
||||
lib/mk/mesa-common.inc \
|
||||
lib/mk/softpipe.mk \
|
||||
lib/mk/spec/arm_v8/etnaviv.mk \
|
||||
lib/mk/spec/arm_v8/lima.mk \
|
||||
lib/mk/spec/arm_v8/mesa.mk \
|
||||
lib/mk/spec/arm_v8/mesa_gpu-etnaviv.mk \
|
||||
lib/mk/spec/arm_v8/mesa_gpu-lima.mk \
|
||||
lib/mk/spec/x86/mesa_gpu-iris.mk \
|
||||
lib/mk/spec/x86/iris.mk \
|
||||
lib/mk/spec/x86/iris_gen110.mk \
|
||||
|
@ -33,6 +33,14 @@ extern int etnaviv_drm_ioctl(unsigned long, void *);
|
||||
extern void *etnaviv_drm_mmap(off_t, size_t);
|
||||
extern int etnaviv_drm_munmap(void *);
|
||||
|
||||
/* lima driver */
|
||||
|
||||
extern void lima_drm_init();
|
||||
extern int lima_drm_ioctl(unsigned long, void *);
|
||||
extern void *lima_drm_mmap(off_t, size_t);
|
||||
extern int lima_drm_munmap(void *);
|
||||
extern int lima_drm_poll(int);
|
||||
|
||||
|
||||
static Libdrm::Driver drm_backend_type = Libdrm::Driver::INVALID;
|
||||
|
||||
@ -47,6 +55,10 @@ void drm_init(Libdrm::Driver driver)
|
||||
etnaviv_drm_init();
|
||||
drm_backend_type = Libdrm::Driver::ETNAVIV;
|
||||
break;
|
||||
case Libdrm::Driver::LIMA:
|
||||
lima_drm_init();
|
||||
drm_backend_type = Libdrm::Driver::LIMA;
|
||||
break;
|
||||
default:
|
||||
Genode::error(__func__, ": unknown back end, abort");
|
||||
abort();
|
||||
@ -61,6 +73,7 @@ extern "C" int genode_ioctl(int /* fd */, unsigned long request, void *arg)
|
||||
{
|
||||
switch (drm_backend_type) {
|
||||
case Libdrm::Driver::ETNAVIV: return etnaviv_drm_ioctl(request, arg);
|
||||
case Libdrm::Driver::LIMA: return lima_drm_ioctl(request, arg);
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
@ -79,6 +92,7 @@ extern "C" void *drm_mmap(void *addr, size_t length, int prot, int flags,
|
||||
|
||||
switch (drm_backend_type) {
|
||||
case Libdrm::Driver::ETNAVIV: return etnaviv_drm_mmap(offset, length);
|
||||
case Libdrm::Driver::LIMA: return lima_drm_mmap(offset, length);
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
@ -93,6 +107,24 @@ extern "C" int drm_munmap(void *addr, size_t length)
|
||||
|
||||
switch (drm_backend_type) {
|
||||
case Libdrm::Driver::ETNAVIV: return etnaviv_drm_munmap(addr);
|
||||
case Libdrm::Driver::LIMA: return lima_drm_munmap(addr);
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" int drm_poll(struct pollfd *fds, nfds_t nfds, int timeout)
|
||||
{
|
||||
(void)timeout;
|
||||
|
||||
if (nfds > 1) {
|
||||
Genode::error(__func__, ": cannot handle more the 1 pollfd");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (drm_backend_type) {
|
||||
case Libdrm::Driver::ETNAVIV: return -1;
|
||||
case Libdrm::Driver::LIMA: return lima_drm_poll(fds[0].fd);
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
864
repos/libports/src/lib/libdrm/ioctl_lima.cc
Normal file
864
repos/libports/src/lib/libdrm/ioctl_lima.cc
Normal file
@ -0,0 +1,864 @@
|
||||
/*
|
||||
* \brief DRM ioctl backend
|
||||
* \author Sebastian Sumpf
|
||||
* \author Josef Soentgen
|
||||
* \date 2017-05-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017-2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/attached_dataspace.h>
|
||||
#include <base/debug.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/log.h>
|
||||
#include <gpu_session/connection.h>
|
||||
#include <gpu/info_lima.h>
|
||||
#include <util/string.h>
|
||||
|
||||
#include <vfs_gpu.h>
|
||||
|
||||
extern "C" {
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include <drm.h>
|
||||
#include <drm-uapi/lima_drm.h>
|
||||
#include <libdrm_macros.h>
|
||||
}
|
||||
|
||||
|
||||
enum { verbose_ioctl = false };
|
||||
|
||||
|
||||
/**
|
||||
* Get DRM command number
|
||||
*/
|
||||
static unsigned long constexpr command_number(unsigned long request)
|
||||
{
|
||||
return request & 0xffu;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get device specific command number
|
||||
*/
|
||||
static unsigned long device_number(unsigned long request)
|
||||
{
|
||||
return command_number(request) - DRM_COMMAND_BASE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if request is device command
|
||||
*/
|
||||
static bool device_ioctl(unsigned long request)
|
||||
{
|
||||
long const cmd = command_number(request);
|
||||
return cmd >= DRM_COMMAND_BASE && cmd < DRM_COMMAND_END;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return name of DRM command
|
||||
*/
|
||||
const char *command_name(unsigned long request)
|
||||
{
|
||||
if (IOCGROUP(request) != DRM_IOCTL_BASE)
|
||||
return "<non-DRM>";
|
||||
|
||||
if (!device_ioctl(request)) {
|
||||
switch (command_number(request)) {
|
||||
case command_number(DRM_IOCTL_GEM_CLOSE): return "DRM_IOCTL_GEM_CLOSE";
|
||||
case command_number(DRM_IOCTL_GEM_FLINK): return "DRM_IOCTL_GEM_FLINK";
|
||||
case command_number(DRM_IOCTL_GEM_OPEN): return "DRM_IOCTL_GEM_OPEN";
|
||||
case command_number(DRM_IOCTL_GET_CAP): return "DRM_IOCTL_GET_CAP";
|
||||
case command_number(DRM_IOCTL_GET_UNIQUE): return "DRM_IOCTL_GET_UNIQUE";
|
||||
case command_number(DRM_IOCTL_PRIME_FD_TO_HANDLE): return "DRM_IOCTL_PRIME_FD_TO_HANDLE";
|
||||
case command_number(DRM_IOCTL_PRIME_HANDLE_TO_FD): return "DRM_IOCTL_PRIME_HANDLE_TO_FD";
|
||||
case command_number(DRM_IOCTL_SYNCOBJ_CREATE): return "DRM_IOCTL_SYNCOBJ_CREATE";
|
||||
case command_number(DRM_IOCTL_SYNCOBJ_DESTROY): return "DRM_IOCTL_SYNCOBJ_DESTROY";
|
||||
case command_number(DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD): return "DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD";
|
||||
case command_number(DRM_IOCTL_VERSION): return "DRM_IOCTL_VERSION";
|
||||
default: return "<unknown drm>";
|
||||
}
|
||||
}
|
||||
|
||||
switch (device_number(request)) {
|
||||
case DRM_LIMA_CTX_CREATE: return "DRM_LIMA_CTX_CREATE";
|
||||
case DRM_LIMA_CTX_FREE: return "DRM_LIMA_CTX_FREE";
|
||||
case DRM_LIMA_GET_PARAM: return "DRM_LIMA_GET_PARAM";
|
||||
case DRM_LIMA_GEM_CREATE: return "DRM_LIMA_GEM_CREATE";
|
||||
case DRM_LIMA_GEM_INFO: return "DRM_LIMA_GEM_INFO";
|
||||
case DRM_LIMA_GEM_SUBMIT: return "DRM_LIMA_GEM_SUBMIT";
|
||||
case DRM_LIMA_GEM_WAIT: return "DRM_LIMA_GEM_WAIT";
|
||||
default: return "<unknown driver>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace Lima {
|
||||
|
||||
size_t get_payload_size(drm_lima_gem_submit const &submit);
|
||||
|
||||
// XXX better implement as 'size_t for_each_object(T const *t, unsigned len, FN const &fn, char *dst)'
|
||||
template <typename FN, typename T> void for_each_object(T const *t, unsigned len, FN const &fn)
|
||||
{
|
||||
for (unsigned i = 0; i < len; i++) {
|
||||
T const *obj = &t[i];
|
||||
fn(obj);
|
||||
}
|
||||
}
|
||||
|
||||
void serialize(drm_lima_gem_submit *submit, char *content);
|
||||
|
||||
size_t get_payload_size(drm_version const &version);
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
|
||||
size_t Lima::get_payload_size(drm_lima_gem_submit const &submit)
|
||||
{
|
||||
size_t size = 0;
|
||||
|
||||
size += sizeof (drm_lima_gem_submit_bo) * submit.nr_bos;
|
||||
size += submit.frame_size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
void Lima::serialize(drm_lima_gem_submit *submit, char *content)
|
||||
{
|
||||
size_t offset = 0;
|
||||
|
||||
/* leave place for object itself first */
|
||||
offset += sizeof (*submit);
|
||||
|
||||
/* next are the buffer-objects */
|
||||
if (submit->nr_bos) {
|
||||
size_t const new_start = offset;
|
||||
|
||||
auto copy_bos = [&] (drm_lima_gem_submit_bo const *bo) {
|
||||
char * const dst = content + offset;
|
||||
Genode::memcpy(dst, bo, sizeof (*bo));
|
||||
offset += sizeof (*bo);
|
||||
};
|
||||
for_each_object((drm_lima_gem_submit_bo*)submit->bos,
|
||||
submit->nr_bos, copy_bos);
|
||||
submit->bos = reinterpret_cast<__u64>(new_start);
|
||||
}
|
||||
|
||||
/* next is the frame */
|
||||
{
|
||||
size_t const new_start = offset;
|
||||
|
||||
char * const dst = content + offset;
|
||||
Genode::memcpy(dst, reinterpret_cast<void const*>(submit->frame), submit->frame_size);
|
||||
offset += submit->frame_size;
|
||||
submit->frame = reinterpret_cast<__u64>(new_start);
|
||||
}
|
||||
|
||||
/* copy submit object last but into the front */
|
||||
Genode::memcpy(content, submit, sizeof (*submit));
|
||||
}
|
||||
|
||||
|
||||
size_t Lima::get_payload_size(drm_version const &version)
|
||||
{
|
||||
size_t size = 0;
|
||||
size += version.name_len;
|
||||
size += version.date_len;
|
||||
size += version.desc_len;
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
namespace Lima {
|
||||
using namespace Genode;
|
||||
using namespace Gpu;
|
||||
|
||||
struct Call;
|
||||
} /* namespace Gpu */
|
||||
|
||||
|
||||
struct Gpu::Buffer
|
||||
{
|
||||
Gpu::Connection &_gpu;
|
||||
|
||||
Genode::Id_space<Gpu::Buffer>::Element const _elem;
|
||||
|
||||
Genode::Dataspace_capability const cap;
|
||||
size_t const size;
|
||||
|
||||
Genode::Constructible<Genode::Attached_dataspace> _attached_buffer { };
|
||||
|
||||
Buffer(Gpu::Connection &gpu,
|
||||
size_t size,
|
||||
Genode::Id_space<Gpu::Buffer> &space)
|
||||
:
|
||||
_gpu { gpu },
|
||||
_elem { *this, space },
|
||||
cap { _gpu.alloc_buffer(_elem.id(), size) },
|
||||
size { size }
|
||||
{ }
|
||||
|
||||
virtual ~Buffer()
|
||||
{
|
||||
_gpu.free_buffer(_elem.id());
|
||||
}
|
||||
|
||||
bool mmap(Genode::Env &env)
|
||||
{
|
||||
if (!_attached_buffer.constructed()) {
|
||||
_attached_buffer.construct(env.rm(), cap);
|
||||
}
|
||||
|
||||
return _attached_buffer.constructed();
|
||||
}
|
||||
|
||||
Genode::addr_t mmap_addr()
|
||||
{
|
||||
return reinterpret_cast<addr_t>(_attached_buffer->local_addr<addr_t>());
|
||||
}
|
||||
|
||||
Gpu::Buffer_id id() const
|
||||
{
|
||||
return _elem.id();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Lima::Call
|
||||
{
|
||||
private:
|
||||
|
||||
/*
|
||||
* Noncopyable
|
||||
*/
|
||||
Call(Call const &) = delete;
|
||||
Call &operator=(Call const &) = delete;
|
||||
|
||||
Genode::Env &_env { *vfs_gpu_env() };
|
||||
Genode::Heap _heap { _env.ram(), _env.rm() };
|
||||
|
||||
/*****************
|
||||
** Gpu session **
|
||||
*****************/
|
||||
|
||||
struct Gpu_context
|
||||
{
|
||||
int const fd;
|
||||
unsigned long const _gpu_id;
|
||||
|
||||
Gpu::Connection &_gpu { *vfs_gpu_connection(_gpu_id) };
|
||||
|
||||
using Id_space = Genode::Id_space<Gpu_context>;
|
||||
Id_space::Element const _elem;
|
||||
|
||||
Gpu_context(int fd, unsigned long gpu,
|
||||
Genode::Id_space<Gpu_context> &space)
|
||||
: fd { fd }, _gpu_id { gpu }, _elem { *this, space } { }
|
||||
|
||||
virtual ~Gpu_context()
|
||||
{
|
||||
::close(fd);
|
||||
}
|
||||
|
||||
unsigned long id() const
|
||||
{
|
||||
return _elem.id().value;
|
||||
}
|
||||
|
||||
Gpu::Connection& gpu()
|
||||
{
|
||||
return _gpu;
|
||||
}
|
||||
};
|
||||
|
||||
using Gpu_context_space = Genode::Id_space<Gpu_context>;
|
||||
Gpu_context_space _gpu_context_space { };
|
||||
|
||||
Gpu_context &_create_ctx()
|
||||
{
|
||||
int const fd = ::open("/dev/gpu", 0);
|
||||
if (fd < 0) {
|
||||
Genode::error("Failed to open '/dev/gpu': ",
|
||||
"try configure '<gpu>' in 'dev' directory of VFS'");
|
||||
throw Gpu::Session::Invalid_state();
|
||||
}
|
||||
|
||||
struct ::stat buf;
|
||||
if (::fstat(fd, &buf) < 0) {
|
||||
Genode::error("Could not stat '/dev/gpu'");
|
||||
::close(fd);
|
||||
throw Gpu::Session::Invalid_state();
|
||||
}
|
||||
Gpu_context * context =
|
||||
new (_heap) Gpu_context(fd, buf.st_ino, _gpu_context_space);
|
||||
|
||||
return *context;
|
||||
}
|
||||
|
||||
struct Syncobj
|
||||
{
|
||||
/*
|
||||
* Noncopyable
|
||||
*/
|
||||
Syncobj(Syncobj const &) = delete;
|
||||
Syncobj &operator=(Syncobj const &) = delete;
|
||||
|
||||
|
||||
Gpu_context *_gc { nullptr };
|
||||
Gpu::Sequence_number _seqno { 0 };
|
||||
|
||||
using Id_space = Genode::Id_space<Syncobj>;
|
||||
Id_space::Element const _elem;
|
||||
|
||||
Syncobj(Id_space &space)
|
||||
: _elem { *this, space } { }
|
||||
|
||||
unsigned long id() const
|
||||
{
|
||||
return _elem.id().value;
|
||||
}
|
||||
|
||||
void adopt(Gpu_context &gc, Gpu::Sequence_number seqno)
|
||||
{
|
||||
_gc = &gc;
|
||||
_seqno = seqno;
|
||||
}
|
||||
|
||||
Gpu_context &gpu_context()
|
||||
{
|
||||
if (!_gc) {
|
||||
struct Invalid_gpu_context { };
|
||||
throw Invalid_gpu_context();
|
||||
}
|
||||
|
||||
return *_gc;
|
||||
}
|
||||
|
||||
Gpu::Sequence_number seqno() const
|
||||
{
|
||||
return _seqno;
|
||||
}
|
||||
};
|
||||
Genode::Id_space<Syncobj> _syncobj_space { };
|
||||
|
||||
struct Gpu_session
|
||||
{
|
||||
int const fd;
|
||||
unsigned long const id;
|
||||
|
||||
Gpu_session(int fd, unsigned long id)
|
||||
: fd { fd }, id { id } { }
|
||||
|
||||
virtual ~Gpu_session()
|
||||
{
|
||||
::close(fd);
|
||||
}
|
||||
|
||||
Gpu::Connection &gpu()
|
||||
{
|
||||
return *vfs_gpu_connection(id);
|
||||
}
|
||||
};
|
||||
|
||||
Gpu_session _open_gpu()
|
||||
{
|
||||
int const fd = ::open("/dev/gpu", 0);
|
||||
if (fd < 0) {
|
||||
Genode::error("Failed to open '/dev/gpu': ",
|
||||
"try configure '<gpu>' in 'dev' directory of VFS'");
|
||||
throw Gpu::Session::Invalid_state();
|
||||
}
|
||||
|
||||
struct ::stat buf;
|
||||
if (::fstat(fd, &buf) < 0) {
|
||||
Genode::error("Could not stat '/dev/gpu'");
|
||||
::close(fd);
|
||||
throw Gpu::Session::Invalid_state();
|
||||
}
|
||||
|
||||
return Gpu_session { fd, buf.st_ino };
|
||||
}
|
||||
|
||||
Gpu_session _gpu_session { _open_gpu() };
|
||||
|
||||
Gpu::Connection &_gpu { _gpu_session.gpu() };
|
||||
Gpu::Info_lima const &_gpu_info {
|
||||
*_gpu.attached_info<Gpu::Info_lima>() };
|
||||
|
||||
Id_space<Buffer> _buffer_space { };
|
||||
|
||||
/*
|
||||
* Play it safe, glmark2 apparently submits araound 110 KiB at
|
||||
* some point.
|
||||
*/
|
||||
enum { EXEC_BUFFER_SIZE = 256u << 10 };
|
||||
Constructible<Buffer> _exec_buffer { };
|
||||
|
||||
void _wait_for_mapping(uint32_t handle, unsigned op)
|
||||
{
|
||||
Buffer_id const id { .value = handle };
|
||||
do {
|
||||
if (_gpu.set_tiling(id, op))
|
||||
break;
|
||||
|
||||
char buf;
|
||||
(void)::read(_gpu_session.fd, &buf, sizeof(buf));
|
||||
} while (true);
|
||||
}
|
||||
|
||||
void _wait_for_syncobj(unsigned int handle)
|
||||
{
|
||||
Syncobj::Id_space::Id syncobj_id { .value = handle };
|
||||
|
||||
try {
|
||||
auto wait = [&] (Syncobj &sync_obj) {
|
||||
|
||||
Gpu_context &gc = sync_obj.gpu_context();
|
||||
do {
|
||||
if (gc.gpu().complete(sync_obj.seqno()))
|
||||
break;
|
||||
|
||||
char buf;
|
||||
(void)::read(gc.fd, &buf, sizeof(buf));
|
||||
} while (true);
|
||||
};
|
||||
_syncobj_space.apply<Syncobj>(syncobj_id, wait);
|
||||
} catch (Genode::Id_space<Lima::Call::Syncobj>::Unknown_id) { }
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
bool _apply_handle(uint32_t handle, FN const &fn)
|
||||
{
|
||||
Buffer_id const id { .value = handle };
|
||||
|
||||
bool found = false;
|
||||
_buffer_space.apply<Buffer>(id, [&] (Buffer &b) {
|
||||
fn(b);
|
||||
found = true;
|
||||
});
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
Dataspace_capability _lookup_cap_from_handle(uint32_t handle)
|
||||
{
|
||||
Dataspace_capability cap { };
|
||||
auto lookup_cap = [&] (Buffer const &b) {
|
||||
cap = b.cap;
|
||||
};
|
||||
(void)_apply_handle(handle, lookup_cap);
|
||||
return cap;
|
||||
}
|
||||
|
||||
/******************************
|
||||
** Device DRM I/O controls **
|
||||
******************************/
|
||||
|
||||
int _drm_lima_gem_info(drm_lima_gem_info &arg)
|
||||
{
|
||||
int result = -1;
|
||||
(void)_apply_handle(arg.handle, [&] (Buffer &b) {
|
||||
if (!b.mmap(_env))
|
||||
return;
|
||||
arg.offset = reinterpret_cast<::uint64_t>(b.mmap_addr());
|
||||
|
||||
Gpu::addr_t const va = _gpu.query_buffer_ppgtt(b.id());
|
||||
if (va == (Gpu::addr_t)-1)
|
||||
return;
|
||||
arg.va = (uint32_t)va;
|
||||
|
||||
result = 0;
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename FUNC>
|
||||
void _alloc_buffer(::uint64_t const size, FUNC const &fn)
|
||||
{
|
||||
size_t donate = size;
|
||||
Buffer *buffer = nullptr;
|
||||
|
||||
retry<Gpu::Session::Out_of_ram>(
|
||||
[&] () {
|
||||
retry<Gpu::Session::Out_of_caps>(
|
||||
[&] () {
|
||||
buffer =
|
||||
new (&_heap) Buffer(_gpu, size,
|
||||
_buffer_space);
|
||||
},
|
||||
[&] () {
|
||||
_gpu.upgrade_caps(2);
|
||||
});
|
||||
},
|
||||
[&] () {
|
||||
_gpu.upgrade_ram(donate);
|
||||
});
|
||||
|
||||
if (buffer)
|
||||
fn(*buffer);
|
||||
}
|
||||
|
||||
int _drm_lima_gem_create(drm_lima_gem_create &arg)
|
||||
{
|
||||
::uint64_t const size = arg.size;
|
||||
|
||||
try {
|
||||
_alloc_buffer(size, [&](Buffer const &b) {
|
||||
arg.handle = b.id().value;
|
||||
});
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int _drm_lima_gem_submit(drm_lima_gem_submit &arg)
|
||||
{
|
||||
Gpu_context::Id_space::Id ctx_id { .value = arg.ctx };
|
||||
|
||||
Syncobj::Id_space::Id syncobj_id { .value = arg.out_sync };
|
||||
|
||||
bool result = false;
|
||||
_syncobj_space.apply<Syncobj>(syncobj_id, [&] (Syncobj &sync_obj) {
|
||||
|
||||
_gpu_context_space.apply<Gpu_context>(ctx_id, [&] (Gpu_context &gc) {
|
||||
|
||||
size_t const payload_size = Lima::get_payload_size(arg);
|
||||
if (payload_size > EXEC_BUFFER_SIZE) {
|
||||
Genode::error(__func__, ": exec buffer too small (",
|
||||
(unsigned)EXEC_BUFFER_SIZE, ") needed ", payload_size);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy each array flat to the exec buffer and adjust the
|
||||
* addresses in the submit object.
|
||||
*/
|
||||
char *local_exec_buffer = (char*)_exec_buffer->mmap_addr();
|
||||
Genode::memset(local_exec_buffer, 0, EXEC_BUFFER_SIZE);
|
||||
Lima::serialize(&arg, local_exec_buffer);
|
||||
|
||||
try {
|
||||
Gpu::Connection &gpu = gc.gpu();
|
||||
|
||||
Gpu::Sequence_number const seqno =
|
||||
gpu.exec_buffer(_exec_buffer->id(), EXEC_BUFFER_SIZE);
|
||||
|
||||
sync_obj.adopt(gc, seqno);
|
||||
|
||||
result = true;
|
||||
} catch (Gpu::Session::Invalid_state) { }
|
||||
});
|
||||
});
|
||||
|
||||
return result ? 0 : -1;
|
||||
}
|
||||
|
||||
int _drm_lima_gem_wait(drm_lima_gem_wait &arg)
|
||||
{
|
||||
/*
|
||||
* For the moment we do not handle timeouts
|
||||
*/
|
||||
(void)arg.timeout_ns;
|
||||
_wait_for_mapping(arg.handle, arg.op);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _drm_lima_get_param(drm_lima_get_param &arg)
|
||||
{
|
||||
if (arg.param > Gpu::Info_lima::MAX_LIMA_PARAMS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
arg.value = _gpu_info.param[arg.param];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _drm_lima_ctx_create(drm_lima_ctx_create &arg)
|
||||
{
|
||||
try {
|
||||
Gpu_context &ctx = _create_ctx();
|
||||
|
||||
arg.id = ctx.id();
|
||||
return 0;
|
||||
} catch (... /* intentional catch-all ... */) {
|
||||
/* ... as the lima GPU driver will not throw */
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _drm_lima_ctx_free(drm_lima_ctx_free &arg)
|
||||
{
|
||||
Gpu_context::Id_space::Id id { .value = arg.id };
|
||||
|
||||
bool result = false;
|
||||
auto free_ctx = [&] (Gpu_context &ctx) {
|
||||
::close(ctx.fd);
|
||||
Genode::destroy(_heap, &ctx);
|
||||
result = true;
|
||||
};
|
||||
_gpu_context_space.apply<Gpu_context>(id, free_ctx);
|
||||
|
||||
return result ? 0 : -1;
|
||||
}
|
||||
|
||||
int _device_ioctl(unsigned cmd, void *arg)
|
||||
{
|
||||
if (!arg) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case DRM_LIMA_CTX_CREATE:
|
||||
return _drm_lima_ctx_create(*reinterpret_cast<drm_lima_ctx_create*>(arg));
|
||||
case DRM_LIMA_CTX_FREE:
|
||||
return _drm_lima_ctx_free(*reinterpret_cast<drm_lima_ctx_free*>(arg));
|
||||
case DRM_LIMA_GEM_INFO:
|
||||
return _drm_lima_gem_info(*reinterpret_cast<drm_lima_gem_info*>(arg));
|
||||
case DRM_LIMA_GEM_CREATE:
|
||||
return _drm_lima_gem_create(*reinterpret_cast<drm_lima_gem_create*>(arg));
|
||||
case DRM_LIMA_GEM_SUBMIT:
|
||||
return _drm_lima_gem_submit(*reinterpret_cast<drm_lima_gem_submit*>(arg));
|
||||
case DRM_LIMA_GEM_WAIT:
|
||||
return _drm_lima_gem_wait(*reinterpret_cast<drm_lima_gem_wait*>(arg));
|
||||
case DRM_LIMA_GET_PARAM:
|
||||
return _drm_lima_get_param(*reinterpret_cast<drm_lima_get_param*>(arg));
|
||||
default: break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************
|
||||
** Generic DRM I/O controls **
|
||||
*******************************/
|
||||
|
||||
int _drm_gem_close(drm_gem_close const &gem_close)
|
||||
{
|
||||
return _apply_handle(gem_close.handle,
|
||||
[&] (Gpu::Buffer &b) {
|
||||
destroy(_heap, &b);
|
||||
}) ? 0 : -1;
|
||||
}
|
||||
|
||||
int _drm_version(drm_version &version)
|
||||
{
|
||||
version.version_major = 1;
|
||||
version.version_minor = 1;
|
||||
version.version_patchlevel = 0;
|
||||
|
||||
/**
|
||||
* Libdrm probes the length by calling version twice
|
||||
* and the second time strings are allocated.
|
||||
*/
|
||||
|
||||
version.name_len = 1;
|
||||
if (version.name)
|
||||
version.name[0] = '\0';
|
||||
version.date_len = 1;
|
||||
if (version.date)
|
||||
version.date[0] = '\0';
|
||||
version.desc_len = 1;
|
||||
if (version.desc)
|
||||
version.desc[0] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _drm_syncobj_create(drm_syncobj_create &arg)
|
||||
{
|
||||
try {
|
||||
Syncobj *obj = new (_heap) Syncobj(_syncobj_space);
|
||||
arg.handle = (uint32_t)obj->id();
|
||||
return 0;
|
||||
} catch (... /* XXX which exceptions can occur? */) { }
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _drm_syncobj_destroy(drm_syncobj_destroy &arg)
|
||||
{
|
||||
Syncobj::Id_space::Id id { .value = arg.handle };
|
||||
|
||||
bool result = false;
|
||||
_syncobj_space.apply<Syncobj>(id, [&] (Syncobj &obj) {
|
||||
Genode::destroy(_heap, &obj);
|
||||
result = true;
|
||||
});
|
||||
return result ? 0 : -1;
|
||||
}
|
||||
|
||||
int _drm_syncobj_handle_to_fd(drm_syncobj_handle &arg)
|
||||
{
|
||||
arg.fd = arg.handle + SYNC_FD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _generic_ioctl(unsigned cmd, void *arg)
|
||||
{
|
||||
if (!arg) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case command_number(DRM_IOCTL_GEM_CLOSE):
|
||||
return _drm_gem_close(*reinterpret_cast<drm_gem_close*>(arg));
|
||||
case command_number(DRM_IOCTL_VERSION):
|
||||
return _drm_version(*reinterpret_cast<drm_version*>(arg));
|
||||
case command_number(DRM_IOCTL_SYNCOBJ_CREATE):
|
||||
return _drm_syncobj_create(*reinterpret_cast<drm_syncobj_create*>(arg));
|
||||
case command_number(DRM_IOCTL_SYNCOBJ_DESTROY):
|
||||
return _drm_syncobj_destroy(*reinterpret_cast<drm_syncobj_destroy*>(arg));
|
||||
case command_number(DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD):
|
||||
return _drm_syncobj_handle_to_fd(*reinterpret_cast<drm_syncobj_handle*>(arg));
|
||||
default:
|
||||
error("unhandled generic DRM ioctl: ", Genode::Hex(cmd));
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
static constexpr int const SYNC_FD { 384 };
|
||||
|
||||
Call()
|
||||
{
|
||||
try {
|
||||
_exec_buffer.construct(_gpu,
|
||||
(size_t)EXEC_BUFFER_SIZE,
|
||||
_buffer_space);
|
||||
} catch (...) {
|
||||
throw Gpu::Session::Invalid_state();
|
||||
}
|
||||
if (!_exec_buffer->mmap(_env))
|
||||
throw Gpu::Session::Invalid_state();
|
||||
}
|
||||
|
||||
~Call()
|
||||
{
|
||||
while (_gpu_context_space.apply_any<Gpu_context>([&] (Gpu_context &ctx) {
|
||||
Genode::destroy(_heap, &ctx); })) { ; }
|
||||
|
||||
while (_syncobj_space.apply_any<Syncobj>([&] (Syncobj &obj) {
|
||||
Genode::destroy(_heap, &obj); })) { ; }
|
||||
}
|
||||
|
||||
int ioctl(unsigned long request, void *arg)
|
||||
{
|
||||
bool const device_request = device_ioctl(request);
|
||||
return device_request ? _device_ioctl(device_number(request), arg)
|
||||
: _generic_ioctl(command_number(request), arg);
|
||||
}
|
||||
|
||||
void *mmap(unsigned long offset, unsigned long /* size */)
|
||||
{
|
||||
/*
|
||||
* Buffer should have been mapped during GEM INFO call.
|
||||
*/
|
||||
return (void*)offset;
|
||||
}
|
||||
|
||||
void munmap(void *addr)
|
||||
{
|
||||
/*
|
||||
* We rely on GEM CLOSE to destroy the buffer and thereby
|
||||
* to remove the local mapping. AFAICT the 'munmap' is indeed
|
||||
* (always) followed by the CLOSE I/O control.
|
||||
*/
|
||||
(void)addr;
|
||||
}
|
||||
|
||||
void wait_for_syncobj(unsigned int handle)
|
||||
{
|
||||
_wait_for_syncobj(handle);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static Genode::Constructible<Lima::Call> _drm;
|
||||
|
||||
|
||||
void lima_drm_init()
|
||||
{
|
||||
/* make sure VFS is initialized */
|
||||
struct ::stat buf;
|
||||
if (stat("/dev/gpu", &buf) < 0) {
|
||||
Genode::error("'/dev/gpu' not accessible: ",
|
||||
"try configure '<gpu>' in 'dev' directory of VFS'");
|
||||
return;
|
||||
}
|
||||
|
||||
_drm.construct();
|
||||
}
|
||||
|
||||
|
||||
static void dump_ioctl(unsigned long request)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
log("ioctl(request=", Hex(request),
|
||||
(request & 0xe0000000u) == IOC_OUT ? " out" :
|
||||
(request & 0xe0000000u) == IOC_IN ? " in" :
|
||||
(request & 0xe0000000u) == IOC_INOUT ? " inout" : " void",
|
||||
" len=", IOCPARM_LEN(request),
|
||||
" cmd=", command_name(request), " (", Hex(command_number(request)), "))");
|
||||
}
|
||||
|
||||
|
||||
int lima_drm_ioctl(unsigned long request, void *arg)
|
||||
{
|
||||
if (verbose_ioctl)
|
||||
dump_ioctl(request);
|
||||
|
||||
try {
|
||||
int ret = _drm->ioctl(request, arg);
|
||||
|
||||
if (verbose_ioctl)
|
||||
Genode::log("returned ", ret);
|
||||
|
||||
return ret;
|
||||
} catch (...) { }
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void *lima_drm_mmap(off_t offset, size_t length)
|
||||
{
|
||||
return _drm->mmap(offset, length);
|
||||
}
|
||||
|
||||
|
||||
int lima_drm_munmap(void *addr)
|
||||
{
|
||||
_drm->munmap(addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int lima_drm_poll(int fd)
|
||||
{
|
||||
int const handle = fd - Lima::Call::SYNC_FD;
|
||||
_drm->wait_for_syncobj((unsigned)handle);
|
||||
return 0;
|
||||
}
|
@ -285,6 +285,7 @@ mesa-21.0.0/src/compiler/nir/nir_lower_double_ops.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_drawpixels.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_flatshade.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_flrp.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_fragcoord_wtrans.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_frexp.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_global_vars_to_local.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_goto_ifs.c
|
||||
@ -305,6 +306,7 @@ mesa-21.0.0/src/compiler/nir/nir_lower_passthrough_edgeflags.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_patch_vertices.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_phis_to_scalar.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_pntc_ytransform.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_point_size.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_point_size_mov.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_regs_to_ssa.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_returns.c
|
||||
@ -320,6 +322,7 @@ mesa-21.0.0/src/compiler/nir/nir_lower_var_copies.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_variable_initializers.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_vars_to_ssa.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_vec_to_movs.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_viewport_transform.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_lower_wpos_ytransform.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_metadata.c
|
||||
mesa-21.0.0/src/compiler/nir/nir_move_vec_src_uses_to_dest.c
|
||||
@ -733,6 +736,7 @@ mesa-21.0.0/src/gallium/auxiliary/util/u_screen.c
|
||||
mesa-21.0.0/src/gallium/auxiliary/util/u_screen.h
|
||||
mesa-21.0.0/src/gallium/auxiliary/util/u_simple_shaders.c
|
||||
mesa-21.0.0/src/gallium/auxiliary/util/u_simple_shaders.h
|
||||
mesa-21.0.0/src/gallium/auxiliary/util/u_split_draw.c
|
||||
mesa-21.0.0/src/gallium/auxiliary/util/u_split_draw.h
|
||||
mesa-21.0.0/src/gallium/auxiliary/util/u_split_prim.h
|
||||
mesa-21.0.0/src/gallium/auxiliary/util/u_sse.h
|
||||
@ -841,6 +845,63 @@ mesa-21.0.0/src/gallium/drivers/etnaviv/hw/state_3d.xml.h
|
||||
mesa-21.0.0/src/gallium/drivers/etnaviv/hw/state_blt.xml.h
|
||||
mesa-21.0.0/src/gallium/drivers/etnaviv/hw/state.xml.h
|
||||
mesa-21.0.0/src/gallium/drivers/etnaviv/hw/texdesc_3d.xml.h
|
||||
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/gp/codegen.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/gp/codegen.h
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/gp/disasm.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/gp/gpir.h
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/gp/instr.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/gp/lower.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/gp/nir.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/gp/node.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/gp/optimize.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/gp/reduce_scheduler.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/gp/regalloc.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/gp/scheduler.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/lima_ir.h
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/lima_nir_algebraic.py
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/lima_nir_duplicate_consts.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/lima_nir_duplicate_intrinsic.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/lima_nir_lower_uniform_to_scalar.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/lima_nir_split_load_input.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/pp/codegen.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/pp/codegen.h
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/pp/disasm.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/pp/instr.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/pp/liveness.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/pp/lower.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/pp/nir.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/pp/node.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/pp/node_to_instr.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/pp/ppir.h
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/pp/regalloc.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/ir/pp/scheduler.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_bo.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_bo.h
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_context.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_context.h
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_draw.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_fence.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_fence.h
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_format.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_format.h
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_gpu.h
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_job.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_job.h
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_parser.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_parser.h
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_program.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_program.h
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_query.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_resource.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_resource.h
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_screen.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_screen.h
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_state.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_texture.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_texture.h
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_util.c
|
||||
mesa-21.0.0/src/gallium/drivers/lima/lima_util.h
|
||||
mesa-21.0.0/src/gallium/drivers/softpipe/sp_buffer.c
|
||||
mesa-21.0.0/src/gallium/drivers/softpipe/sp_buffer.h
|
||||
mesa-21.0.0/src/gallium/drivers/softpipe/sp_clear.c
|
||||
@ -934,6 +995,8 @@ mesa-21.0.0/src/gallium/include/pipe/p_video_state.h
|
||||
mesa-21.0.0/src/gallium/targets/dri/target.c
|
||||
mesa-21.0.0/src/gallium/winsys/etnaviv/drm/etnaviv_drm_public.h
|
||||
mesa-21.0.0/src/gallium/winsys/etnaviv/drm/etnaviv_drm_winsys.c
|
||||
mesa-21.0.0/src/gallium/winsys/lima/drm/lima_drm_winsys.c
|
||||
mesa-21.0.0/src/gallium/winsys/lima/drm/lima_drm_public.h
|
||||
mesa-21.0.0/src/gallium/winsys/sw/dri/dri_sw_winsys.c
|
||||
mesa-21.0.0/src/gallium/winsys/sw/dri/dri_sw_winsys.h
|
||||
mesa-21.0.0/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.h
|
||||
@ -1584,6 +1647,10 @@ mesa-21.0.0/src/mesa/x86/norm_args.h
|
||||
mesa-21.0.0/src/mesa/x86/sse.h
|
||||
mesa-21.0.0/src/mesa/x86/x86_xform.h
|
||||
mesa-21.0.0/src/mesa/x86/xform_args.h
|
||||
mesa-21.0.0/src/panfrost/shared/pan_minmax_cache.c
|
||||
mesa-21.0.0/src/panfrost/shared/pan_minmax_cache.h
|
||||
mesa-21.0.0/src/panfrost/shared/pan_tiling.c
|
||||
mesa-21.0.0/src/panfrost/shared/pan_tiling.h
|
||||
mesa-21.0.0/src/util/anon_file.h
|
||||
mesa-21.0.0/src/util/bigmath.h
|
||||
mesa-21.0.0/src/util/bitscan.h
|
||||
|
27
repos/libports/src/lib/mesa/lima/drm_init.cc
Normal file
27
repos/libports/src/lib/mesa/lima/drm_init.cc
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* \brief Initialize DRM libraries session interface
|
||||
* \author Josef Soentgen
|
||||
* \date 2021-04-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021-2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <../include/util/list.h>
|
||||
#include <base/env.h>
|
||||
|
||||
#include <libdrm/ioctl_dispatch.h>
|
||||
|
||||
extern "C" {
|
||||
#include <platform.h>
|
||||
}
|
||||
|
||||
void genode_drm_init(void)
|
||||
{
|
||||
drm_init(Libdrm::Driver::LIMA);
|
||||
}
|
269
repos/libports/src/lib/mesa/lima/platform_lima.c
Normal file
269
repos/libports/src/lib/mesa/lima/platform_lima.c
Normal file
@ -0,0 +1,269 @@
|
||||
/**
|
||||
* \brief lima (mali) EGL-DRI2 back end
|
||||
* \author Sebastian Sumpf
|
||||
* \author Josef Soentgen
|
||||
* \date 2021-04-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021-2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
/*
|
||||
* Mesa
|
||||
*/
|
||||
#include <egl_dri2.h>
|
||||
#include <drivers/dri/common/utils.h>
|
||||
/*
|
||||
* Libc
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
/*
|
||||
* Local
|
||||
*/
|
||||
#include <platform.h>
|
||||
|
||||
|
||||
static int stride(int value)
|
||||
{
|
||||
/* 32-bit RGB888 */
|
||||
return value * 4;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dri2_genode_lima_put_image(__DRIdrawable * draw, int op,
|
||||
int x, int y, int w, int h,
|
||||
char *data, void *loaderPrivate)
|
||||
{
|
||||
struct dri2_egl_surface *dri2_surf = loaderPrivate;
|
||||
struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display);
|
||||
struct Genode_egl_window *window = dri2_surf->g_win;
|
||||
unsigned char *dst = window->addr;
|
||||
|
||||
int src_stride;
|
||||
int dst_stride = stride(dri2_surf->base.Width);
|
||||
dri2_dpy->image->queryImage(dri2_surf->back_image, __DRI_IMAGE_ATTRIB_STRIDE, &src_stride);
|
||||
|
||||
int copy_width = src_stride;
|
||||
int x_offset = stride(x);
|
||||
|
||||
dst += x_offset;
|
||||
dst += y * dst_stride;
|
||||
|
||||
/* copy width over stride boundary */
|
||||
if (copy_width > dst_stride - x_offset)
|
||||
copy_width = dst_stride - x_offset;
|
||||
|
||||
/* limit height */
|
||||
if (h > dri2_surf->base.Height - y)
|
||||
h = dri2_surf->base.Height - y;
|
||||
|
||||
/* copy to frame buffer and refresh */
|
||||
genode_blit(data, src_stride, dst, dst_stride, copy_width, h);
|
||||
}
|
||||
|
||||
|
||||
static EGLBoolean
|
||||
dri2_genode_lima_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
|
||||
{
|
||||
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
|
||||
struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display);
|
||||
|
||||
dri2_flush_drawable_for_swapbuffers(disp, draw);
|
||||
dri2_dpy->flush->invalidate(dri2_surf->dri_drawable);
|
||||
|
||||
_EGLContext *ctx = _eglGetCurrentContext();
|
||||
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
|
||||
void *map_data = NULL;
|
||||
int stride;
|
||||
void *data =
|
||||
dri2_dpy->image->mapImage(dri2_ctx->dri_context, dri2_surf->back_image,
|
||||
0, 0,
|
||||
dri2_surf->base.Width,
|
||||
dri2_surf->base.Height,
|
||||
__DRI_IMAGE_TRANSFER_READ, &stride,
|
||||
&map_data);
|
||||
if (data) {
|
||||
dri2_genode_lima_put_image(dri2_surf->dri_drawable, 0, 0, 0,
|
||||
dri2_surf->base.Width, dri2_surf->base.Height,
|
||||
(char *)data, (void *)dri2_surf);
|
||||
|
||||
dri2_dpy->image->unmapImage(dri2_ctx->dri_context,
|
||||
dri2_surf->back_image, map_data);
|
||||
}
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static struct dri2_egl_display_vtbl dri2_genode_display_vtbl = {
|
||||
.authenticate = NULL,
|
||||
.create_window_surface = dri2_genode_create_window_surface,
|
||||
.create_pixmap_surface = dri2_genode_create_pixmap_surface,
|
||||
.destroy_surface = dri2_genode_destroy_surface,
|
||||
.swap_interval = dri2_genode_swap_interval,
|
||||
.swap_buffers = dri2_genode_lima_swap_buffers,
|
||||
.get_dri_drawable = dri2_surface_get_dri_drawable,
|
||||
};
|
||||
|
||||
|
||||
static __DRIbuffer *
|
||||
dri2_genode_get_buffers(__DRIdrawable * driDrawable,
|
||||
int *width, int *height,
|
||||
unsigned int *attachments, int count,
|
||||
int *out_count, void *loaderPrivate)
|
||||
{
|
||||
_eglError(EGL_BAD_PARAMETER, "dri2_genode_get_buffers not implemented");
|
||||
*out_count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dri2_genode_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
|
||||
{
|
||||
_eglError(EGL_BAD_PARAMETER, "dri2_genode_flush_front_buffer not implemented");
|
||||
}
|
||||
|
||||
|
||||
static __DRIbuffer *
|
||||
dri2_genode_get_buffers_with_format(__DRIdrawable * driDrawable,
|
||||
int *width, int *height,
|
||||
unsigned int *attachments, int count,
|
||||
int *out_count, void *loaderPrivate)
|
||||
{
|
||||
_eglError(EGL_BAD_PARAMETER, "dri2_genode_get_buffers_with_format not implemented");
|
||||
*out_count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dri2_genode_image_get_buffers(__DRIdrawable *driDrawable,
|
||||
unsigned int format,
|
||||
uint32_t *stamp,
|
||||
void *loaderPrivate,
|
||||
uint32_t buffer_mask,
|
||||
struct __DRIimageList *buffers)
|
||||
{
|
||||
struct dri2_egl_surface *dri2_surf = loaderPrivate;
|
||||
|
||||
buffers->image_mask = 0;
|
||||
buffers->front = NULL;
|
||||
buffers->back = NULL;
|
||||
|
||||
buffers->image_mask = __DRI_IMAGE_BUFFER_BACK;
|
||||
buffers->back = dri2_surf->back_image;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const __DRIdri2LoaderExtension dri2_loader_extension = {
|
||||
.base = { __DRI_DRI2_LOADER, 3 },
|
||||
|
||||
.getBuffers = dri2_genode_get_buffers,
|
||||
.flushFrontBuffer = dri2_genode_flush_front_buffer,
|
||||
.getBuffersWithFormat = dri2_genode_get_buffers_with_format,
|
||||
};
|
||||
|
||||
|
||||
static const __DRIimageLoaderExtension image_loader_extension = {
|
||||
.base = { __DRI_IMAGE_LOADER, 1 },
|
||||
.getBuffers = dri2_genode_image_get_buffers,
|
||||
.flushFrontBuffer = dri2_genode_flush_front_buffer,
|
||||
};
|
||||
|
||||
static const __DRIextension *dri2_loader_extensions[] = {
|
||||
&dri2_loader_extension.base,
|
||||
&image_loader_extension.base,
|
||||
&image_lookup_extension.base,
|
||||
&background_callable_extension.base,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
|
||||
static EGLBoolean dri2_initialize_genode_lima(_EGLDisplay *disp)
|
||||
{
|
||||
struct dri2_egl_display *dri2_dpy;
|
||||
static int rgb888_shifts[4] = { 16, 8, 0, 24 };
|
||||
static unsigned rgb888_sizes[4] = { 8, 8, 8, 8 };
|
||||
int i;
|
||||
|
||||
/* initialize DRM back end */
|
||||
genode_drm_init();
|
||||
|
||||
dri2_dpy = calloc(1, sizeof *dri2_dpy);
|
||||
if (!dri2_dpy)
|
||||
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||
|
||||
dri2_dpy->fd = 44;
|
||||
dri2_dpy->driver_name = strdup("lima");
|
||||
|
||||
disp->DriverData = (void *)dri2_dpy;
|
||||
if (!dri2_load_driver_dri3(disp))
|
||||
goto close_driver;
|
||||
|
||||
dri2_dpy->dri2_major = 2;
|
||||
dri2_dpy->dri2_minor = __DRI_DRI2_VERSION;
|
||||
|
||||
dri2_dpy->loader_extensions = dri2_loader_extensions;
|
||||
|
||||
/*
|
||||
* The driver extensions are queried by the loader, where the
|
||||
* extensions point to '__driDriverGetExtensions_lima' that
|
||||
* in return is wraps the 'galliumdrm_driver_extensions'.
|
||||
* The the third entry in the 'galliumdrm_driver_extensions' array
|
||||
* points 'driDRI2Extension.base', which is the extension we are
|
||||
* interested in.
|
||||
*
|
||||
* extern const __DRIextension **__driDriverGetExtensions_lima(void);
|
||||
* dri2_dpy->driver_extensions = __driDriverGetExtensions_lima();
|
||||
*/
|
||||
dri2_dpy->dri2 = (const __DRIdri2Extension*)dri2_dpy->driver_extensions[2];
|
||||
|
||||
if (!dri2_create_screen(disp))
|
||||
goto close_screen;
|
||||
|
||||
if (!dri2_setup_extensions(disp))
|
||||
goto close_screen;
|
||||
|
||||
dri2_setup_screen(disp);
|
||||
|
||||
EGLint attrs[] = {
|
||||
EGL_DEPTH_SIZE, 0, /* set in loop below (from DRI config) */
|
||||
EGL_NATIVE_VISUAL_TYPE, 0,
|
||||
EGL_NATIVE_VISUAL_ID, 0,
|
||||
EGL_NONE };
|
||||
|
||||
for (i = 0; dri2_dpy->driver_configs[i]; i++) {
|
||||
/* set depth size in attrs */
|
||||
attrs[1] = dri2_dpy->driver_configs[i]->modes.depthBits;
|
||||
dri2_add_config(disp, dri2_dpy->driver_configs[i], i,
|
||||
EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT,
|
||||
attrs, rgb888_shifts, rgb888_sizes);
|
||||
}
|
||||
|
||||
dri2_dpy->vtbl = &dri2_genode_display_vtbl;
|
||||
|
||||
return EGL_TRUE;
|
||||
|
||||
close_screen:
|
||||
dlclose(dri2_dpy->driver);
|
||||
close_driver:
|
||||
free(dri2_dpy);
|
||||
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
EGLBoolean dri2_initialize_genode_backend(_EGLDisplay *disp)
|
||||
{
|
||||
return dri2_initialize_genode_lima(disp);
|
||||
}
|
3
repos/libports/src/lib/mesa/lima/target.mk
Normal file
3
repos/libports/src/lib/mesa/lima/target.mk
Normal file
@ -0,0 +1,3 @@
|
||||
REQUIRES := arm_v8a
|
||||
TARGET := dummy-mesa_gpu-lima
|
||||
LIBS := mesa_gpu-lima
|
12
repos/libports/src/lib/mesa/patches/lima.patch
Normal file
12
repos/libports/src/lib/mesa/patches/lima.patch
Normal file
@ -0,0 +1,12 @@
|
||||
--- a/src/lib/mesa/src/loader/loader.c
|
||||
--- b/src/lib/mesa/src/loader/loader.c
|
||||
@@ -473,6 +473,9 @@
|
||||
if (fd == 43) {
|
||||
return strdup("iris");
|
||||
}
|
||||
+ if (fd == 44) {
|
||||
+ return strdup("lima");
|
||||
+ }
|
||||
char *driver;
|
||||
|
||||
/* Allow an environment variable to force choosing a different driver
|
20
repos/libports/src/lib/mesa/patches/sync_wait.patch
Normal file
20
repos/libports/src/lib/mesa/patches/sync_wait.patch
Normal file
@ -0,0 +1,20 @@
|
||||
--- a/src/lib/mesa/src/util/libsync.h
|
||||
+++ b/src/lib/mesa/src/util/libsync.h
|
||||
@@ -65,6 +65,8 @@
|
||||
#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 3, struct sync_merge_data)
|
||||
#endif
|
||||
|
||||
+extern int drm_poll(struct pollfd *, nfds_t, int);
|
||||
+
|
||||
static inline int sync_wait(int fd, int timeout)
|
||||
{
|
||||
struct pollfd fds = {0};
|
||||
@@ -74,7 +76,7 @@
|
||||
fds.events = POLLIN;
|
||||
|
||||
do {
|
||||
- ret = poll(&fds, 1, timeout);
|
||||
+ ret = drm_poll(&fds, 1, timeout);
|
||||
if (ret > 0) {
|
||||
if (fds.revents & (POLLERR | POLLNVAL)) {
|
||||
errno = EINVAL;
|
Loading…
x
Reference in New Issue
Block a user