nouveau: adapt
[mesa.git] / src / mesa / pipe / nv50 / nv50_context.c
1 #include "pipe/draw/draw_context.h"
2 #include "pipe/p_defines.h"
3 #include "pipe/p_winsys.h"
4 #include "pipe/p_util.h"
5
6 #include "nv50_context.h"
7 #include "nv50_dma.h"
8
9 static boolean
10 nv50_is_format_supported(struct pipe_context *pipe, enum pipe_format format,
11 uint type)
12 {
13 return FALSE;
14 }
15
16 static const char *
17 nv50_get_name(struct pipe_context *pipe)
18 {
19 struct nv50_context *nv50 = (struct nv50_context *)pipe;
20 static char buffer[128];
21
22 snprintf(buffer, sizeof(buffer), "NV%02X", nv50->chipset);
23 return buffer;
24 }
25
26 static const char *
27 nv50_get_vendor(struct pipe_context *pipe)
28 {
29 return "nouveau";
30 }
31
32 static int
33 nv50_get_param(struct pipe_context *pipe, int param)
34 {
35 switch (param) {
36 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
37 return 32;
38 case PIPE_CAP_NPOT_TEXTURES:
39 return 0;
40 case PIPE_CAP_TWO_SIDED_STENCIL:
41 return 1;
42 case PIPE_CAP_GLSL:
43 return 0;
44 case PIPE_CAP_S3TC:
45 return 0;
46 case PIPE_CAP_ANISOTROPIC_FILTER:
47 return 0;
48 case PIPE_CAP_POINT_SPRITE:
49 return 0;
50 case PIPE_CAP_MAX_RENDER_TARGETS:
51 return 8;
52 case PIPE_CAP_OCCLUSION_QUERY:
53 return 0;
54 case PIPE_CAP_TEXTURE_SHADOW_MAP:
55 return 0;
56 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
57 return 13;
58 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
59 return 10;
60 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
61 return 13;
62 default:
63 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
64 return 0;
65 }
66 }
67
68 static float
69 nv50_get_paramf(struct pipe_context *pipe, int param)
70 {
71 switch (param) {
72 case PIPE_CAP_MAX_LINE_WIDTH:
73 case PIPE_CAP_MAX_LINE_WIDTH_AA:
74 return 10.0;
75 case PIPE_CAP_MAX_POINT_WIDTH:
76 case PIPE_CAP_MAX_POINT_WIDTH_AA:
77 return 64.0;
78 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
79 return 16.0;
80 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
81 return 4.0;
82 default:
83 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
84 return 0.0;
85 }
86 }
87
88 static void
89 nv50_flush(struct pipe_context *pipe, unsigned flags)
90 {
91 struct nv50_context *nv50 = (struct nv50_context *)pipe;
92 struct nouveau_winsys *nvws = nv50->nvws;
93
94 if (flags & PIPE_FLUSH_WAIT) {
95 nvws->notifier_reset(nv50->sync, 0);
96 BEGIN_RING(tesla, 0x104, 1);
97 OUT_RING (0);
98 BEGIN_RING(tesla, 0x100, 1);
99 OUT_RING (0);
100 }
101
102 FIRE_RING();
103
104 if (flags & PIPE_FLUSH_WAIT)
105 nvws->notifier_wait(nv50->sync, 0, 0, 2000);
106 }
107
108 static void
109 nv50_destroy(struct pipe_context *pipe)
110 {
111 struct nv50_context *nv50 = (struct nv50_context *)pipe;
112
113 draw_destroy(nv50->draw);
114 free(nv50);
115 }
116
117 static boolean
118 nv50_init_hwctx(struct nv50_context *nv50, int tesla_class)
119 {
120 struct nouveau_winsys *nvws = nv50->nvws;
121 int ret;
122
123 if ((ret = nvws->grobj_alloc(nvws, tesla_class, &nv50->tesla))) {
124 NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
125 return FALSE;
126 }
127
128 BEGIN_RING(tesla, NV50TCL_DMA_NOTIFY, 1);
129 OUT_RING (nv50->sync->handle);
130
131 FIRE_RING ();
132 return TRUE;
133 }
134
135 #define GRCLASS5097_CHIPSETS 0x00000000
136 #define GRCLASS8297_CHIPSETS 0x00000010
137 struct pipe_context *
138 nv50_create(struct pipe_winsys *pipe_winsys, struct nouveau_winsys *nvws,
139 unsigned chipset)
140 {
141 struct nv50_context *nv50;
142 int tesla_class, ret;
143
144 if ((chipset & 0xf0) != 0x50 && (chipset & 0xf0) != 0x80) {
145 NOUVEAU_ERR("Not a G8x chipset\n");
146 return NULL;
147 }
148
149 if (GRCLASS5097_CHIPSETS & (1 << (chipset & 0x0f))) {
150 tesla_class = 0x5097;
151 } else
152 if (GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) {
153 tesla_class = 0x8297;
154 } else {
155 NOUVEAU_ERR("Unknown G8x chipset: NV%02x\n", chipset);
156 return NULL;
157 }
158
159 nv50 = CALLOC_STRUCT(nv50_context);
160 if (!nv50)
161 return NULL;
162 nv50->chipset = chipset;
163 nv50->nvws = nvws;
164
165 if ((ret = nvws->notifier_alloc(nvws, 1, &nv50->sync))) {
166 NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
167 free(nv50);
168 return NULL;
169 }
170
171 if (!nv50_init_hwctx(nv50, tesla_class)) {
172 free(nv50);
173 return NULL;
174 }
175
176 nv50->pipe.winsys = pipe_winsys;
177
178 nv50->pipe.destroy = nv50_destroy;
179 nv50->pipe.is_format_supported = nv50_is_format_supported;
180 nv50->pipe.get_name = nv50_get_name;
181 nv50->pipe.get_vendor = nv50_get_vendor;
182 nv50->pipe.get_param = nv50_get_param;
183 nv50->pipe.get_paramf = nv50_get_paramf;
184
185 nv50->pipe.draw_arrays = nv50_draw_arrays;
186 nv50->pipe.draw_elements = nv50_draw_elements;
187 nv50->pipe.clear = nv50_clear;
188
189 nv50->pipe.flush = nv50_flush;
190
191 nv50_init_miptree_functions(nv50);
192 nv50_init_surface_functions(nv50);
193 nv50_init_state_functions(nv50);
194 nv50_init_query_functions(nv50);
195
196 nv50->draw = draw_create();
197 assert(nv50->draw);
198 draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50));
199
200 return &nv50->pipe;
201 }
202
203