Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
[mesa.git] / src / gallium / drivers / i965simple / brw_state.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 /* Authors: Zack Rusin <zack@tungstengraphics.com>
29 * Keith Whitwell <keith@tungstengraphics.com>
30 */
31
32
33 #include "pipe/p_winsys.h"
34 #include "pipe/p_util.h"
35 #include "pipe/p_inlines.h"
36 #include "pipe/p_shader_tokens.h"
37 #include "tgsi/util/tgsi_dump.h"
38
39 #include "brw_context.h"
40 #include "brw_defines.h"
41 #include "brw_state.h"
42 #include "brw_draw.h"
43
44
45 #define DUP( TYPE, VAL ) \
46 do { \
47 struct TYPE *x = malloc(sizeof(*x)); \
48 memcpy(x, VAL, sizeof(*x) ); \
49 return x; \
50 } while (0)
51
52 /************************************************************************
53 * Blend
54 */
55 static void *
56 brw_create_blend_state(struct pipe_context *pipe,
57 const struct pipe_blend_state *blend)
58 {
59 DUP( pipe_blend_state, blend );
60 }
61
62 static void brw_bind_blend_state(struct pipe_context *pipe,
63 void *blend)
64 {
65 struct brw_context *brw = brw_context(pipe);
66
67 brw->attribs.Blend = (struct pipe_blend_state*)blend;
68 brw->state.dirty.brw |= BRW_NEW_BLEND;
69 }
70
71
72 static void brw_delete_blend_state(struct pipe_context *pipe, void *blend)
73 {
74 free(blend);
75 }
76
77 static void brw_set_blend_color( struct pipe_context *pipe,
78 const struct pipe_blend_color *blend_color )
79 {
80 struct brw_context *brw = brw_context(pipe);
81
82 brw->attribs.BlendColor = *blend_color;
83
84 brw->state.dirty.brw |= BRW_NEW_BLEND;
85 }
86
87 /************************************************************************
88 * Sampler
89 */
90
91 static void *
92 brw_create_sampler_state(struct pipe_context *pipe,
93 const struct pipe_sampler_state *sampler)
94 {
95 DUP( pipe_sampler_state, sampler );
96 }
97
98 static void brw_bind_sampler_states(struct pipe_context *pipe,
99 unsigned num, void **sampler)
100 {
101 struct brw_context *brw = brw_context(pipe);
102
103 assert(num <= PIPE_MAX_SAMPLERS);
104
105 /* Check for no-op */
106 if (num == brw->num_samplers &&
107 !memcmp(brw->attribs.Samplers, sampler, num * sizeof(void *)))
108 return;
109
110 memcpy(brw->attribs.Samplers, sampler, num * sizeof(void *));
111 memset(&brw->attribs.Samplers[num], 0, (PIPE_MAX_SAMPLERS - num) *
112 sizeof(void *));
113
114 brw->num_samplers = num;
115
116 brw->state.dirty.brw |= BRW_NEW_SAMPLER;
117 }
118
119 static void brw_delete_sampler_state(struct pipe_context *pipe,
120 void *sampler)
121 {
122 free(sampler);
123 }
124
125
126 /************************************************************************
127 * Depth stencil
128 */
129
130 static void *
131 brw_create_depth_stencil_state(struct pipe_context *pipe,
132 const struct pipe_depth_stencil_alpha_state *depth_stencil)
133 {
134 DUP( pipe_depth_stencil_alpha_state, depth_stencil );
135 }
136
137 static void brw_bind_depth_stencil_state(struct pipe_context *pipe,
138 void *depth_stencil)
139 {
140 struct brw_context *brw = brw_context(pipe);
141
142 brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil;
143
144 brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL;
145 }
146
147 static void brw_delete_depth_stencil_state(struct pipe_context *pipe,
148 void *depth_stencil)
149 {
150 free(depth_stencil);
151 }
152
153 /************************************************************************
154 * Scissor
155 */
156 static void brw_set_scissor_state( struct pipe_context *pipe,
157 const struct pipe_scissor_state *scissor )
158 {
159 struct brw_context *brw = brw_context(pipe);
160
161 memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) );
162 brw->state.dirty.brw |= BRW_NEW_SCISSOR;
163 }
164
165
166 /************************************************************************
167 * Stipple
168 */
169
170 static void brw_set_polygon_stipple( struct pipe_context *pipe,
171 const struct pipe_poly_stipple *stipple )
172 {
173 }
174
175
176 /************************************************************************
177 * Fragment shader
178 */
179
180 static void * brw_create_fs_state(struct pipe_context *pipe,
181 const struct pipe_shader_state *shader)
182 {
183 struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program);
184
185 /* XXX: Do I have to duplicate the tokens as well??
186 */
187 brw_fp->program = *shader;
188 brw_fp->id = brw_context(pipe)->program_id++;
189
190 tgsi_scan_shader(shader->tokens, &brw_fp->info);
191
192 #if 0
193 brw_shader_info(shader->tokens,
194 &brw_fp->info2);
195 #endif
196
197 tgsi_dump(shader->tokens, 0);
198
199
200 return (void *)brw_fp;
201 }
202
203 static void brw_bind_fs_state(struct pipe_context *pipe, void *shader)
204 {
205 struct brw_context *brw = brw_context(pipe);
206
207 brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader;
208 brw->state.dirty.brw |= BRW_NEW_FS;
209 }
210
211 static void brw_delete_fs_state(struct pipe_context *pipe, void *shader)
212 {
213 FREE(shader);
214 }
215
216
217 /************************************************************************
218 * Vertex shader and other TNL state
219 */
220
221 static void *brw_create_vs_state(struct pipe_context *pipe,
222 const struct pipe_shader_state *shader)
223 {
224 struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program);
225
226 /* XXX: Do I have to duplicate the tokens as well??
227 */
228 brw_vp->program = *shader;
229 brw_vp->id = brw_context(pipe)->program_id++;
230
231 tgsi_scan_shader(shader->tokens, &brw_vp->info);
232
233 #if 0
234 brw_shader_info(shader->tokens,
235 &brw_vp->info2);
236 #endif
237 tgsi_dump(shader->tokens, 0);
238
239 return (void *)brw_vp;
240 }
241
242 static void brw_bind_vs_state(struct pipe_context *pipe, void *vs)
243 {
244 struct brw_context *brw = brw_context(pipe);
245
246 brw->attribs.VertexProgram = (struct brw_vertex_program *)vs;
247 brw->state.dirty.brw |= BRW_NEW_VS;
248
249 debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n");
250 }
251
252 static void brw_delete_vs_state(struct pipe_context *pipe, void *shader)
253 {
254 FREE(shader);
255 }
256
257
258 static void brw_set_clip_state( struct pipe_context *pipe,
259 const struct pipe_clip_state *clip )
260 {
261 struct brw_context *brw = brw_context(pipe);
262
263 brw->attribs.Clip = *clip;
264 }
265
266
267 static void brw_set_viewport_state( struct pipe_context *pipe,
268 const struct pipe_viewport_state *viewport )
269 {
270 struct brw_context *brw = brw_context(pipe);
271
272 brw->attribs.Viewport = *viewport; /* struct copy */
273 brw->state.dirty.brw |= BRW_NEW_VIEWPORT;
274
275 /* pass the viewport info to the draw module */
276 //draw_set_viewport_state(brw->draw, viewport);
277 }
278
279
280 static void brw_set_vertex_buffer( struct pipe_context *pipe,
281 unsigned index,
282 const struct pipe_vertex_buffer *buffer )
283 {
284 struct brw_context *brw = brw_context(pipe);
285 brw->vb.vbo_array[index] = buffer;
286 }
287
288 static void brw_set_vertex_element(struct pipe_context *pipe,
289 unsigned index,
290 const struct pipe_vertex_element *element)
291 {
292 /* flush ? */
293 struct brw_context *brw = brw_context(pipe);
294
295 assert(index < PIPE_ATTRIB_MAX);
296 struct brw_vertex_element_state el;
297 memset(&el, 0, sizeof(el));
298
299 el.ve0.src_offset = element->src_offset;
300 el.ve0.src_format = brw_translate_surface_format(element->src_format);
301 el.ve0.valid = 1;
302 el.ve0.vertex_buffer_index = element->vertex_buffer_index;
303
304 el.ve1.dst_offset = index * 4;
305
306 el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC;
307 el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC;
308 el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC;
309 el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC;
310
311 switch (element->nr_components) {
312 case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0;
313 case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0;
314 case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT;
315 break;
316 }
317
318 brw->vb.inputs[index] = el;
319 }
320
321
322
323 /************************************************************************
324 * Constant buffers
325 */
326
327 static void brw_set_constant_buffer(struct pipe_context *pipe,
328 uint shader, uint index,
329 const struct pipe_constant_buffer *buf)
330 {
331 struct brw_context *brw = brw_context(pipe);
332
333 assert(buf == 0 || index == 0);
334
335 brw->attribs.Constants[shader] = buf;
336 brw->state.dirty.brw |= BRW_NEW_CONSTANTS;
337 }
338
339
340 /************************************************************************
341 * Texture surfaces
342 */
343
344
345 static void brw_set_sampler_textures(struct pipe_context *pipe,
346 unsigned num,
347 struct pipe_texture **texture)
348 {
349 struct brw_context *brw = brw_context(pipe);
350 uint i;
351
352 assert(num <= PIPE_MAX_SAMPLERS);
353
354 /* Check for no-op */
355 if (num == brw->num_textures &&
356 !memcmp(brw->attribs.Texture, texture, num *
357 sizeof(struct pipe_texture *)))
358 return;
359
360 for (i = 0; i < num; i++)
361 pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i],
362 texture[i]);
363
364 for (i = num; i < brw->num_textures; i++)
365 pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i],
366 NULL);
367
368 brw->num_textures = num;
369
370 brw->state.dirty.brw |= BRW_NEW_TEXTURE;
371 }
372
373
374 /************************************************************************
375 * Render targets, etc
376 */
377
378 static void brw_set_framebuffer_state(struct pipe_context *pipe,
379 const struct pipe_framebuffer_state *fb)
380 {
381 struct brw_context *brw = brw_context(pipe);
382
383 brw->attribs.FrameBuffer = *fb; /* struct copy */
384
385 brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER;
386 }
387
388
389
390 /************************************************************************
391 * Rasterizer state
392 */
393
394 static void *
395 brw_create_rasterizer_state(struct pipe_context *pipe,
396 const struct pipe_rasterizer_state *rasterizer)
397 {
398 DUP(pipe_rasterizer_state, rasterizer);
399 }
400
401 static void brw_bind_rasterizer_state( struct pipe_context *pipe,
402 void *setup )
403 {
404 struct brw_context *brw = brw_context(pipe);
405
406 brw->attribs.Raster = (struct pipe_rasterizer_state *)setup;
407
408 /* Also pass-through to draw module:
409 */
410 //draw_set_rasterizer_state(brw->draw, setup);
411
412 brw->state.dirty.brw |= BRW_NEW_RASTERIZER;
413 }
414
415 static void brw_delete_rasterizer_state(struct pipe_context *pipe,
416 void *setup)
417 {
418 free(setup);
419 }
420
421
422
423 void
424 brw_init_state_functions( struct brw_context *brw )
425 {
426 brw->pipe.create_blend_state = brw_create_blend_state;
427 brw->pipe.bind_blend_state = brw_bind_blend_state;
428 brw->pipe.delete_blend_state = brw_delete_blend_state;
429
430 brw->pipe.create_sampler_state = brw_create_sampler_state;
431 brw->pipe.bind_sampler_states = brw_bind_sampler_states;
432 brw->pipe.delete_sampler_state = brw_delete_sampler_state;
433
434 brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state;
435 brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state;
436 brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state;
437
438 brw->pipe.create_rasterizer_state = brw_create_rasterizer_state;
439 brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state;
440 brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state;
441 brw->pipe.create_fs_state = brw_create_fs_state;
442 brw->pipe.bind_fs_state = brw_bind_fs_state;
443 brw->pipe.delete_fs_state = brw_delete_fs_state;
444 brw->pipe.create_vs_state = brw_create_vs_state;
445 brw->pipe.bind_vs_state = brw_bind_vs_state;
446 brw->pipe.delete_vs_state = brw_delete_vs_state;
447
448 brw->pipe.set_blend_color = brw_set_blend_color;
449 brw->pipe.set_clip_state = brw_set_clip_state;
450 brw->pipe.set_constant_buffer = brw_set_constant_buffer;
451 brw->pipe.set_framebuffer_state = brw_set_framebuffer_state;
452
453 // brw->pipe.set_feedback_state = brw_set_feedback_state;
454 // brw->pipe.set_feedback_buffer = brw_set_feedback_buffer;
455
456 brw->pipe.set_polygon_stipple = brw_set_polygon_stipple;
457 brw->pipe.set_scissor_state = brw_set_scissor_state;
458 brw->pipe.set_sampler_textures = brw_set_sampler_textures;
459 brw->pipe.set_viewport_state = brw_set_viewport_state;
460 brw->pipe.set_vertex_buffer = brw_set_vertex_buffer;
461 brw->pipe.set_vertex_element = brw_set_vertex_element;
462 }