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