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