Merge commit 'origin/master' 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 default:
54 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
55 return 0;
56 }
57 }
58
59 static float
60 nv04_screen_get_paramf(struct pipe_screen *screen, int param)
61 {
62 switch (param) {
63 case PIPE_CAP_MAX_LINE_WIDTH:
64 case PIPE_CAP_MAX_LINE_WIDTH_AA:
65 return 0.0;
66 case PIPE_CAP_MAX_POINT_WIDTH:
67 case PIPE_CAP_MAX_POINT_WIDTH_AA:
68 return 0.0;
69 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
70 return 0.0;
71 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
72 return 0.0;
73 default:
74 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
75 return 0.0;
76 }
77 }
78
79 static boolean
80 nv04_screen_is_format_supported(struct pipe_screen *screen,
81 enum pipe_format format,
82 enum pipe_texture_target target,
83 unsigned tex_usage, unsigned geom_flags)
84 {
85 if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
86 switch (format) {
87 case PIPE_FORMAT_A8R8G8B8_UNORM:
88 case PIPE_FORMAT_R5G6B5_UNORM:
89 case PIPE_FORMAT_Z16_UNORM:
90 return TRUE;
91 default:
92 break;
93 }
94 } else {
95 switch (format) {
96 case PIPE_FORMAT_A8R8G8B8_UNORM:
97 case PIPE_FORMAT_X8R8G8B8_UNORM:
98 case PIPE_FORMAT_A1R5G5B5_UNORM:
99 case PIPE_FORMAT_R5G6B5_UNORM:
100 case PIPE_FORMAT_L8_UNORM:
101 case PIPE_FORMAT_A8_UNORM:
102 return TRUE;
103 default:
104 break;
105 }
106 }
107
108 return FALSE;
109 }
110
111 static void *
112 nv04_surface_map(struct pipe_screen *screen, struct pipe_surface *surface,
113 unsigned flags )
114 {
115 struct pipe_winsys *ws = screen->winsys;
116 void *map;
117
118 map = ws->buffer_map(ws, surface->buffer, flags);
119 if (!map)
120 return NULL;
121
122 return map + surface->offset;
123 }
124
125 static void
126 nv04_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface)
127 {
128 struct pipe_winsys *ws = screen->winsys;
129
130 ws->buffer_unmap(ws, surface->buffer);
131 }
132
133 static void
134 nv04_screen_destroy(struct pipe_screen *pscreen)
135 {
136 struct nv04_screen *screen = nv04_screen(pscreen);
137 struct nouveau_winsys *nvws = screen->nvws;
138
139 nvws->notifier_free(&screen->sync);
140 nvws->grobj_free(&screen->fahrenheit);
141
142 FREE(pscreen);
143 }
144
145 struct pipe_screen *
146 nv04_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
147 {
148 struct nv04_screen *screen = CALLOC_STRUCT(nv04_screen);
149 unsigned fahrenheit_class = 0, sub3d_class = 0;
150 unsigned chipset = nvws->channel->device->chipset;
151 int ret;
152
153 if (!screen)
154 return NULL;
155 screen->nvws = nvws;
156
157 if (chipset>=0x20) {
158 fahrenheit_class = 0;
159 sub3d_class = 0;
160 } else if (chipset>=0x10) {
161 fahrenheit_class = NV10_DX5_TEXTURED_TRIANGLE;
162 sub3d_class = NV10_CONTEXT_SURFACES_3D;
163 } else {
164 fahrenheit_class=NV04_DX5_TEXTURED_TRIANGLE;
165 sub3d_class = NV04_CONTEXT_SURFACES_3D;
166 }
167
168 if (!fahrenheit_class) {
169 NOUVEAU_ERR("Unknown nv04 chipset: nv%02x\n", chipset);
170 return NULL;
171 }
172
173 /* 3D object */
174 ret = nvws->grobj_alloc(nvws, fahrenheit_class, &screen->fahrenheit);
175 if (ret) {
176 NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
177 return NULL;
178 }
179
180 /* 3D surface object */
181 ret = nvws->grobj_alloc(nvws, sub3d_class, &screen->context_surfaces_3d);
182 if (ret) {
183 NOUVEAU_ERR("Error creating 3D surface object: %d\n", ret);
184 return NULL;
185 }
186
187 /* Notifier for sync purposes */
188 ret = nvws->notifier_alloc(nvws, 1, &screen->sync);
189 if (ret) {
190 NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
191 nv04_screen_destroy(&screen->pipe);
192 return NULL;
193 }
194
195 screen->pipe.winsys = ws;
196 screen->pipe.destroy = nv04_screen_destroy;
197
198 screen->pipe.get_name = nv04_screen_get_name;
199 screen->pipe.get_vendor = nv04_screen_get_vendor;
200 screen->pipe.get_param = nv04_screen_get_param;
201 screen->pipe.get_paramf = nv04_screen_get_paramf;
202
203 screen->pipe.is_format_supported = nv04_screen_is_format_supported;
204
205 screen->pipe.surface_map = nv04_surface_map;
206 screen->pipe.surface_unmap = nv04_surface_unmap;
207
208 nv04_screen_init_miptree_functions(&screen->pipe);
209
210 return &screen->pipe;
211 }
212