From 00ba5a9ddd04b44cebf2bbd6014da57f06413d5e Mon Sep 17 00:00:00 2001 From: Chih-Wei Huang Date: Thu, 1 Jan 2015 16:21:46 +0800 Subject: gralloc_drm: improve log --- gralloc_drm.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/gralloc_drm.c b/gralloc_drm.c index bd38d57..bd752cb 100644 --- a/gralloc_drm.c +++ b/gralloc_drm.c @@ -70,26 +70,31 @@ init_drv_from_fd(int fd) if (version->name) { #ifdef ENABLE_PIPE drv = gralloc_drm_drv_create_for_pipe(fd, version->name); + ALOGI_IF(drv, "create pipe for driver %s", version->name); #endif #ifdef ENABLE_INTEL - if (!drv && !strcmp(version->name, "i915")) + if (!drv && !strcmp(version->name, "i915")) { drv = gralloc_drm_drv_create_for_intel(fd); + ALOGI_IF(drv, "create intel for driver i915"); + } #endif #ifdef ENABLE_RADEON - if (!drv && !strcmp(version->name, "radeon")) + if (!drv && !strcmp(version->name, "radeon")) { drv = gralloc_drm_drv_create_for_radeon(fd); + ALOGI_IF(drv, "create radeon for driver radeon"); + } #endif #ifdef ENABLE_NOUVEAU - if (!drv && !strcmp(version->name, "nouveau")) + if (!drv && !strcmp(version->name, "nouveau")) { drv = gralloc_drm_drv_create_for_nouveau(fd); + ALOGI_IF(drv, "create nouveau for driver nouveau"); + } #endif } - if (!drv) { - ALOGE("unsupported driver: %s", (version->name) ? - version->name : "NULL"); - } + ALOGE_IF(!drv, "unsupported driver: %s", (version->name) ? + version->name : "NULL"); drmFreeVersion(version); -- cgit v1.1 From c46b2ee2cace20f67b0c5e1121e1973a7678fd60 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 1 Aug 2014 20:02:02 +0100 Subject: freedreno: completely untested initial support v2: [Emil Velikov] - drmGetVersion returns the kernel module name. - Add it to the build :) - freedreno_map returns void * while gralloc::map expects int. Signed-off-by: Emil Velikov --- Android.mk | 9 +++ gralloc_drm.c | 4 + gralloc_drm_freedreno.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++ gralloc_drm_pipe.c | 10 +++ gralloc_drm_priv.h | 2 + 5 files changed, 234 insertions(+) create mode 100644 gralloc_drm_freedreno.c diff --git a/Android.mk b/Android.mk index c701b6e..116225a 100644 --- a/Android.mk +++ b/Android.mk @@ -23,6 +23,7 @@ DRM_GPU_DRIVERS := $(strip $(filter-out swrast, $(BOARD_GPU_DRIVERS))) +freedreno_drivers := freedreno intel_drivers := i915 i965 i915g ilo radeon_drivers := r300g r600g nouveau_drivers := nouveau @@ -30,6 +31,7 @@ vmwgfx_drivers := vmwgfx valid_drivers := \ prebuilt \ + $(freedreno_drivers) \ $(intel_drivers) \ $(radeon_drivers) \ $(nouveau_drivers) \ @@ -95,6 +97,13 @@ LOCAL_SHARED_LIBRARIES := \ libcutils \ libhardware_legacy \ +ifneq ($(filter $(freedreno_drivers), $(DRM_GPU_DRIVERS)),) +LOCAL_SRC_FILES += gralloc_drm_freedreno.c +LOCAL_C_INCLUDES += external/drm/freedreno +LOCAL_CFLAGS += -DENABLE_FREEDRENO +LOCAL_SHARED_LIBRARIES += libdrm_freedreno +endif + ifneq ($(filter $(intel_drivers), $(DRM_GPU_DRIVERS)),) LOCAL_SRC_FILES += gralloc_drm_intel.c LOCAL_C_INCLUDES += external/drm/intel diff --git a/gralloc_drm.c b/gralloc_drm.c index bd752cb..c53e556 100644 --- a/gralloc_drm.c +++ b/gralloc_drm.c @@ -73,6 +73,10 @@ init_drv_from_fd(int fd) ALOGI_IF(drv, "create pipe for driver %s", version->name); #endif +#ifdef ENABLE_FREEDRENO + if (!drv && !strcmp(version->name, "msm")) + drv = gralloc_drm_drv_create_for_freedreno(fd); +#endif #ifdef ENABLE_INTEL if (!drv && !strcmp(version->name, "i915")) { drv = gralloc_drm_drv_create_for_intel(fd); diff --git a/gralloc_drm_freedreno.c b/gralloc_drm_freedreno.c new file mode 100644 index 0000000..10b0939 --- /dev/null +++ b/gralloc_drm_freedreno.c @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2011 Chia-I Wu + * Copyright (C) 2011 LunarG Inc. + * Copyright (C) 2014 Rob Clark + * + * Based on xf86-video-nouveau, which has + * + * Copyright © 2007 Red Hat, Inc. + * Copyright © 2008 Maarten Maathuis + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#define LOG_TAG "GRALLOC-FREEDRENO" + +#include +#include +#include +#include +#include + +#include "gralloc_drm.h" +#include "gralloc_drm_priv.h" + +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1)) + +struct fd_info { + struct gralloc_drm_drv_t base; + + int fd; + struct fd_device *dev; +}; + +struct fd_buffer { + struct gralloc_drm_bo_t base; + + struct fd_bo *bo; +}; + +static struct fd_bo *alloc_bo(struct fd_info *info, + int width, int height, int cpp, int usage, int *pitch) +{ + struct fd_bo *bo = NULL; + int flags, size; + + /* TODO need a scanout flag if (usage & GRALLOC_USAGE_HW_FB).. */ + flags = DRM_FREEDRENO_GEM_CACHE_WCOMBINE; + + *pitch = ALIGN(width, 32) * cpp; + size = *pitch * height; + + return fd_bo_new(info->dev, size, flags); +} + +static struct gralloc_drm_bo_t * +fd_alloc(struct gralloc_drm_drv_t *drv, struct gralloc_drm_handle_t *handle) +{ + struct fd_info *info = (struct fd_info *) drv; + struct fd_buffer *fd_buf; + int cpp; + + cpp = gralloc_drm_get_bpp(handle->format); + if (!cpp) { + ALOGE("unrecognized format 0x%x", handle->format); + return NULL; + } + + fd_buf = calloc(1, sizeof(*fd_buf)); + if (!fd_buf) + return NULL; + + if (handle->name) { + fd_buf->bo = fd_bo_from_name(info->dev, handle->name); + if (!fd_buf->bo) { + ALOGE("failed to create fd bo from name %u", + handle->name); + free(fd_buf); + return NULL; + } + } + else { + int width, height, pitch; + + width = handle->width; + height = handle->height; + gralloc_drm_align_geometry(handle->format, &width, &height); + + fd_buf->bo = alloc_bo(info, width, height, + cpp, handle->usage, &pitch); + if (!fd_buf->bo) { + ALOGE("failed to allocate fd bo %dx%dx%d", + handle->width, handle->height, cpp); + free(fd_buf); + return NULL; + } + + if (fd_bo_get_name(fd_buf->bo, (uint32_t *) &handle->name)) { + ALOGE("failed to flink fd bo"); + fd_bo_del(fd_buf->bo); + free(fd_buf); + return NULL; + } + + handle->stride = pitch; + } + + if (handle->usage & GRALLOC_USAGE_HW_FB) + fd_buf->base.fb_handle = fd_bo_handle(fd_buf->bo); + + fd_buf->base.handle = handle; + + return &fd_buf->base; +} + +static void fd_free(struct gralloc_drm_drv_t *drv, + struct gralloc_drm_bo_t *bo) +{ + struct fd_buffer *fd_buf = (struct fd_buffer *) bo; + fd_bo_del(fd_buf->bo); + free(fd_buf); +} + +static int fd_map(struct gralloc_drm_drv_t *drv, + struct gralloc_drm_bo_t *bo, int x, int y, int w, int h, + int enable_write, void **addr) +{ + struct fd_buffer *fd_buf = (struct fd_buffer *) bo; + if (fd_bo_map(fd_buf->bo)) + return 0; + return -errno; +} + +static void fd_unmap(struct gralloc_drm_drv_t *drv, + struct gralloc_drm_bo_t *bo) +{ + // TODO should add fd_bo_unmap() to libdrm_freedreno someday.. +} + +static void fd_init_kms_features(struct gralloc_drm_drv_t *drv, + struct gralloc_drm_t *drm) +{ + struct fd_info *info = (struct fd_info *) drv; + + switch (drm->primary.fb_format) { + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_RGB_565: + break; + default: + drm->primary.fb_format = HAL_PIXEL_FORMAT_BGRA_8888; + break; + } + + drm->mode_quirk_vmwgfx = 0; + drm->swap_mode = DRM_SWAP_FLIP; + drm->mode_sync_flip = 1; + drm->swap_interval = 1; + drm->vblank_secondary = 0; +} + +static void fd_destroy(struct gralloc_drm_drv_t *drv) +{ + struct fd_info *info = (struct fd_info *) drv; + fd_device_del(info->dev); + free(info); +} + +struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_freedreno(int fd) +{ + struct fd_info *info; + int err; + + info = calloc(1, sizeof(*info)); + if (!info) + return NULL; + + info->fd = fd; + info->dev = fd_device_new_dup(info->fd); + if (!info->dev) { + ALOGE("failed to create fd device"); + free(info); + return NULL; + } + + info->base.destroy = fd_destroy; + info->base.init_kms_features = fd_init_kms_features; + info->base.alloc = fd_alloc; + info->base.free = fd_free; + info->base.map = fd_map; + info->base.unmap = fd_unmap; + + return &info->base; +} \ No newline at end of file diff --git a/gralloc_drm_pipe.c b/gralloc_drm_pipe.c index ec3e19d..1183ba1 100644 --- a/gralloc_drm_pipe.c +++ b/gralloc_drm_pipe.c @@ -368,6 +368,8 @@ static void pipe_destroy(struct gralloc_drm_drv_t *drv) FREE(pm); } +/* for freedreno */ +#include "freedreno/drm/freedreno_drm_public.h" /* for nouveau */ #include "nouveau/drm/nouveau_drm_public.h" /* for r300 */ @@ -387,6 +389,10 @@ static int pipe_init_screen(struct pipe_manager *pm) { struct pipe_screen *screen = NULL; +#ifdef ENABLE_PIPE_FREEDRENO + if (strcmp(pm->driver, "msm")) + screen = fd_drm_screen_create(pm->fd); +#endif #ifdef ENABLE_PIPE_NOUVEAU if (strcmp(pm->driver, "nouveau") == 0) screen = nouveau_drm_screen_create(pm->fd); @@ -520,6 +526,10 @@ static int pipe_find_driver(struct pipe_manager *pm, const char *name) driver = "vmwgfx"; err = 0; } + if (strcmp(name, "msm") == 0) { + driver = "msm"; + err = 0; + } } if (!err) diff --git a/gralloc_drm_priv.h b/gralloc_drm_priv.h index 1a36cc1..fd3b72e 100644 --- a/gralloc_drm_priv.h +++ b/gralloc_drm_priv.h @@ -197,6 +197,8 @@ struct gralloc_drm_bo_t { }; struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_pipe(int fd, const char *name); + +struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_freedreno(int fd); struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_intel(int fd); struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_radeon(int fd); struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_nouveau(int fd); -- cgit v1.1 From eccafc5cee44cb0a42a465bd6d9e3ec9018d5a2a Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Fri, 1 Aug 2014 20:11:07 +0100 Subject: gralloc_drm: bail out early when we find the driver ... rather than going through all the conditionals. Signed-off-by: Emil Velikov --- gralloc_drm.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/gralloc_drm.c b/gralloc_drm.c index c53e556..a175cbe 100644 --- a/gralloc_drm.c +++ b/gralloc_drm.c @@ -70,36 +70,41 @@ init_drv_from_fd(int fd) if (version->name) { #ifdef ENABLE_PIPE drv = gralloc_drm_drv_create_for_pipe(fd, version->name); - ALOGI_IF(drv, "create pipe for driver %s", version->name); + if (drv) { + ALOGI("create pipe for driver %s", version->name); + } else #endif #ifdef ENABLE_FREEDRENO - if (!drv && !strcmp(version->name, "msm")) + if (!strcmp(version->name, "msm")) { drv = gralloc_drm_drv_create_for_freedreno(fd); + ALOGI_IF(drv, "create freedreno for driver msm"); + } else #endif #ifdef ENABLE_INTEL - if (!drv && !strcmp(version->name, "i915")) { + if (!strcmp(version->name, "i915")) { drv = gralloc_drm_drv_create_for_intel(fd); ALOGI_IF(drv, "create intel for driver i915"); - } + } else #endif #ifdef ENABLE_RADEON - if (!drv && !strcmp(version->name, "radeon")) { + if (!strcmp(version->name, "radeon")) { drv = gralloc_drm_drv_create_for_radeon(fd); ALOGI_IF(drv, "create radeon for driver radeon"); - } + } else #endif #ifdef ENABLE_NOUVEAU - if (!drv && !strcmp(version->name, "nouveau")) { + if (!strcmp(version->name, "nouveau")) { drv = gralloc_drm_drv_create_for_nouveau(fd); ALOGI_IF(drv, "create nouveau for driver nouveau"); - } + } else #endif + if (!drv) { + ALOGE("unsupported driver: %s", (version->name) ? + version->name : "NULL"); + } } - ALOGE_IF(!drv, "unsupported driver: %s", (version->name) ? - version->name : "NULL"); - drmFreeVersion(version); return drv; -- cgit v1.1 From 10334153b198f59cd598fc5fd25185d9032921c9 Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Fri, 1 Aug 2014 20:21:30 +0100 Subject: gralloc_drm_pipe: bail out as soon as the correct screen_create is called Signed-off-by: Emil Velikov --- gralloc_drm_pipe.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gralloc_drm_pipe.c b/gralloc_drm_pipe.c index 1183ba1..2f96ab5 100644 --- a/gralloc_drm_pipe.c +++ b/gralloc_drm_pipe.c @@ -387,15 +387,17 @@ static void pipe_destroy(struct gralloc_drm_drv_t *drv) static int pipe_init_screen(struct pipe_manager *pm) { - struct pipe_screen *screen = NULL; + struct pipe_screen *screen; #ifdef ENABLE_PIPE_FREEDRENO if (strcmp(pm->driver, "msm")) screen = fd_drm_screen_create(pm->fd); + else #endif #ifdef ENABLE_PIPE_NOUVEAU if (strcmp(pm->driver, "nouveau") == 0) screen = nouveau_drm_screen_create(pm->fd); + else #endif #ifdef ENABLE_PIPE_R300 if (strcmp(pm->driver, "r300") == 0) { @@ -407,6 +409,7 @@ static int pipe_init_screen(struct pipe_manager *pm) sws->destroy(sws); } } + else #endif #ifdef ENABLE_PIPE_R600 if (strcmp(pm->driver, "r600") == 0) { @@ -418,6 +421,7 @@ static int pipe_init_screen(struct pipe_manager *pm) sws->destroy(sws); } } + else #endif #ifdef ENABLE_PIPE_VMWGFX if (strcmp(pm->driver, "vmwgfx") == 0) { @@ -430,7 +434,9 @@ static int pipe_init_screen(struct pipe_manager *pm) sws->destroy(sws); } } + else #endif + screen = NULL; if (!screen) { ALOGW("failed to create screen for %s", pm->driver); -- cgit v1.1 From b88e243781d9b89d500c94decf2b405edb730752 Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Fri, 1 Aug 2014 20:33:17 +0100 Subject: all: Cleanup duplicated macros. - Move MAX macro to gralloc_drm.h - Drop the freedreno's duplicated ALIGN macro. Signed-off-by: Emil Velikov --- gralloc_drm.h | 1 + gralloc_drm_freedreno.c | 3 --- gralloc_drm_nouveau.c | 2 -- gralloc_drm_radeon.c | 2 -- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/gralloc_drm.h b/gralloc_drm.h index c32aaf6..e53ecd9 100644 --- a/gralloc_drm.h +++ b/gralloc_drm.h @@ -31,6 +31,7 @@ extern "C" { #endif +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1)) struct gralloc_drm_t; diff --git a/gralloc_drm_freedreno.c b/gralloc_drm_freedreno.c index 10b0939..3da5a65 100644 --- a/gralloc_drm_freedreno.c +++ b/gralloc_drm_freedreno.c @@ -38,9 +38,6 @@ #include "gralloc_drm.h" #include "gralloc_drm_priv.h" -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1)) - struct fd_info { struct gralloc_drm_drv_t base; diff --git a/gralloc_drm_nouveau.c b/gralloc_drm_nouveau.c index 576966e..8a84332 100644 --- a/gralloc_drm_nouveau.c +++ b/gralloc_drm_nouveau.c @@ -39,8 +39,6 @@ #include "gralloc_drm.h" #include "gralloc_drm_priv.h" -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) - #define NVC0_TILE_HEIGHT(m) (8 << ((m) >> 4)) enum { diff --git a/gralloc_drm_radeon.c b/gralloc_drm_radeon.c index be2ea9b..2911a45 100644 --- a/gralloc_drm_radeon.c +++ b/gralloc_drm_radeon.c @@ -45,8 +45,6 @@ #define RADEON_GPU_PAGE_SIZE 4096 -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) - struct radeon_info { struct gralloc_drm_drv_t base; -- cgit v1.1 From fb8246b8b2dc9f9de59c516ab56e31ac06c98a5b Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Fri, 1 Aug 2014 23:19:03 +0100 Subject: nouveau: update against libdrm_nouveau-2.0 Signed-off-by: Emil Velikov --- gralloc_drm_nouveau.c | 230 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 139 insertions(+), 91 deletions(-) diff --git a/gralloc_drm_nouveau.c b/gralloc_drm_nouveau.c index 8a84332..3d27bc9 100644 --- a/gralloc_drm_nouveau.c +++ b/gralloc_drm_nouveau.c @@ -32,28 +32,34 @@ #include #include #include -#include -#include -#include +#include #include "gralloc_drm.h" #include "gralloc_drm_priv.h" +#define NV_ARCH_03 0x03 +#define NV_ARCH_04 0x04 +#define NV_ARCH_10 0x10 +#define NV_ARCH_20 0x20 +#define NV_ARCH_30 0x30 +#define NV_ARCH_40 0x40 +#define NV_TESLA 0x50 +#define NV_FERMI 0xc0 +#define NV_KEPLER 0xe0 +#define NV_MAXWELL 0x110 + +#define NV50_TILE_HEIGHT(m) (4 << ((m) >> 4)) #define NVC0_TILE_HEIGHT(m) (8 << ((m) >> 4)) -enum { - NvDmaFB = 0xd8000001, - NvDmaTT = 0xd8000002, -}; - struct nouveau_info { struct gralloc_drm_drv_t base; int fd; + uint32_t arch; struct nouveau_device *dev; - struct nouveau_channel *chan; - int arch; - int tiled_scanout; + struct nouveau_client *client; + struct nouveau_object *channel; + struct nouveau_pushbuf *pushbuf; }; struct nouveau_buffer { @@ -66,67 +72,64 @@ static struct nouveau_bo *alloc_bo(struct nouveau_info *info, int width, int height, int cpp, int usage, int *pitch) { struct nouveau_bo *bo = NULL; - int flags, tile_mode, tile_flags; + union nouveau_bo_config cfg = {}; + int flags; int tiled, scanout; unsigned int align; flags = NOUVEAU_BO_MAP | NOUVEAU_BO_VRAM; - tile_mode = 0; - tile_flags = 0; scanout = !!(usage & GRALLOC_USAGE_HW_FB); tiled = !(usage & (GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); - if (!info->chan) - tiled = 0; - else if (scanout && info->tiled_scanout) - tiled = 1; - /* calculate pitch align */ - align = 64; - if (info->arch >= 0x50) { - if (scanout && !info->tiled_scanout) - align = 256; - else + if (info->arch >= NV_TESLA) { + tiled = 1; + align = 64; + } + else { + if (scanout) tiled = 1; + align = 64; } *pitch = ALIGN(width * cpp, align); if (tiled) { - if (info->arch >= 0xc0) { + if (info->arch >= NV_FERMI) { if (height > 64) - tile_mode = 0x40; + cfg.nvc0.tile_mode = 0x0040; else if (height > 32) - tile_mode = 0x30; + cfg.nvc0.tile_mode = 0x0030; else if (height > 16) - tile_mode = 0x20; + cfg.nvc0.tile_mode = 0x0020; else if (height > 8) - tile_mode = 0x10; + cfg.nvc0.tile_mode = 0x0010; else - tile_mode = 0x00; + cfg.nvc0.tile_mode = 0x0000; - tile_flags = 0xfe00; + cfg.nvc0.memtype = 0x00fe; - align = NVC0_TILE_HEIGHT(tile_mode); + align = NVC0_TILE_HEIGHT(cfg.nvc0.tile_mode); height = ALIGN(height, align); } - else if (info->arch >= 0x50) { + else if (info->arch >= NV_TESLA) { if (height > 32) - tile_mode = 4; + cfg.nv50.tile_mode = 0x0040; else if (height > 16) - tile_mode = 3; - else if (height > 8) - tile_mode = 2; - else if (height > 4) - tile_mode = 1; + cfg.nv50.tile_mode = 0x0030; + else if (height > 8) + cfg.nv50.tile_mode = 0x0020; + else if (height > 4) + cfg.nv50.tile_mode = 0x0010; else - tile_mode = 0; + cfg.nv50.tile_mode = 0x0000; - tile_flags = (scanout && cpp != 2) ? 0x7a00 : 0x7000; + cfg.nv50.memtype = (scanout && cpp != 2) ? + 0x007a : 0x0070; - align = 1 << (tile_mode + 2); + align = NV50_TILE_HEIGHT(cfg.nv50.tile_mode); height = ALIGN(height, align); } else { @@ -141,36 +144,36 @@ static struct nouveau_bo *alloc_bo(struct nouveau_info *info, align |= align >> 16; align++; - align = MAX((info->dev->chipset >= 0x40) ? 1024 : 256, - align); + align = MAX((info->dev->chipset >= NV_ARCH_40) ? + 1024 : 256, align); /* adjust pitch */ *pitch = ALIGN(*pitch, align); - - tile_mode = *pitch; + cfg.nv04.surf_pitch = *pitch; } } - if (cpp == 4) - tile_flags |= NOUVEAU_BO_TILE_32BPP; - else if (cpp == 2) - tile_flags |= NOUVEAU_BO_TILE_16BPP; + if (info->arch < NV_TESLA) { + if (cpp == 4) + cfg.nv04.surf_flags |= NV04_BO_32BPP; + else if (cpp == 2) + cfg.nv04.surf_flags |= NV04_BO_16BPP; + } if (scanout) - tile_flags |= NOUVEAU_BO_TILE_SCANOUT; + flags |= NOUVEAU_BO_CONTIG; - if (nouveau_bo_new_tile(info->dev, flags, 0, *pitch * height, - tile_mode, tile_flags, &bo)) { - ALOGE("failed to allocate bo (flags 0x%x, size %d, tile_mode 0x%x, tile_flags 0x%x)", - flags, *pitch * height, tile_mode, tile_flags); + if (nouveau_bo_new(info->dev, flags, 0, *pitch * height, &cfg, &bo)) { + ALOGE("failed to allocate bo (flags 0x%x, size %d)", + flags, *pitch * height); bo = NULL; } return bo; } -static struct gralloc_drm_bo_t * -nouveau_alloc(struct gralloc_drm_drv_t *drv, struct gralloc_drm_handle_t *handle) +static struct gralloc_drm_bo_t *nouveau_alloc(struct gralloc_drm_drv_t *drv, + struct gralloc_drm_handle_t *handle) { struct nouveau_info *info = (struct nouveau_info *) drv; struct nouveau_buffer *nb; @@ -187,7 +190,7 @@ nouveau_alloc(struct gralloc_drm_drv_t *drv, struct gralloc_drm_handle_t *handle return NULL; if (handle->name) { - if (nouveau_bo_handle_ref(info->dev, handle->name, &nb->bo)) { + if (nouveau_bo_name_ref(info->dev, handle->name, &nb->bo)) { ALOGE("failed to create nouveau bo from name %u", handle->name); free(nb); @@ -201,8 +204,8 @@ nouveau_alloc(struct gralloc_drm_drv_t *drv, struct gralloc_drm_handle_t *handle height = handle->height; gralloc_drm_align_geometry(handle->format, &width, &height); - nb->bo = alloc_bo(info, width, height, - cpp, handle->usage, &pitch); + nb->bo = alloc_bo(info, width, height, cpp, + handle->usage, &pitch); if (!nb->bo) { ALOGE("failed to allocate nouveau bo %dx%dx%d", handle->width, handle->height, cpp); @@ -210,7 +213,7 @@ nouveau_alloc(struct gralloc_drm_drv_t *drv, struct gralloc_drm_handle_t *handle return NULL; } - if (nouveau_bo_handle_get(nb->bo, + if (nouveau_bo_name_get(nb->bo, (uint32_t *) &handle->name)) { ALOGE("failed to flink nouveau bo"); nouveau_bo_ref(NULL, &nb->bo); @@ -241,6 +244,7 @@ static int nouveau_map(struct gralloc_drm_drv_t *drv, struct gralloc_drm_bo_t *bo, int x, int y, int w, int h, int enable_write, void **addr) { + struct nouveau_info *info = (struct nouveau_info *) drv; struct nouveau_buffer *nb = (struct nouveau_buffer *) bo; uint32_t flags; int err; @@ -250,7 +254,7 @@ static int nouveau_map(struct gralloc_drm_drv_t *drv, flags |= NOUVEAU_BO_WR; /* TODO if tiled, allocate a linear copy of bo in GART and map it */ - err = nouveau_bo_map(nb->bo, flags); + err = nouveau_bo_map(nb->bo, flags, info->client); if (!err) *addr = nb->bo->map; @@ -260,9 +264,7 @@ static int nouveau_map(struct gralloc_drm_drv_t *drv, static void nouveau_unmap(struct gralloc_drm_drv_t *drv, struct gralloc_drm_bo_t *bo) { - struct nouveau_buffer *nb = (struct nouveau_buffer *) bo; - /* TODO if tiled, unmap the linear bo and copy back */ - nouveau_bo_unmap(nb->bo); + /* The bo is implicitly unmapped at nouveau_bo_ref(NULL, bo) */ } static void nouveau_init_kms_features(struct gralloc_drm_drv_t *drv, @@ -280,7 +282,7 @@ static void nouveau_init_kms_features(struct gralloc_drm_drv_t *drv, } drm->mode_quirk_vmwgfx = 0; - drm->swap_mode = (info->chan) ? DRM_SWAP_FLIP : DRM_SWAP_SETCRTC; + drm->swap_mode = DRM_SWAP_FLIP; drm->mode_sync_flip = 1; drm->swap_interval = 1; drm->vblank_secondary = 0; @@ -290,9 +292,10 @@ static void nouveau_destroy(struct gralloc_drm_drv_t *drv) { struct nouveau_info *info = (struct nouveau_info *) drv; - if (info->chan) - nouveau_channel_free(&info->chan); - nouveau_device_close(&info->dev); + nouveau_pushbuf_del(&info->pushbuf); + nouveau_object_del(&info->channel); + nouveau_client_del(&info->client); + nouveau_device_del(&info->dev); free(info); } @@ -300,31 +303,39 @@ static int nouveau_init(struct nouveau_info *info) { int err = 0; - switch (info->dev->chipset & 0xf0) { + switch (info->dev->chipset & ~0xf) { case 0x00: - info->arch = 0x04; + info->arch = NV_ARCH_04; break; case 0x10: - info->arch = 0x10; + info->arch = NV_ARCH_10; break; case 0x20: - info->arch = 0x20; + info->arch = NV_ARCH_20; break; case 0x30: - info->arch = 0x30; + info->arch = NV_ARCH_30; break; case 0x40: case 0x60: - info->arch = 0x40; + info->arch = NV_ARCH_40; break; case 0x50: case 0x80: case 0x90: case 0xa0: - info->arch = 0x50; + info->arch = NV_TESLA; break; case 0xc0: - info->arch = 0xc0; + case 0xd0: + info->arch = NV_FERMI; + break; + case 0xe0: + case 0xf0: + info->arch = NV_KEPLER; + break; + case 0x110: + info->arch = NV_MAXWELL; break; default: ALOGE("unknown nouveau chipset 0x%x", info->dev->chipset); @@ -332,41 +343,78 @@ static int nouveau_init(struct nouveau_info *info) break; } - info->tiled_scanout = (info->chan != NULL); + if (info->dev->drm_version < 0x01000000 && info->dev->chipset >= 0xc0) { + ALOGE("nouveau kernel module is too old 0x%x", + info->dev->drm_version); + err = -EINVAL; + } return err; } -struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_nouveau(int fd) +struct gralloc_drm_drv_t * +gralloc_drm_drv_create_for_nouveau(int fd) { struct nouveau_info *info; - int err; + struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 }; + struct nvc0_fifo nvc0_data = { }; + int size, err; + void *data; info = calloc(1, sizeof(*info)); if (!info) return NULL; info->fd = fd; - err = nouveau_device_open_existing(&info->dev, 0, info->fd, 0); + err = nouveau_device_wrap(fd, 0, &info->dev); if (err) { - ALOGE("failed to create nouveau device"); + ALOGE("failed to wrap existing nouveau device"); free(info); return NULL; } - err = nouveau_channel_alloc(info->dev, NvDmaFB, NvDmaTT, - 24 * 1024, &info->chan); + err = nouveau_init(info); if (err) { - /* make it non-fatal temporarily as it may require firmwares */ - ALOGW("failed to create nouveau channel"); - info->chan = NULL; + free(info); + return NULL; } - err = nouveau_init(info); + err = nouveau_client_new(info->dev, &info->client); + if (err) { + ALOGW("failed to create nouveau client: %d", err); + nouveau_device_del(&info->dev); + free(info); + return NULL; + } + + if (info->dev->chipset < 0xc0) { + data = &nv04_data; + size = sizeof(nv04_data); + } + else { + data = &nvc0_data; + size = sizeof(nvc0_data); + } + + err = nouveau_object_new(&info->dev->object, 0, + NOUVEAU_FIFO_CHANNEL_CLASS, data, size, + &info->channel); + + if (err) { + ALOGE("failed to create nouveau channel: %d", err); + nouveau_client_del(&info->client); + nouveau_device_del(&info->dev); + free(info); + return NULL; + } + + err = nouveau_pushbuf_new(info->client, info->channel, + 4, 32 * 1024, true, &info->pushbuf); if (err) { - if (info->chan) - nouveau_channel_free(&info->chan); - nouveau_device_close(&info->dev); + ALOGE("failed to allocate DMA push buffer: %d", err); + nouveau_object_del(&info->channel); + nouveau_client_del(&info->client); + nouveau_device_del(&info->dev); free(info); return NULL; } -- cgit v1.1 From 1d8f169759171dcced5d9f71f9ae2f5bd1dcfdcc Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Tue, 11 Nov 2014 03:11:43 +0000 Subject: nouveau: bring some sw_indicator love Based on some work by pstglia, one needs to switch off (partially or fully?) the tiling when creating the BO. Comment/uncomment the SW_INDICATOR_FULLY_DISABLES_TILING define to toggle between the two. Signed-off-by: Emil Velikov --- gralloc_drm_nouveau.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/gralloc_drm_nouveau.c b/gralloc_drm_nouveau.c index 3d27bc9..3ba352c 100644 --- a/gralloc_drm_nouveau.c +++ b/gralloc_drm_nouveau.c @@ -51,6 +51,14 @@ #define NV50_TILE_HEIGHT(m) (4 << ((m) >> 4)) #define NVC0_TILE_HEIGHT(m) (8 << ((m) >> 4)) + +// Comment out the following to switch between the "sw_indicator disables all +// tiling" and "sw_indicator zeroes the tile|surf_flags (object tiling?)". +// Does the latter even make sense ... ? Going through the kernel on the +// topic is slightly annoying :\ + +#define SW_INDICATOR_FULLY_DISABLES_TILING + struct nouveau_info { struct gralloc_drm_drv_t base; @@ -74,7 +82,7 @@ static struct nouveau_bo *alloc_bo(struct nouveau_info *info, struct nouveau_bo *bo = NULL; union nouveau_bo_config cfg = {}; int flags; - int tiled, scanout; + int tiled, scanout, sw_indicator; unsigned int align; flags = NOUVEAU_BO_MAP | NOUVEAU_BO_VRAM; @@ -84,6 +92,9 @@ static struct nouveau_bo *alloc_bo(struct nouveau_info *info, tiled = !(usage & (GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); + sw_indicator = (usage & (GRALLOC_USAGE_SW_READ_OFTEN | + GRALLOC_USAGE_SW_WRITE_OFTEN)); + if (info->arch >= NV_TESLA) { tiled = 1; align = 64; @@ -109,7 +120,12 @@ static struct nouveau_bo *alloc_bo(struct nouveau_info *info, else cfg.nvc0.tile_mode = 0x0000; - cfg.nvc0.memtype = 0x00fe; +#ifndef SW_INDICATOR_FULLY_DISABLES_TILING + if (sw_indicator) + cfg.nvc0.memtype = 0x0000; + else +#endif + cfg.nvc0.memtype = 0x00fe; align = NVC0_TILE_HEIGHT(cfg.nvc0.tile_mode); height = ALIGN(height, align); @@ -126,8 +142,13 @@ static struct nouveau_bo *alloc_bo(struct nouveau_info *info, else cfg.nv50.tile_mode = 0x0000; - cfg.nv50.memtype = (scanout && cpp != 2) ? - 0x007a : 0x0070; +#ifndef SW_INDICATOR_FULLY_DISABLES_TILING + if (sw_indicator) + cfg.nv50.memtype = 0x0000; + else +#endif + cfg.nv50.memtype = (scanout && cpp != 2) ? + 0x007a : 0x0070; align = NV50_TILE_HEIGHT(cfg.nv50.tile_mode); height = ALIGN(height, align); @@ -154,6 +175,11 @@ static struct nouveau_bo *alloc_bo(struct nouveau_info *info, } if (info->arch < NV_TESLA) { +#ifndef SW_INDICATOR_FULLY_DISABLES_TILING + if (sw_indicator) + cfg.nv04.surf_flags = 0x0000; + else +#endif if (cpp == 4) cfg.nv04.surf_flags |= NV04_BO_32BPP; else if (cpp == 2) @@ -163,7 +189,11 @@ static struct nouveau_bo *alloc_bo(struct nouveau_info *info, if (scanout) flags |= NOUVEAU_BO_CONTIG; +#ifdef SW_INDICATOR_FULLY_DISABLES_TILING + if (nouveau_bo_new(info->dev, flags, 0, *pitch * height, NULL, &bo)) { +#else if (nouveau_bo_new(info->dev, flags, 0, *pitch * height, &cfg, &bo)) { +#endif ALOGE("failed to allocate bo (flags 0x%x, size %d)", flags, *pitch * height); bo = NULL; -- cgit v1.1 From d71e7963c186d6c83b5c11028bf1261bab65fa54 Mon Sep 17 00:00:00 2001 From: Chih-Wei Huang Date: Thu, 22 Jan 2015 10:48:03 +0800 Subject: add radeonsi to pci_id_driver_map.h --- pci_ids/pci_id_driver_map.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pci_ids/pci_id_driver_map.h b/pci_ids/pci_id_driver_map.h index c3eec14..b89414a 100644 --- a/pci_ids/pci_id_driver_map.h +++ b/pci_ids/pci_id_driver_map.h @@ -53,6 +53,12 @@ static const int r600_chip_ids[] = { #undef CHIPSET }; +static const int radeonsi_chip_ids[] = { +#define CHIPSET(chip, name, family) chip, +#include "pci_ids/radeonsi_pci_ids.h" +#undef CHIPSET +}; + static const int vmwgfx_chip_ids[] = { #define CHIPSET(chip, name, family) chip, #include "pci_ids/vmwgfx_pci_ids.h" @@ -76,6 +82,7 @@ static const struct { #endif { 0x1002, "r300", r300_chip_ids, ARRAY_SIZE(r300_chip_ids) }, { 0x1002, "r600", r600_chip_ids, ARRAY_SIZE(r600_chip_ids) }, + { 0x1002, "radeonsi", radeonsi_chip_ids, ARRAY_SIZE(radeonsi_chip_ids) }, { 0x10de, "nouveau", NULL, -1 }, { 0x15ad, "vmwgfx", vmwgfx_chip_ids, ARRAY_SIZE(vmwgfx_chip_ids) }, { 0x0000, NULL, NULL, 0 }, -- cgit v1.1 From 703199caf7160a33015685b2b0dbf3a29619d354 Mon Sep 17 00:00:00 2001 From: Chih-Wei Huang Date: Thu, 22 Jan 2015 18:18:26 +0800 Subject: gralloc_drm_pipe: fix building errors with mesa 10.4 --- Android.mk | 4 +++- gralloc_drm_pipe.c | 26 ++++++++------------------ 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/Android.mk b/Android.mk index 116225a..b31538b 100644 --- a/Android.mk +++ b/Android.mk @@ -153,7 +153,9 @@ LOCAL_C_INCLUDES += \ endif LOCAL_STATIC_LIBRARIES += \ - libmesa_gallium + libmesa_gallium \ + libmesa_util \ + LOCAL_SHARED_LIBRARIES += libdl endif # DRM_USES_PIPE include $(BUILD_SHARED_LIBRARY) diff --git a/gralloc_drm_pipe.c b/gralloc_drm_pipe.c index 2f96ab5..477e98f 100644 --- a/gralloc_drm_pipe.c +++ b/gralloc_drm_pipe.c @@ -401,25 +401,19 @@ static int pipe_init_screen(struct pipe_manager *pm) #endif #ifdef ENABLE_PIPE_R300 if (strcmp(pm->driver, "r300") == 0) { - struct radeon_winsys *sws = radeon_drm_winsys_create(pm->fd); + struct radeon_winsys *sws = + radeon_drm_winsys_create(pm->fd, r300_screen_create); - if (sws) { - screen = r300_screen_create(sws); - if (!screen) - sws->destroy(sws); - } + screen = sws ? sws->screen : NULL; } else #endif #ifdef ENABLE_PIPE_R600 if (strcmp(pm->driver, "r600") == 0) { - struct radeon_winsys *sws = radeon_drm_winsys_create(pm->fd); + struct radeon_winsys *sws = + radeon_drm_winsys_create(pm->fd, r600_screen_create); - if (sws) { - screen = r600_screen_create(sws); - if (!screen) - sws->destroy(sws); - } + screen = sws ? sws->screen : NULL; } else #endif @@ -428,18 +422,14 @@ static int pipe_init_screen(struct pipe_manager *pm) struct svga_winsys_screen *sws = svga_drm_winsys_screen_create(pm->fd); - if (sws) { - screen = svga_screen_create(sws); - if (!screen) - sws->destroy(sws); - } + screen = sws ? svga_screen_create(sws) : NULL; } else #endif screen = NULL; if (!screen) { - ALOGW("failed to create screen for %s", pm->driver); + ALOGW("failed to create pipe screen for %s", pm->driver); return -EINVAL; } -- cgit v1.1 From 28207c005b70a1384c1f70fa107b172d6d469f22 Mon Sep 17 00:00:00 2001 From: Chih-Wei Huang Date: Thu, 29 Jan 2015 14:16:34 +0800 Subject: nouveau: undefine SW_INDICATOR_FULLY_DISABLES_TILING Based on the work by pstglia. --- gralloc_drm_nouveau.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gralloc_drm_nouveau.c b/gralloc_drm_nouveau.c index 3ba352c..b93c564 100644 --- a/gralloc_drm_nouveau.c +++ b/gralloc_drm_nouveau.c @@ -57,7 +57,7 @@ // Does the latter even make sense ... ? Going through the kernel on the // topic is slightly annoying :\ -#define SW_INDICATOR_FULLY_DISABLES_TILING +#undef SW_INDICATOR_FULLY_DISABLES_TILING struct nouveau_info { struct gralloc_drm_drv_t base; -- cgit v1.1 From dc21193e3252ba2d6526546ba1d0c02116baf3ee Mon Sep 17 00:00:00 2001 From: Paulo Sergio Travaglia Date: Mon, 16 Feb 2015 21:37:05 -0200 Subject: Changed format constants to match what vmwgfx driver expects When allocating a new buffer using pipe driver, pipe constants are used to define a format based on corresponding HAL_PIXEL_FORMAT However, vmwgfx driver expects other constants (SVGA3D_A8R8G8B8, SVGA3D_X8R8G8B8, SVGA3D_R5G6B5, etc) Changed the returning constants to match what driver expects. v2: [cwhuang] - Use the constants defined in svga3d_types.h. - Use C99 standard to avoid building errors with mesa 10.6. --- Android.mk | 3 +++ gralloc_drm_pipe.c | 10 ++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Android.mk b/Android.mk index b31538b..18b02c4 100644 --- a/Android.mk +++ b/Android.mk @@ -83,6 +83,8 @@ include $(CLEAR_VARS) LOCAL_MODULE := libgralloc_drm LOCAL_MODULE_TAGS := optional +LOCAL_CFLAGS := -std=c99 + LOCAL_SRC_FILES := \ gralloc_drm.c \ gralloc_drm_kms.c @@ -130,6 +132,7 @@ LOCAL_SRC_FILES += gralloc_drm_pipe.c LOCAL_CFLAGS += -DENABLE_PIPE LOCAL_C_INCLUDES += \ external/mesa/include \ + external/mesa/src \ external/mesa/src/gallium/include \ external/mesa/src/gallium/winsys \ external/mesa/src/gallium/drivers \ diff --git a/gralloc_drm_pipe.c b/gralloc_drm_pipe.c index 477e98f..64b1e56 100644 --- a/gralloc_drm_pipe.c +++ b/gralloc_drm_pipe.c @@ -26,6 +26,8 @@ #include #include +#include +#include #include #include #include @@ -60,19 +62,19 @@ static enum pipe_format get_pipe_format(int format) switch (format) { case HAL_PIXEL_FORMAT_RGBA_8888: - fmt = PIPE_FORMAT_R8G8B8A8_UNORM; + fmt = SVGA3D_A8R8G8B8; break; case HAL_PIXEL_FORMAT_RGBX_8888: - fmt = PIPE_FORMAT_R8G8B8X8_UNORM; + fmt = SVGA3D_X8R8G8B8; break; case HAL_PIXEL_FORMAT_RGB_888: fmt = PIPE_FORMAT_R8G8B8_UNORM; break; case HAL_PIXEL_FORMAT_RGB_565: - fmt = PIPE_FORMAT_B5G6R5_UNORM; + fmt = SVGA3D_R5G6B5; break; case HAL_PIXEL_FORMAT_BGRA_8888: - fmt = PIPE_FORMAT_B8G8R8A8_UNORM; + fmt = SVGA3D_A8R8G8B8; break; case HAL_PIXEL_FORMAT_YV12: case HAL_PIXEL_FORMAT_DRM_NV12: -- cgit v1.1