Merge 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_state(struct pipe_context *pipe,
99 unsigned unit, void *sampler)
100 {
101 struct brw_context *brw = brw_context(pipe);
102
103 brw->attribs.Samplers[unit] = sampler;
104 brw->state.dirty.brw |= BRW_NEW_SAMPLER;
105 }
106
107 static void brw_delete_sampler_state(struct pipe_context *pipe,
108 void *sampler)
109 {
110 free(sampler);
111 }
112
113
114 /************************************************************************
115 * Depth stencil
116 */
117
118 static void *
119 brw_create_depth_stencil_state(struct pipe_context *pipe,
120 const struct pipe_depth_stencil_alpha_state *depth_stencil)
121 {
122 DUP( pipe_depth_stencil_alpha_state, depth_stencil );
123 }
124
125 static void brw_bind_depth_stencil_state(struct pipe_context *pipe,
126 void *depth_stencil)
127 {
128 struct brw_context *brw = brw_context(pipe);
129
130 brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil;
131
132 brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL;
133 }
134
135 static void brw_delete_depth_stencil_state(struct pipe_context *pipe,
136 void *depth_stencil)
137 {
138 free(depth_stencil);
139 }
140
141 /************************************************************************
142 * Scissor
143 */
144 static void brw_set_scissor_state( struct pipe_context *pipe,
145 const struct pipe_scissor_state *scissor )
146 {
147 struct brw_context *brw = brw_context(pipe);
148
149 memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) );
150 brw->state.dirty.brw |= BRW_NEW_SCISSOR;
151 }
152
153
154 /************************************************************************
155 * Stipple
156 */
157
158 static void brw_set_polygon_stipple( struct pipe_context *pipe,
159 const struct pipe_poly_stipple *stipple )
160 {
161 }
162
163
164 /************************************************************************
165 * Fragment shader
166 */
167
168 static void * brw_create_fs_state(struct pipe_context *pipe,
169 const struct pipe_shader_state *shader)
170 {
171 struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program);
172
173 /* XXX: Do I have to duplicate the tokens as well??
174 */
175 brw_fp->program = *shader;
176 brw_fp->id = brw_context(pipe)->program_id++;
177
178 brw_shader_info(shader->tokens,
179 &brw_fp->info);
180
181 tgsi_dump(shader->tokens, 0);
182
183
184 return (void *)brw_fp;
185 }
186
187 static void brw_bind_fs_state(struct pipe_context *pipe, void *shader)
188 {
189 struct brw_context *brw = brw_context(pipe);
190
191 brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader;
192 brw->state.dirty.brw |= BRW_NEW_FS;
193 }
194
195 static void brw_delete_fs_state(struct pipe_context *pipe, void *shader)
196 {
197 FREE(shader);
198 }
199
200
201 /************************************************************************
202 * Vertex shader and other TNL state
203 */
204
205 static void *brw_create_vs_state(struct pipe_context *pipe,
206 const struct pipe_shader_state *shader)
207 {
208 struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program);
209
210 /* XXX: Do I have to duplicate the tokens as well??
211 */
212 brw_vp->program = *shader;
213 brw_vp->id = brw_context(pipe)->program_id++;
214 brw_shader_info(shader->tokens,
215 &brw_vp->info);
216
217 tgsi_dump(shader->tokens, 0);
218
219 return (void *)brw_vp;
220 }
221
222 static void brw_bind_vs_state(struct pipe_context *pipe, void *vs)
223 {
224 struct brw_context *brw = brw_context(pipe);
225
226 brw->attribs.VertexProgram = (struct brw_vertex_program *)vs;
227 brw->state.dirty.brw |= BRW_NEW_VS;
228
229 debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n");
230 }
231
232 static void brw_delete_vs_state(struct pipe_context *pipe, void *shader)
233 {
234 FREE(shader);
235 }
236
237
238 static void brw_set_clip_state( struct pipe_context *pipe,
239 const struct pipe_clip_state *clip )
240 {
241 struct brw_context *brw = brw_context(pipe);
242
243 brw->attribs.Clip = *clip;
244 }
245
246
247 static void brw_set_viewport_state( struct pipe_context *pipe,
248 const struct pipe_viewport_state *viewport )
249 {
250 struct brw_context *brw = brw_context(pipe);
251
252 brw->attribs.Viewport = *viewport; /* struct copy */
253 brw->state.dirty.brw |= BRW_NEW_VIEWPORT;
254
255 /* pass the viewport info to the draw module */
256 //draw_set_viewport_state(brw->draw, viewport);
257 }
258
259
260 static void brw_set_vertex_buffer( struct pipe_context *pipe,
261 unsigned index,
262 const struct pipe_vertex_buffer *buffer )
263 {
264 struct brw_context *brw = brw_context(pipe);
265 brw->vb.vbo_array[index] = buffer;
266 }
267
268 static void brw_set_vertex_element(struct pipe_context *pipe,
269 unsigned index,
270 const struct pipe_vertex_element *element)
271 {
272 /* flush ? */
273 struct brw_context *brw = brw_context(pipe);
274
275 assert(index < PIPE_ATTRIB_MAX);
276 struct brw_vertex_element_state el;
277 memset(&el, 0, sizeof(el));
278
279 el.ve0.src_offset = element->src_offset;
280 el.ve0.src_format = brw_translate_surface_format(element->src_format);
281 el.ve0.valid = 1;
282 el.ve0.vertex_buffer_index = element->vertex_buffer_index;
283
284 el.ve1.dst_offset = index * 4;
285
286 el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC;
287 el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC;
288 el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC;
289 el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC;
290
291 switch (element->nr_components) {
292 case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0;
293 case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0;
294 case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT;
295 break;
296 }
297
298 brw->vb.inputs[index] = el;
299 }
300
301
302
303 /************************************************************************
304 * Constant buffers
305 */
306
307 static void brw_set_constant_buffer(struct pipe_context *pipe,
308 uint shader, uint index,
309 const struct pipe_constant_buffer *buf)
310 {
311 struct brw_context *brw = brw_context(pipe);
312
313 assert(buf == 0 || index == 0);
314
315 brw->attribs.Constants[shader] = buf;
316 brw->state.dirty.brw |= BRW_NEW_CONSTANTS;
317 }
318
319
320 /************************************************************************
321 * Texture surfaces
322 */
323
324
325 static void brw_set_sampler_texture(struct pipe_context *pipe,
326 unsigned unit,
327 struct pipe_texture *texture)
328 {
329 struct brw_context *brw = brw_context(pipe);
330
331 pipe_texture_reference(pipe,
332 (struct pipe_texture **) &brw->attribs.Texture[unit],
333 texture);
334
335 brw->state.dirty.brw |= BRW_NEW_TEXTURE;
336 }
337
338
339 /************************************************************************
340 * Render targets, etc
341 */
342
343 static void brw_set_framebuffer_state(struct pipe_context *pipe,
344 const struct pipe_framebuffer_state *fb)
345 {
346 struct brw_context *brw = brw_context(pipe);
347
348 brw->attribs.FrameBuffer = *fb; /* struct copy */
349
350 brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER;
351 }
352
353
354
355 /************************************************************************
356 * Rasterizer state
357 */
358
359 static void *
360 brw_create_rasterizer_state(struct pipe_context *pipe,
361 const struct pipe_rasterizer_state *rasterizer)
362 {
363 DUP(pipe_rasterizer_state, rasterizer);
364 }
365
366 static void brw_bind_rasterizer_state( struct pipe_context *pipe,
367 void *setup )
368 {
369 struct brw_context *brw = brw_context(pipe);
370
371 brw->attribs.Raster = (struct pipe_rasterizer_state *)setup;
372
373 /* Also pass-through to draw module:
374 */
375 //draw_set_rasterizer_state(brw->draw, setup);
376
377 brw->state.dirty.brw |= BRW_NEW_RASTERIZER;
378 }
379
380 static void brw_delete_rasterizer_state(struct pipe_context *pipe,
381 void *setup)
382 {
383 free(setup);
384 }
385
386
387
388 void
389 brw_init_state_functions( struct brw_context *brw )
390 {
391 brw->pipe.create_blend_state = brw_create_blend_state;
392 brw->pipe.bind_blend_state = brw_bind_blend_state;
393 brw->pipe.delete_blend_state = brw_delete_blend_state;
394
395 brw->pipe.create_sampler_state = brw_create_sampler_state;
396 brw->pipe.bind_sampler_state = brw_bind_sampler_state;
397 brw->pipe.delete_sampler_state = brw_delete_sampler_state;
398
399 brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state;
400 brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state;
401 brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state;
402
403 brw->pipe.create_rasterizer_state = brw_create_rasterizer_state;
404 brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state;
405 brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state;
406 brw->pipe.create_fs_state = brw_create_fs_state;
407 brw->pipe.bind_fs_state = brw_bind_fs_state;
408 brw->pipe.delete_fs_state = brw_delete_fs_state;
409 brw->pipe.create_vs_state = brw_create_vs_state;
410 brw->pipe.bind_vs_state = brw_bind_vs_state;
411 brw->pipe.delete_vs_state = brw_delete_vs_state;
412
413 brw->pipe.set_blend_color = brw_set_blend_color;
414 brw->pipe.set_clip_state = brw_set_clip_state;
415 brw->pipe.set_constant_buffer = brw_set_constant_buffer;
416 brw->pipe.set_framebuffer_state = brw_set_framebuffer_state;
417
418 // brw->pipe.set_feedback_state = brw_set_feedback_state;
419 // brw->pipe.set_feedback_buffer = brw_set_feedback_buffer;
420
421 brw->pipe.set_polygon_stipple = brw_set_polygon_stipple;
422 brw->pipe.set_scissor_state = brw_set_scissor_state;
423 brw->pipe.set_sampler_texture = brw_set_sampler_texture;
424 brw->pipe.set_viewport_state = brw_set_viewport_state;
425 brw->pipe.set_vertex_buffer = brw_set_vertex_buffer;
426 brw->pipe.set_vertex_element = brw_set_vertex_element;
427 }