Merge commit 'origin/gallium-0.1' into gallium-0.2
[mesa.git] / src / gallium / drivers / nv04 / nv04_screen.c
1 #include "pipe/p_screen.h"
2
3 #include "nv04_context.h"
4 #include "nv04_screen.h"
5
6 static const char *
7 nv04_screen_get_name(struct pipe_screen *screen)
8 {
9 struct nv04_screen *nv04screen = nv04_screen(screen);
10 struct nouveau_device *dev = nv04screen->nvws->channel->device;
11 static char buffer[128];
12
13 snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
14 return buffer;
15 }
16
17 static const char *
18 nv04_screen_get_vendor(struct pipe_screen *screen)
19 {
20 return "nouveau";
21 }
22
23 static int
24 nv04_screen_get_param(struct pipe_screen *screen, int param)
25 {
26 switch (param) {
27 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
28 return 1;
29 case PIPE_CAP_NPOT_TEXTURES:
30 return 0;
31 case PIPE_CAP_TWO_SIDED_STENCIL:
32 return 0;
33 case PIPE_CAP_GLSL:
34 return 0;
35 case PIPE_CAP_S3TC:
36 return 0;
37 case PIPE_CAP_ANISOTROPIC_FILTER:
38 return 0;
39 case PIPE_CAP_POINT_SPRITE:
40 return 0;
41 case PIPE_CAP_MAX_RENDER_TARGETS:
42 return 1;
43 case PIPE_CAP_OCCLUSION_QUERY:
44 return 0;
45 case PIPE_CAP_TEXTURE_SHADOW_MAP:
46 return 0;
47 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
48 return 10;
49 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
50 return 0;
51 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
52 return 0;
53 case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
54 return 0;
55 default:
56 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
57 return 0;
58 }
59 }
60
61 static float
62 nv04_screen_get_paramf(struct pipe_screen *screen, int param)
63 {
64 switch (param) {
65 case PIPE_CAP_MAX_LINE_WIDTH:
66 case PIPE_CAP_MAX_LINE_WIDTH_AA:
67 return 0.0;
68 case PIPE_CAP_MAX_POINT_WIDTH:
69 case PIPE_CAP_MAX_POINT_WIDTH_AA:
70 return 0.0;
71 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
72 return 0.0;
73 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
74 return 0.0;
75 default:
76 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
77 return 0.0;
78 }
79 }
80
81 static boolean
82 nv04_screen_is_format_supported(struct pipe_screen *screen,
83 enum pipe_format format,
84 enum pipe_texture_target target,
85 unsigned tex_usage, unsigned geom_flags)
86 {
87 if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
88 switch (format) {
89 case PIPE_FORMAT_A8R8G8B8_UNORM:
90 case PIPE_FORMAT_R5G6B5_UNORM:
91 case PIPE_FORMAT_Z16_UNORM:
92 return TRUE;
93 default:
94 break;
95 }
96 } else {
97 switch (format) {
98 case PIPE_FORMAT_A8R8G8B8_UNORM:
99 case PIPE_FORMAT_X8R8G8B8_UNORM:
100 case PIPE_FORMAT_A1R5G5B5_UNORM:
101 case PIPE_FORMAT_R5G6B5_UNORM:
102 case PIPE_FORMAT_L8_UNORM:
103 case PIPE_FORMAT_A8_UNORM:
104 return TRUE;
105 default:
106 break;
107 }
108 }
109
110 return FALSE;
111 }
112
113 static void *
114 nv04_surface_map(struct pipe_screen *screen, struct pipe_surface *surface,
115 unsigned flags )
116 {
117 struct pipe_winsys *ws = screen->winsys;
118 void *map;
119
120 map = ws->buffer_map(ws, surface->buffer, flags);
121 if (!map)
122 return NULL;
123
124 return map + surface->offset;
125 }
126
127 static void
128 nv04_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface)
129 {
130 struct pipe_winsys *ws = screen->winsys;
131
132 ws->buffer_unmap(ws, surface->buffer);
133 }
134
135 static void
136 nv04_screen_destroy(struct pipe_screen *pscreen)
137 {
138 struct nv04_screen *screen = nv04_screen(pscreen);
139 struct nouveau_winsys *nvws = screen->nvws;
140
141 nvws->notifier_free(&screen->sync);
142 nvws->grobj_free(&screen->fahrenheit);
143
144 FREE(pscreen);
145 }
146
147 struct pipe_screen *
148 nv04_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
149 {
150 struct nv04_screen *screen = CALLOC_STRUCT(nv04_screen);
151 unsigned fahrenheit_class = 0, sub3d_class = 0;
152 unsigned chipset = nvws->channel->device->chipset;
153 int ret;
154
155 if (!screen)
156 return NULL;
157 screen->nvws = nvws;
158
159 if (chipset>=0x20) {
160 fahrenheit_class = 0;
161 sub3d_class = 0;
162 } else if (chipset>=0x10) {
163 fahrenheit_class = NV10_DX5_TEXTURED_TRIANGLE;
164 sub3d_class = NV10_CONTEXT_SURFACES_3D;
165 } else {
166 fahrenheit_class=NV04_DX5_TEXTURED_TRIANGLE;
167 sub3d_class = NV04_CONTEXT_SURFACES_3D;
168 }
169
170 if (!fahrenheit_class) {
171 NOUVEAU_ERR("Unknown nv04 chipset: nv%02x\n", chipset);
172 return NULL;
173 }
174
175 /* 3D object */
176 ret = nvws->grobj_alloc(nvws, fahrenheit_class, &screen->fahrenheit);
177 if (ret) {
178 NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
179 return NULL;
180 }
181
182 /* 3D surface object */
183 ret = nvws->grobj_alloc(nvws, sub3d_class, &screen->context_surfaces_3d);
184 if (ret) {
185 NOUVEAU_ERR("Error creating 3D surface object: %d\n", ret);
186 return NULL;
187 }
188
189 /* Notifier for sync purposes */
190 ret = nvws->notifier_alloc(nvws, 1, &screen->sync);
191 if (ret) {
192 NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
193 nv04_screen_destroy(&screen->pipe);
194 return NULL;
195 }
196
197 screen->pipe.winsys = ws;
198 screen->pipe.destroy = nv04_screen_destroy;
199
200 screen->pipe.get_name = nv04_screen_get_name;
201 screen->pipe.get_vendor = nv04_screen_get_vendor;
202 screen->pipe.get_param = nv04_screen_get_param;
203 screen->pipe.get_paramf = nv04_screen_get_paramf;
204
205 screen->pipe.is_format_supported = nv04_screen_is_format_supported;
206
207 screen->pipe.surface_map = nv04_surface_map;
208 screen->pipe.surface_unmap = nv04_surface_unmap;
209
210 nv04_screen_init_miptree_functions(&screen->pipe);
211
212 return &screen->pipe;
213 }
214