gallium: use SSE by default
[mesa.git] / src / mesa / pipe / softpipe / sp_context.c
1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /* Author:
29 * Keith Whitwell <keith@tungstengraphics.com>
30 */
31
32 #include "pipe/draw/draw_context.h"
33 #include "pipe/p_defines.h"
34 #include "pipe/p_inlines.h"
35 #include "pipe/p_util.h"
36 #include "sp_clear.h"
37 #include "sp_context.h"
38 #include "sp_flush.h"
39 #include "sp_prim_setup.h"
40 #include "sp_state.h"
41 #include "sp_surface.h"
42 #include "sp_tile_cache.h"
43 #include "sp_texture.h"
44 #include "sp_winsys.h"
45
46
47
48 /**
49 * Query format support.
50 * If we find texture and drawable support differs, add a selector
51 * parameter or another function.
52 */
53 static boolean
54 softpipe_is_format_supported( struct pipe_context *pipe,
55 enum pipe_format format )
56 {
57 struct softpipe_context *softpipe = softpipe_context( pipe );
58 /* ask winsys if the format is supported */
59 return softpipe->winsys->is_format_supported( softpipe->winsys, format );
60 }
61
62
63 /**
64 * Map any drawing surfaces which aren't already mapped
65 */
66 void
67 softpipe_map_surfaces(struct softpipe_context *sp)
68 {
69 struct pipe_surface *ps;
70 unsigned i;
71
72 for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
73 ps = sp->framebuffer.cbufs[i];
74 if (ps->buffer)
75 pipe_surface_map(ps);
76 }
77
78 ps = sp->framebuffer.zbuf;
79 if (ps && ps->buffer)
80 pipe_surface_map(ps);
81
82 ps = sp->framebuffer.sbuf;
83 if (ps && ps->buffer)
84 pipe_surface_map(ps);
85 }
86
87
88 /**
89 * Unmap any mapped drawing surfaces
90 */
91 void
92 softpipe_unmap_surfaces(struct softpipe_context *sp)
93 {
94 struct pipe_surface *ps;
95 uint i;
96
97 for (i = 0; i < sp->framebuffer.num_cbufs; i++)
98 sp_flush_tile_cache(sp, sp->cbuf_cache[i]);
99 sp_flush_tile_cache(sp, sp->zbuf_cache);
100 sp_flush_tile_cache(sp, sp->sbuf_cache);
101
102 for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
103 ps = sp->framebuffer.cbufs[i];
104 if (ps->map)
105 pipe_surface_unmap(ps);
106 }
107
108 ps = sp->framebuffer.zbuf;
109 if (ps && ps->map)
110 pipe_surface_unmap(ps);
111
112 ps = sp->framebuffer.sbuf;
113 if (ps && ps->map)
114 pipe_surface_unmap(ps);
115 }
116
117
118 static void softpipe_destroy( struct pipe_context *pipe )
119 {
120 struct softpipe_context *softpipe = softpipe_context( pipe );
121
122 draw_destroy( softpipe->draw );
123
124 softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple );
125 softpipe->quad.earlyz->destroy( softpipe->quad.earlyz );
126 softpipe->quad.shade->destroy( softpipe->quad.shade );
127 softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test );
128 softpipe->quad.depth_test->destroy( softpipe->quad.depth_test );
129 softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test );
130 softpipe->quad.occlusion->destroy( softpipe->quad.occlusion );
131 softpipe->quad.coverage->destroy( softpipe->quad.coverage );
132 softpipe->quad.bufloop->destroy( softpipe->quad.bufloop );
133 softpipe->quad.blend->destroy( softpipe->quad.blend );
134 softpipe->quad.colormask->destroy( softpipe->quad.colormask );
135 softpipe->quad.output->destroy( softpipe->quad.output );
136
137 FREE( softpipe );
138 }
139
140
141 static void
142 softpipe_begin_query(struct pipe_context *pipe, struct pipe_query_object *q)
143 {
144 struct softpipe_context *softpipe = softpipe_context( pipe );
145 assert(q->type < PIPE_QUERY_TYPES);
146 assert(!softpipe->queries[q->type]);
147 softpipe->queries[q->type] = q;
148 }
149
150
151 static void
152 softpipe_end_query(struct pipe_context *pipe, struct pipe_query_object *q)
153 {
154 struct softpipe_context *softpipe = softpipe_context( pipe );
155 assert(q->type < PIPE_QUERY_TYPES);
156 assert(softpipe->queries[q->type]);
157 q->ready = 1; /* software rendering is synchronous */
158 softpipe->queries[q->type] = NULL;
159 }
160
161
162 static void
163 softpipe_wait_query(struct pipe_context *pipe, struct pipe_query_object *q)
164 {
165 /* Should never get here since we indicated that the result was
166 * ready in softpipe_end_query().
167 */
168 assert(0);
169 }
170
171
172 static const char *softpipe_get_name( struct pipe_context *pipe )
173 {
174 return "softpipe";
175 }
176
177 static const char *softpipe_get_vendor( struct pipe_context *pipe )
178 {
179 return "Tungsten Graphics, Inc.";
180 }
181
182 static int softpipe_get_param(struct pipe_context *pipe, int param)
183 {
184 switch (param) {
185 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
186 return 8;
187 case PIPE_CAP_NPOT_TEXTURES:
188 return 1;
189 case PIPE_CAP_TWO_SIDED_STENCIL:
190 return 1;
191 case PIPE_CAP_GLSL:
192 return 1;
193 case PIPE_CAP_S3TC:
194 return 0;
195 case PIPE_CAP_ANISOTROPIC_FILTER:
196 return 0;
197 case PIPE_CAP_POINT_SPRITE:
198 return 1;
199 case PIPE_CAP_MAX_RENDER_TARGETS:
200 return 1;
201 case PIPE_CAP_OCCLUSION_QUERY:
202 return 1;
203 case PIPE_CAP_TEXTURE_SHADOW_MAP:
204 return 1;
205 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
206 return 12; /* max 2Kx2K */
207 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
208 return 8; /* max 128x128x128 */
209 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
210 return 12; /* max 2Kx2K */
211 default:
212 return 0;
213 }
214 }
215
216 static float softpipe_get_paramf(struct pipe_context *pipe, int param)
217 {
218 switch (param) {
219 case PIPE_CAP_MAX_LINE_WIDTH:
220 /* fall-through */
221 case PIPE_CAP_MAX_LINE_WIDTH_AA:
222 return 255.0; /* arbitrary */
223
224 case PIPE_CAP_MAX_POINT_WIDTH:
225 /* fall-through */
226 case PIPE_CAP_MAX_POINT_WIDTH_AA:
227 return 255.0; /* arbitrary */
228
229 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
230 return 0.0;
231
232 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
233 return 16.0; /* arbitrary */
234
235 default:
236 return 0;
237 }
238 }
239
240 struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
241 struct softpipe_winsys *softpipe_winsys )
242 {
243 struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);
244 uint i;
245
246 #if defined(__i386__) || defined(__386__)
247 softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL;
248 #else
249 softpipe->use_sse = FALSE;
250 #endif
251
252 softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL;
253
254 softpipe->pipe.winsys = pipe_winsys;
255 softpipe->pipe.destroy = softpipe_destroy;
256
257 /* queries */
258 softpipe->pipe.is_format_supported = softpipe_is_format_supported;
259 softpipe->pipe.get_name = softpipe_get_name;
260 softpipe->pipe.get_vendor = softpipe_get_vendor;
261 softpipe->pipe.get_param = softpipe_get_param;
262 softpipe->pipe.get_paramf = softpipe_get_paramf;
263
264 /* state setters */
265 softpipe->pipe.create_alpha_test_state = softpipe_create_alpha_test_state;
266 softpipe->pipe.bind_alpha_test_state = softpipe_bind_alpha_test_state;
267 softpipe->pipe.delete_alpha_test_state = softpipe_delete_alpha_test_state;
268
269 softpipe->pipe.create_blend_state = softpipe_create_blend_state;
270 softpipe->pipe.bind_blend_state = softpipe_bind_blend_state;
271 softpipe->pipe.delete_blend_state = softpipe_delete_blend_state;
272
273 softpipe->pipe.create_sampler_state = softpipe_create_sampler_state;
274 softpipe->pipe.bind_sampler_state = softpipe_bind_sampler_state;
275 softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state;
276
277 softpipe->pipe.create_depth_stencil_state = softpipe_create_depth_stencil_state;
278 softpipe->pipe.bind_depth_stencil_state = softpipe_bind_depth_stencil_state;
279 softpipe->pipe.delete_depth_stencil_state = softpipe_delete_depth_stencil_state;
280
281 softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state;
282 softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state;
283 softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state;
284
285 softpipe->pipe.create_fs_state = softpipe_create_fs_state;
286 softpipe->pipe.bind_fs_state = softpipe_bind_fs_state;
287 softpipe->pipe.delete_fs_state = softpipe_delete_fs_state;
288
289 softpipe->pipe.create_vs_state = softpipe_create_vs_state;
290 softpipe->pipe.bind_vs_state = softpipe_bind_vs_state;
291 softpipe->pipe.delete_vs_state = softpipe_delete_vs_state;
292
293 softpipe->pipe.set_blend_color = softpipe_set_blend_color;
294 softpipe->pipe.set_clip_state = softpipe_set_clip_state;
295 softpipe->pipe.set_clear_color_state = softpipe_set_clear_color_state;
296 softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer;
297 softpipe->pipe.set_feedback_state = softpipe_set_feedback_state;
298 softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
299 softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
300 softpipe->pipe.set_sampler_units = softpipe_set_sampler_units;
301 softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
302 softpipe->pipe.set_texture_state = softpipe_set_texture_state;
303 softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
304
305 softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer;
306 softpipe->pipe.set_vertex_element = softpipe_set_vertex_element;
307 softpipe->pipe.set_feedback_buffer = softpipe_set_feedback_buffer;
308
309 softpipe->pipe.draw_arrays = softpipe_draw_arrays;
310 softpipe->pipe.draw_elements = softpipe_draw_elements;
311
312 softpipe->pipe.clear = softpipe_clear;
313 softpipe->pipe.flush = softpipe_flush;
314
315 softpipe->pipe.begin_query = softpipe_begin_query;
316 softpipe->pipe.end_query = softpipe_end_query;
317 softpipe->pipe.wait_query = softpipe_wait_query;
318
319 /* textures */
320 softpipe->pipe.texture_create = softpipe_texture_create;
321 softpipe->pipe.texture_release = softpipe_texture_release;
322 softpipe->pipe.get_tex_surface = softpipe_get_tex_surface;
323
324 /*
325 * Alloc caches for accessing drawing surfaces and textures.
326 * Must be before quad stage setup!
327 */
328 for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
329 softpipe->cbuf_cache[i] = sp_create_tile_cache();
330 softpipe->zbuf_cache = sp_create_tile_cache();
331 softpipe->sbuf_cache_sep = sp_create_tile_cache();
332 softpipe->sbuf_cache = softpipe->sbuf_cache_sep; /* initial value */
333
334 for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
335 softpipe->tex_cache[i] = sp_create_tile_cache();
336
337
338 /* setup quad rendering stages */
339 softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe);
340 softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe);
341 softpipe->quad.shade = sp_quad_shade_stage(softpipe);
342 softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe);
343 softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);
344 softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe);
345 softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe);
346 softpipe->quad.coverage = sp_quad_coverage_stage(softpipe);
347 softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe);
348 softpipe->quad.blend = sp_quad_blend_stage(softpipe);
349 softpipe->quad.colormask = sp_quad_colormask_stage(softpipe);
350 softpipe->quad.output = sp_quad_output_stage(softpipe);
351
352 softpipe->winsys = softpipe_winsys;
353
354 /*
355 * Create drawing context and plug our rendering stage into it.
356 */
357 softpipe->draw = draw_create();
358 assert(softpipe->draw);
359 softpipe->setup = sp_draw_render_stage(softpipe);
360
361 if (GETENV( "SP_VBUF" ) != NULL) {
362 softpipe->vbuf = sp_draw_vbuf_stage(softpipe->draw,
363 &softpipe->pipe,
364 sp_vbuf_setup_draw);
365
366 draw_set_rasterize_stage(softpipe->draw, softpipe->vbuf);
367 }
368 else {
369 draw_set_rasterize_stage(softpipe->draw, softpipe->setup);
370 }
371
372 sp_init_surface_functions(softpipe);
373
374 return &softpipe->pipe;
375 }