1 /**************************************************************************
3 * Copyright 2007 VMware, Inc.
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 VMWARE 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 <keithw@vmware.com>
32 #include "draw/draw_context.h"
33 #include "util/u_helpers.h"
34 #include "util/u_inlines.h"
35 #include "util/u_math.h"
36 #include "util/u_memory.h"
37 #include "util/u_transfer.h"
38 #include "tgsi/tgsi_parse.h"
40 #include "i915_context.h"
42 #include "i915_state_inlines.h"
44 #include "i915_resource.h"
45 #include "i915_state.h"
47 /* The i915 (and related graphics cores) do not support GL_CLAMP. The
48 * Intel drivers for "other operating systems" implement GL_CLAMP as
49 * GL_CLAMP_TO_EDGE, so the same is done here.
52 translate_wrap_mode(unsigned wrap
)
55 case PIPE_TEX_WRAP_REPEAT
:
56 return TEXCOORDMODE_WRAP
;
57 case PIPE_TEX_WRAP_CLAMP
:
58 return TEXCOORDMODE_CLAMP_EDGE
; /* not quite correct */
59 case PIPE_TEX_WRAP_CLAMP_TO_EDGE
:
60 return TEXCOORDMODE_CLAMP_EDGE
;
61 case PIPE_TEX_WRAP_CLAMP_TO_BORDER
:
62 return TEXCOORDMODE_CLAMP_BORDER
;
63 case PIPE_TEX_WRAP_MIRROR_REPEAT
:
64 return TEXCOORDMODE_MIRROR
;
66 return TEXCOORDMODE_WRAP
;
70 static unsigned translate_img_filter( unsigned filter
)
73 case PIPE_TEX_FILTER_NEAREST
:
74 return FILTER_NEAREST
;
75 case PIPE_TEX_FILTER_LINEAR
:
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
;
98 /* None of this state is actually used for anything yet.
101 i915_create_blend_state(struct pipe_context
*pipe
,
102 const struct pipe_blend_state
*blend
)
104 struct i915_blend_state
*cso_data
= CALLOC_STRUCT( i915_blend_state
);
107 unsigned eqRGB
= blend
->rt
[0].rgb_func
;
108 unsigned srcRGB
= blend
->rt
[0].rgb_src_factor
;
109 unsigned dstRGB
= blend
->rt
[0].rgb_dst_factor
;
111 unsigned eqA
= blend
->rt
[0].alpha_func
;
112 unsigned srcA
= blend
->rt
[0].alpha_src_factor
;
113 unsigned dstA
= blend
->rt
[0].alpha_dst_factor
;
115 /* Special handling for MIN/MAX filter modes handled at
116 * state_tracker level.
119 if (srcA
!= srcRGB
||
123 cso_data
->iab
= (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD
|
127 IAB_MODIFY_SRC_FACTOR
|
128 IAB_MODIFY_DST_FACTOR
|
129 SRC_ABLND_FACT(i915_translate_blend_factor(srcA
)) |
130 DST_ABLND_FACT(i915_translate_blend_factor(dstA
)) |
131 (i915_translate_blend_func(eqA
) << IAB_FUNC_SHIFT
));
134 cso_data
->iab
= (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD
|
140 cso_data
->modes4
|= (_3DSTATE_MODES_4_CMD
|
141 ENABLE_LOGIC_OP_FUNC
|
142 LOGIC_OP_FUNC(i915_translate_logic_op(blend
->logicop_func
)));
144 if (blend
->logicop_enable
)
145 cso_data
->LIS5
|= S5_LOGICOP_ENABLE
;
148 cso_data
->LIS5
|= S5_COLOR_DITHER_ENABLE
;
150 /* We potentially do some fixup at emission for non-BGRA targets */
151 if ((blend
->rt
[0].colormask
& PIPE_MASK_R
) == 0)
152 cso_data
->LIS5
|= S5_WRITEDISABLE_RED
;
154 if ((blend
->rt
[0].colormask
& PIPE_MASK_G
) == 0)
155 cso_data
->LIS5
|= S5_WRITEDISABLE_GREEN
;
157 if ((blend
->rt
[0].colormask
& PIPE_MASK_B
) == 0)
158 cso_data
->LIS5
|= S5_WRITEDISABLE_BLUE
;
160 if ((blend
->rt
[0].colormask
& PIPE_MASK_A
) == 0)
161 cso_data
->LIS5
|= S5_WRITEDISABLE_ALPHA
;
163 if (blend
->rt
[0].blend_enable
) {
164 unsigned funcRGB
= blend
->rt
[0].rgb_func
;
165 unsigned srcRGB
= blend
->rt
[0].rgb_src_factor
;
166 unsigned dstRGB
= blend
->rt
[0].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
);
182 if (i915
->blend
== blend
)
185 i915
->blend
= (struct i915_blend_state
*)blend
;
187 i915
->dirty
|= I915_NEW_BLEND
;
191 static void i915_delete_blend_state(struct pipe_context
*pipe
, void *blend
)
196 static void i915_set_blend_color( struct pipe_context
*pipe
,
197 const struct pipe_blend_color
*blend_color
)
199 struct i915_context
*i915
= i915_context(pipe
);
204 i915
->blend_color
= *blend_color
;
206 i915
->dirty
|= I915_NEW_BLEND
;
209 static void i915_set_stencil_ref( struct pipe_context
*pipe
,
210 const struct pipe_stencil_ref
*stencil_ref
)
212 struct i915_context
*i915
= i915_context(pipe
);
214 i915
->stencil_ref
= *stencil_ref
;
216 i915
->dirty
|= I915_NEW_DEPTH_STENCIL
;
220 i915_create_sampler_state(struct pipe_context
*pipe
,
221 const struct pipe_sampler_state
*sampler
)
223 struct i915_sampler_state
*cso
= CALLOC_STRUCT( i915_sampler_state
);
224 const unsigned ws
= sampler
->wrap_s
;
225 const unsigned wt
= sampler
->wrap_t
;
226 const unsigned wr
= sampler
->wrap_r
;
227 unsigned minFilt
, magFilt
;
230 cso
->templ
= *sampler
;
232 mipFilt
= translate_mip_filter(sampler
->min_mip_filter
);
233 minFilt
= translate_img_filter( sampler
->min_img_filter
);
234 magFilt
= translate_img_filter( sampler
->mag_img_filter
);
236 if (sampler
->max_anisotropy
> 1)
237 minFilt
= magFilt
= FILTER_ANISOTROPIC
;
239 if (sampler
->max_anisotropy
> 2) {
240 cso
->state
[0] |= SS2_MAX_ANISO_4
;
244 int b
= (int) (sampler
->lod_bias
* 16.0);
245 b
= CLAMP(b
, -256, 255);
246 cso
->state
[0] |= ((b
<< SS2_LOD_BIAS_SHIFT
) & SS2_LOD_BIAS_MASK
);
251 if (sampler
->compare_mode
== PIPE_TEX_COMPARE_R_TO_TEXTURE
)
253 cso
->state
[0] |= (SS2_SHADOW_ENABLE
|
254 i915_translate_shadow_compare_func(sampler
->compare_func
));
256 minFilt
= FILTER_4X4_FLAT
;
257 magFilt
= FILTER_4X4_FLAT
;
260 cso
->state
[0] |= ((minFilt
<< SS2_MIN_FILTER_SHIFT
) |
261 (mipFilt
<< SS2_MIP_FILTER_SHIFT
) |
262 (magFilt
<< SS2_MAG_FILTER_SHIFT
));
265 ((translate_wrap_mode(ws
) << SS3_TCX_ADDR_MODE_SHIFT
) |
266 (translate_wrap_mode(wt
) << SS3_TCY_ADDR_MODE_SHIFT
) |
267 (translate_wrap_mode(wr
) << SS3_TCZ_ADDR_MODE_SHIFT
));
269 if (sampler
->normalized_coords
)
270 cso
->state
[1] |= SS3_NORMALIZED_COORDS
;
273 int minlod
= (int) (16.0 * sampler
->min_lod
);
274 int maxlod
= (int) (16.0 * sampler
->max_lod
);
275 minlod
= CLAMP(minlod
, 0, 16 * 11);
276 maxlod
= CLAMP(maxlod
, 0, 16 * 11);
281 cso
->minlod
= minlod
;
282 cso
->maxlod
= maxlod
;
286 ubyte r
= float_to_ubyte(sampler
->border_color
.f
[0]);
287 ubyte g
= float_to_ubyte(sampler
->border_color
.f
[1]);
288 ubyte b
= float_to_ubyte(sampler
->border_color
.f
[2]);
289 ubyte a
= float_to_ubyte(sampler
->border_color
.f
[3]);
290 cso
->state
[2] = I915PACKCOLOR8888(r
, g
, b
, a
);
296 i915_bind_vertex_sampler_states(struct pipe_context
*pipe
,
301 struct i915_context
*i915
= i915_context(pipe
);
304 assert(start
+ num
<= Elements(i915
->vertex_samplers
));
306 /* Check for no-op */
307 if (num
== i915
->num_vertex_samplers
&&
308 !memcmp(i915
->vertex_samplers
+ start
, samplers
,
309 num
* sizeof(void *)))
312 for (i
= 0; i
< num
; ++i
)
313 i915
->vertex_samplers
[i
+ start
] = samplers
[i
];
315 /* find highest non-null samplers[] entry */
317 unsigned j
= MAX2(i915
->num_vertex_samplers
, start
+ num
);
318 while (j
> 0 && i915
->vertex_samplers
[j
- 1] == NULL
)
320 i915
->num_vertex_samplers
= j
;
323 draw_set_samplers(i915
->draw
,
325 i915
->vertex_samplers
,
326 i915
->num_vertex_samplers
);
331 static void i915_bind_fragment_sampler_states(struct pipe_context
*pipe
,
336 struct i915_context
*i915
= i915_context(pipe
);
339 /* Check for no-op */
340 if (num
== i915
->num_samplers
&&
341 !memcmp(i915
->fragment_sampler
+ start
, samplers
,
342 num
* sizeof(void *)))
345 for (i
= 0; i
< num
; ++i
)
346 i915
->fragment_sampler
[i
+ start
] = samplers
[i
];
348 /* find highest non-null samplers[] entry */
350 unsigned j
= MAX2(i915
->num_samplers
, start
+ num
);
351 while (j
> 0 && i915
->fragment_sampler
[j
- 1] == NULL
)
353 i915
->num_samplers
= j
;
356 i915
->dirty
|= I915_NEW_SAMPLER
;
361 i915_bind_sampler_states(struct pipe_context
*pipe
, unsigned shader
,
362 unsigned start
, unsigned num_samplers
,
366 case PIPE_SHADER_VERTEX
:
367 i915_bind_vertex_sampler_states(pipe
, start
, num_samplers
, samplers
);
369 case PIPE_SHADER_FRAGMENT
:
370 i915_bind_fragment_sampler_states(pipe
, start
, num_samplers
, samplers
);
378 static void i915_delete_sampler_state(struct pipe_context
*pipe
,
386 * Called before drawing VBO to map vertex samplers and hand them to draw
389 i915_prepare_vertex_sampling(struct i915_context
*i915
)
391 struct i915_winsys
*iws
= i915
->iws
;
393 uint32_t row_stride
[PIPE_MAX_TEXTURE_LEVELS
];
394 uint32_t img_stride
[PIPE_MAX_TEXTURE_LEVELS
];
395 uint32_t mip_offsets
[PIPE_MAX_TEXTURE_LEVELS
];
396 unsigned num
= i915
->num_vertex_sampler_views
;
397 struct pipe_sampler_view
**views
= i915
->vertex_sampler_views
;
399 assert(num
<= PIPE_MAX_SAMPLERS
);
403 for (i
= 0; i
< PIPE_MAX_SAMPLERS
; i
++) {
404 struct pipe_sampler_view
*view
= i
< num
? views
[i
] : NULL
;
407 struct pipe_resource
*tex
= view
->texture
;
408 struct i915_texture
*i915_tex
= i915_texture(tex
);
411 /* We're referencing the texture's internal data, so save a
414 pipe_resource_reference(&i915
->mapped_vs_tex
[i
], tex
);
416 i915
->mapped_vs_tex_buffer
[i
] = i915_tex
->buffer
;
417 addr
= iws
->buffer_map(iws
,
419 FALSE
/* read only */);
421 /* Setup array of mipmap level pointers */
422 /* FIXME: handle 3D textures? */
423 for (j
= view
->u
.tex
.first_level
; j
<= tex
->last_level
; j
++) {
424 mip_offsets
[j
] = i915_texture_offset(i915_tex
, j
, 0 /* FIXME depth */);
425 row_stride
[j
] = i915_tex
->stride
;
426 img_stride
[j
] = 0; /* FIXME */;
429 draw_set_mapped_texture(i915
->draw
,
432 tex
->width0
, tex
->height0
, tex
->depth0
,
433 view
->u
.tex
.first_level
, tex
->last_level
,
435 row_stride
, img_stride
, mip_offsets
);
437 i915
->mapped_vs_tex
[i
] = NULL
;
442 i915_cleanup_vertex_sampling(struct i915_context
*i915
)
444 struct i915_winsys
*iws
= i915
->iws
;
446 for (i
= 0; i
< Elements(i915
->mapped_vs_tex
); i
++) {
447 if (i915
->mapped_vs_tex_buffer
[i
]) {
448 iws
->buffer_unmap(iws
, i915
->mapped_vs_tex_buffer
[i
]);
449 pipe_resource_reference(&i915
->mapped_vs_tex
[i
], NULL
);
456 /** XXX move someday? Or consolidate all these simple state setters
461 i915_create_depth_stencil_state(struct pipe_context
*pipe
,
462 const struct pipe_depth_stencil_alpha_state
*depth_stencil
)
464 struct i915_depth_stencil_state
*cso
= CALLOC_STRUCT( i915_depth_stencil_state
);
467 int testmask
= depth_stencil
->stencil
[0].valuemask
& 0xff;
468 int writemask
= depth_stencil
->stencil
[0].writemask
& 0xff;
470 cso
->stencil_modes4
|= (_3DSTATE_MODES_4_CMD
|
471 ENABLE_STENCIL_TEST_MASK
|
472 STENCIL_TEST_MASK(testmask
) |
473 ENABLE_STENCIL_WRITE_MASK
|
474 STENCIL_WRITE_MASK(writemask
));
477 if (depth_stencil
->stencil
[0].enabled
) {
478 int test
= i915_translate_compare_func(depth_stencil
->stencil
[0].func
);
479 int fop
= i915_translate_stencil_op(depth_stencil
->stencil
[0].fail_op
);
480 int dfop
= i915_translate_stencil_op(depth_stencil
->stencil
[0].zfail_op
);
481 int dpop
= i915_translate_stencil_op(depth_stencil
->stencil
[0].zpass_op
);
483 cso
->stencil_LIS5
|= (S5_STENCIL_TEST_ENABLE
|
484 S5_STENCIL_WRITE_ENABLE
|
485 (test
<< S5_STENCIL_TEST_FUNC_SHIFT
) |
486 (fop
<< S5_STENCIL_FAIL_SHIFT
) |
487 (dfop
<< S5_STENCIL_PASS_Z_FAIL_SHIFT
) |
488 (dpop
<< S5_STENCIL_PASS_Z_PASS_SHIFT
));
491 if (depth_stencil
->stencil
[1].enabled
) {
492 int test
= i915_translate_compare_func(depth_stencil
->stencil
[1].func
);
493 int fop
= i915_translate_stencil_op(depth_stencil
->stencil
[1].fail_op
);
494 int dfop
= i915_translate_stencil_op(depth_stencil
->stencil
[1].zfail_op
);
495 int dpop
= i915_translate_stencil_op(depth_stencil
->stencil
[1].zpass_op
);
496 int tmask
= depth_stencil
->stencil
[1].valuemask
& 0xff;
497 int wmask
= depth_stencil
->stencil
[1].writemask
& 0xff;
499 cso
->bfo
[0] = (_3DSTATE_BACKFACE_STENCIL_OPS
|
500 BFO_ENABLE_STENCIL_FUNCS
|
501 BFO_ENABLE_STENCIL_TWO_SIDE
|
502 BFO_ENABLE_STENCIL_REF
|
503 BFO_STENCIL_TWO_SIDE
|
504 (test
<< BFO_STENCIL_TEST_SHIFT
) |
505 (fop
<< BFO_STENCIL_FAIL_SHIFT
) |
506 (dfop
<< BFO_STENCIL_PASS_Z_FAIL_SHIFT
) |
507 (dpop
<< BFO_STENCIL_PASS_Z_PASS_SHIFT
));
509 cso
->bfo
[1] = (_3DSTATE_BACKFACE_STENCIL_MASKS
|
510 BFM_ENABLE_STENCIL_TEST_MASK
|
511 BFM_ENABLE_STENCIL_WRITE_MASK
|
512 (tmask
<< BFM_STENCIL_TEST_MASK_SHIFT
) |
513 (wmask
<< BFM_STENCIL_WRITE_MASK_SHIFT
));
516 /* This actually disables two-side stencil: The bit set is a
517 * modify-enable bit to indicate we are changing the two-side
518 * setting. Then there is a symbolic zero to show that we are
519 * setting the flag to zero/off.
521 cso
->bfo
[0] = (_3DSTATE_BACKFACE_STENCIL_OPS
|
522 BFO_ENABLE_STENCIL_TWO_SIDE
|
527 if (depth_stencil
->depth
.enabled
) {
528 int func
= i915_translate_compare_func(depth_stencil
->depth
.func
);
530 cso
->depth_LIS6
|= (S6_DEPTH_TEST_ENABLE
|
531 (func
<< S6_DEPTH_TEST_FUNC_SHIFT
));
533 if (depth_stencil
->depth
.writemask
)
534 cso
->depth_LIS6
|= S6_DEPTH_WRITE_ENABLE
;
537 if (depth_stencil
->alpha
.enabled
) {
538 int test
= i915_translate_compare_func(depth_stencil
->alpha
.func
);
539 ubyte refByte
= float_to_ubyte(depth_stencil
->alpha
.ref_value
);
541 cso
->depth_LIS6
|= (S6_ALPHA_TEST_ENABLE
|
542 (test
<< S6_ALPHA_TEST_FUNC_SHIFT
) |
543 (((unsigned) refByte
) << S6_ALPHA_REF_SHIFT
));
549 static void i915_bind_depth_stencil_state(struct pipe_context
*pipe
,
552 struct i915_context
*i915
= i915_context(pipe
);
554 if (i915
->depth_stencil
== depth_stencil
)
557 i915
->depth_stencil
= (const struct i915_depth_stencil_state
*)depth_stencil
;
559 i915
->dirty
|= I915_NEW_DEPTH_STENCIL
;
562 static void i915_delete_depth_stencil_state(struct pipe_context
*pipe
,
569 static void i915_set_scissor_states( struct pipe_context
*pipe
,
571 unsigned num_scissors
,
572 const struct pipe_scissor_state
*scissor
)
574 struct i915_context
*i915
= i915_context(pipe
);
576 memcpy( &i915
->scissor
, scissor
, sizeof(*scissor
) );
577 i915
->dirty
|= I915_NEW_SCISSOR
;
581 static void i915_set_polygon_stipple( struct pipe_context
*pipe
,
582 const struct pipe_poly_stipple
*stipple
)
589 i915_create_fs_state(struct pipe_context
*pipe
,
590 const struct pipe_shader_state
*templ
)
592 struct i915_context
*i915
= i915_context(pipe
);
593 struct i915_fragment_shader
*ifs
= CALLOC_STRUCT(i915_fragment_shader
);
597 ifs
->draw_data
= draw_create_fragment_shader(i915
->draw
, templ
);
598 ifs
->state
.tokens
= tgsi_dup_tokens(templ
->tokens
);
600 tgsi_scan_shader(templ
->tokens
, &ifs
->info
);
602 /* The shader's compiled to i915 instructions here */
603 i915_translate_fragment_program(i915
, ifs
);
609 i915_bind_fs_state(struct pipe_context
*pipe
, void *shader
)
611 struct i915_context
*i915
= i915_context(pipe
);
613 if (i915
->fs
== shader
)
616 i915
->fs
= (struct i915_fragment_shader
*) shader
;
618 draw_bind_fragment_shader(i915
->draw
, (i915
->fs
? i915
->fs
->draw_data
: NULL
));
620 i915
->dirty
|= I915_NEW_FS
;
624 void i915_delete_fs_state(struct pipe_context
*pipe
, void *shader
)
626 struct i915_fragment_shader
*ifs
= (struct i915_fragment_shader
*) shader
;
634 FREE((struct tgsi_token
*)ifs
->state
.tokens
);
635 ifs
->state
.tokens
= NULL
;
638 ifs
->program_len
= 0;
646 i915_create_vs_state(struct pipe_context
*pipe
,
647 const struct pipe_shader_state
*templ
)
649 struct i915_context
*i915
= i915_context(pipe
);
651 /* just pass-through to draw module */
652 return draw_create_vertex_shader(i915
->draw
, templ
);
655 static void i915_bind_vs_state(struct pipe_context
*pipe
, void *shader
)
657 struct i915_context
*i915
= i915_context(pipe
);
659 if (i915
->vs
== shader
)
664 /* just pass-through to draw module */
665 draw_bind_vertex_shader(i915
->draw
, (struct draw_vertex_shader
*) shader
);
667 i915
->dirty
|= I915_NEW_VS
;
670 static void i915_delete_vs_state(struct pipe_context
*pipe
, void *shader
)
672 struct i915_context
*i915
= i915_context(pipe
);
674 /* just pass-through to draw module */
675 draw_delete_vertex_shader(i915
->draw
, (struct draw_vertex_shader
*) shader
);
678 static void i915_set_constant_buffer(struct pipe_context
*pipe
,
679 uint shader
, uint index
,
680 struct pipe_constant_buffer
*cb
)
682 struct i915_context
*i915
= i915_context(pipe
);
683 struct pipe_resource
*buf
= cb
? cb
->buffer
: NULL
;
684 unsigned new_num
= 0;
687 /* XXX don't support geom shaders now */
688 if (shader
== PIPE_SHADER_GEOMETRY
)
691 if (cb
&& cb
->user_buffer
) {
692 buf
= i915_user_buffer_create(pipe
->screen
, (void *) cb
->user_buffer
,
694 PIPE_BIND_CONSTANT_BUFFER
);
697 /* if we have a new buffer compare it with the old one */
699 struct i915_buffer
*ibuf
= i915_buffer(buf
);
700 struct pipe_resource
*old_buf
= i915
->constants
[shader
];
701 struct i915_buffer
*old
= old_buf
? i915_buffer(old_buf
) : NULL
;
702 unsigned old_num
= i915
->current
.num_user_constants
[shader
];
704 new_num
= ibuf
->b
.b
.width0
/ 4 * sizeof(float);
706 if (old_num
== new_num
) {
710 /* XXX no point in running this code since st/mesa only uses user buffers */
711 /* Can't compare the buffer data since they are userbuffers */
712 else if (old
&& old
->free_on_destroy
)
713 diff
= memcmp(old
->data
, ibuf
->data
, ibuf
->b
.b
.width0
);
719 diff
= i915
->current
.num_user_constants
[shader
] != 0;
722 pipe_resource_reference(&i915
->constants
[shader
], buf
);
723 i915
->current
.num_user_constants
[shader
] = new_num
;
726 i915
->dirty
|= shader
== PIPE_SHADER_VERTEX
? I915_NEW_VS_CONSTANTS
: I915_NEW_FS_CONSTANTS
;
728 if (cb
&& cb
->user_buffer
) {
729 pipe_resource_reference(&buf
, NULL
);
734 static void i915_set_fragment_sampler_views(struct pipe_context
*pipe
,
736 struct pipe_sampler_view
**views
)
738 struct i915_context
*i915
= i915_context(pipe
);
741 assert(num
<= PIPE_MAX_SAMPLERS
);
743 /* Check for no-op */
744 if (num
== i915
->num_fragment_sampler_views
&&
745 !memcmp(i915
->fragment_sampler_views
, views
, num
* sizeof(struct pipe_sampler_view
*)))
748 for (i
= 0; i
< num
; i
++) {
749 /* Note: we're using pipe_sampler_view_release() here to work around
750 * a possible crash when the old view belongs to another context that
751 * was already destroyed.
753 pipe_sampler_view_release(pipe
, &i915
->fragment_sampler_views
[i
]);
754 pipe_sampler_view_reference(&i915
->fragment_sampler_views
[i
],
758 for (i
= num
; i
< i915
->num_fragment_sampler_views
; i
++)
759 pipe_sampler_view_release(pipe
, &i915
->fragment_sampler_views
[i
]);
761 i915
->num_fragment_sampler_views
= num
;
763 i915
->dirty
|= I915_NEW_SAMPLER_VIEW
;
767 i915_set_vertex_sampler_views(struct pipe_context
*pipe
,
769 struct pipe_sampler_view
**views
)
771 struct i915_context
*i915
= i915_context(pipe
);
774 assert(num
<= Elements(i915
->vertex_sampler_views
));
776 /* Check for no-op */
777 if (num
== i915
->num_vertex_sampler_views
&&
778 !memcmp(i915
->vertex_sampler_views
, views
, num
* sizeof(struct pipe_sampler_view
*))) {
782 for (i
= 0; i
< Elements(i915
->vertex_sampler_views
); i
++) {
783 struct pipe_sampler_view
*view
= i
< num
? views
[i
] : NULL
;
785 pipe_sampler_view_reference(&i915
->vertex_sampler_views
[i
], view
);
788 i915
->num_vertex_sampler_views
= num
;
790 draw_set_sampler_views(i915
->draw
,
792 i915
->vertex_sampler_views
,
793 i915
->num_vertex_sampler_views
);
798 i915_set_sampler_views(struct pipe_context
*pipe
, unsigned shader
,
799 unsigned start
, unsigned num
,
800 struct pipe_sampler_view
**views
)
804 case PIPE_SHADER_FRAGMENT
:
805 i915_set_fragment_sampler_views(pipe
, num
, views
);
807 case PIPE_SHADER_VERTEX
:
808 i915_set_vertex_sampler_views(pipe
, num
, views
);
816 struct pipe_sampler_view
*
817 i915_create_sampler_view_custom(struct pipe_context
*pipe
,
818 struct pipe_resource
*texture
,
819 const struct pipe_sampler_view
*templ
,
823 struct pipe_sampler_view
*view
= CALLOC_STRUCT(pipe_sampler_view
);
827 view
->reference
.count
= 1;
828 view
->texture
= NULL
;
829 pipe_resource_reference(&view
->texture
, texture
);
830 view
->context
= pipe
;
836 static struct pipe_sampler_view
*
837 i915_create_sampler_view(struct pipe_context
*pipe
,
838 struct pipe_resource
*texture
,
839 const struct pipe_sampler_view
*templ
)
841 struct pipe_sampler_view
*view
= CALLOC_STRUCT(pipe_sampler_view
);
845 view
->reference
.count
= 1;
846 view
->texture
= NULL
;
847 pipe_resource_reference(&view
->texture
, texture
);
848 view
->context
= pipe
;
856 i915_sampler_view_destroy(struct pipe_context
*pipe
,
857 struct pipe_sampler_view
*view
)
859 pipe_resource_reference(&view
->texture
, NULL
);
864 static void i915_set_framebuffer_state(struct pipe_context
*pipe
,
865 const struct pipe_framebuffer_state
*fb
)
867 struct i915_context
*i915
= i915_context(pipe
);
870 i915
->framebuffer
.width
= fb
->width
;
871 i915
->framebuffer
.height
= fb
->height
;
872 i915
->framebuffer
.nr_cbufs
= fb
->nr_cbufs
;
873 for (i
= 0; i
< PIPE_MAX_COLOR_BUFS
; i
++) {
874 pipe_surface_reference(&i915
->framebuffer
.cbufs
[i
],
875 i
< fb
->nr_cbufs
? fb
->cbufs
[i
] : NULL
);
877 pipe_surface_reference(&i915
->framebuffer
.zsbuf
, fb
->zsbuf
);
879 i915
->dirty
|= I915_NEW_FRAMEBUFFER
;
884 static void i915_set_clip_state( struct pipe_context
*pipe
,
885 const struct pipe_clip_state
*clip
)
887 struct i915_context
*i915
= i915_context(pipe
);
891 draw_set_clip_state(i915
->draw
, clip
);
893 i915
->dirty
|= I915_NEW_CLIP
;
898 /* Called when driver state tracker notices changes to the viewport
901 static void i915_set_viewport_states( struct pipe_context
*pipe
,
903 unsigned num_viewports
,
904 const struct pipe_viewport_state
*viewport
)
906 struct i915_context
*i915
= i915_context(pipe
);
908 i915
->viewport
= *viewport
; /* struct copy */
910 /* pass the viewport info to the draw module */
911 draw_set_viewport_states(i915
->draw
, start_slot
, num_viewports
,
914 i915
->dirty
|= I915_NEW_VIEWPORT
;
919 i915_create_rasterizer_state(struct pipe_context
*pipe
,
920 const struct pipe_rasterizer_state
*rasterizer
)
922 struct i915_rasterizer_state
*cso
= CALLOC_STRUCT( i915_rasterizer_state
);
924 cso
->templ
= *rasterizer
;
925 cso
->color_interp
= rasterizer
->flatshade
? INTERP_CONSTANT
: INTERP_LINEAR
;
926 cso
->light_twoside
= rasterizer
->light_twoside
;
927 cso
->ds
[0].u
= _3DSTATE_DEPTH_OFFSET_SCALE
;
928 cso
->ds
[1].f
= rasterizer
->offset_scale
;
929 if (rasterizer
->poly_stipple_enable
) {
930 cso
->st
|= ST1_ENABLE
;
933 if (rasterizer
->scissor
)
934 cso
->sc
[0] = _3DSTATE_SCISSOR_ENABLE_CMD
| ENABLE_SCISSOR_RECT
;
936 cso
->sc
[0] = _3DSTATE_SCISSOR_ENABLE_CMD
| DISABLE_SCISSOR_RECT
;
938 switch (rasterizer
->cull_face
) {
940 cso
->LIS4
|= S4_CULLMODE_NONE
;
942 case PIPE_FACE_FRONT
:
943 if (rasterizer
->front_ccw
)
944 cso
->LIS4
|= S4_CULLMODE_CCW
;
946 cso
->LIS4
|= S4_CULLMODE_CW
;
949 if (rasterizer
->front_ccw
)
950 cso
->LIS4
|= S4_CULLMODE_CW
;
952 cso
->LIS4
|= S4_CULLMODE_CCW
;
954 case PIPE_FACE_FRONT_AND_BACK
:
955 cso
->LIS4
|= S4_CULLMODE_BOTH
;
960 int line_width
= CLAMP((int)(rasterizer
->line_width
* 2), 1, 0xf);
962 cso
->LIS4
|= line_width
<< S4_LINE_WIDTH_SHIFT
;
964 if (rasterizer
->line_smooth
)
965 cso
->LIS4
|= S4_LINE_ANTIALIAS_ENABLE
;
969 int point_size
= CLAMP((int) rasterizer
->point_size
, 1, 0xff);
971 cso
->LIS4
|= point_size
<< S4_POINT_WIDTH_SHIFT
;
974 if (rasterizer
->flatshade
) {
975 cso
->LIS4
|= (S4_FLATSHADE_ALPHA
|
977 S4_FLATSHADE_SPECULAR
);
980 cso
->LIS7
= fui( rasterizer
->offset_units
);
986 static void i915_bind_rasterizer_state( struct pipe_context
*pipe
,
989 struct i915_context
*i915
= i915_context(pipe
);
991 if (i915
->rasterizer
== raster
)
994 i915
->rasterizer
= (struct i915_rasterizer_state
*)raster
;
996 /* pass-through to draw module */
997 draw_set_rasterizer_state(i915
->draw
,
998 (i915
->rasterizer
? &(i915
->rasterizer
->templ
) : NULL
),
1001 i915
->dirty
|= I915_NEW_RASTERIZER
;
1004 static void i915_delete_rasterizer_state(struct pipe_context
*pipe
,
1010 static void i915_set_vertex_buffers(struct pipe_context
*pipe
,
1011 unsigned start_slot
, unsigned count
,
1012 const struct pipe_vertex_buffer
*buffers
)
1014 struct i915_context
*i915
= i915_context(pipe
);
1015 struct draw_context
*draw
= i915
->draw
;
1017 util_set_vertex_buffers_count(i915
->vertex_buffers
,
1018 &i915
->nr_vertex_buffers
,
1019 buffers
, start_slot
, count
);
1021 /* pass-through to draw module */
1022 draw_set_vertex_buffers(draw
, start_slot
, count
, buffers
);
1026 i915_create_vertex_elements_state(struct pipe_context
*pipe
,
1028 const struct pipe_vertex_element
*attribs
)
1030 struct i915_velems_state
*velems
;
1031 assert(count
<= PIPE_MAX_ATTRIBS
);
1032 velems
= (struct i915_velems_state
*) MALLOC(sizeof(struct i915_velems_state
));
1034 velems
->count
= count
;
1035 memcpy(velems
->velem
, attribs
, sizeof(*attribs
) * count
);
1041 i915_bind_vertex_elements_state(struct pipe_context
*pipe
,
1044 struct i915_context
*i915
= i915_context(pipe
);
1045 struct i915_velems_state
*i915_velems
= (struct i915_velems_state
*) velems
;
1047 if (i915
->velems
== velems
)
1050 i915
->velems
= velems
;
1052 /* pass-through to draw module */
1054 draw_set_vertex_elements(i915
->draw
,
1055 i915_velems
->count
, i915_velems
->velem
);
1060 i915_delete_vertex_elements_state(struct pipe_context
*pipe
, void *velems
)
1065 static void i915_set_index_buffer(struct pipe_context
*pipe
,
1066 const struct pipe_index_buffer
*ib
)
1068 struct i915_context
*i915
= i915_context(pipe
);
1071 memcpy(&i915
->index_buffer
, ib
, sizeof(i915
->index_buffer
));
1073 memset(&i915
->index_buffer
, 0, sizeof(i915
->index_buffer
));
1077 i915_set_sample_mask(struct pipe_context
*pipe
,
1078 unsigned sample_mask
)
1083 i915_init_state_functions( struct i915_context
*i915
)
1085 i915
->base
.create_blend_state
= i915_create_blend_state
;
1086 i915
->base
.bind_blend_state
= i915_bind_blend_state
;
1087 i915
->base
.delete_blend_state
= i915_delete_blend_state
;
1089 i915
->base
.create_sampler_state
= i915_create_sampler_state
;
1090 i915
->base
.bind_sampler_states
= i915_bind_sampler_states
;
1091 i915
->base
.delete_sampler_state
= i915_delete_sampler_state
;
1093 i915
->base
.create_depth_stencil_alpha_state
= i915_create_depth_stencil_state
;
1094 i915
->base
.bind_depth_stencil_alpha_state
= i915_bind_depth_stencil_state
;
1095 i915
->base
.delete_depth_stencil_alpha_state
= i915_delete_depth_stencil_state
;
1097 i915
->base
.create_rasterizer_state
= i915_create_rasterizer_state
;
1098 i915
->base
.bind_rasterizer_state
= i915_bind_rasterizer_state
;
1099 i915
->base
.delete_rasterizer_state
= i915_delete_rasterizer_state
;
1100 i915
->base
.create_fs_state
= i915_create_fs_state
;
1101 i915
->base
.bind_fs_state
= i915_bind_fs_state
;
1102 i915
->base
.delete_fs_state
= i915_delete_fs_state
;
1103 i915
->base
.create_vs_state
= i915_create_vs_state
;
1104 i915
->base
.bind_vs_state
= i915_bind_vs_state
;
1105 i915
->base
.delete_vs_state
= i915_delete_vs_state
;
1106 i915
->base
.create_vertex_elements_state
= i915_create_vertex_elements_state
;
1107 i915
->base
.bind_vertex_elements_state
= i915_bind_vertex_elements_state
;
1108 i915
->base
.delete_vertex_elements_state
= i915_delete_vertex_elements_state
;
1110 i915
->base
.set_blend_color
= i915_set_blend_color
;
1111 i915
->base
.set_stencil_ref
= i915_set_stencil_ref
;
1112 i915
->base
.set_clip_state
= i915_set_clip_state
;
1113 i915
->base
.set_sample_mask
= i915_set_sample_mask
;
1114 i915
->base
.set_constant_buffer
= i915_set_constant_buffer
;
1115 i915
->base
.set_framebuffer_state
= i915_set_framebuffer_state
;
1117 i915
->base
.set_polygon_stipple
= i915_set_polygon_stipple
;
1118 i915
->base
.set_scissor_states
= i915_set_scissor_states
;
1119 i915
->base
.set_sampler_views
= i915_set_sampler_views
;
1120 i915
->base
.create_sampler_view
= i915_create_sampler_view
;
1121 i915
->base
.sampler_view_destroy
= i915_sampler_view_destroy
;
1122 i915
->base
.set_viewport_states
= i915_set_viewport_states
;
1123 i915
->base
.set_vertex_buffers
= i915_set_vertex_buffers
;
1124 i915
->base
.set_index_buffer
= i915_set_index_buffer
;