nouveau: NV9X is basically a G80, fix issue with NV6X being detected as G80.
[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 default:
67 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
68 return 0;
69 }
70 }
71
72 static float
73 nv50_screen_get_paramf(struct pipe_screen *pscreen, int param)
74 {
75 switch (param) {
76 case PIPE_CAP_MAX_LINE_WIDTH:
77 case PIPE_CAP_MAX_LINE_WIDTH_AA:
78 return 10.0;
79 case PIPE_CAP_MAX_POINT_WIDTH:
80 case PIPE_CAP_MAX_POINT_WIDTH_AA:
81 return 64.0;
82 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
83 return 16.0;
84 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
85 return 4.0;
86 case PIPE_CAP_BITMAP_TEXCOORD_BIAS:
87 return 0.0;
88 default:
89 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
90 return 0.0;
91 }
92 }
93
94 static void
95 nv50_screen_destroy(struct pipe_screen *pscreen)
96 {
97 FREE(pscreen);
98 }
99
100 struct pipe_screen *
101 nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws,
102 unsigned chipset)
103 {
104 struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen);
105 struct nouveau_stateobj *so;
106 unsigned tesla_class = 0, ret;
107 int i;
108
109 if (!screen)
110 return NULL;
111 screen->chipset = chipset;
112 screen->nvws = nvws;
113
114 /* 3D object */
115 if ((chipset & 0xf0) != 0x50 && (chipset & 0xf0) != 0x80) {
116 NOUVEAU_ERR("Not a G8x chipset\n");
117 nv50_screen_destroy(&screen->pipe);
118 return NULL;
119 }
120
121 switch (chipset & 0xf0) {
122 case 0x50:
123 if (NV5X_GRCLASS5097_CHIPSETS & (1 << (chipset & 0x0f)))
124 tesla_class = 0x5097;
125 break;
126 case 0x80:
127 if (NV8X_GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f)))
128 tesla_class = 0x8297;
129 break;
130 case 0x90:
131 if (NV9X_GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f)))
132 tesla_class = 0x8297;
133 break;
134 default:
135 break;
136 }
137
138 if (tesla_class == 0) {
139 NOUVEAU_ERR("Unknown G8x chipset: NV%02x\n", chipset);
140 nv50_screen_destroy(&screen->pipe);
141 return NULL;
142 }
143
144 ret = nvws->grobj_alloc(nvws, tesla_class, &screen->tesla);
145 if (ret) {
146 NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
147 nv50_screen_destroy(&screen->pipe);
148 return NULL;
149 }
150
151 /* Sync notifier */
152 ret = nvws->notifier_alloc(nvws, 1, &screen->sync);
153 if (ret) {
154 NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
155 nv50_screen_destroy(&screen->pipe);
156 return NULL;
157 }
158
159 /* Static tesla init */
160 so = so_new(128, 0);
161 so_method(so, screen->tesla, NV50TCL_DMA_NOTIFY, 1);
162 so_data (so, screen->sync->handle);
163 so_method(so, screen->tesla, NV50TCL_DMA_IN_MEMORY0(0),
164 NV50TCL_DMA_IN_MEMORY0__SIZE);
165 for (i = 0; i < NV50TCL_DMA_IN_MEMORY0__SIZE; i++)
166 so_data(so, nvws->channel->vram->handle);
167 so_method(so, screen->tesla, NV50TCL_DMA_IN_MEMORY1(0),
168 NV50TCL_DMA_IN_MEMORY1__SIZE);
169 for (i = 0; i < NV50TCL_DMA_IN_MEMORY1__SIZE; i++)
170 so_data(so, nvws->channel->vram->handle);
171
172 so_emit(nvws, so);
173 so_ref(NULL, &so);
174 nvws->push_flush(nvws->channel, 0);
175
176 screen->pipe.winsys = ws;
177
178 screen->pipe.destroy = nv50_screen_destroy;
179
180 screen->pipe.get_name = nv50_screen_get_name;
181 screen->pipe.get_vendor = nv50_screen_get_vendor;
182 screen->pipe.get_param = nv50_screen_get_param;
183 screen->pipe.get_paramf = nv50_screen_get_paramf;
184
185 screen->pipe.is_format_supported = nv50_screen_is_format_supported;
186
187 nv50_screen_init_miptree_functions(&screen->pipe);
188
189 return &screen->pipe;
190 }
191