nouveau: very quick port to tex-surface changes.
[mesa.git] / src / gallium / drivers / nv50 / nv50_screen.c
1 #include "pipe/p_screen.h"
2 #include "pipe/p_util.h"
3
4 #include "nv50_context.h"
5 #include "nv50_screen.h"
6
7 #include "nouveau/nouveau_stateobj.h"
8
9 #define NV5X_GRCLASS5097_CHIPSETS 0x00000001
10 #define NV8X_GRCLASS8297_CHIPSETS 0x00000010
11 #define NV9X_GRCLASS8297_CHIPSETS 0x00000004
12
13 static boolean
14 nv50_screen_is_format_supported(struct pipe_screen *pscreen,
15 enum pipe_format format, uint type)
16 {
17 switch (type) {
18 case PIPE_SURFACE:
19 switch (format) {
20 case PIPE_FORMAT_A8R8G8B8_UNORM:
21 case PIPE_FORMAT_R5G6B5_UNORM:
22 case PIPE_FORMAT_Z24S8_UNORM:
23 case PIPE_FORMAT_Z16_UNORM:
24 return TRUE;
25 default:
26 break;
27 }
28 break;
29 case PIPE_TEXTURE:
30 switch (format) {
31 case PIPE_FORMAT_I8_UNORM:
32 return TRUE;
33 default:
34 break;
35 }
36 break;
37 default:
38 assert(0);
39 }
40
41 return FALSE;
42 }
43
44 static const char *
45 nv50_screen_get_name(struct pipe_screen *pscreen)
46 {
47 struct nv50_screen *screen = nv50_screen(pscreen);
48 struct nouveau_device *dev = screen->nvws->channel->device;
49 static char buffer[128];
50
51 snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
52 return buffer;
53 }
54
55 static const char *
56 nv50_screen_get_vendor(struct pipe_screen *pscreen)
57 {
58 return "nouveau";
59 }
60
61 static int
62 nv50_screen_get_param(struct pipe_screen *pscreen, int param)
63 {
64 switch (param) {
65 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
66 return 32;
67 case PIPE_CAP_NPOT_TEXTURES:
68 return 0;
69 case PIPE_CAP_TWO_SIDED_STENCIL:
70 return 1;
71 case PIPE_CAP_GLSL:
72 return 0;
73 case PIPE_CAP_S3TC:
74 return 0;
75 case PIPE_CAP_ANISOTROPIC_FILTER:
76 return 0;
77 case PIPE_CAP_POINT_SPRITE:
78 return 0;
79 case PIPE_CAP_MAX_RENDER_TARGETS:
80 return 8;
81 case PIPE_CAP_OCCLUSION_QUERY:
82 return 0;
83 case PIPE_CAP_TEXTURE_SHADOW_MAP:
84 return 0;
85 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
86 return 13;
87 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
88 return 10;
89 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
90 return 13;
91 case NOUVEAU_CAP_HW_VTXBUF:
92 case NOUVEAU_CAP_HW_IDXBUF:
93 return 0;
94 default:
95 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
96 return 0;
97 }
98 }
99
100 static float
101 nv50_screen_get_paramf(struct pipe_screen *pscreen, int param)
102 {
103 switch (param) {
104 case PIPE_CAP_MAX_LINE_WIDTH:
105 case PIPE_CAP_MAX_LINE_WIDTH_AA:
106 return 10.0;
107 case PIPE_CAP_MAX_POINT_WIDTH:
108 case PIPE_CAP_MAX_POINT_WIDTH_AA:
109 return 64.0;
110 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
111 return 16.0;
112 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
113 return 4.0;
114 default:
115 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
116 return 0.0;
117 }
118 }
119
120 static void *
121 nv50_surface_map(struct pipe_screen *screen, struct pipe_surface *surface,
122 unsigned flags )
123 {
124 struct pipe_winsys *ws = screen->winsys;
125 void *map;
126
127 map = ws->buffer_map(ws, surface->buffer, flags);
128 if (!map)
129 return NULL;
130
131 return map + surface->offset;
132 }
133
134 static void
135 nv50_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface)
136 {
137 struct pipe_winsys *ws = screen->winsys;
138
139 ws->buffer_unmap(ws, surface->buffer);
140 }
141
142 static void
143 nv50_screen_destroy(struct pipe_screen *pscreen)
144 {
145 FREE(pscreen);
146 }
147
148 struct pipe_screen *
149 nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
150 {
151 struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen);
152 struct nouveau_stateobj *so;
153 unsigned tesla_class = 0, ret;
154 unsigned chipset = nvws->channel->device->chipset;
155 int i;
156
157 if (!screen)
158 return NULL;
159 screen->nvws = nvws;
160
161 /* 3D object */
162 if ((chipset & 0xf0) != 0x50 && (chipset & 0xf0) != 0x80) {
163 NOUVEAU_ERR("Not a G8x chipset\n");
164 nv50_screen_destroy(&screen->pipe);
165 return NULL;
166 }
167
168 switch (chipset & 0xf0) {
169 case 0x50:
170 if (NV5X_GRCLASS5097_CHIPSETS & (1 << (chipset & 0x0f)))
171 tesla_class = 0x5097;
172 break;
173 case 0x80:
174 if (NV8X_GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f)))
175 tesla_class = 0x8297;
176 break;
177 case 0x90:
178 if (NV9X_GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f)))
179 tesla_class = 0x8297;
180 break;
181 default:
182 break;
183 }
184
185 if (tesla_class == 0) {
186 NOUVEAU_ERR("Unknown G8x chipset: NV%02x\n", chipset);
187 nv50_screen_destroy(&screen->pipe);
188 return NULL;
189 }
190
191 ret = nvws->grobj_alloc(nvws, tesla_class, &screen->tesla);
192 if (ret) {
193 NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
194 nv50_screen_destroy(&screen->pipe);
195 return NULL;
196 }
197
198 /* Sync notifier */
199 ret = nvws->notifier_alloc(nvws, 1, &screen->sync);
200 if (ret) {
201 NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
202 nv50_screen_destroy(&screen->pipe);
203 return NULL;
204 }
205
206 /* Static tesla init */
207 so = so_new(128, 0);
208 so_method(so, screen->tesla, NV50TCL_DMA_NOTIFY, 1);
209 so_data (so, screen->sync->handle);
210 so_method(so, screen->tesla, NV50TCL_DMA_IN_MEMORY0(0),
211 NV50TCL_DMA_IN_MEMORY0__SIZE);
212 for (i = 0; i < NV50TCL_DMA_IN_MEMORY0__SIZE; i++)
213 so_data(so, nvws->channel->vram->handle);
214 so_method(so, screen->tesla, NV50TCL_DMA_IN_MEMORY1(0),
215 NV50TCL_DMA_IN_MEMORY1__SIZE);
216 for (i = 0; i < NV50TCL_DMA_IN_MEMORY1__SIZE; i++)
217 so_data(so, nvws->channel->vram->handle);
218
219 so_emit(nvws, so);
220 so_ref(NULL, &so);
221 nvws->push_flush(nvws, 0, NULL);
222
223 screen->pipe.winsys = ws;
224
225 screen->pipe.destroy = nv50_screen_destroy;
226
227 screen->pipe.get_name = nv50_screen_get_name;
228 screen->pipe.get_vendor = nv50_screen_get_vendor;
229 screen->pipe.get_param = nv50_screen_get_param;
230 screen->pipe.get_paramf = nv50_screen_get_paramf;
231
232 screen->pipe.is_format_supported = nv50_screen_is_format_supported;
233
234 screen->pipe.surface_map = nv50_surface_map;
235 screen->pipe.surface_unmap = nv50_surface_unmap;
236
237 nv50_screen_init_miptree_functions(&screen->pipe);
238
239 return &screen->pipe;
240 }
241