xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/nouveau/nouveau_winsys.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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 #include "nouveau_screen.h"
13 
14 #ifndef NV04_PFIFO_MAX_PACKET_LEN
15 #define NV04_PFIFO_MAX_PACKET_LEN 2047
16 #endif
17 
18 #define NOUVEAU_MIN_BUFFER_MAP_ALIGN      64
19 #define NOUVEAU_MIN_BUFFER_MAP_ALIGN_MASK (NOUVEAU_MIN_BUFFER_MAP_ALIGN - 1)
20 
21 static inline uint32_t
PUSH_AVAIL(struct nouveau_pushbuf * push)22 PUSH_AVAIL(struct nouveau_pushbuf *push)
23 {
24    return push->end - push->cur;
25 }
26 
27 static inline bool
PUSH_SPACE_EX(struct nouveau_pushbuf * push,uint32_t size,uint32_t relocs,uint32_t pushes)28 PUSH_SPACE_EX(struct nouveau_pushbuf *push, uint32_t size, uint32_t relocs, uint32_t pushes)
29 {
30    struct nouveau_pushbuf_priv *ppush = push->user_priv;
31    simple_mtx_lock(&ppush->screen->fence.lock);
32    bool res = nouveau_pushbuf_space(push, size, relocs, pushes) == 0;
33    simple_mtx_unlock(&ppush->screen->fence.lock);
34    return res;
35 }
36 
37 static inline bool
PUSH_SPACE(struct nouveau_pushbuf * push,uint32_t size)38 PUSH_SPACE(struct nouveau_pushbuf *push, uint32_t size)
39 {
40    /* Provide a buffer so that fences always have room to be emitted */
41    size += 8;
42    if (PUSH_AVAIL(push) < size)
43       return PUSH_SPACE_EX(push, size, 0, 0);
44    return true;
45 }
46 
47 static inline void
PUSH_DATA(struct nouveau_pushbuf * push,uint32_t data)48 PUSH_DATA(struct nouveau_pushbuf *push, uint32_t data)
49 {
50    *push->cur++ = data;
51 }
52 
53 static inline void
PUSH_DATAp(struct nouveau_pushbuf * push,const void * data,uint32_t size)54 PUSH_DATAp(struct nouveau_pushbuf *push, const void *data, uint32_t size)
55 {
56    memcpy(push->cur, data, size * 4);
57    push->cur += size;
58 }
59 
60 static inline void
PUSH_DATAb(struct nouveau_pushbuf * push,const void * data,uint32_t size)61 PUSH_DATAb(struct nouveau_pushbuf *push, const void *data, uint32_t size)
62 {
63    memcpy(push->cur, data, size);
64    push->cur += DIV_ROUND_UP(size, 4);
65 }
66 
67 static inline void
PUSH_DATAf(struct nouveau_pushbuf * push,float f)68 PUSH_DATAf(struct nouveau_pushbuf *push, float f)
69 {
70    union { float f; uint32_t i; } u;
71    u.f = f;
72    PUSH_DATA(push, u.i);
73 }
74 
75 static inline int
PUSH_REFN(struct nouveau_pushbuf * push,struct nouveau_pushbuf_refn * refs,int nr)76 PUSH_REFN(struct nouveau_pushbuf *push, struct nouveau_pushbuf_refn *refs, int nr)
77 {
78    struct nouveau_pushbuf_priv *ppush = push->user_priv;
79    simple_mtx_lock(&ppush->screen->fence.lock);
80    int ret = nouveau_pushbuf_refn(push, refs, nr);
81    simple_mtx_unlock(&ppush->screen->fence.lock);
82    return ret;
83 }
84 
85 static inline int
PUSH_REF1(struct nouveau_pushbuf * push,struct nouveau_bo * bo,uint32_t flags)86 PUSH_REF1(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t flags)
87 {
88    struct nouveau_pushbuf_refn ref = { bo, flags };
89    return PUSH_REFN(push, &ref, 1);
90 }
91 
92 static inline void
PUSH_KICK(struct nouveau_pushbuf * push)93 PUSH_KICK(struct nouveau_pushbuf *push)
94 {
95    struct nouveau_pushbuf_priv *ppush = push->user_priv;
96    simple_mtx_lock(&ppush->screen->fence.lock);
97    int ASSERTED ret = nouveau_pushbuf_kick(push);
98    assert(!ret);
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