[Nouveau] [PATCH 2/2] drm/nouveau: Set tile mode
From: Ari Hirvonen ahirvo...@nvidia.com Add new NOUVEAU_GEM_SET_TILING ioctl to set correct tiling mode for imported dma-bufs. This ioctl is staging for now. Signed-off-by: Ari Hirvonen ahirvo...@nvidia.com [acour...@nvidia.com: carry upstream, fix style] Signed-off-by: Alexandre Courbot acour...@nvidia.com --- drm/nouveau/nouveau_drm.c | 1 + drm/nouveau/nouveau_gem.c | 55 ++ drm/nouveau/nouveau_gem.h | 2 ++ drm/nouveau/uapi/drm/nouveau_drm.h | 8 ++ 4 files changed, 66 insertions(+) diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c index e4bd6ed51e73..1c7898ec100c 100644 --- a/drm/nouveau/nouveau_drm.c +++ b/drm/nouveau/nouveau_drm.c @@ -900,6 +900,7 @@ nouveau_ioctls[] = { DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), /* Staging ioctls */ + DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_SET_TILING, nouveau_gem_ioctl_set_tiling, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), }; long diff --git a/drm/nouveau/nouveau_gem.c b/drm/nouveau/nouveau_gem.c index 0e690bf19fc9..46fa4df0b390 100644 --- a/drm/nouveau/nouveau_gem.c +++ b/drm/nouveau/nouveau_gem.c @@ -173,6 +173,61 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) } int +nouveau_gem_ioctl_set_tiling(struct drm_device *dev, void *data, +struct drm_file *file_priv) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_cli *cli = nouveau_cli(file_priv); + struct nvkm_fb *pfb = nvxx_fb(drm-device); + struct drm_nouveau_gem_set_tiling *req = data; + struct drm_gem_object *gem; + struct nouveau_bo *nvbo; + struct nvkm_mem *mem; + struct nvkm_vma *vma; + int ret = 0; + + if (!pfb-memtype_valid(pfb, req-tile_flags)) { + NV_PRINTK(error, cli, bad memtype: 0x%08x\n, req-tile_flags); + return -EINVAL; + } + + gem = drm_gem_object_lookup(dev, file_priv, req-handle); + if (!gem) + return -ENOENT; + + nvbo = nouveau_gem_object(gem); + + if (nvbo-tile_mode != req-tile_mode || + nvbo-tile_flags != req-tile_flags) { + + ret = ttm_bo_reserve(nvbo-bo, false, false, false, NULL); + if (ret) + goto out; + + vma = nouveau_bo_vma_find(nvbo, cli-vm); + if (!vma) { + ret = -ENOENT; + goto unreserve; + } + + mem = nvbo-bo.mem.mm_node; + nvbo-tile_mode = req-tile_mode; + nvbo-tile_flags = req-tile_flags; + + /* Need to rewrite page tables */ + mem-memtype = (nvbo-tile_flags 8) 0xff; + nvkm_vm_map(vma, nvbo-bo.mem.mm_node); + +unreserve: + ttm_bo_unreserve(nvbo-bo); + } + +out: + drm_gem_object_unreference_unlocked(gem); + return ret; +} + +int nouveau_gem_new(struct drm_device *dev, int size, int align, uint32_t domain, uint32_t tile_mode, uint32_t tile_flags, struct nouveau_bo **pnvbo) diff --git a/drm/nouveau/nouveau_gem.h b/drm/nouveau/nouveau_gem.h index e4049faca780..56e741d98bcd 100644 --- a/drm/nouveau/nouveau_gem.h +++ b/drm/nouveau/nouveau_gem.h @@ -23,6 +23,8 @@ extern void nouveau_gem_object_del(struct drm_gem_object *); extern int nouveau_gem_object_open(struct drm_gem_object *, struct drm_file *); extern void nouveau_gem_object_close(struct drm_gem_object *, struct drm_file *); +extern int nouveau_gem_ioctl_set_tiling(struct drm_device *, void *, + struct drm_file *); extern int nouveau_gem_ioctl_new(struct drm_device *, void *, struct drm_file *); extern int nouveau_gem_ioctl_pushbuf(struct drm_device *, void *, diff --git a/drm/nouveau/uapi/drm/nouveau_drm.h b/drm/nouveau/uapi/drm/nouveau_drm.h index 4e7e21f41b5c..8f10b16b1473 100644 --- a/drm/nouveau/uapi/drm/nouveau_drm.h +++ b/drm/nouveau/uapi/drm/nouveau_drm.h @@ -64,6 +64,12 @@ struct drm_nouveau_gem_new { uint32_t align; }; +struct drm_nouveau_gem_set_tiling { + uint32_t handle; + uint32_t tile_mode; + uint32_t tile_flags; +}; + #define NOUVEAU_GEM_MAX_BUFFERS 1024 struct drm_nouveau_gem_pushbuf_bo_presumed { uint32_t valid; @@ -142,6 +148,7 @@ struct drm_nouveau_gem_cpu_fini { #define DRM_NOUVEAU_GEM_INFO 0x44 /* range 0x98..DRM_COMMAND_END (8 entries) is reserved for staging, unstable ioctls */ #define DRM_NOUVEAU_STAGING_IOCTL 0x58 +#define DRM_NOUVEAU_GEM_SET_TILING (DRM_NOUVEAU_STAGING_IOCTL + 0x0) #define DRM_IOCTL_NOUVEAU_GEM_NEW
[Nouveau] [PATCH 1/2] drm/nouveau: add staging module option
Add a module option allowing to enable staging/unstable APIs. This will allow us to experiment freely with experimental APIs for a while before setting them in stone. Signed-off-by: Alexandre Courbot acour...@nvidia.com --- drm/nouveau/nouveau_drm.c | 18 ++ drm/nouveau/uapi/drm/nouveau_drm.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c index 89049335b738..e4bd6ed51e73 100644 --- a/drm/nouveau/nouveau_drm.c +++ b/drm/nouveau/nouveau_drm.c @@ -75,6 +75,10 @@ MODULE_PARM_DESC(runpm, disable (0), force enable (1), optimus only default (-1 int nouveau_runtime_pm = -1; module_param_named(runpm, nouveau_runtime_pm, int, 0400); +MODULE_PARM_DESC(staging, enable staging APIs); +int nouveau_staging = 0; +module_param_named(staging, nouveau_staging, int, 0400); + static struct drm_driver driver_stub; static struct drm_driver driver_pci; static struct drm_driver driver_platform; @@ -895,6 +899,7 @@ nouveau_ioctls[] = { DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), + /* Staging ioctls */ }; long @@ -1027,6 +1032,7 @@ static void nouveau_display_options(void) DRM_DEBUG_DRIVER(... runpm: %d\n, nouveau_runtime_pm); DRM_DEBUG_DRIVER(... vram_pushbuf : %d\n, nouveau_vram_pushbuf); DRM_DEBUG_DRIVER(... pstate : %d\n, nouveau_pstate); + DRM_DEBUG_DRIVER(... staging : %d\n, nouveau_staging); } static const struct dev_pm_ops nouveau_pm_ops = { @@ -1088,6 +1094,18 @@ err_free: static int __init nouveau_drm_init(void) { + /* Do not register staging ioctsl if option not specified */ + if (!nouveau_staging) { + unsigned i; + + /* This keeps us safe is no staging ioctls are defined */ + i = min(driver_stub.num_ioctls, DRM_NOUVEAU_STAGING_IOCTL); + while (!nouveau_ioctls[i - 1].func) + i--; + + driver_stub.num_ioctls = i; + } + driver_pci = driver_stub; driver_pci.set_busid = drm_pci_set_busid; driver_platform = driver_stub; diff --git a/drm/nouveau/uapi/drm/nouveau_drm.h b/drm/nouveau/uapi/drm/nouveau_drm.h index 5507eead5863..4e7e21f41b5c 100644 --- a/drm/nouveau/uapi/drm/nouveau_drm.h +++ b/drm/nouveau/uapi/drm/nouveau_drm.h @@ -140,11 +140,14 @@ struct drm_nouveau_gem_cpu_fini { #define DRM_NOUVEAU_GEM_CPU_PREP 0x42 #define DRM_NOUVEAU_GEM_CPU_FINI 0x43 #define DRM_NOUVEAU_GEM_INFO 0x44 +/* range 0x98..DRM_COMMAND_END (8 entries) is reserved for staging, unstable ioctls */ +#define DRM_NOUVEAU_STAGING_IOCTL 0x58 #define DRM_IOCTL_NOUVEAU_GEM_NEWDRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_NEW, struct drm_nouveau_gem_new) #define DRM_IOCTL_NOUVEAU_GEM_PUSHBUFDRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_PUSHBUF, struct drm_nouveau_gem_pushbuf) #define DRM_IOCTL_NOUVEAU_GEM_CPU_PREP DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_PREP, struct drm_nouveau_gem_cpu_prep) #define DRM_IOCTL_NOUVEAU_GEM_CPU_FINI DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_FINI, struct drm_nouveau_gem_cpu_fini) #define DRM_IOCTL_NOUVEAU_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_INFO, struct drm_nouveau_gem_info) +/* staging ioctls */ #endif /* __NOUVEAU_DRM_H__ */ -- 2.4.0 ___ Nouveau mailing list Nouveau@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/nouveau
[Nouveau] [PATCH 0/2] drm/nouveau: option for staging ioctls and new SET_TILING ioctl
This patchset proposes to introduce a staging module option to dynamically enable features (mostly ioctls) that are merged but may be refined before they are declared stable. The second patch illustrates the use of this staging option with the SET_TILING ioctl, which can be used to specify the tiling options of a PRIME-imported buffer. The staging parameter will allow us (especially, us at NVIDIA) to experiment more freely with new features and avoid carrying patches across version. To prevent abuse, the number of staging IOCTLs is limited to 8 (range 0x98 to 0xa0) that are to be recycled as staging IOCTLs become stable and are assigned a final number. Alexandre Courbot (1): drm: add staging module option Ari Hirvonen (1): drm/nouveau: Set tile mode drm/nouveau/nouveau_drm.c | 19 + drm/nouveau/nouveau_gem.c | 55 ++ drm/nouveau/nouveau_gem.h | 2 ++ drm/nouveau/uapi/drm/nouveau_drm.h | 11 4 files changed, 87 insertions(+) -- 2.4.0 ___ Nouveau mailing list Nouveau@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/nouveau
[Nouveau] [Bug 90513] Odd gray and red flicker in The Talos Principle on GK104
https://bugs.freedesktop.org/show_bug.cgi?id=90513 --- Comment #2 from Ilia Mirkin imir...@alum.mit.edu --- Confirmed that I get redness coming in on that draw on my GK208, whereas it's fine on i965. There are a few awkward things, but nothing completely ridiculous: 1. 4096x4096 srgb dxt1/5 textures, specifically GL_TEXTURE4, GL_TEXTURE6. 2. Multiple vertex elements are mapped to the same position in the same buffer (3, 4, and 5). Curiously, no shaders appear to be bound, which is very odd. I'm guessing that's some sort of qapitrace fail. Very weird. -- You are receiving this mail because: You are the QA Contact for the bug. You are the assignee for the bug. ___ Nouveau mailing list Nouveau@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/nouveau
[Nouveau] [PATCH 2/2] nv04-nv40: don't attempt to do 32-bit shifts
A 32-bit shift is a no-op, which will also make the new planemask get or'd with ~0, thus negating the usefulness of the subsequent planemask != ~0 check. Only do this if it's a less-than-32-bit per pixel format, in which case it will have the desired effect of setting the high bits. Signed-off-by: Ilia Mirkin imir...@alum.mit.edu --- src/nv04_exa.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nv04_exa.c b/src/nv04_exa.c index 7a58dd7..d5dec68 100644 --- a/src/nv04_exa.c +++ b/src/nv04_exa.c @@ -49,7 +49,8 @@ NV04EXASetROP(PixmapPtr ppix, int subc, int mthd, int alu, Pixel planemask) NVPtr pNv = NVPTR(pScrn); struct nouveau_pushbuf *push = pNv-pushbuf; - planemask |= ~0 ppix-drawable.bitsPerPixel; + if (ppix-drawable.bitsPerPixel 32) + planemask |= ~0 ppix-drawable.bitsPerPixel; if (planemask != ~0 || alu != GXcopy) { if (ppix-drawable.bitsPerPixel == 32) return FALSE; -- 2.3.6 ___ Nouveau mailing list Nouveau@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/nouveau
Re: [Nouveau] [PATCH 2/2] nv04-nv40: don't attempt to do 32-bit shifts
On 19/05/15 23:28, Ilia Mirkin wrote: A 32-bit shift is a no-op, which will also make the new planemask get or'd with ~0, thus negating the usefulness of the subsequent planemask != ~0 check. Only do this if it's a less-than-32-bit per pixel format, in which case it will have the desired effect of setting the high bits. Signed-off-by: Ilia Mirkin imir...@alum.mit.edu --- src/nv04_exa.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nv04_exa.c b/src/nv04_exa.c index 7a58dd7..d5dec68 100644 --- a/src/nv04_exa.c +++ b/src/nv04_exa.c @@ -49,7 +49,8 @@ NV04EXASetROP(PixmapPtr ppix, int subc, int mthd, int alu, Pixel planemask) NVPtr pNv = NVPTR(pScrn); struct nouveau_pushbuf *push = pNv-pushbuf; - planemask |= ~0 ppix-drawable.bitsPerPixel; + if (ppix-drawable.bitsPerPixel 32) + planemask |= ~0 ppix-drawable.bitsPerPixel; if (planemask != ~0 || alu != GXcopy) { if (ppix-drawable.bitsPerPixel == 32) return FALSE; Both patches look good to me. Thanks for tracking those bugs down :) Reviewed-by: Martin Peres martin.pe...@free.fr ___ Nouveau mailing list Nouveau@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/nouveau
Re: [Nouveau] [PATCH 2/2] nv04-nv40: don't attempt to do 32-bit shifts
On Tue, May 19, 2015 at 4:35 PM, Martin Peres martin.pe...@free.fr wrote: On 19/05/15 23:28, Ilia Mirkin wrote: A 32-bit shift is a no-op, which will also make the new planemask get or'd with ~0, thus negating the usefulness of the subsequent planemask != ~0 check. Only do this if it's a less-than-32-bit per pixel format, in which case it will have the desired effect of setting the high bits. Signed-off-by: Ilia Mirkin imir...@alum.mit.edu --- src/nv04_exa.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nv04_exa.c b/src/nv04_exa.c index 7a58dd7..d5dec68 100644 --- a/src/nv04_exa.c +++ b/src/nv04_exa.c @@ -49,7 +49,8 @@ NV04EXASetROP(PixmapPtr ppix, int subc, int mthd, int alu, Pixel planemask) NVPtr pNv = NVPTR(pScrn); struct nouveau_pushbuf *push = pNv-pushbuf; - planemask |= ~0 ppix-drawable.bitsPerPixel; + if (ppix-drawable.bitsPerPixel 32) + planemask |= ~0 ppix-drawable.bitsPerPixel; if (planemask != ~0 || alu != GXcopy) { if (ppix-drawable.bitsPerPixel == 32) return FALSE; Both patches look good to me. Thanks for tracking those bugs down :) Reviewed-by: Martin Peres martin.pe...@free.fr Thanks! FWIW I just happened to notice this as I was reading the code, so it's untested and not in response to any bug. I have no idea if it actually affects things... I suspect planemask != ~0U is pretty rare to begin with, outside of things that test it explicitly. -ilia ___ Nouveau mailing list Nouveau@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/nouveau