1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
28 /* Authors: Keith Whitwell <keith@tungstengraphics.com>
32 #include "draw/draw_context.h"
33 #include "util/u_inlines.h"
34 #include "util/u_math.h"
35 #include "util/u_memory.h"
36 #include "util/u_transfer.h"
37 #include "tgsi/tgsi_parse.h"
39 #include "i915_context.h"
41 #include "i915_state_inlines.h"
43 #include "i915_resource.h"
45 /* The i915 (and related graphics cores) do not support GL_CLAMP. The
46 * Intel drivers for "other operating systems" implement GL_CLAMP as
47 * GL_CLAMP_TO_EDGE, so the same is done here.
50 translate_wrap_mode(unsigned wrap
)
53 case PIPE_TEX_WRAP_REPEAT
:
54 return TEXCOORDMODE_WRAP
;
55 case PIPE_TEX_WRAP_CLAMP
:
56 return TEXCOORDMODE_CLAMP_EDGE
; /* not quite correct */
57 case PIPE_TEX_WRAP_CLAMP_TO_EDGE
:
58 return TEXCOORDMODE_CLAMP_EDGE
;
59 case PIPE_TEX_WRAP_CLAMP_TO_BORDER
:
60 return TEXCOORDMODE_CLAMP_BORDER
;
61 case PIPE_TEX_WRAP_MIRROR_REPEAT
:
62 return TEXCOORDMODE_MIRROR
;
64 return TEXCOORDMODE_WRAP
;
68 static unsigned translate_img_filter( unsigned filter
)
71 case PIPE_TEX_FILTER_NEAREST
:
72 return FILTER_NEAREST
;
73 case PIPE_TEX_FILTER_LINEAR
:
77 return FILTER_NEAREST
;
81 static unsigned translate_mip_filter( unsigned filter
)
84 case PIPE_TEX_MIPFILTER_NONE
:
85 return MIPFILTER_NONE
;
86 case PIPE_TEX_MIPFILTER_NEAREST
:
87 return MIPFILTER_NEAREST
;
88 case PIPE_TEX_MIPFILTER_LINEAR
:
89 return MIPFILTER_LINEAR
;
92 return MIPFILTER_NONE
;
97 /* None of this state is actually used for anything yet.
100 i915_create_blend_state(struct pipe_context
*pipe
,
101 const struct pipe_blend_state
*blend
)
103 struct i915_blend_state
*cso_data
= CALLOC_STRUCT( i915_blend_state
);
106 unsigned eqRGB
= blend
->rt
[0].rgb_func
;
107 unsigned srcRGB
= blend
->rt
[0].rgb_src_factor
;
108 unsigned dstRGB
= blend
->rt
[0].rgb_dst_factor
;
110 unsigned eqA
= blend
->rt
[0].alpha_func
;
111 unsigned srcA
= blend
->rt
[0].alpha_src_factor
;
112 unsigned dstA
= blend
->rt
[0].alpha_dst_factor
;
114 /* Special handling for MIN/MAX filter modes handled at
115 * state_tracker level.
118 if (srcA
!= srcRGB
||
122 cso_data
->iab
= (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD
|
126 IAB_MODIFY_SRC_FACTOR
|
127 IAB_MODIFY_DST_FACTOR
|
128 SRC_ABLND_FACT(i915_translate_blend_factor(srcA
)) |
129 DST_ABLND_FACT(i915_translate_blend_factor(dstA
)) |
130 (i915_translate_blend_func(eqA
) << IAB_FUNC_SHIFT
));
133 cso_data
->iab
= (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD
|
139 cso_data
->modes4
|= (_3DSTATE_MODES_4_CMD
|
140 ENABLE_LOGIC_OP_FUNC
|
141 LOGIC_OP_FUNC(i915_translate_logic_op(blend
->logicop_func
)));
143 if (blend
->logicop_enable
)
144 cso_data
->LIS5
|= S5_LOGICOP_ENABLE
;
147 cso_data
->LIS5
|= S5_COLOR_DITHER_ENABLE
;
149 /* XXX here take the target fixup into account */
150 if ((blend
->rt
[0].colormask
& PIPE_MASK_R
) == 0)
151 cso_data
->LIS5
|= S5_WRITEDISABLE_RED
;
153 if ((blend
->rt
[0].colormask
& PIPE_MASK_G
) == 0)
154 cso_data
->LIS5
|= S5_WRITEDISABLE_GREEN
;
156 if ((blend
->rt
[0].colormask
& PIPE_MASK_B
) == 0)
157 cso_data
->LIS5
|= S5_WRITEDISABLE_BLUE
;
159 if ((blend
->rt
[0].colormask
& PIPE_MASK_A
) == 0)
160 cso_data
->LIS5
|= S5_WRITEDISABLE_ALPHA
;
162 if (blend
->rt
[0].blend_enable
) {
163 unsigned funcRGB
= blend
->rt
[0].rgb_func
;
164 unsigned srcRGB
= blend
->rt
[0].rgb_src_factor
;
165 unsigned dstRGB
= blend
->rt
[0].rgb_dst_factor
;
167 cso_data
->LIS6
|= (S6_CBUF_BLEND_ENABLE
|
168 SRC_BLND_FACT(i915_translate_blend_factor(srcRGB
)) |
169 DST_BLND_FACT(i915_translate_blend_factor(dstRGB
)) |
170 (i915_translate_blend_func(funcRGB
) << S6_CBUF_BLEND_FUNC_SHIFT
));
176 static void i915_bind_blend_state(struct pipe_context
*pipe
,
179 struct i915_context
*i915
= i915_context(pipe
);
180 draw_flush(i915
->draw
);
182 i915
->blend
= (struct i915_blend_state
*)blend
;
184 i915
->dirty
|= I915_NEW_BLEND
;
188 static void i915_delete_blend_state(struct pipe_context
*pipe
, void *blend
)
193 static void i915_set_blend_color( struct pipe_context
*pipe
,
194 const struct pipe_blend_color
*blend_color
)
196 struct i915_context
*i915
= i915_context(pipe
);
197 draw_flush(i915
->draw
);
199 i915
->blend_color
= *blend_color
;
201 i915
->dirty
|= I915_NEW_BLEND
;
204 static void i915_set_stencil_ref( struct pipe_context
*pipe
,
205 const struct pipe_stencil_ref
*stencil_ref
)
207 struct i915_context
*i915
= i915_context(pipe
);
208 draw_flush(i915
->draw
);
210 i915
->stencil_ref
= *stencil_ref
;
212 i915
->dirty
|= I915_NEW_DEPTH_STENCIL
;
216 i915_create_sampler_state(struct pipe_context
*pipe
,
217 const struct pipe_sampler_state
*sampler
)
219 struct i915_sampler_state
*cso
= CALLOC_STRUCT( i915_sampler_state
);
220 const unsigned ws
= sampler
->wrap_s
;
221 const unsigned wt
= sampler
->wrap_t
;
222 const unsigned wr
= sampler
->wrap_r
;
223 unsigned minFilt
, magFilt
;
226 cso
->templ
= sampler
;
228 mipFilt
= translate_mip_filter(sampler
->min_mip_filter
);
229 minFilt
= translate_img_filter( sampler
->min_img_filter
);
230 magFilt
= translate_img_filter( sampler
->mag_img_filter
);
232 if (sampler
->max_anisotropy
> 1)
233 minFilt
= magFilt
= FILTER_ANISOTROPIC
;
235 if (sampler
->max_anisotropy
> 2) {
236 cso
->state
[0] |= SS2_MAX_ANISO_4
;
240 int b
= (int) (sampler
->lod_bias
* 16.0);
241 b
= CLAMP(b
, -256, 255);
242 cso
->state
[0] |= ((b
<< SS2_LOD_BIAS_SHIFT
) & SS2_LOD_BIAS_MASK
);
247 if (sampler
->compare_mode
== PIPE_TEX_COMPARE_R_TO_TEXTURE
)
249 cso
->state
[0] |= (SS2_SHADOW_ENABLE
|
250 i915_translate_shadow_compare_func(sampler
->compare_func
));
252 minFilt
= FILTER_4X4_FLAT
;
253 magFilt
= FILTER_4X4_FLAT
;
256 cso
->state
[0] |= ((minFilt
<< SS2_MIN_FILTER_SHIFT
) |
257 (mipFilt
<< SS2_MIP_FILTER_SHIFT
) |
258 (magFilt
<< SS2_MAG_FILTER_SHIFT
));
261 ((translate_wrap_mode(ws
) << SS3_TCX_ADDR_MODE_SHIFT
) |
262 (translate_wrap_mode(wt
) << SS3_TCY_ADDR_MODE_SHIFT
) |
263 (translate_wrap_mode(wr
) << SS3_TCZ_ADDR_MODE_SHIFT
));
265 if (sampler
->normalized_coords
)
266 cso
->state
[1] |= SS3_NORMALIZED_COORDS
;
269 int minlod
= (int) (16.0 * sampler
->min_lod
);
270 int maxlod
= (int) (16.0 * sampler
->max_lod
);
271 minlod
= CLAMP(minlod
, 0, 16 * 11);
272 maxlod
= CLAMP(maxlod
, 0, 16 * 11);
277 cso
->minlod
= minlod
;
278 cso
->maxlod
= maxlod
;
282 ubyte r
= float_to_ubyte(sampler
->border_color
.f
[0]);
283 ubyte g
= float_to_ubyte(sampler
->border_color
.f
[1]);
284 ubyte b
= float_to_ubyte(sampler
->border_color
.f
[2]);
285 ubyte a
= float_to_ubyte(sampler
->border_color
.f
[3]);
286 cso
->state
[2] = I915PACKCOLOR8888(r
, g
, b
, a
);
291 static void i915_fixup_bind_sampler_states(struct pipe_context
*pipe
,
292 unsigned num
, void **sampler
)
294 struct i915_context
*i915
= i915_context(pipe
);
296 i915
->saved_nr_samplers
= num
;
297 memcpy(&i915
->saved_samplers
, sampler
, sizeof(void *) * num
);
299 i915
->saved_bind_sampler_states(pipe
, num
, sampler
);
302 static void i915_bind_sampler_states(struct pipe_context
*pipe
,
303 unsigned num
, void **sampler
)
305 struct i915_context
*i915
= i915_context(pipe
);
308 /* Check for no-op */
309 if (num
== i915
->num_samplers
&&
310 !memcmp(i915
->sampler
, sampler
, num
* sizeof(void *)))
313 draw_flush(i915
->draw
);
315 for (i
= 0; i
< num
; ++i
)
316 i915
->sampler
[i
] = sampler
[i
];
317 for (i
= num
; i
< PIPE_MAX_SAMPLERS
; ++i
)
318 i915
->sampler
[i
] = NULL
;
320 i915
->num_samplers
= num
;
322 i915
->dirty
|= I915_NEW_SAMPLER
;
325 static void i915_delete_sampler_state(struct pipe_context
*pipe
,
332 /** XXX move someday? Or consolidate all these simple state setters
337 i915_create_depth_stencil_state(struct pipe_context
*pipe
,
338 const struct pipe_depth_stencil_alpha_state
*depth_stencil
)
340 struct i915_depth_stencil_state
*cso
= CALLOC_STRUCT( i915_depth_stencil_state
);
343 int testmask
= depth_stencil
->stencil
[0].valuemask
& 0xff;
344 int writemask
= depth_stencil
->stencil
[0].writemask
& 0xff;
346 cso
->stencil_modes4
|= (_3DSTATE_MODES_4_CMD
|
347 ENABLE_STENCIL_TEST_MASK
|
348 STENCIL_TEST_MASK(testmask
) |
349 ENABLE_STENCIL_WRITE_MASK
|
350 STENCIL_WRITE_MASK(writemask
));
353 if (depth_stencil
->stencil
[0].enabled
) {
354 int test
= i915_translate_compare_func(depth_stencil
->stencil
[0].func
);
355 int fop
= i915_translate_stencil_op(depth_stencil
->stencil
[0].fail_op
);
356 int dfop
= i915_translate_stencil_op(depth_stencil
->stencil
[0].zfail_op
);
357 int dpop
= i915_translate_stencil_op(depth_stencil
->stencil
[0].zpass_op
);
359 cso
->stencil_LIS5
|= (S5_STENCIL_TEST_ENABLE
|
360 S5_STENCIL_WRITE_ENABLE
|
361 (test
<< S5_STENCIL_TEST_FUNC_SHIFT
) |
362 (fop
<< S5_STENCIL_FAIL_SHIFT
) |
363 (dfop
<< S5_STENCIL_PASS_Z_FAIL_SHIFT
) |
364 (dpop
<< S5_STENCIL_PASS_Z_PASS_SHIFT
));
367 if (depth_stencil
->stencil
[1].enabled
) {
368 int test
= i915_translate_compare_func(depth_stencil
->stencil
[1].func
);
369 int fop
= i915_translate_stencil_op(depth_stencil
->stencil
[1].fail_op
);
370 int dfop
= i915_translate_stencil_op(depth_stencil
->stencil
[1].zfail_op
);
371 int dpop
= i915_translate_stencil_op(depth_stencil
->stencil
[1].zpass_op
);
372 int tmask
= depth_stencil
->stencil
[1].valuemask
& 0xff;
373 int wmask
= depth_stencil
->stencil
[1].writemask
& 0xff;
375 cso
->bfo
[0] = (_3DSTATE_BACKFACE_STENCIL_OPS
|
376 BFO_ENABLE_STENCIL_FUNCS
|
377 BFO_ENABLE_STENCIL_TWO_SIDE
|
378 BFO_ENABLE_STENCIL_REF
|
379 BFO_STENCIL_TWO_SIDE
|
380 (test
<< BFO_STENCIL_TEST_SHIFT
) |
381 (fop
<< BFO_STENCIL_FAIL_SHIFT
) |
382 (dfop
<< BFO_STENCIL_PASS_Z_FAIL_SHIFT
) |
383 (dpop
<< BFO_STENCIL_PASS_Z_PASS_SHIFT
));
385 cso
->bfo
[1] = (_3DSTATE_BACKFACE_STENCIL_MASKS
|
386 BFM_ENABLE_STENCIL_TEST_MASK
|
387 BFM_ENABLE_STENCIL_WRITE_MASK
|
388 (tmask
<< BFM_STENCIL_TEST_MASK_SHIFT
) |
389 (wmask
<< BFM_STENCIL_WRITE_MASK_SHIFT
));
392 /* This actually disables two-side stencil: The bit set is a
393 * modify-enable bit to indicate we are changing the two-side
394 * setting. Then there is a symbolic zero to show that we are
395 * setting the flag to zero/off.
397 cso
->bfo
[0] = (_3DSTATE_BACKFACE_STENCIL_OPS
|
398 BFO_ENABLE_STENCIL_TWO_SIDE
|
403 if (depth_stencil
->depth
.enabled
) {
404 int func
= i915_translate_compare_func(depth_stencil
->depth
.func
);
406 cso
->depth_LIS6
|= (S6_DEPTH_TEST_ENABLE
|
407 (func
<< S6_DEPTH_TEST_FUNC_SHIFT
));
409 if (depth_stencil
->depth
.writemask
)
410 cso
->depth_LIS6
|= S6_DEPTH_WRITE_ENABLE
;
413 if (depth_stencil
->alpha
.enabled
) {
414 int test
= i915_translate_compare_func(depth_stencil
->alpha
.func
);
415 ubyte refByte
= float_to_ubyte(depth_stencil
->alpha
.ref_value
);
417 cso
->depth_LIS6
|= (S6_ALPHA_TEST_ENABLE
|
418 (test
<< S6_ALPHA_TEST_FUNC_SHIFT
) |
419 (((unsigned) refByte
) << S6_ALPHA_REF_SHIFT
));
425 static void i915_bind_depth_stencil_state(struct pipe_context
*pipe
,
428 struct i915_context
*i915
= i915_context(pipe
);
429 draw_flush(i915
->draw
);
431 i915
->depth_stencil
= (const struct i915_depth_stencil_state
*)depth_stencil
;
433 i915
->dirty
|= I915_NEW_DEPTH_STENCIL
;
436 static void i915_delete_depth_stencil_state(struct pipe_context
*pipe
,
443 static void i915_set_scissor_state( struct pipe_context
*pipe
,
444 const struct pipe_scissor_state
*scissor
)
446 struct i915_context
*i915
= i915_context(pipe
);
447 draw_flush(i915
->draw
);
449 memcpy( &i915
->scissor
, scissor
, sizeof(*scissor
) );
450 i915
->dirty
|= I915_NEW_SCISSOR
;
454 static void i915_set_polygon_stipple( struct pipe_context
*pipe
,
455 const struct pipe_poly_stipple
*stipple
)
462 i915_create_fs_state(struct pipe_context
*pipe
,
463 const struct pipe_shader_state
*templ
)
465 struct i915_context
*i915
= i915_context(pipe
);
466 struct i915_fragment_shader
*ifs
= CALLOC_STRUCT(i915_fragment_shader
);
470 ifs
->draw_data
= draw_create_fragment_shader(i915
->draw
, templ
);
471 ifs
->state
.tokens
= tgsi_dup_tokens(templ
->tokens
);
473 tgsi_scan_shader(templ
->tokens
, &ifs
->info
);
475 /* The shader's compiled to i915 instructions here */
476 i915_translate_fragment_program(i915
, ifs
);
482 i915_fixup_bind_fs_state(struct pipe_context
*pipe
, void *shader
)
484 struct i915_context
*i915
= i915_context(pipe
);
485 draw_flush(i915
->draw
);
487 i915
->saved_fs
= shader
;
489 i915
->saved_bind_fs_state(pipe
, shader
);
493 i915_bind_fs_state(struct pipe_context
*pipe
, void *shader
)
495 struct i915_context
*i915
= i915_context(pipe
);
496 draw_flush(i915
->draw
);
498 i915
->fs
= (struct i915_fragment_shader
*) shader
;
500 draw_bind_fragment_shader(i915
->draw
, (i915
->fs
? i915
->fs
->draw_data
: NULL
));
502 i915
->dirty
|= I915_NEW_FS
;
506 void i915_delete_fs_state(struct pipe_context
*pipe
, void *shader
)
508 struct i915_fragment_shader
*ifs
= (struct i915_fragment_shader
*) shader
;
513 FREE((struct tgsi_token
*)ifs
->state
.tokens
);
514 ifs
->state
.tokens
= NULL
;
516 ifs
->program_len
= 0;
523 i915_create_vs_state(struct pipe_context
*pipe
,
524 const struct pipe_shader_state
*templ
)
526 struct i915_context
*i915
= i915_context(pipe
);
528 /* just pass-through to draw module */
529 return draw_create_vertex_shader(i915
->draw
, templ
);
532 static void i915_bind_vs_state(struct pipe_context
*pipe
, void *shader
)
534 struct i915_context
*i915
= i915_context(pipe
);
536 i915
->saved_vs
= shader
;
538 /* just pass-through to draw module */
539 draw_bind_vertex_shader(i915
->draw
, (struct draw_vertex_shader
*) shader
);
541 i915
->dirty
|= I915_NEW_VS
;
544 static void i915_delete_vs_state(struct pipe_context
*pipe
, void *shader
)
546 struct i915_context
*i915
= i915_context(pipe
);
548 /* just pass-through to draw module */
549 draw_delete_vertex_shader(i915
->draw
, (struct draw_vertex_shader
*) shader
);
552 static void i915_set_constant_buffer(struct pipe_context
*pipe
,
553 uint shader
, uint index
,
554 struct pipe_resource
*buf
)
556 struct i915_context
*i915
= i915_context(pipe
);
557 unsigned new_num
= 0;
561 /* XXX don't support geom shaders now */
562 if (shader
== PIPE_SHADER_GEOMETRY
)
565 /* if we have a new buffer compare it with the old one */
567 struct i915_buffer
*ibuf
= i915_buffer(buf
);
568 struct pipe_resource
*old_buf
= i915
->constants
[shader
];
569 struct i915_buffer
*old
= old_buf
? i915_buffer(old_buf
) : NULL
;
570 unsigned old_num
= i915
->current
.num_user_constants
[shader
];
572 new_num
= ibuf
->b
.b
.width0
/ 4 * sizeof(float);
574 if (old_num
== new_num
) {
578 /* XXX no point in running this code since st/mesa only uses user buffers */
579 /* Can't compare the buffer data since they are userbuffers */
580 else if (old
&& old
->free_on_destroy
)
581 diff
= memcmp(old
->data
, ibuf
->data
, ibuf
->b
.b
.width0
);
587 diff
= i915
->current
.num_user_constants
[shader
] != 0;
591 * flush before updateing the state.
593 if (diff
&& shader
== PIPE_SHADER_FRAGMENT
)
594 draw_flush(i915
->draw
);
596 pipe_resource_reference(&i915
->constants
[shader
], buf
);
597 i915
->current
.num_user_constants
[shader
] = new_num
;
600 i915
->dirty
|= shader
== PIPE_SHADER_VERTEX
? I915_NEW_VS_CONSTANTS
: I915_NEW_FS_CONSTANTS
;
605 i915_fixup_set_fragment_sampler_views(struct pipe_context
*pipe
,
607 struct pipe_sampler_view
**views
)
609 struct i915_context
*i915
= i915_context(pipe
);
612 for (i
= 0; i
< num
; i
++)
613 pipe_sampler_view_reference(&i915
->saved_sampler_views
[i
],
616 for (i
= num
; i
< i915
->saved_nr_sampler_views
; i
++)
617 pipe_sampler_view_reference(&i915
->saved_sampler_views
[i
],
620 i915
->saved_nr_sampler_views
= num
;
622 i915
->saved_set_sampler_views(pipe
, num
, views
);
625 static void i915_set_fragment_sampler_views(struct pipe_context
*pipe
,
627 struct pipe_sampler_view
**views
)
629 struct i915_context
*i915
= i915_context(pipe
);
632 assert(num
<= PIPE_MAX_SAMPLERS
);
634 /* Check for no-op */
635 if (num
== i915
->num_fragment_sampler_views
&&
636 !memcmp(i915
->fragment_sampler_views
, views
, num
* sizeof(struct pipe_sampler_view
*)))
639 /* Fixes wrong texture in texobj with VBUF */
640 draw_flush(i915
->draw
);
642 for (i
= 0; i
< num
; i
++)
643 pipe_sampler_view_reference(&i915
->fragment_sampler_views
[i
],
646 for (i
= num
; i
< i915
->num_fragment_sampler_views
; i
++)
647 pipe_sampler_view_reference(&i915
->fragment_sampler_views
[i
],
650 i915
->num_fragment_sampler_views
= num
;
652 i915
->dirty
|= I915_NEW_SAMPLER_VIEW
;
656 static struct pipe_sampler_view
*
657 i915_create_sampler_view(struct pipe_context
*pipe
,
658 struct pipe_resource
*texture
,
659 const struct pipe_sampler_view
*templ
)
661 struct pipe_sampler_view
*view
= CALLOC_STRUCT(pipe_sampler_view
);
665 view
->reference
.count
= 1;
666 view
->texture
= NULL
;
667 pipe_resource_reference(&view
->texture
, texture
);
668 view
->context
= pipe
;
676 i915_sampler_view_destroy(struct pipe_context
*pipe
,
677 struct pipe_sampler_view
*view
)
679 pipe_resource_reference(&view
->texture
, NULL
);
684 static void i915_set_framebuffer_state(struct pipe_context
*pipe
,
685 const struct pipe_framebuffer_state
*fb
)
687 struct i915_context
*i915
= i915_context(pipe
);
690 draw_flush(i915
->draw
);
692 i915
->framebuffer
.width
= fb
->width
;
693 i915
->framebuffer
.height
= fb
->height
;
694 i915
->framebuffer
.nr_cbufs
= fb
->nr_cbufs
;
695 for (i
= 0; i
< PIPE_MAX_COLOR_BUFS
; i
++) {
696 pipe_surface_reference(&i915
->framebuffer
.cbufs
[i
],
697 i
< fb
->nr_cbufs
? fb
->cbufs
[i
] : NULL
);
699 pipe_surface_reference(&i915
->framebuffer
.zsbuf
, fb
->zsbuf
);
701 i915
->dirty
|= I915_NEW_FRAMEBUFFER
;
706 static void i915_set_clip_state( struct pipe_context
*pipe
,
707 const struct pipe_clip_state
*clip
)
709 struct i915_context
*i915
= i915_context(pipe
);
710 draw_flush(i915
->draw
);
712 i915
->saved_clip
= *clip
;
714 draw_set_clip_state(i915
->draw
, clip
);
716 i915
->dirty
|= I915_NEW_CLIP
;
721 /* Called when driver state tracker notices changes to the viewport
724 static void i915_set_viewport_state( struct pipe_context
*pipe
,
725 const struct pipe_viewport_state
*viewport
)
727 struct i915_context
*i915
= i915_context(pipe
);
729 i915
->viewport
= *viewport
; /* struct copy */
731 /* pass the viewport info to the draw module */
732 draw_set_viewport_state(i915
->draw
, &i915
->viewport
);
734 i915
->dirty
|= I915_NEW_VIEWPORT
;
739 i915_create_rasterizer_state(struct pipe_context
*pipe
,
740 const struct pipe_rasterizer_state
*rasterizer
)
742 struct i915_rasterizer_state
*cso
= CALLOC_STRUCT( i915_rasterizer_state
);
744 cso
->templ
= *rasterizer
;
745 cso
->color_interp
= rasterizer
->flatshade
? INTERP_CONSTANT
: INTERP_LINEAR
;
746 cso
->light_twoside
= rasterizer
->light_twoside
;
747 cso
->ds
[0].u
= _3DSTATE_DEPTH_OFFSET_SCALE
;
748 cso
->ds
[1].f
= rasterizer
->offset_scale
;
749 if (rasterizer
->poly_stipple_enable
) {
750 cso
->st
|= ST1_ENABLE
;
753 if (rasterizer
->scissor
)
754 cso
->sc
[0] = _3DSTATE_SCISSOR_ENABLE_CMD
| ENABLE_SCISSOR_RECT
;
756 cso
->sc
[0] = _3DSTATE_SCISSOR_ENABLE_CMD
| DISABLE_SCISSOR_RECT
;
758 switch (rasterizer
->cull_face
) {
760 cso
->LIS4
|= S4_CULLMODE_NONE
;
762 case PIPE_FACE_FRONT
:
763 if (rasterizer
->front_ccw
)
764 cso
->LIS4
|= S4_CULLMODE_CCW
;
766 cso
->LIS4
|= S4_CULLMODE_CW
;
769 if (rasterizer
->front_ccw
)
770 cso
->LIS4
|= S4_CULLMODE_CW
;
772 cso
->LIS4
|= S4_CULLMODE_CCW
;
774 case PIPE_FACE_FRONT_AND_BACK
:
775 cso
->LIS4
|= S4_CULLMODE_BOTH
;
780 int line_width
= CLAMP((int)(rasterizer
->line_width
* 2), 1, 0xf);
782 cso
->LIS4
|= line_width
<< S4_LINE_WIDTH_SHIFT
;
784 if (rasterizer
->line_smooth
)
785 cso
->LIS4
|= S4_LINE_ANTIALIAS_ENABLE
;
789 int point_size
= CLAMP((int) rasterizer
->point_size
, 1, 0xff);
791 cso
->LIS4
|= point_size
<< S4_POINT_WIDTH_SHIFT
;
794 if (rasterizer
->flatshade
) {
795 cso
->LIS4
|= (S4_FLATSHADE_ALPHA
|
797 S4_FLATSHADE_SPECULAR
);
800 cso
->LIS7
= fui( rasterizer
->offset_units
);
806 static void i915_bind_rasterizer_state( struct pipe_context
*pipe
,
809 struct i915_context
*i915
= i915_context(pipe
);
811 i915
->rasterizer
= (struct i915_rasterizer_state
*)raster
;
813 /* pass-through to draw module */
814 draw_set_rasterizer_state(i915
->draw
,
815 (i915
->rasterizer
? &(i915
->rasterizer
->templ
) : NULL
),
818 i915
->dirty
|= I915_NEW_RASTERIZER
;
821 static void i915_delete_rasterizer_state(struct pipe_context
*pipe
,
827 static void i915_set_vertex_buffers(struct pipe_context
*pipe
,
829 const struct pipe_vertex_buffer
*buffers
)
831 struct i915_context
*i915
= i915_context(pipe
);
832 struct draw_context
*draw
= i915
->draw
;
835 util_copy_vertex_buffers(i915
->saved_vertex_buffers
,
836 &i915
->saved_nr_vertex_buffers
,
839 /* XXX doesn't look like this is needed */
841 for (i
= 0; i
< i915
->num_vertex_buffers
; i
++) {
842 draw_set_mapped_vertex_buffer(draw
, i
, NULL
);
846 /* pass-through to draw module */
847 draw_set_vertex_buffers(draw
, count
, buffers
);
850 for (i
= 0; i
< count
; i
++) {
851 void *buf
= i915_buffer(buffers
[i
].buffer
)->data
;
852 draw_set_mapped_vertex_buffer(draw
, i
, buf
);
857 i915_create_vertex_elements_state(struct pipe_context
*pipe
,
859 const struct pipe_vertex_element
*attribs
)
861 struct i915_velems_state
*velems
;
862 assert(count
<= PIPE_MAX_ATTRIBS
);
863 velems
= (struct i915_velems_state
*) MALLOC(sizeof(struct i915_velems_state
));
865 velems
->count
= count
;
866 memcpy(velems
->velem
, attribs
, sizeof(*attribs
) * count
);
872 i915_bind_vertex_elements_state(struct pipe_context
*pipe
,
875 struct i915_context
*i915
= i915_context(pipe
);
876 struct i915_velems_state
*i915_velems
= (struct i915_velems_state
*) velems
;
878 i915
->saved_velems
= velems
;
880 /* pass-through to draw module */
882 draw_set_vertex_elements(i915
->draw
,
883 i915_velems
->count
, i915_velems
->velem
);
888 i915_delete_vertex_elements_state(struct pipe_context
*pipe
, void *velems
)
893 static void i915_set_index_buffer(struct pipe_context
*pipe
,
894 const struct pipe_index_buffer
*ib
)
896 struct i915_context
*i915
= i915_context(pipe
);
899 memcpy(&i915
->index_buffer
, ib
, sizeof(i915
->index_buffer
));
901 memset(&i915
->index_buffer
, 0, sizeof(i915
->index_buffer
));
903 /* pass-through to draw module */
904 draw_set_index_buffer(i915
->draw
, ib
);
908 i915_set_sample_mask(struct pipe_context
*pipe
,
909 unsigned sample_mask
)
914 i915_init_state_functions( struct i915_context
*i915
)
916 i915
->base
.create_blend_state
= i915_create_blend_state
;
917 i915
->base
.bind_blend_state
= i915_bind_blend_state
;
918 i915
->base
.delete_blend_state
= i915_delete_blend_state
;
920 i915
->base
.create_sampler_state
= i915_create_sampler_state
;
921 i915
->base
.bind_fragment_sampler_states
= i915_bind_sampler_states
;
922 i915
->base
.delete_sampler_state
= i915_delete_sampler_state
;
924 i915
->base
.create_depth_stencil_alpha_state
= i915_create_depth_stencil_state
;
925 i915
->base
.bind_depth_stencil_alpha_state
= i915_bind_depth_stencil_state
;
926 i915
->base
.delete_depth_stencil_alpha_state
= i915_delete_depth_stencil_state
;
928 i915
->base
.create_rasterizer_state
= i915_create_rasterizer_state
;
929 i915
->base
.bind_rasterizer_state
= i915_bind_rasterizer_state
;
930 i915
->base
.delete_rasterizer_state
= i915_delete_rasterizer_state
;
931 i915
->base
.create_fs_state
= i915_create_fs_state
;
932 i915
->base
.bind_fs_state
= i915_bind_fs_state
;
933 i915
->base
.delete_fs_state
= i915_delete_fs_state
;
934 i915
->base
.create_vs_state
= i915_create_vs_state
;
935 i915
->base
.bind_vs_state
= i915_bind_vs_state
;
936 i915
->base
.delete_vs_state
= i915_delete_vs_state
;
937 i915
->base
.create_vertex_elements_state
= i915_create_vertex_elements_state
;
938 i915
->base
.bind_vertex_elements_state
= i915_bind_vertex_elements_state
;
939 i915
->base
.delete_vertex_elements_state
= i915_delete_vertex_elements_state
;
941 i915
->base
.set_blend_color
= i915_set_blend_color
;
942 i915
->base
.set_stencil_ref
= i915_set_stencil_ref
;
943 i915
->base
.set_clip_state
= i915_set_clip_state
;
944 i915
->base
.set_sample_mask
= i915_set_sample_mask
;
945 i915
->base
.set_constant_buffer
= i915_set_constant_buffer
;
946 i915
->base
.set_framebuffer_state
= i915_set_framebuffer_state
;
948 i915
->base
.set_polygon_stipple
= i915_set_polygon_stipple
;
949 i915
->base
.set_scissor_state
= i915_set_scissor_state
;
950 i915
->base
.set_fragment_sampler_views
= i915_set_fragment_sampler_views
;
951 i915
->base
.create_sampler_view
= i915_create_sampler_view
;
952 i915
->base
.sampler_view_destroy
= i915_sampler_view_destroy
;
953 i915
->base
.set_viewport_state
= i915_set_viewport_state
;
954 i915
->base
.set_vertex_buffers
= i915_set_vertex_buffers
;
955 i915
->base
.set_index_buffer
= i915_set_index_buffer
;
956 i915
->base
.redefine_user_buffer
= u_default_redefine_user_buffer
;
960 i915_init_fixup_state_functions( struct i915_context
*i915
)
962 i915
->saved_bind_fs_state
= i915
->base
.bind_fs_state
;
963 i915
->base
.bind_fs_state
= i915_fixup_bind_fs_state
;
964 i915
->saved_bind_sampler_states
= i915
->base
.bind_fragment_sampler_states
;
965 i915
->base
.bind_fragment_sampler_states
= i915_fixup_bind_sampler_states
;
966 i915
->saved_set_sampler_views
= i915
->base
.set_fragment_sampler_views
;
967 i915
->base
.set_fragment_sampler_views
= i915_fixup_set_fragment_sampler_views
;