• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef NOUVEAU_WINSYS_H
2 #define NOUVEAU_WINSYS_H
3 
4 #include <stdint.h>
5 #include <inttypes.h>
6 
7 #include "pipe/p_defines.h"
8 #include "util/os_misc.h"
9 
10 #include "drm-uapi/drm.h"
11 #include <nouveau.h>
12 
13 #include "nouveau_screen.h"
14 
15 #ifndef NV04_PFIFO_MAX_PACKET_LEN
16 #define NV04_PFIFO_MAX_PACKET_LEN 2047
17 #endif
18 
19 #define NOUVEAU_MIN_BUFFER_MAP_ALIGN      64
20 #define NOUVEAU_MIN_BUFFER_MAP_ALIGN_MASK (NOUVEAU_MIN_BUFFER_MAP_ALIGN - 1)
21 
22 static inline uint32_t
PUSH_AVAIL(struct nouveau_pushbuf * push)23 PUSH_AVAIL(struct nouveau_pushbuf *push)
24 {
25    return push->end - push->cur;
26 }
27 
28 static inline bool
PUSH_SPACE_EX(struct nouveau_pushbuf * push,uint32_t size,uint32_t relocs,uint32_t pushes)29 PUSH_SPACE_EX(struct nouveau_pushbuf *push, uint32_t size, uint32_t relocs, uint32_t pushes)
30 {
31    struct nouveau_pushbuf_priv *ppush = push->user_priv;
32    simple_mtx_lock(&ppush->screen->fence.lock);
33    bool res = nouveau_pushbuf_space(push, size, relocs, pushes) == 0;
34    simple_mtx_unlock(&ppush->screen->fence.lock);
35    return res;
36 }
37 
38 static inline bool
PUSH_SPACE(struct nouveau_pushbuf * push,uint32_t size)39 PUSH_SPACE(struct nouveau_pushbuf *push, uint32_t size)
40 {
41    /* Provide a buffer so that fences always have room to be emitted */
42    size += 8;
43    if (PUSH_AVAIL(push) < size)
44       return PUSH_SPACE_EX(push, size, 0, 0);
45    return true;
46 }
47 
48 static inline void
PUSH_DATA(struct nouveau_pushbuf * push,uint32_t data)49 PUSH_DATA(struct nouveau_pushbuf *push, uint32_t data)
50 {
51    *push->cur++ = data;
52 }
53 
54 static inline void
PUSH_DATAp(struct nouveau_pushbuf * push,const void * data,uint32_t size)55 PUSH_DATAp(struct nouveau_pushbuf *push, const void *data, uint32_t size)
56 {
57    memcpy(push->cur, data, size * 4);
58    push->cur += size;
59 }
60 
61 static inline void
PUSH_DATAb(struct nouveau_pushbuf * push,const void * data,uint32_t size)62 PUSH_DATAb(struct nouveau_pushbuf *push, const void *data, uint32_t size)
63 {
64    memcpy(push->cur, data, size);
65    push->cur += DIV_ROUND_UP(size, 4);
66 }
67 
68 static inline void
PUSH_DATAf(struct nouveau_pushbuf * push,float f)69 PUSH_DATAf(struct nouveau_pushbuf *push, float f)
70 {
71    union { float f; uint32_t i; } u;
72    u.f = f;
73    PUSH_DATA(push, u.i);
74 }
75 
76 static inline int
PUSH_REFN(struct nouveau_pushbuf * push,struct nouveau_pushbuf_refn * refs,int nr)77 PUSH_REFN(struct nouveau_pushbuf *push, struct nouveau_pushbuf_refn *refs, int nr)
78 {
79    struct nouveau_pushbuf_priv *ppush = push->user_priv;
80    simple_mtx_lock(&ppush->screen->fence.lock);
81    int ret = nouveau_pushbuf_refn(push, refs, nr);
82    simple_mtx_unlock(&ppush->screen->fence.lock);
83    return ret;
84 }
85 
86 static inline int
PUSH_REF1(struct nouveau_pushbuf * push,struct nouveau_bo * bo,uint32_t flags)87 PUSH_REF1(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t flags)
88 {
89    struct nouveau_pushbuf_refn ref = { bo, flags };
90    return PUSH_REFN(push, &ref, 1);
91 }
92 
93 static inline void
PUSH_KICK(struct nouveau_pushbuf * push)94 PUSH_KICK(struct nouveau_pushbuf *push)
95 {
96    struct nouveau_pushbuf_priv *ppush = push->user_priv;
97    simple_mtx_lock(&ppush->screen->fence.lock);
98    nouveau_pushbuf_kick(push, push->channel);
99    simple_mtx_unlock(&ppush->screen->fence.lock);
100 }
101 
102 static inline int
PUSH_VAL(struct nouveau_pushbuf * push)103 PUSH_VAL(struct nouveau_pushbuf *push)
104 {
105    struct nouveau_pushbuf_priv *ppush = push->user_priv;
106    simple_mtx_lock(&ppush->screen->fence.lock);
107    int res = nouveau_pushbuf_validate(push);
108    simple_mtx_unlock(&ppush->screen->fence.lock);
109    return res;
110 }
111 
112 static inline uint32_t
NV04_FIFO_PKHDR(int subc,int mthd,unsigned size)113 NV04_FIFO_PKHDR(int subc, int mthd, unsigned size)
114 {
115    return 0x00000000 | (size << 18) | (subc << 13) | mthd;
116 }
117 
118 static inline uint32_t
NV04_FIFO_PKHDR_NI(int subc,int mthd,unsigned size)119 NV04_FIFO_PKHDR_NI(int subc, int mthd, unsigned size)
120 {
121    return 0x40000000 | (size << 18) | (subc << 13) | mthd;
122 }
123 
124 static inline void
BEGIN_NV04(struct nouveau_pushbuf * push,int subc,int mthd,unsigned size)125 BEGIN_NV04(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
126 {
127 #ifndef NV50_PUSH_EXPLICIT_SPACE_CHECKING
128    PUSH_SPACE(push, size + 1);
129 #endif
130    PUSH_DATA (push, NV04_FIFO_PKHDR(subc, mthd, size));
131 }
132 
133 static inline void
BEGIN_NI04(struct nouveau_pushbuf * push,int subc,int mthd,unsigned size)134 BEGIN_NI04(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
135 {
136 #ifndef NV50_PUSH_EXPLICIT_SPACE_CHECKING
137    PUSH_SPACE(push, size + 1);
138 #endif
139    PUSH_DATA (push, NV04_FIFO_PKHDR_NI(subc, mthd, size));
140 }
141 
142 static inline int
BO_MAP(struct nouveau_screen * screen,struct nouveau_bo * bo,uint32_t access,struct nouveau_client * client)143 BO_MAP(struct nouveau_screen *screen, struct nouveau_bo *bo, uint32_t access, struct nouveau_client *client)
144 {
145    int res;
146    simple_mtx_lock(&screen->fence.lock);
147    res = nouveau_bo_map(bo, access, client);
148    simple_mtx_unlock(&screen->fence.lock);
149    return res;
150 }
151 
152 static inline int
BO_WAIT(struct nouveau_screen * screen,struct nouveau_bo * bo,uint32_t access,struct nouveau_client * client)153 BO_WAIT(struct nouveau_screen *screen, struct nouveau_bo *bo, uint32_t access, struct nouveau_client *client)
154 {
155    int res;
156    simple_mtx_lock(&screen->fence.lock);
157    res = nouveau_bo_wait(bo, access, client);
158    simple_mtx_unlock(&screen->fence.lock);
159    return res;
160 }
161 
162 #define NOUVEAU_RESOURCE_FLAG_LINEAR   (PIPE_RESOURCE_FLAG_DRV_PRIV << 0)
163 #define NOUVEAU_RESOURCE_FLAG_DRV_PRIV (PIPE_RESOURCE_FLAG_DRV_PRIV << 1)
164 
165 static inline uint32_t
nouveau_screen_transfer_flags(unsigned pipe)166 nouveau_screen_transfer_flags(unsigned pipe)
167 {
168    uint32_t flags = 0;
169 
170    if (!(pipe & PIPE_MAP_UNSYNCHRONIZED)) {
171       if (pipe & PIPE_MAP_READ)
172          flags |= NOUVEAU_BO_RD;
173       if (pipe & PIPE_MAP_WRITE)
174          flags |= NOUVEAU_BO_WR;
175       if (pipe & PIPE_MAP_DONTBLOCK)
176          flags |= NOUVEAU_BO_NOBLOCK;
177    }
178 
179    return flags;
180 }
181 
182 extern struct nouveau_screen *
183 nv30_screen_create(struct nouveau_device *);
184 
185 extern struct nouveau_screen *
186 nv50_screen_create(struct nouveau_device *);
187 
188 extern struct nouveau_screen *
189 nvc0_screen_create(struct nouveau_device *);
190 
191 static inline uint64_t
nouveau_device_get_global_mem_size(struct nouveau_device * dev)192 nouveau_device_get_global_mem_size(struct nouveau_device *dev)
193 {
194    uint64_t size = dev->vram_size;
195 
196    if (!size) {
197       os_get_available_system_memory(&size);
198       size = MIN2(dev->gart_size, size);
199    }
200 
201    /* cap to 32 bit on nv50 and older */
202    if (dev->chipset < 0xc0)
203       size = MIN2(size, 1ull << 32);
204    else
205       size = MIN2(size, 1ull << 40);
206 
207    return size;
208 }
209 
210 #endif
211