Merge branch 'mesa_7_7_branch'
[mesa.git] / src / gallium / drivers / nv10 / nv10_screen.c
1 #include "pipe/p_screen.h"
2
3 #include "nv10_context.h"
4 #include "nv10_screen.h"
5
6 static int
7 nv10_screen_get_param(struct pipe_screen *screen, int param)
8 {
9 switch (param) {
10 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
11 return 2;
12 case PIPE_CAP_NPOT_TEXTURES:
13 return 0;
14 case PIPE_CAP_TWO_SIDED_STENCIL:
15 return 0;
16 case PIPE_CAP_GLSL:
17 return 0;
18 case PIPE_CAP_ANISOTROPIC_FILTER:
19 return 1;
20 case PIPE_CAP_POINT_SPRITE:
21 return 0;
22 case PIPE_CAP_MAX_RENDER_TARGETS:
23 return 1;
24 case PIPE_CAP_OCCLUSION_QUERY:
25 return 0;
26 case PIPE_CAP_TEXTURE_SHADOW_MAP:
27 return 0;
28 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
29 return 12;
30 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
31 return 0;
32 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
33 return 12;
34 case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
35 return 0;
36 case PIPE_CAP_TGSI_CONT_SUPPORTED:
37 return 0;
38 case PIPE_CAP_BLEND_EQUATION_SEPARATE:
39 return 0;
40 case NOUVEAU_CAP_HW_VTXBUF:
41 case NOUVEAU_CAP_HW_IDXBUF:
42 return 0;
43 default:
44 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
45 return 0;
46 }
47 }
48
49 static float
50 nv10_screen_get_paramf(struct pipe_screen *screen, int param)
51 {
52 switch (param) {
53 case PIPE_CAP_MAX_LINE_WIDTH:
54 case PIPE_CAP_MAX_LINE_WIDTH_AA:
55 return 10.0;
56 case PIPE_CAP_MAX_POINT_WIDTH:
57 case PIPE_CAP_MAX_POINT_WIDTH_AA:
58 return 64.0;
59 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
60 return 2.0;
61 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
62 return 4.0;
63 default:
64 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
65 return 0.0;
66 }
67 }
68
69 static boolean
70 nv10_screen_is_format_supported(struct pipe_screen *screen,
71 enum pipe_format format,
72 enum pipe_texture_target target,
73 unsigned tex_usage, unsigned geom_flags)
74 {
75 if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
76 switch (format) {
77 case PIPE_FORMAT_A8R8G8B8_UNORM:
78 case PIPE_FORMAT_R5G6B5_UNORM:
79 return TRUE;
80 default:
81 break;
82 }
83 } else
84 if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
85 switch (format) {
86 case PIPE_FORMAT_Z24S8_UNORM:
87 case PIPE_FORMAT_Z24X8_UNORM:
88 case PIPE_FORMAT_Z16_UNORM:
89 return TRUE;
90 default:
91 break;
92 }
93 } else {
94 switch (format) {
95 case PIPE_FORMAT_A8R8G8B8_UNORM:
96 case PIPE_FORMAT_A1R5G5B5_UNORM:
97 case PIPE_FORMAT_A4R4G4B4_UNORM:
98 case PIPE_FORMAT_R5G6B5_UNORM:
99 case PIPE_FORMAT_L8_UNORM:
100 case PIPE_FORMAT_A8_UNORM:
101 case PIPE_FORMAT_I8_UNORM:
102 return TRUE;
103 default:
104 break;
105 }
106 }
107
108 return FALSE;
109 }
110
111 static void
112 nv10_screen_destroy(struct pipe_screen *pscreen)
113 {
114 struct nv10_screen *screen = nv10_screen(pscreen);
115
116 nouveau_notifier_free(&screen->sync);
117 nouveau_grobj_free(&screen->celsius);
118 nv04_surface_2d_takedown(&screen->eng2d);
119
120 nouveau_screen_fini(&screen->base);
121
122 FREE(pscreen);
123 }
124
125 static struct pipe_buffer *
126 nv10_surface_buffer(struct pipe_surface *surf)
127 {
128 struct nv10_miptree *mt = (struct nv10_miptree *)surf->texture;
129
130 return mt->buffer;
131 }
132
133 struct pipe_screen *
134 nv10_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
135 {
136 struct nv10_screen *screen = CALLOC_STRUCT(nv10_screen);
137 struct nouveau_channel *chan;
138 struct pipe_screen *pscreen;
139 unsigned celsius_class;
140 int ret;
141
142 if (!screen)
143 return NULL;
144 pscreen = &screen->base.base;
145
146 ret = nouveau_screen_init(&screen->base, dev);
147 if (ret) {
148 nv10_screen_destroy(pscreen);
149 return NULL;
150 }
151 chan = screen->base.channel;
152
153 pscreen->winsys = ws;
154 pscreen->destroy = nv10_screen_destroy;
155 pscreen->get_param = nv10_screen_get_param;
156 pscreen->get_paramf = nv10_screen_get_paramf;
157 pscreen->is_format_supported = nv10_screen_is_format_supported;
158
159 nv10_screen_init_miptree_functions(pscreen);
160 nv10_screen_init_transfer_functions(pscreen);
161
162 /* 3D object */
163 if (dev->chipset >= 0x20)
164 celsius_class = NV11TCL;
165 else if (dev->chipset >= 0x17)
166 celsius_class = NV17TCL;
167 else if (dev->chipset >= 0x11)
168 celsius_class = NV11TCL;
169 else
170 celsius_class = NV10TCL;
171
172 if (!celsius_class) {
173 NOUVEAU_ERR("Unknown nv1x chipset: nv%02x\n", dev->chipset);
174 return NULL;
175 }
176
177 ret = nouveau_grobj_alloc(chan, 0xbeef0001, celsius_class,
178 &screen->celsius);
179 if (ret) {
180 NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
181 return FALSE;
182 }
183
184 /* 2D engine setup */
185 screen->eng2d = nv04_surface_2d_init(&screen->base);
186 screen->eng2d->buf = nv10_surface_buffer;
187
188 /* Notifier for sync purposes */
189 ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
190 if (ret) {
191 NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
192 nv10_screen_destroy(pscreen);
193 return NULL;
194 }
195
196 return pscreen;
197 }
198