Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
[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 return FALSE;
18 }
19
20 static const char *
21 nv50_screen_get_name(struct pipe_screen *pscreen)
22 {
23 struct nv50_screen *screen = nv50_screen(pscreen);
24 static char buffer[128];
25
26 snprintf(buffer, sizeof(buffer), "NV%02X", screen->chipset);
27 return buffer;
28 }
29
30 static const char *
31 nv50_screen_get_vendor(struct pipe_screen *pscreen)
32 {
33 return "nouveau";
34 }
35
36 static int
37 nv50_screen_get_param(struct pipe_screen *pscreen, int param)
38 {
39 switch (param) {
40 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
41 return 32;
42 case PIPE_CAP_NPOT_TEXTURES:
43 return 0;
44 case PIPE_CAP_TWO_SIDED_STENCIL:
45 return 1;
46 case PIPE_CAP_GLSL:
47 return 0;
48 case PIPE_CAP_S3TC:
49 return 0;
50 case PIPE_CAP_ANISOTROPIC_FILTER:
51 return 0;
52 case PIPE_CAP_POINT_SPRITE:
53 return 0;
54 case PIPE_CAP_MAX_RENDER_TARGETS:
55 return 8;
56 case PIPE_CAP_OCCLUSION_QUERY:
57 return 0;
58 case PIPE_CAP_TEXTURE_SHADOW_MAP:
59 return 0;
60 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
61 return 13;
62 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
63 return 10;
64 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
65 return 13;
66 case NOUVEAU_CAP_HW_VTXBUF:
67 case NOUVEAU_CAP_HW_IDXBUF:
68 return 0;
69 default:
70 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
71 return 0;
72 }
73 }
74
75 static float
76 nv50_screen_get_paramf(struct pipe_screen *pscreen, int param)
77 {
78 switch (param) {
79 case PIPE_CAP_MAX_LINE_WIDTH:
80 case PIPE_CAP_MAX_LINE_WIDTH_AA:
81 return 10.0;
82 case PIPE_CAP_MAX_POINT_WIDTH:
83 case PIPE_CAP_MAX_POINT_WIDTH_AA:
84 return 64.0;
85 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
86 return 16.0;
87 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
88 return 4.0;
89 case PIPE_CAP_BITMAP_TEXCOORD_BIAS:
90 return 0.0;
91 default:
92 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
93 return 0.0;
94 }
95 }
96
97 static void
98 nv50_screen_destroy(struct pipe_screen *pscreen)
99 {
100 FREE(pscreen);
101 }
102
103 struct pipe_screen *
104 nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws,
105 unsigned chipset)
106 {
107 struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen);
108 struct nouveau_stateobj *so;
109 unsigned tesla_class = 0, ret;
110 int i;
111
112 if (!screen)
113 return NULL;
114 screen->chipset = chipset;
115 screen->nvws = nvws;
116
117 /* 3D object */
118 if ((chipset & 0xf0) != 0x50 && (chipset & 0xf0) != 0x80) {
119 NOUVEAU_ERR("Not a G8x chipset\n");
120 nv50_screen_destroy(&screen->pipe);
121 return NULL;
122 }
123
124 switch (chipset & 0xf0) {
125 case 0x50:
126 if (NV5X_GRCLASS5097_CHIPSETS & (1 << (chipset & 0x0f)))
127 tesla_class = 0x5097;
128 break;
129 case 0x80:
130 if (NV8X_GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f)))
131 tesla_class = 0x8297;
132 break;
133 case 0x90:
134 if (NV9X_GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f)))
135 tesla_class = 0x8297;
136 break;
137 default:
138 break;
139 }
140
141 if (tesla_class == 0) {
142 NOUVEAU_ERR("Unknown G8x chipset: NV%02x\n", chipset);
143 nv50_screen_destroy(&screen->pipe);
144 return NULL;
145 }
146
147 ret = nvws->grobj_alloc(nvws, tesla_class, &screen->tesla);
148 if (ret) {
149 NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
150 nv50_screen_destroy(&screen->pipe);
151 return NULL;
152 }
153
154 /* Sync notifier */
155 ret = nvws->notifier_alloc(nvws, 1, &screen->sync);
156 if (ret) {
157 NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
158 nv50_screen_destroy(&screen->pipe);
159 return NULL;
160 }
161
162 /* Static tesla init */
163 so = so_new(128, 0);
164 so_method(so, screen->tesla, NV50TCL_DMA_NOTIFY, 1);
165 so_data (so, screen->sync->handle);
166 so_method(so, screen->tesla, NV50TCL_DMA_IN_MEMORY0(0),
167 NV50TCL_DMA_IN_MEMORY0__SIZE);
168 for (i = 0; i < NV50TCL_DMA_IN_MEMORY0__SIZE; i++)
169 so_data(so, nvws->channel->vram->handle);
170 so_method(so, screen->tesla, NV50TCL_DMA_IN_MEMORY1(0),
171 NV50TCL_DMA_IN_MEMORY1__SIZE);
172 for (i = 0; i < NV50TCL_DMA_IN_MEMORY1__SIZE; i++)
173 so_data(so, nvws->channel->vram->handle);
174
175 so_emit(nvws, so);
176 so_ref(NULL, &so);
177 nvws->push_flush(nvws, 0, NULL);
178
179 screen->pipe.winsys = ws;
180
181 screen->pipe.destroy = nv50_screen_destroy;
182
183 screen->pipe.get_name = nv50_screen_get_name;
184 screen->pipe.get_vendor = nv50_screen_get_vendor;
185 screen->pipe.get_param = nv50_screen_get_param;
186 screen->pipe.get_paramf = nv50_screen_get_paramf;
187
188 screen->pipe.is_format_supported = nv50_screen_is_format_supported;
189
190 nv50_screen_init_miptree_functions(&screen->pipe);
191
192 return &screen->pipe;
193 }
194