nv50_screen.c revision 1cec61e441ad5b4b1ac8d1abcaa7535bc1827eb3
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
13static boolean
14nv50_screen_is_format_supported(struct pipe_screen *pscreen,
15				enum pipe_format format, uint type)
16{
17	return FALSE;
18}
19
20static const char *
21nv50_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
30static const char *
31nv50_screen_get_vendor(struct pipe_screen *pscreen)
32{
33	return "nouveau";
34}
35
36static int
37nv50_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
72static float
73nv50_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
94static void
95nv50_screen_destroy(struct pipe_screen *pscreen)
96{
97	FREE(pscreen);
98}
99
100struct pipe_screen *
101nv50_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
192