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