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_state.h"
43 //#include "i915_cache.h"
50 /* The i915 (and related graphics cores) do not support GL_CLAMP. The
51 * Intel drivers for "other operating systems" implement GL_CLAMP as
52 * GL_CLAMP_TO_EDGE, so the same is done here.
55 translate_wrap_mode(unsigned wrap
)
58 case PIPE_TEX_WRAP_REPEAT
:
59 return TEXCOORDMODE_WRAP
;
60 case PIPE_TEX_WRAP_CLAMP
:
61 return TEXCOORDMODE_CLAMP_EDGE
; /* not quite correct */
62 case PIPE_TEX_WRAP_CLAMP_TO_EDGE
:
63 return TEXCOORDMODE_CLAMP_EDGE
;
64 case PIPE_TEX_WRAP_CLAMP_TO_BORDER
:
65 return TEXCOORDMODE_CLAMP_BORDER
;
66 // case PIPE_TEX_WRAP_MIRRORED_REPEAT:
67 // return TEXCOORDMODE_MIRROR;
69 return TEXCOORDMODE_WRAP
;
73 static unsigned translate_img_filter( unsigned filter
)
76 case PIPE_TEX_FILTER_NEAREST
:
77 return FILTER_NEAREST
;
78 case PIPE_TEX_FILTER_LINEAR
:
82 return FILTER_NEAREST
;
86 static unsigned translate_mip_filter( unsigned filter
)
89 case PIPE_TEX_MIPFILTER_NONE
:
90 return MIPFILTER_NONE
;
91 case PIPE_TEX_MIPFILTER_NEAREST
:
92 return MIPFILTER_NEAREST
;
93 case PIPE_TEX_FILTER_LINEAR
:
94 return MIPFILTER_LINEAR
;
97 return MIPFILTER_NONE
;
101 static unsigned translate_compare_func(unsigned func
)
104 case PIPE_FUNC_NEVER
:
106 case PIPE_FUNC_EQUAL
:
107 case PIPE_FUNC_LEQUAL
:
108 case PIPE_FUNC_GREATER
:
109 case PIPE_FUNC_NOTEQUAL
:
110 case PIPE_FUNC_GEQUAL
:
111 case PIPE_FUNC_ALWAYS
:
134 is_power_of_two_texture(const struct pipe_mipmap_tree
*mt
)
136 if (bitcount(mt
->width0
) == 1 &&
137 bitcount(mt
->height0
) == 1 &&
138 bitcount(mt
->depth0
) == 1) {
147 * Compute i915 texture sampling state.
149 * Recalculate all state from scratch. Perhaps not the most
150 * efficient, but this has gotten complex enough that we need
151 * something which is understandable and reliable.
152 * \param state returns the 3 words of compute state
154 static void update_sampler(struct i915_context
*i915
,
156 const struct pipe_sampler_state
*sampler
,
157 const struct pipe_mipmap_tree
*mt
,
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 (mt
->format
== PIPE_FORMAT_YCBCR
||
190 mt
->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
)
263 i915
->current
.sampler_enable_nr
= 0;
264 i915
->current
.sampler_enable_flags
= 0x0;
266 for (unit
= 0; unit
< I915_TEX_UNITS
; unit
++) {
267 /* determine unit enable/disable by looking for a bound mipmap tree */
268 /* could also examine the fragment program? */
269 if (i915
->texture
[unit
]) {
270 update_sampler( i915
,
272 i915
->sampler
+ unit
, /* sampler state */
273 i915
->texture
[unit
], /* mipmap tree */
274 i915
->current
.sampler
[unit
] /* the result */
277 i915
->current
.sampler_enable_nr
++;
278 i915
->current
.sampler_enable_flags
|= (1 << unit
);
282 i915
->hardware_dirty
|= I915_HW_SAMPLER
;
289 translate_texture_format(uint pipeFormat
)
291 switch (pipeFormat
) {
292 case PIPE_FORMAT_U_L8
:
293 return MAPSURF_8BIT
| MT_8BIT_L8
;
294 case PIPE_FORMAT_U_I8
:
295 return MAPSURF_8BIT
| MT_8BIT_I8
;
296 case PIPE_FORMAT_U_A8
:
297 return MAPSURF_8BIT
| MT_8BIT_A8
;
298 case PIPE_FORMAT_U_A8_L8
:
299 return MAPSURF_16BIT
| MT_16BIT_AY88
;
300 case PIPE_FORMAT_U_R5_G6_B5
:
301 return MAPSURF_16BIT
| MT_16BIT_RGB565
;
302 case PIPE_FORMAT_U_A1_R5_G5_B5
:
303 return MAPSURF_16BIT
| MT_16BIT_ARGB1555
;
304 case PIPE_FORMAT_U_A4_R4_G4_B4
:
305 return MAPSURF_16BIT
| MT_16BIT_ARGB4444
;
306 case PIPE_FORMAT_U_A8_R8_G8_B8
:
307 return MAPSURF_32BIT
| MT_32BIT_ARGB8888
;
308 case PIPE_FORMAT_YCBCR_REV
:
309 return (MAPSURF_422
| MT_422_YCRCB_NORMAL
);
310 case PIPE_FORMAT_YCBCR
:
311 return (MAPSURF_422
| MT_422_YCRCB_SWAPY
);
313 case PIPE_FORMAT_RGB_FXT1
:
314 case PIPE_FORMAT_RGBA_FXT1
:
315 return (MAPSURF_COMPRESSED
| MT_COMPRESS_FXT1
);
317 case PIPE_FORMAT_U_Z16
:
318 return (MAPSURF_16BIT
| MT_16BIT_L16
);
320 case PIPE_FORMAT_RGBA_DXT1
:
321 case PIPE_FORMAT_RGB_DXT1
:
322 return (MAPSURF_COMPRESSED
| MT_COMPRESS_DXT1
);
323 case PIPE_FORMAT_RGBA_DXT3
:
324 return (MAPSURF_COMPRESSED
| MT_COMPRESS_DXT2_3
);
325 case PIPE_FORMAT_RGBA_DXT5
:
326 return (MAPSURF_COMPRESSED
| MT_COMPRESS_DXT4_5
);
328 case PIPE_FORMAT_S8_Z24
:
329 return (MAPSURF_32BIT
| MT_32BIT_xL824
);
331 fprintf(stderr
, "i915: translate_texture_format() bad image format %x\n",
339 #define I915_TEXREG_MS3 1
340 #define I915_TEXREG_MS4 2
344 i915_update_texture(struct i915_context
*i915
, uint unit
,
347 const struct pipe_mipmap_tree
*mt
= i915
->texture
[unit
];
349 const uint width
= mt
->width0
, height
= mt
->height0
, depth
= mt
->depth0
;
350 const uint num_levels
= mt
->last_level
- mt
->first_level
;
358 if (i915
->state
.tex_buffer
[unit
] != NULL
) {
359 driBOUnReference(i915
->state
.tex_buffer
[unit
]);
360 i915
->state
.tex_buffer
[unit
] = NULL
;
366 struct pipe_buffer_handle
*p
= driBOReference(mt
->region
->buffer
);
370 i915
->state
.tex_buffer
[unit
] = driBOReference(intelObj
->mt
->region
->
372 i915
->state
.tex_offset
[unit
] = intel_miptree_image_offset(intelObj
->mt
,
377 format
= translate_texture_format(mt
->format
);
378 pitch
= mt
->pitch
* mt
->cpp
;
383 printf("texture format = 0x%x\n", format
);
387 (((height
- 1) << MS3_HEIGHT_SHIFT
)
388 | ((width
- 1) << MS3_WIDTH_SHIFT
)
390 | MS3_USE_FENCE_REGS
);
394 ((((pitch
/ 4) - 1) << MS4_PITCH_SHIFT
)
395 | MS4_CUBE_FACE_ENA_MASK
396 | ((num_levels
* 4) << MS4_MAX_LOD_SHIFT
)
397 | ((depth
- 1) << MS4_VOLUME_DEPTH_SHIFT
));
403 i915_update_textures(struct i915_context
*i915
)
407 for (unit
= 0; unit
< I915_TEX_UNITS
; unit
++) {
408 /* determine unit enable/disable by looking for a bound mipmap tree */
409 /* could also examine the fragment program? */
410 if (i915
->texture
[unit
]) {
411 i915_update_texture(i915
, unit
, i915
->current
.texbuffer
[unit
]);
415 i915
->hardware_dirty
|= I915_HW_MAP
;