Merge branch 'mesa_7_5_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_S3TC:
19 return 0;
20 case PIPE_CAP_ANISOTROPIC_FILTER:
21 return 1;
22 case PIPE_CAP_POINT_SPRITE:
23 return 0;
24 case PIPE_CAP_MAX_RENDER_TARGETS:
25 return 1;
26 case PIPE_CAP_OCCLUSION_QUERY:
27 return 0;
28 case PIPE_CAP_TEXTURE_SHADOW_MAP:
29 return 0;
30 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
31 return 12;
32 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
33 return 0;
34 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
35 return 12;
36 case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
37 return 0;
38 case PIPE_CAP_TGSI_CONT_SUPPORTED:
39 return 0;
40 case PIPE_CAP_BLEND_EQUATION_SEPARATE:
41 return 0;
42 case NOUVEAU_CAP_HW_VTXBUF:
43 case NOUVEAU_CAP_HW_IDXBUF:
44 return 0;
45 default:
46 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
47 return 0;
48 }
49 }
50
51 static float
52 nv10_screen_get_paramf(struct pipe_screen *screen, int param)
53 {
54 switch (param) {
55 case PIPE_CAP_MAX_LINE_WIDTH:
56 case PIPE_CAP_MAX_LINE_WIDTH_AA:
57 return 10.0;
58 case PIPE_CAP_MAX_POINT_WIDTH:
59 case PIPE_CAP_MAX_POINT_WIDTH_AA:
60 return 64.0;
61 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
62 return 2.0;
63 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
64 return 4.0;
65 default:
66 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
67 return 0.0;
68 }
69 }
70
71 static boolean
72 nv10_screen_is_format_supported(struct pipe_screen *screen,
73 enum pipe_format format,
74 enum pipe_texture_target target,
75 unsigned tex_usage, unsigned geom_flags)
76 {
77 if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
78 switch (format) {
79 case PIPE_FORMAT_A8R8G8B8_UNORM:
80 case PIPE_FORMAT_R5G6B5_UNORM:
81 return TRUE;
82 default:
83 break;
84 }
85 } else
86 if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
87 switch (format) {
88 case PIPE_FORMAT_Z24S8_UNORM:
89 case PIPE_FORMAT_Z24X8_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_A1R5G5B5_UNORM:
99 case PIPE_FORMAT_A4R4G4B4_UNORM:
100 case PIPE_FORMAT_R5G6B5_UNORM:
101 case PIPE_FORMAT_L8_UNORM:
102 case PIPE_FORMAT_A8_UNORM:
103 case PIPE_FORMAT_I8_UNORM:
104 return TRUE;
105 default:
106 break;
107 }
108 }
109
110 return FALSE;
111 }
112
113 static void
114 nv10_screen_destroy(struct pipe_screen *pscreen)
115 {
116 struct nv10_screen *screen = nv10_screen(pscreen);
117
118 nouveau_notifier_free(&screen->sync);
119 nouveau_grobj_free(&screen->celsius);
120
121 FREE(pscreen);
122 }
123
124 static struct pipe_buffer *
125 nv10_surface_buffer(struct pipe_surface *surf)
126 {
127 struct nv10_miptree *mt = (struct nv10_miptree *)surf->texture;
128
129 return mt->buffer;
130 }
131
132 struct pipe_screen *
133 nv10_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
134 {
135 struct nv10_screen *screen = CALLOC_STRUCT(nv10_screen);
136 struct nouveau_channel *chan;
137 struct pipe_screen *pscreen;
138 unsigned celsius_class;
139 int ret;
140
141 if (!screen)
142 return NULL;
143 pscreen = &screen->base.base;
144
145 ret = nouveau_screen_init(&screen->base, dev);
146 if (ret) {
147 nv10_screen_destroy(pscreen);
148 return NULL;
149 }
150 chan = screen->base.channel;
151
152 pscreen->winsys = ws;
153 pscreen->destroy = nv10_screen_destroy;
154 pscreen->get_param = nv10_screen_get_param;
155 pscreen->get_paramf = nv10_screen_get_paramf;
156 pscreen->is_format_supported = nv10_screen_is_format_supported;
157
158 nv10_screen_init_miptree_functions(pscreen);
159 nv10_screen_init_transfer_functions(pscreen);
160
161 /* 3D object */
162 if (dev->chipset >= 0x20)
163 celsius_class = NV11TCL;
164 else if (dev->chipset >= 0x17)
165 celsius_class = NV17TCL;
166 else if (dev->chipset >= 0x11)
167 celsius_class = NV11TCL;
168 else
169 celsius_class = NV10TCL;
170
171 if (!celsius_class) {
172 NOUVEAU_ERR("Unknown nv1x chipset: nv%02x\n", dev->chipset);
173 return NULL;
174 }
175
176 ret = nouveau_grobj_alloc(chan, 0xbeef0001, celsius_class,
177 &screen->celsius);
178 if (ret) {
179 NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
180 return FALSE;
181 }
182 BIND_RING(chan, screen->celsius, 7);
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