1 /**************************************************************************
3 * Copyright 2003 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 **************************************************************************/
30 //#include "texformat.h"
32 //#include "dri_bufmgr.h"
35 #include "pipe/p_context.h"
36 #include "pipe/p_state.h"
37 #include "pipe/p_util.h"
39 #include "i915_state_inlines.h"
40 #include "i915_context.h"
42 //#include "i915_cache.h"
49 /* The i915 (and related graphics cores) do not support GL_CLAMP. The
50 * Intel drivers for "other operating systems" implement GL_CLAMP as
51 * GL_CLAMP_TO_EDGE, so the same is done here.
54 translate_wrap_mode(unsigned wrap
)
57 case PIPE_TEX_WRAP_REPEAT
:
58 return TEXCOORDMODE_WRAP
;
59 case PIPE_TEX_WRAP_CLAMP
:
60 return TEXCOORDMODE_CLAMP_EDGE
; /* not quite correct */
61 case PIPE_TEX_WRAP_CLAMP_TO_EDGE
:
62 return TEXCOORDMODE_CLAMP_EDGE
;
63 case PIPE_TEX_WRAP_CLAMP_TO_BORDER
:
64 return TEXCOORDMODE_CLAMP_BORDER
;
65 // case PIPE_TEX_WRAP_MIRRORED_REPEAT:
66 // return TEXCOORDMODE_MIRROR;
68 return TEXCOORDMODE_WRAP
;
72 static unsigned translate_img_filter( unsigned filter
)
75 case PIPE_TEX_FILTER_NEAREST
:
76 return FILTER_NEAREST
;
77 case PIPE_TEX_FILTER_LINEAR
:
81 return FILTER_NEAREST
;
85 static unsigned translate_mip_filter( unsigned filter
)
88 case PIPE_TEX_MIPFILTER_NONE
:
89 return MIPFILTER_NONE
;
90 case PIPE_TEX_MIPFILTER_NEAREST
:
91 return MIPFILTER_NEAREST
;
92 case PIPE_TEX_FILTER_LINEAR
:
93 return MIPFILTER_LINEAR
;
96 return MIPFILTER_NONE
;
100 static unsigned translate_compare_func(unsigned func
)
103 case PIPE_FUNC_NEVER
:
105 case PIPE_FUNC_EQUAL
:
106 case PIPE_FUNC_LEQUAL
:
107 case PIPE_FUNC_GREATER
:
108 case PIPE_FUNC_NOTEQUAL
:
109 case PIPE_FUNC_GEQUAL
:
110 case PIPE_FUNC_ALWAYS
:
133 is_power_of_two_texture(const struct pipe_mipmap_tree
*mt
)
135 if (bitcount(mt
->width0
) == 1 &&
136 bitcount(mt
->height0
) == 1 &&
137 bitcount(mt
->depth0
) == 1) {
146 * Compute i915 texture sampling state.
148 * Recalculate all state from scratch. Perhaps not the most
149 * efficient, but this has gotten complex enough that we need
150 * something which is understandable and reliable.
151 * \param state returns the 3 words of compute state
153 static void update_sampler(struct i915_context
*i915
,
155 const struct pipe_sampler_state
*sampler
,
156 const struct pipe_mipmap_tree
*mt
,
157 const struct pipe_surface
*surface
,
160 const unsigned ws
= sampler
->wrap_s
;
161 const unsigned wt
= sampler
->wrap_t
;
162 const unsigned wr
= sampler
->wrap_r
;
164 /* Need to do this after updating the maps, which call the
165 * intel_finalize_mipmap_tree and hence can update firstLevel:
167 unsigned minFilt
, magFilt
;
170 state
[0] = state
[1] = state
[2] = 0;
172 mipFilt
= translate_mip_filter( sampler
->min_mip_filter
);
174 if (sampler
->max_anisotropy
> 1.0) {
175 minFilt
= FILTER_ANISOTROPIC
;
176 magFilt
= FILTER_ANISOTROPIC
;
179 minFilt
= translate_img_filter( sampler
->min_img_filter
);
180 magFilt
= translate_img_filter( sampler
->mag_img_filter
);
184 int b
= sampler
->lod_bias
* 16.0;
185 b
= CLAMP(b
, -256, 255);
186 state
[0] |= ((b
<< SS2_LOD_BIAS_SHIFT
) & SS2_LOD_BIAS_MASK
);
189 if (surface
->format
== PIPE_FORMAT_YCBCR
||
190 surface
->format
== PIPE_FORMAT_YCBCR_REV
)
191 state
[0] |= SS2_COLORSPACE_CONVERSION
;
196 if (sampler
->compare_mode
== PIPE_TEX_COMPARE_R_TO_TEXTURE
)
198 state
[0] |= (SS2_SHADOW_ENABLE
|
199 translate_compare_func(sampler
->compare_func
));
201 minFilt
= FILTER_4X4_FLAT
;
202 magFilt
= FILTER_4X4_FLAT
;
205 state
[0] |= ((minFilt
<< SS2_MIN_FILTER_SHIFT
) |
206 (mipFilt
<< SS2_MIP_FILTER_SHIFT
) |
207 (magFilt
<< SS2_MAG_FILTER_SHIFT
));
210 /* 3D textures don't seem to respect the border color.
211 * Fallback if there's ever a danger that they might refer to
214 * Effectively this means fallback on 3D clamp or
217 * XXX: Check if this is true on i945.
218 * XXX: Check if this bug got fixed in release silicon.
220 if (mt
->target
== PIPE_TEXTURE_3D
&&
221 (sampler
->min_img_filter
!= PIPE_TEX_FILTER_NEAREST
||
222 sampler
->mag_img_filter
!= PIPE_TEX_FILTER_NEAREST
) &&
223 (ws
== PIPE_TEX_WRAP_CLAMP
||
224 wt
== PIPE_TEX_WRAP_CLAMP
||
225 wr
== PIPE_TEX_WRAP_CLAMP
||
226 ws
== PIPE_TEX_WRAP_CLAMP_TO_BORDER
||
227 wt
== PIPE_TEX_WRAP_CLAMP_TO_BORDER
||
228 wr
== PIPE_TEX_WRAP_CLAMP_TO_BORDER
)) {
230 if (i915
->strict_conformance
) {
232 /* sampler->fallback = true; */
239 ((translate_wrap_mode(ws
) << SS3_TCX_ADDR_MODE_SHIFT
) |
240 (translate_wrap_mode(wt
) << SS3_TCY_ADDR_MODE_SHIFT
) |
241 (translate_wrap_mode(wr
) << SS3_TCZ_ADDR_MODE_SHIFT
) |
242 (unit
<< SS3_TEXTUREMAP_INDEX_SHIFT
));
244 if (is_power_of_two_texture(mt
)) {
245 state
[1] |= SS3_NORMALIZED_COORDS
;
249 ubyte r
= float_to_ubyte(sampler
->border_color
[0]);
250 ubyte g
= float_to_ubyte(sampler
->border_color
[1]);
251 ubyte b
= float_to_ubyte(sampler
->border_color
[2]);
252 ubyte a
= float_to_ubyte(sampler
->border_color
[3]);
253 state
[2] = I915PACKCOLOR8888(r
, g
, b
, a
);
259 void i915_update_samplers( struct i915_context
*i915
)
261 const struct pipe_surface
*surface
= i915
->framebuffer
.cbufs
[0];
264 i915
->current
.sampler_enable_nr
= 0;
265 i915
->current
.sampler_enable_flags
= 0x0;
267 for (unit
= 0; unit
< I915_TEX_UNITS
; unit
++) {
268 /* determine unit enable/disable by looking for a bound mipmap tree */
269 /* could also examine the fragment program? */
270 if (i915
->texture
[unit
]) {
271 update_sampler( i915
,
273 i915
->sampler
+ unit
, /* sampler state */
274 i915
->texture
[unit
], /* mipmap tree */
275 surface
, /* cbuffer info */
276 i915
->current
.sampler
[unit
] /* the result */
279 i915
->current
.sampler_enable_nr
++;
280 i915
->current
.sampler_enable_flags
|= (1 << unit
);
284 i915
->hardware_dirty
|= I915_HW_SAMPLER
;