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 "pipe/internal/p_winsys_screen.h"
34 #include "pipe/p_inlines.h"
35 #include "util/u_math.h"
36 #include "util/u_memory.h"
37 #include "tgsi/tgsi_parse.h"
39 #include "i915_context.h"
41 #include "i915_state.h"
42 #include "i915_state_inlines.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_MIRRORED_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
:
75 case PIPE_TEX_FILTER_ANISO
:
76 return FILTER_ANISOTROPIC
;
79 return FILTER_NEAREST
;
83 static unsigned translate_mip_filter( unsigned filter
)
86 case PIPE_TEX_MIPFILTER_NONE
:
87 return MIPFILTER_NONE
;
88 case PIPE_TEX_MIPFILTER_NEAREST
:
89 return MIPFILTER_NEAREST
;
90 case PIPE_TEX_MIPFILTER_LINEAR
:
91 return MIPFILTER_LINEAR
;
94 return MIPFILTER_NONE
;
99 /* None of this state is actually used for anything yet.
102 i915_create_blend_state(struct pipe_context
*pipe
,
103 const struct pipe_blend_state
*blend
)
105 struct i915_blend_state
*cso_data
= CALLOC_STRUCT( i915_blend_state
);
108 unsigned eqRGB
= blend
->rgb_func
;
109 unsigned srcRGB
= blend
->rgb_src_factor
;
110 unsigned dstRGB
= blend
->rgb_dst_factor
;
112 unsigned eqA
= blend
->alpha_func
;
113 unsigned srcA
= blend
->alpha_src_factor
;
114 unsigned dstA
= blend
->alpha_dst_factor
;
116 /* Special handling for MIN/MAX filter modes handled at
117 * state_tracker level.
120 if (srcA
!= srcRGB
||
124 cso_data
->iab
= (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD
|
128 IAB_MODIFY_SRC_FACTOR
|
129 IAB_MODIFY_DST_FACTOR
|
130 SRC_ABLND_FACT(i915_translate_blend_factor(srcA
)) |
131 DST_ABLND_FACT(i915_translate_blend_factor(dstA
)) |
132 (i915_translate_blend_func(eqA
) << IAB_FUNC_SHIFT
));
135 cso_data
->iab
= (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD
|
141 cso_data
->modes4
|= (_3DSTATE_MODES_4_CMD
|
142 ENABLE_LOGIC_OP_FUNC
|
143 LOGIC_OP_FUNC(i915_translate_logic_op(blend
->logicop_func
)));
145 if (blend
->logicop_enable
)
146 cso_data
->LIS5
|= S5_LOGICOP_ENABLE
;
149 cso_data
->LIS5
|= S5_COLOR_DITHER_ENABLE
;
151 if ((blend
->colormask
& PIPE_MASK_R
) == 0)
152 cso_data
->LIS5
|= S5_WRITEDISABLE_RED
;
154 if ((blend
->colormask
& PIPE_MASK_G
) == 0)
155 cso_data
->LIS5
|= S5_WRITEDISABLE_GREEN
;
157 if ((blend
->colormask
& PIPE_MASK_B
) == 0)
158 cso_data
->LIS5
|= S5_WRITEDISABLE_BLUE
;
160 if ((blend
->colormask
& PIPE_MASK_A
) == 0)
161 cso_data
->LIS5
|= S5_WRITEDISABLE_ALPHA
;
163 if (blend
->blend_enable
) {
164 unsigned funcRGB
= blend
->rgb_func
;
165 unsigned srcRGB
= blend
->rgb_src_factor
;
166 unsigned dstRGB
= blend
->rgb_dst_factor
;
168 cso_data
->LIS6
|= (S6_CBUF_BLEND_ENABLE
|
169 SRC_BLND_FACT(i915_translate_blend_factor(srcRGB
)) |
170 DST_BLND_FACT(i915_translate_blend_factor(dstRGB
)) |
171 (i915_translate_blend_func(funcRGB
) << S6_CBUF_BLEND_FUNC_SHIFT
));
177 static void i915_bind_blend_state(struct pipe_context
*pipe
,
180 struct i915_context
*i915
= i915_context(pipe
);
181 draw_flush(i915
->draw
);
183 i915
->blend
= (struct i915_blend_state
*)blend
;
185 i915
->dirty
|= I915_NEW_BLEND
;
189 static void i915_delete_blend_state(struct pipe_context
*pipe
, void *blend
)
194 static void i915_set_blend_color( struct pipe_context
*pipe
,
195 const struct pipe_blend_color
*blend_color
)
197 struct i915_context
*i915
= i915_context(pipe
);
198 draw_flush(i915
->draw
);
200 i915
->blend_color
= *blend_color
;
202 i915
->dirty
|= I915_NEW_BLEND
;
206 i915_create_sampler_state(struct pipe_context
*pipe
,
207 const struct pipe_sampler_state
*sampler
)
209 struct i915_sampler_state
*cso
= CALLOC_STRUCT( i915_sampler_state
);
210 const unsigned ws
= sampler
->wrap_s
;
211 const unsigned wt
= sampler
->wrap_t
;
212 const unsigned wr
= sampler
->wrap_r
;
213 unsigned minFilt
, magFilt
;
216 cso
->templ
= sampler
;
218 mipFilt
= translate_mip_filter(sampler
->min_mip_filter
);
219 minFilt
= translate_img_filter( sampler
->min_img_filter
);
220 magFilt
= translate_img_filter( sampler
->mag_img_filter
);
222 if (sampler
->max_anisotropy
> 2.0) {
223 cso
->state
[0] |= SS2_MAX_ANISO_4
;
227 int b
= (int) (sampler
->lod_bias
* 16.0);
228 b
= CLAMP(b
, -256, 255);
229 cso
->state
[0] |= ((b
<< SS2_LOD_BIAS_SHIFT
) & SS2_LOD_BIAS_MASK
);
234 if (sampler
->compare_mode
== PIPE_TEX_COMPARE_R_TO_TEXTURE
)
236 cso
->state
[0] |= (SS2_SHADOW_ENABLE
|
237 i915_translate_compare_func(sampler
->compare_func
));
239 minFilt
= FILTER_4X4_FLAT
;
240 magFilt
= FILTER_4X4_FLAT
;
243 cso
->state
[0] |= ((minFilt
<< SS2_MIN_FILTER_SHIFT
) |
244 (mipFilt
<< SS2_MIP_FILTER_SHIFT
) |
245 (magFilt
<< SS2_MAG_FILTER_SHIFT
));
248 ((translate_wrap_mode(ws
) << SS3_TCX_ADDR_MODE_SHIFT
) |
249 (translate_wrap_mode(wt
) << SS3_TCY_ADDR_MODE_SHIFT
) |
250 (translate_wrap_mode(wr
) << SS3_TCZ_ADDR_MODE_SHIFT
));
252 if (sampler
->normalized_coords
)
253 cso
->state
[1] |= SS3_NORMALIZED_COORDS
;
256 int minlod
= (int) (16.0 * sampler
->min_lod
);
257 int maxlod
= (int) (16.0 * sampler
->max_lod
);
258 minlod
= CLAMP(minlod
, 0, 16 * 11);
259 maxlod
= CLAMP(maxlod
, 0, 16 * 11);
264 cso
->minlod
= minlod
;
265 cso
->maxlod
= maxlod
;
269 ubyte r
= float_to_ubyte(sampler
->border_color
[0]);
270 ubyte g
= float_to_ubyte(sampler
->border_color
[1]);
271 ubyte b
= float_to_ubyte(sampler
->border_color
[2]);
272 ubyte a
= float_to_ubyte(sampler
->border_color
[3]);
273 cso
->state
[2] = I915PACKCOLOR8888(r
, g
, b
, a
);
278 static void i915_bind_sampler_states(struct pipe_context
*pipe
,
279 unsigned num
, void **sampler
)
281 struct i915_context
*i915
= i915_context(pipe
);
284 assert(num
<= PIPE_MAX_SAMPLERS
);
286 /* Check for no-op */
287 if (num
== i915
->num_samplers
&&
288 !memcmp(i915
->sampler
, sampler
, num
* sizeof(void *)))
291 draw_flush(i915
->draw
);
293 for (i
= 0; i
< num
; ++i
)
294 i915
->sampler
[i
] = sampler
[i
];
295 for (i
= num
; i
< PIPE_MAX_SAMPLERS
; ++i
)
296 i915
->sampler
[i
] = NULL
;
298 i915
->num_samplers
= num
;
300 i915
->dirty
|= I915_NEW_SAMPLER
;
303 static void i915_delete_sampler_state(struct pipe_context
*pipe
,
310 /** XXX move someday? Or consolidate all these simple state setters
315 i915_create_depth_stencil_state(struct pipe_context
*pipe
,
316 const struct pipe_depth_stencil_alpha_state
*depth_stencil
)
318 struct i915_depth_stencil_state
*cso
= CALLOC_STRUCT( i915_depth_stencil_state
);
321 int testmask
= depth_stencil
->stencil
[0].valuemask
& 0xff;
322 int writemask
= depth_stencil
->stencil
[0].writemask
& 0xff;
324 cso
->stencil_modes4
|= (_3DSTATE_MODES_4_CMD
|
325 ENABLE_STENCIL_TEST_MASK
|
326 STENCIL_TEST_MASK(testmask
) |
327 ENABLE_STENCIL_WRITE_MASK
|
328 STENCIL_WRITE_MASK(writemask
));
331 if (depth_stencil
->stencil
[0].enabled
) {
332 int test
= i915_translate_compare_func(depth_stencil
->stencil
[0].func
);
333 int fop
= i915_translate_stencil_op(depth_stencil
->stencil
[0].fail_op
);
334 int dfop
= i915_translate_stencil_op(depth_stencil
->stencil
[0].zfail_op
);
335 int dpop
= i915_translate_stencil_op(depth_stencil
->stencil
[0].zpass_op
);
336 int ref
= depth_stencil
->stencil
[0].ref_value
& 0xff;
338 cso
->stencil_LIS5
|= (S5_STENCIL_TEST_ENABLE
|
339 S5_STENCIL_WRITE_ENABLE
|
340 (ref
<< S5_STENCIL_REF_SHIFT
) |
341 (test
<< S5_STENCIL_TEST_FUNC_SHIFT
) |
342 (fop
<< S5_STENCIL_FAIL_SHIFT
) |
343 (dfop
<< S5_STENCIL_PASS_Z_FAIL_SHIFT
) |
344 (dpop
<< S5_STENCIL_PASS_Z_PASS_SHIFT
));
347 if (depth_stencil
->stencil
[1].enabled
) {
348 int test
= i915_translate_compare_func(depth_stencil
->stencil
[1].func
);
349 int fop
= i915_translate_stencil_op(depth_stencil
->stencil
[1].fail_op
);
350 int dfop
= i915_translate_stencil_op(depth_stencil
->stencil
[1].zfail_op
);
351 int dpop
= i915_translate_stencil_op(depth_stencil
->stencil
[1].zpass_op
);
352 int ref
= depth_stencil
->stencil
[1].ref_value
& 0xff;
353 int tmask
= depth_stencil
->stencil
[1].valuemask
& 0xff;
354 int wmask
= depth_stencil
->stencil
[1].writemask
& 0xff;
356 cso
->bfo
[0] = (_3DSTATE_BACKFACE_STENCIL_OPS
|
357 BFO_ENABLE_STENCIL_FUNCS
|
358 BFO_ENABLE_STENCIL_TWO_SIDE
|
359 BFO_ENABLE_STENCIL_REF
|
360 BFO_STENCIL_TWO_SIDE
|
361 (ref
<< BFO_STENCIL_REF_SHIFT
) |
362 (test
<< BFO_STENCIL_TEST_SHIFT
) |
363 (fop
<< BFO_STENCIL_FAIL_SHIFT
) |
364 (dfop
<< BFO_STENCIL_PASS_Z_FAIL_SHIFT
) |
365 (dpop
<< BFO_STENCIL_PASS_Z_PASS_SHIFT
));
367 cso
->bfo
[1] = (_3DSTATE_BACKFACE_STENCIL_MASKS
|
368 BFM_ENABLE_STENCIL_TEST_MASK
|
369 BFM_ENABLE_STENCIL_WRITE_MASK
|
370 (tmask
<< BFM_STENCIL_TEST_MASK_SHIFT
) |
371 (wmask
<< BFM_STENCIL_WRITE_MASK_SHIFT
));
374 /* This actually disables two-side stencil: The bit set is a
375 * modify-enable bit to indicate we are changing the two-side
376 * setting. Then there is a symbolic zero to show that we are
377 * setting the flag to zero/off.
379 cso
->bfo
[0] = (_3DSTATE_BACKFACE_STENCIL_OPS
|
380 BFO_ENABLE_STENCIL_TWO_SIDE
|
385 if (depth_stencil
->depth
.enabled
) {
386 int func
= i915_translate_compare_func(depth_stencil
->depth
.func
);
388 cso
->depth_LIS6
|= (S6_DEPTH_TEST_ENABLE
|
389 (func
<< S6_DEPTH_TEST_FUNC_SHIFT
));
391 if (depth_stencil
->depth
.writemask
)
392 cso
->depth_LIS6
|= S6_DEPTH_WRITE_ENABLE
;
395 if (depth_stencil
->alpha
.enabled
) {
396 int test
= i915_translate_compare_func(depth_stencil
->alpha
.func
);
397 ubyte refByte
= float_to_ubyte(depth_stencil
->alpha
.ref_value
);
399 cso
->depth_LIS6
|= (S6_ALPHA_TEST_ENABLE
|
400 (test
<< S6_ALPHA_TEST_FUNC_SHIFT
) |
401 (((unsigned) refByte
) << S6_ALPHA_REF_SHIFT
));
407 static void i915_bind_depth_stencil_state(struct pipe_context
*pipe
,
410 struct i915_context
*i915
= i915_context(pipe
);
411 draw_flush(i915
->draw
);
413 i915
->depth_stencil
= (const struct i915_depth_stencil_state
*)depth_stencil
;
415 i915
->dirty
|= I915_NEW_DEPTH_STENCIL
;
418 static void i915_delete_depth_stencil_state(struct pipe_context
*pipe
,
425 static void i915_set_scissor_state( struct pipe_context
*pipe
,
426 const struct pipe_scissor_state
*scissor
)
428 struct i915_context
*i915
= i915_context(pipe
);
429 draw_flush(i915
->draw
);
431 memcpy( &i915
->scissor
, scissor
, sizeof(*scissor
) );
432 i915
->dirty
|= I915_NEW_SCISSOR
;
436 static void i915_set_polygon_stipple( struct pipe_context
*pipe
,
437 const struct pipe_poly_stipple
*stipple
)
444 i915_create_fs_state(struct pipe_context
*pipe
,
445 const struct pipe_shader_state
*templ
)
447 struct i915_context
*i915
= i915_context(pipe
);
448 struct i915_fragment_shader
*ifs
= CALLOC_STRUCT(i915_fragment_shader
);
452 ifs
->state
.tokens
= tgsi_dup_tokens(templ
->tokens
);
454 tgsi_scan_shader(templ
->tokens
, &ifs
->info
);
456 /* The shader's compiled to i915 instructions here */
457 i915_translate_fragment_program(i915
, ifs
);
463 i915_bind_fs_state(struct pipe_context
*pipe
, void *shader
)
465 struct i915_context
*i915
= i915_context(pipe
);
466 draw_flush(i915
->draw
);
468 i915
->fs
= (struct i915_fragment_shader
*) shader
;
470 i915
->dirty
|= I915_NEW_FS
;
474 void i915_delete_fs_state(struct pipe_context
*pipe
, void *shader
)
476 struct i915_fragment_shader
*ifs
= (struct i915_fragment_shader
*) shader
;
480 ifs
->program_len
= 0;
482 FREE((struct tgsi_token
*)ifs
->state
.tokens
);
489 i915_create_vs_state(struct pipe_context
*pipe
,
490 const struct pipe_shader_state
*templ
)
492 struct i915_context
*i915
= i915_context(pipe
);
494 /* just pass-through to draw module */
495 return draw_create_vertex_shader(i915
->draw
, templ
);
498 static void i915_bind_vs_state(struct pipe_context
*pipe
, void *shader
)
500 struct i915_context
*i915
= i915_context(pipe
);
502 /* just pass-through to draw module */
503 draw_bind_vertex_shader(i915
->draw
, (struct draw_vertex_shader
*) shader
);
505 i915
->dirty
|= I915_NEW_VS
;
508 static void i915_delete_vs_state(struct pipe_context
*pipe
, void *shader
)
510 struct i915_context
*i915
= i915_context(pipe
);
512 /* just pass-through to draw module */
513 draw_delete_vertex_shader(i915
->draw
, (struct draw_vertex_shader
*) shader
);
516 static void i915_set_constant_buffer(struct pipe_context
*pipe
,
517 uint shader
, uint index
,
518 const struct pipe_constant_buffer
*buf
)
520 struct i915_context
*i915
= i915_context(pipe
);
521 struct pipe_screen
*screen
= pipe
->screen
;
522 draw_flush(i915
->draw
);
524 assert(shader
< PIPE_SHADER_TYPES
);
527 /* Make a copy of shader constants.
528 * During fragment program translation we may add additional
529 * constants to the array.
531 * We want to consider the situation where some user constants
532 * (ex: a material color) may change frequently but the shader program
533 * stays the same. In that case we should only be updating the first
534 * N constants, leaving any extras from shader translation alone.
538 if (buf
->buffer
&& buf
->buffer
->size
&&
539 (mapped
= pipe_buffer_map(screen
, buf
->buffer
,
540 PIPE_BUFFER_USAGE_CPU_READ
))) {
541 memcpy(i915
->current
.constants
[shader
], mapped
, buf
->buffer
->size
);
542 pipe_buffer_unmap(screen
, buf
->buffer
);
543 i915
->current
.num_user_constants
[shader
]
544 = buf
->buffer
->size
/ (4 * sizeof(float));
547 i915
->current
.num_user_constants
[shader
] = 0;
551 i915
->dirty
|= I915_NEW_CONSTANTS
;
555 static void i915_set_sampler_textures(struct pipe_context
*pipe
,
557 struct pipe_texture
**texture
)
559 struct i915_context
*i915
= i915_context(pipe
);
562 assert(num
<= PIPE_MAX_SAMPLERS
);
564 /* Check for no-op */
565 if (num
== i915
->num_textures
&&
566 !memcmp(i915
->texture
, texture
, num
* sizeof(struct pipe_texture
*)))
569 /* Fixes wrong texture in texobj with VBUF */
570 draw_flush(i915
->draw
);
572 for (i
= 0; i
< num
; i
++)
573 pipe_texture_reference((struct pipe_texture
**) &i915
->texture
[i
],
576 for (i
= num
; i
< i915
->num_textures
; i
++)
577 pipe_texture_reference((struct pipe_texture
**) &i915
->texture
[i
],
580 i915
->num_textures
= num
;
582 i915
->dirty
|= I915_NEW_TEXTURE
;
587 static void i915_set_framebuffer_state(struct pipe_context
*pipe
,
588 const struct pipe_framebuffer_state
*fb
)
590 struct i915_context
*i915
= i915_context(pipe
);
593 draw_flush(i915
->draw
);
595 i915
->framebuffer
.width
= fb
->width
;
596 i915
->framebuffer
.height
= fb
->height
;
597 i915
->framebuffer
.nr_cbufs
= fb
->nr_cbufs
;
598 for (i
= 0; i
< PIPE_MAX_COLOR_BUFS
; i
++) {
599 pipe_surface_reference(&i915
->framebuffer
.cbufs
[i
], fb
->cbufs
[i
]);
601 pipe_surface_reference(&i915
->framebuffer
.zsbuf
, fb
->zsbuf
);
603 i915
->dirty
|= I915_NEW_FRAMEBUFFER
;
608 static void i915_set_clip_state( struct pipe_context
*pipe
,
609 const struct pipe_clip_state
*clip
)
611 struct i915_context
*i915
= i915_context(pipe
);
612 draw_flush(i915
->draw
);
614 draw_set_clip_state(i915
->draw
, clip
);
616 i915
->dirty
|= I915_NEW_CLIP
;
621 /* Called when driver state tracker notices changes to the viewport
624 static void i915_set_viewport_state( struct pipe_context
*pipe
,
625 const struct pipe_viewport_state
*viewport
)
627 struct i915_context
*i915
= i915_context(pipe
);
629 i915
->viewport
= *viewport
; /* struct copy */
631 /* pass the viewport info to the draw module */
632 draw_set_viewport_state(i915
->draw
, &i915
->viewport
);
634 i915
->dirty
|= I915_NEW_VIEWPORT
;
639 i915_create_rasterizer_state(struct pipe_context
*pipe
,
640 const struct pipe_rasterizer_state
*rasterizer
)
642 struct i915_rasterizer_state
*cso
= CALLOC_STRUCT( i915_rasterizer_state
);
644 cso
->templ
= rasterizer
;
645 cso
->color_interp
= rasterizer
->flatshade
? INTERP_CONSTANT
: INTERP_LINEAR
;
646 cso
->light_twoside
= rasterizer
->light_twoside
;
647 cso
->ds
[0].u
= _3DSTATE_DEPTH_OFFSET_SCALE
;
648 cso
->ds
[1].f
= rasterizer
->offset_scale
;
649 if (rasterizer
->poly_stipple_enable
) {
650 cso
->st
|= ST1_ENABLE
;
653 if (rasterizer
->scissor
)
654 cso
->sc
[0] = _3DSTATE_SCISSOR_ENABLE_CMD
| ENABLE_SCISSOR_RECT
;
656 cso
->sc
[0] = _3DSTATE_SCISSOR_ENABLE_CMD
| DISABLE_SCISSOR_RECT
;
658 switch (rasterizer
->cull_mode
) {
659 case PIPE_WINDING_NONE
:
660 cso
->LIS4
|= S4_CULLMODE_NONE
;
662 case PIPE_WINDING_CW
:
663 cso
->LIS4
|= S4_CULLMODE_CW
;
665 case PIPE_WINDING_CCW
:
666 cso
->LIS4
|= S4_CULLMODE_CCW
;
668 case PIPE_WINDING_BOTH
:
669 cso
->LIS4
|= S4_CULLMODE_BOTH
;
674 int line_width
= CLAMP((int)(rasterizer
->line_width
* 2), 1, 0xf);
676 cso
->LIS4
|= line_width
<< S4_LINE_WIDTH_SHIFT
;
678 if (rasterizer
->line_smooth
)
679 cso
->LIS4
|= S4_LINE_ANTIALIAS_ENABLE
;
683 int point_size
= CLAMP((int) rasterizer
->point_size
, 1, 0xff);
685 cso
->LIS4
|= point_size
<< S4_POINT_WIDTH_SHIFT
;
688 if (rasterizer
->flatshade
) {
689 cso
->LIS4
|= (S4_FLATSHADE_ALPHA
|
691 S4_FLATSHADE_SPECULAR
);
694 cso
->LIS7
= fui( rasterizer
->offset_units
);
700 static void i915_bind_rasterizer_state( struct pipe_context
*pipe
,
703 struct i915_context
*i915
= i915_context(pipe
);
705 i915
->rasterizer
= (struct i915_rasterizer_state
*)raster
;
707 /* pass-through to draw module */
708 draw_set_rasterizer_state(i915
->draw
,
709 (i915
->rasterizer
? i915
->rasterizer
->templ
: NULL
));
711 i915
->dirty
|= I915_NEW_RASTERIZER
;
714 static void i915_delete_rasterizer_state(struct pipe_context
*pipe
,
720 static void i915_set_vertex_buffers(struct pipe_context
*pipe
,
722 const struct pipe_vertex_buffer
*buffers
)
724 struct i915_context
*i915
= i915_context(pipe
);
725 /* Because we change state before the draw_set_vertex_buffers call
726 * we need a flush here, just to be sure.
728 draw_flush(i915
->draw
);
730 memcpy(i915
->vertex_buffer
, buffers
, count
* sizeof(buffers
[0]));
731 i915
->num_vertex_buffers
= count
;
733 /* pass-through to draw module */
734 draw_set_vertex_buffers(i915
->draw
, count
, buffers
);
737 static void i915_set_vertex_elements(struct pipe_context
*pipe
,
739 const struct pipe_vertex_element
*elements
)
741 struct i915_context
*i915
= i915_context(pipe
);
742 /* Because we change state before the draw_set_vertex_buffers call
743 * we need a flush here, just to be sure.
745 draw_flush(i915
->draw
);
747 i915
->num_vertex_elements
= count
;
748 /* pass-through to draw module */
749 draw_set_vertex_elements(i915
->draw
, count
, elements
);
753 static void i915_set_edgeflags(struct pipe_context
*pipe
,
754 const unsigned *bitfield
)
756 /* TODO do something here */
760 i915_init_state_functions( struct i915_context
*i915
)
762 i915
->base
.set_edgeflags
= i915_set_edgeflags
;
763 i915
->base
.create_blend_state
= i915_create_blend_state
;
764 i915
->base
.bind_blend_state
= i915_bind_blend_state
;
765 i915
->base
.delete_blend_state
= i915_delete_blend_state
;
767 i915
->base
.create_sampler_state
= i915_create_sampler_state
;
768 i915
->base
.bind_sampler_states
= i915_bind_sampler_states
;
769 i915
->base
.delete_sampler_state
= i915_delete_sampler_state
;
771 i915
->base
.create_depth_stencil_alpha_state
= i915_create_depth_stencil_state
;
772 i915
->base
.bind_depth_stencil_alpha_state
= i915_bind_depth_stencil_state
;
773 i915
->base
.delete_depth_stencil_alpha_state
= i915_delete_depth_stencil_state
;
775 i915
->base
.create_rasterizer_state
= i915_create_rasterizer_state
;
776 i915
->base
.bind_rasterizer_state
= i915_bind_rasterizer_state
;
777 i915
->base
.delete_rasterizer_state
= i915_delete_rasterizer_state
;
778 i915
->base
.create_fs_state
= i915_create_fs_state
;
779 i915
->base
.bind_fs_state
= i915_bind_fs_state
;
780 i915
->base
.delete_fs_state
= i915_delete_fs_state
;
781 i915
->base
.create_vs_state
= i915_create_vs_state
;
782 i915
->base
.bind_vs_state
= i915_bind_vs_state
;
783 i915
->base
.delete_vs_state
= i915_delete_vs_state
;
785 i915
->base
.set_blend_color
= i915_set_blend_color
;
786 i915
->base
.set_clip_state
= i915_set_clip_state
;
787 i915
->base
.set_constant_buffer
= i915_set_constant_buffer
;
788 i915
->base
.set_framebuffer_state
= i915_set_framebuffer_state
;
790 i915
->base
.set_polygon_stipple
= i915_set_polygon_stipple
;
791 i915
->base
.set_scissor_state
= i915_set_scissor_state
;
792 i915
->base
.set_sampler_textures
= i915_set_sampler_textures
;
793 i915
->base
.set_viewport_state
= i915_set_viewport_state
;
794 i915
->base
.set_vertex_buffers
= i915_set_vertex_buffers
;
795 i915
->base
.set_vertex_elements
= i915_set_vertex_elements
;