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