1#ifndef __NVC0_SCREEN_H__
2#define __NVC0_SCREEN_H__
3
4#include "nouveau_screen.h"
5#include "nouveau_mm.h"
6#include "nouveau_fence.h"
7#include "nouveau_heap.h"
8
9#include "nv_object.xml.h"
10
11#include "nvc0/nvc0_winsys.h"
12#include "nvc0/nvc0_stateobj.h"
13
14#define NVC0_TIC_MAX_ENTRIES 2048
15#define NVC0_TSC_MAX_ENTRIES 2048
16#define NVE4_IMG_MAX_HANDLES 512
17
18/* doesn't count driver-reserved slot */
19#define NVC0_MAX_PIPE_CONSTBUFS 15
20#define NVC0_MAX_CONST_BUFFERS  16
21#define NVC0_MAX_CONSTBUF_SIZE  65536
22
23#define NVC0_MAX_SURFACE_SLOTS 16
24
25#define NVC0_MAX_VIEWPORTS 16
26
27#define NVC0_MAX_BUFFERS 32
28
29#define NVC0_MAX_IMAGES 8
30
31#define NVC0_MAX_WINDOW_RECTANGLES 8
32
33struct nvc0_context;
34
35struct nvc0_blitter;
36
37struct nvc0_graph_state {
38   bool flushed;
39   bool rasterizer_discard;
40   bool early_z_forced;
41   bool prim_restart;
42   uint32_t instance_elts; /* bitmask of per-instance elements */
43   uint32_t instance_base;
44   uint32_t constant_vbos;
45   uint32_t constant_elts;
46   int32_t index_bias;
47   uint16_t scissor;
48   bool flatshade;
49   uint8_t patch_vertices;
50   uint8_t vbo_mode; /* 0 = normal, 1 = translate, 3 = translate, forced */
51   uint8_t num_vtxbufs;
52   uint8_t num_vtxelts;
53   uint8_t num_textures[6];
54   uint8_t num_samplers[6];
55   uint8_t tls_required; /* bitmask of shader types using l[] */
56   uint8_t clip_enable;
57   uint32_t clip_mode;
58   bool uniform_buffer_bound[6];
59   struct nvc0_transform_feedback_state *tfb;
60   bool seamless_cube_map;
61   bool post_depth_coverage;
62};
63
64struct nvc0_cb_binding {
65   uint64_t addr;
66   int size;
67};
68
69struct nvc0_screen {
70   struct nouveau_screen base;
71
72   struct nvc0_context *cur_ctx;
73   struct nvc0_graph_state save_state;
74
75   int num_occlusion_queries_active;
76
77   struct nouveau_bo *text;
78   struct nouveau_bo *uniform_bo;
79   struct nouveau_bo *tls;
80   struct nouveau_bo *txc; /* TIC (offset 0) and TSC (65536) */
81   struct nouveau_bo *poly_cache;
82
83   uint8_t gpc_count;
84   uint16_t mp_count;
85   uint16_t mp_count_compute; /* magic reg can make compute use fewer MPs */
86
87   struct nouveau_heap *text_heap;
88   struct nouveau_heap *lib_code; /* allocated from text_heap */
89
90   struct nvc0_blitter *blitter;
91
92   struct {
93      void **entries;
94      int next;
95      uint32_t lock[NVC0_TIC_MAX_ENTRIES / 32];
96      bool maxwell;
97   } tic;
98
99   struct {
100      void **entries;
101      int next;
102      uint32_t lock[NVC0_TSC_MAX_ENTRIES / 32];
103   } tsc;
104
105   struct {
106      struct pipe_image_view **entries;
107      int next;
108   } img;
109
110   struct {
111      struct nouveau_bo *bo;
112      uint32_t *map;
113   } fence;
114
115   struct {
116      struct nvc0_program *prog; /* compute state object to read MP counters */
117      struct nvc0_hw_sm_query *mp_counter[8]; /* counter to query allocation */
118      uint8_t num_hw_sm_active[2];
119      bool mp_counters_enabled;
120   } pm;
121
122   /* only maintained on Maxwell+ */
123   struct nvc0_cb_binding cb_bindings[5][NVC0_MAX_CONST_BUFFERS];
124
125   struct nouveau_object *eng3d; /* sqrt(1/2)|kepler> + sqrt(1/2)|fermi> */
126   struct nouveau_object *eng2d;
127   struct nouveau_object *m2mf;
128   struct nouveau_object *compute;
129   struct nouveau_object *nvsw;
130};
131
132static inline struct nvc0_screen *
133nvc0_screen(struct pipe_screen *screen)
134{
135   return (struct nvc0_screen *)screen;
136}
137
138int nvc0_screen_get_driver_query_info(struct pipe_screen *, unsigned,
139                                      struct pipe_driver_query_info *);
140
141int nvc0_screen_get_driver_query_group_info(struct pipe_screen *, unsigned,
142                                            struct pipe_driver_query_group_info *);
143
144bool nvc0_blitter_create(struct nvc0_screen *);
145void nvc0_blitter_destroy(struct nvc0_screen *);
146
147void nvc0_screen_make_buffers_resident(struct nvc0_screen *);
148
149int nvc0_screen_tic_alloc(struct nvc0_screen *, void *);
150int nvc0_screen_tsc_alloc(struct nvc0_screen *, void *);
151
152int nve4_screen_compute_setup(struct nvc0_screen *, struct nouveau_pushbuf *);
153int nvc0_screen_compute_setup(struct nvc0_screen *, struct nouveau_pushbuf *);
154
155int nvc0_screen_resize_text_area(struct nvc0_screen *, uint64_t);
156
157// 3D Only
158void nvc0_screen_bind_cb_3d(struct nvc0_screen *, bool *, int, int, int, uint64_t);
159
160static inline void
161nvc0_resource_fence(struct nv04_resource *res, uint32_t flags)
162{
163   struct nvc0_screen *screen = nvc0_screen(res->base.screen);
164
165   if (res->mm) {
166      nouveau_fence_ref(screen->base.fence.current, &res->fence);
167      if (flags & NOUVEAU_BO_WR)
168         nouveau_fence_ref(screen->base.fence.current, &res->fence_wr);
169   }
170}
171
172static inline void
173nvc0_resource_validate(struct nv04_resource *res, uint32_t flags)
174{
175   if (likely(res->bo)) {
176      if (flags & NOUVEAU_BO_WR)
177         res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING |
178            NOUVEAU_BUFFER_STATUS_DIRTY;
179      if (flags & NOUVEAU_BO_RD)
180         res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
181
182      nvc0_resource_fence(res, flags);
183   }
184}
185
186struct nvc0_format {
187   uint32_t rt;
188   struct {
189      unsigned format:7;
190      unsigned type_r:3;
191      unsigned type_g:3;
192      unsigned type_b:3;
193      unsigned type_a:3;
194      unsigned src_x:3;
195      unsigned src_y:3;
196      unsigned src_z:3;
197      unsigned src_w:3;
198   } tic;
199   uint32_t usage;
200};
201
202struct nvc0_vertex_format {
203   uint32_t vtx;
204   uint32_t usage;
205};
206
207extern const struct nvc0_format nvc0_format_table[];
208extern const struct nvc0_vertex_format nvc0_vertex_format[];
209
210static inline void
211nvc0_screen_tic_unlock(struct nvc0_screen *screen, struct nv50_tic_entry *tic)
212{
213   if (tic->bindless)
214      return;
215   if (tic->id >= 0)
216      screen->tic.lock[tic->id / 32] &= ~(1 << (tic->id % 32));
217}
218
219static inline void
220nvc0_screen_tsc_unlock(struct nvc0_screen *screen, struct nv50_tsc_entry *tsc)
221{
222   if (tsc->id >= 0)
223      screen->tsc.lock[tsc->id / 32] &= ~(1 << (tsc->id % 32));
224}
225
226static inline void
227nvc0_screen_tic_free(struct nvc0_screen *screen, struct nv50_tic_entry *tic)
228{
229   if (tic->id >= 0) {
230      screen->tic.entries[tic->id] = NULL;
231      screen->tic.lock[tic->id / 32] &= ~(1 << (tic->id % 32));
232   }
233}
234
235static inline void
236nvc0_screen_tsc_free(struct nvc0_screen *screen, struct nv50_tsc_entry *tsc)
237{
238   if (tsc->id >= 0) {
239      screen->tsc.entries[tsc->id] = NULL;
240      screen->tsc.lock[tsc->id / 32] &= ~(1 << (tsc->id % 32));
241   }
242}
243
244#endif
245