2 #include "main/glheader.h"
3 #include "main/mtypes.h"
4 #include "main/colormac.h"
5 #include "main/imports.h"
6 #include "main/simple_list.h"
7 #include "main/enums.h"
9 #include "main/texstore.h"
10 #include "main/teximage.h"
11 #include "main/texobj.h"
13 #include "swrast/swrast.h"
15 #include "gammacontext.h"
19 * Compute the 'S2.4' lod bias factor from the floating point OpenGL bias.
22 static GLuint
gammaComputeLodBias(GLfloat bias
)
28 static void gammaSetTexWrapping(gammaTextureObjectPtr t
,
29 GLenum wraps
, GLenum wrapt
)
31 uint32_t t1
= t
->TextureAddressMode
;
32 uint32_t t2
= t
->TextureReadMode
;
34 t1
&= ~(TAM_SWrap_Mask
| TAM_TWrap_Mask
);
35 t2
&= ~(TRM_UWrap_Mask
| TRM_VWrap_Mask
);
37 if (wraps
!= GL_CLAMP
) {
38 t1
|= TAM_SWrap_Repeat
;
39 t2
|= TRM_UWrap_Repeat
;
42 if (wrapt
!= GL_CLAMP
) {
43 t1
|= TAM_TWrap_Repeat
;
44 t2
|= TRM_VWrap_Repeat
;
47 t
->TextureAddressMode
= t1
;
48 t
->TextureReadMode
= t2
;
52 static void gammaSetTexFilter(gammaContextPtr gmesa
,
53 gammaTextureObjectPtr t
,
54 GLenum minf
, GLenum magf
,
57 uint32_t t1
= t
->TextureAddressMode
;
58 uint32_t t2
= t
->TextureReadMode
;
60 t2
&= ~(TRM_Mag_Mask
| TRM_Min_Mask
);
65 t2
&= ~TRM_MipMapEnable
;
66 t2
|= TRM_Min_Nearest
;
70 t2
&= ~TRM_MipMapEnable
;
73 case GL_NEAREST_MIPMAP_NEAREST
:
74 t2
|= TRM_Min_NearestMMNearest
;
76 case GL_LINEAR_MIPMAP_NEAREST
:
77 t2
|= TRM_Min_LinearMMNearest
;
79 case GL_NEAREST_MIPMAP_LINEAR
:
80 t2
|= TRM_Min_NearestMMLinear
;
82 case GL_LINEAR_MIPMAP_LINEAR
:
83 t2
|= TRM_Min_LinearMMLinear
;
91 t2
|= TRM_Mag_Nearest
;
100 t
->TextureAddressMode
= t1
;
101 t
->TextureReadMode
= t2
;
105 static void gammaSetTexBorderColor(gammaContextPtr gmesa
,
106 gammaTextureObjectPtr t
,
107 const GLfloat color
[4])
110 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
111 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
112 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
113 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
114 t
->TextureBorderColor
= PACK_COLOR_8888(c
[0], c
[1], c
[2], c
[3]);
118 static void gammaTexParameter( GLcontext
*ctx
, GLenum target
,
119 struct gl_texture_object
*tObj
,
120 GLenum pname
, const GLfloat
*params
)
122 gammaContextPtr gmesa
= GAMMA_CONTEXT(ctx
);
123 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
) tObj
->DriverData
;
127 /* Can't do the update now as we don't know whether to flush
128 * vertices or not. Setting gmesa->new_state means that
129 * gammaUpdateTextureState() will be called before any triangles are
130 * rendered. If a statechange has occurred, it will be detected at
131 * that point, and buffered vertices flushed.
134 case GL_TEXTURE_MIN_FILTER
:
135 case GL_TEXTURE_MAG_FILTER
:
137 GLfloat bias
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].LodBias
;
138 gammaSetTexFilter( gmesa
, t
, tObj
->MinFilter
, tObj
->MagFilter
, bias
);
142 case GL_TEXTURE_WRAP_S
:
143 case GL_TEXTURE_WRAP_T
:
144 gammaSetTexWrapping( t
, tObj
->WrapS
, tObj
->WrapT
);
147 case GL_TEXTURE_BORDER_COLOR
:
148 gammaSetTexBorderColor( gmesa
, t
, tObj
->BorderColor
);
151 case GL_TEXTURE_BASE_LEVEL
:
152 case GL_TEXTURE_MAX_LEVEL
:
153 case GL_TEXTURE_MIN_LOD
:
154 case GL_TEXTURE_MAX_LOD
:
155 /* This isn't the most efficient solution but there doesn't appear to
156 * be a nice alternative for Radeon. Since there's no LOD clamping,
157 * we just have to rely on loading the right subset of mipmap levels
158 * to simulate a clamped LOD.
160 gammaSwapOutTexObj( gmesa
, t
);
167 if (t
== gmesa
->CurrentTexObj
[0])
168 gmesa
->dirty
|= GAMMA_UPLOAD_TEX0
;
171 if (t
== gmesa
->CurrentTexObj
[1]) {
172 gmesa
->dirty
|= GAMMA_UPLOAD_TEX1
;
178 static void gammaTexEnv( GLcontext
*ctx
, GLenum target
,
179 GLenum pname
, const GLfloat
*param
)
181 gammaContextPtr gmesa
= GAMMA_CONTEXT( ctx
);
182 GLuint unit
= ctx
->Texture
.CurrentUnit
;
184 /* Only one env color. Need a fallback if env colors are different
185 * and texture setup references env color in both units.
188 case GL_TEXTURE_ENV_COLOR
: {
189 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
190 GLfloat
*fc
= texUnit
->EnvColor
;
191 GLuint r
, g
, b
, a
, col
;
192 CLAMPED_FLOAT_TO_UBYTE(r
, fc
[0]);
193 CLAMPED_FLOAT_TO_UBYTE(g
, fc
[1]);
194 CLAMPED_FLOAT_TO_UBYTE(b
, fc
[2]);
195 CLAMPED_FLOAT_TO_UBYTE(a
, fc
[3]);
204 case GL_TEXTURE_ENV_MODE
:
205 gmesa
->TexEnvImageFmt
[unit
] = 0; /* force recalc of env state */
208 case GL_TEXTURE_LOD_BIAS_EXT
:
211 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[unit
]._Current
;
212 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
) tObj
->DriverData
;
214 /* XXX Looks like there's something missing here */
225 static void gammaTexImage1D( GLcontext
*ctx
, GLenum target
, GLint level
,
226 GLint internalFormat
,
227 GLint width
, GLint border
,
228 GLenum format
, GLenum type
,
229 const GLvoid
*pixels
,
230 const struct gl_pixelstore_attrib
*pack
,
231 struct gl_texture_object
*texObj
,
232 struct gl_texture_image
*texImage
)
234 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
) texObj
->DriverData
;
236 gammaSwapOutTexObj( GAMMA_CONTEXT(ctx
), t
);
238 _mesa_store_teximage1d( ctx
, target
, level
, internalFormat
,
239 width
, border
, format
, type
,
240 pixels
, pack
, texObj
, texImage
);
245 static void gammaTexSubImage1D( GLcontext
*ctx
,
250 GLenum format
, GLenum type
,
251 const GLvoid
*pixels
,
252 const struct gl_pixelstore_attrib
*pack
,
253 struct gl_texture_object
*texObj
,
254 struct gl_texture_image
*texImage
)
256 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
) texObj
->DriverData
;
258 gammaSwapOutTexObj( GAMMA_CONTEXT(ctx
), t
);
260 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
261 format
, type
, pixels
, pack
, texObj
,
266 static void gammaTexImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
267 GLint internalFormat
,
268 GLint width
, GLint height
, GLint border
,
269 GLenum format
, GLenum type
, const GLvoid
*pixels
,
270 const struct gl_pixelstore_attrib
*packing
,
271 struct gl_texture_object
*texObj
,
272 struct gl_texture_image
*texImage
)
274 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
) texObj
->DriverData
;
276 gammaSwapOutTexObj( GAMMA_CONTEXT(ctx
), t
);
278 _mesa_store_teximage2d( ctx
, target
, level
, internalFormat
,
279 width
, height
, border
, format
, type
,
280 pixels
, packing
, texObj
, texImage
);
283 static void gammaTexSubImage2D( GLcontext
*ctx
,
286 GLint xoffset
, GLint yoffset
,
287 GLsizei width
, GLsizei height
,
288 GLenum format
, GLenum type
,
289 const GLvoid
*pixels
,
290 const struct gl_pixelstore_attrib
*packing
,
291 struct gl_texture_object
*texObj
,
292 struct gl_texture_image
*texImage
)
294 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
) texObj
->DriverData
;
296 gammaSwapOutTexObj( GAMMA_CONTEXT(ctx
), t
);
298 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
299 height
, format
, type
, pixels
, packing
, texObj
,
303 static void gammaBindTexture( GLcontext
*ctx
, GLenum target
,
304 struct gl_texture_object
*tObj
)
306 gammaContextPtr gmesa
= GAMMA_CONTEXT( ctx
);
307 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
) tObj
->DriverData
;
310 GLfloat bias
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].LodBias
;
311 t
= CALLOC_STRUCT(gamma_texture_object_t
);
313 /* Initialize non-image-dependent parts of the state:
317 t
->TextureAddressMode
= TextureAddressModeEnable
| TAM_Operation_3D
|
318 TAM_DY_Enable
| TAM_LODEnable
;
319 t
->TextureReadMode
= TextureReadModeEnable
| TRM_PrimaryCacheEnable
|
320 TRM_MipMapEnable
| TRM_BorderClamp
| TRM_Border
;
321 t
->TextureColorMode
= TextureColorModeEnable
;
322 t
->TextureFilterMode
= TextureFilterModeEnable
;
324 if (target
== GL_TEXTURE_2D
) {
325 t
->TextureAddressMode
|= TAM_TexMapType_2D
;
326 t
->TextureReadMode
|= TRM_TexMapType_2D
;
328 else if (target
== GL_TEXTURE_1D
) {
329 t
->TextureAddressMode
|= TAM_TexMapType_1D
;
330 t
->TextureReadMode
|= TRM_TexMapType_1D
;
333 t
->TextureColorMode
= TextureColorModeEnable
;
335 t
->TextureFilterMode
= TextureFilterModeEnable
;
337 #ifdef MESA_LITTLE_ENDIAN
338 t
->TextureFormat
= (TF_LittleEndian
|
340 t
->TextureFormat
= (TF_BigEndian
|
345 t
->dirty_images
= ~0;
347 tObj
->DriverData
= t
;
348 make_empty_list( t
);
350 gammaSetTexWrapping( t
, tObj
->WrapS
, tObj
->WrapT
);
351 gammaSetTexFilter( gmesa
, t
, tObj
->MinFilter
, tObj
->MagFilter
, bias
);
352 gammaSetTexBorderColor( gmesa
, t
, tObj
->BorderColor
);
356 static void gammaDeleteTexture( GLcontext
*ctx
, struct gl_texture_object
*tObj
)
358 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
)tObj
->DriverData
;
361 gammaContextPtr gmesa
= GAMMA_CONTEXT( ctx
);
364 GAMMA_FIREVERTICES( gmesa
);
366 gammaDestroyTexObj( gmesa
, t
);
367 tObj
->DriverData
= 0;
369 /* Free mipmap images and the texture object itself */
370 _mesa_delete_texture_object(ctx
, tObj
);
373 static GLboolean
gammaIsTextureResident( GLcontext
*ctx
,
374 struct gl_texture_object
*tObj
)
376 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
)tObj
->DriverData
;
377 return t
&& t
->MemBlock
;
382 * Allocate a new texture object.
383 * Called via ctx->Driver.NewTextureObject.
384 * Note: this function will be called during context creation to
385 * allocate the default texture objects.
386 * Note: we could use containment here to 'derive' the driver-specific
387 * texture object from the core mesa gl_texture_object. Not done at this time.
389 static struct gl_texture_object
*
390 gammaNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
392 struct gl_texture_object
*obj
;
393 obj
= _mesa_new_texture_object(ctx
, name
, target
);
398 void gammaInitTextureObjects( GLcontext
*ctx
)
400 struct gl_texture_object
*texObj
;
401 GLuint tmp
= ctx
->Texture
.CurrentUnit
;
403 ctx
->Texture
.CurrentUnit
= 0;
405 texObj
= ctx
->Texture
.Unit
[0].CurrentTex
[TEXTURE_1D_INDEX
];
406 gammaBindTexture( ctx
, GL_TEXTURE_1D
, texObj
);
408 texObj
= ctx
->Texture
.Unit
[0].CurrentTex
[TEXTURE_2D_INDEX
];
409 gammaBindTexture( ctx
, GL_TEXTURE_2D
, texObj
);
412 ctx
->Texture
.CurrentUnit
= 1;
414 texObj
= ctx
->Texture
.Unit
[1].CurrentTex
[TEXTURE_1D_INDEX
];
415 gammaBindTexture( ctx
, GL_TEXTURE_1D
, texObj
);
417 texObj
= ctx
->Texture
.Unit
[1].CurrentTex
[TEXTURE_2D_INDEX
];
418 gammaBindTexture( ctx
, GL_TEXTURE_2D
, texObj
);
421 ctx
->Texture
.CurrentUnit
= tmp
;
425 void gammaDDInitTextureFuncs( struct dd_function_table
*functions
)
427 functions
->TexEnv
= gammaTexEnv
;
428 functions
->TexImage2D
= gammaTexImage2D
;
429 functions
->TexSubImage2D
= gammaTexSubImage2D
;
430 functions
->BindTexture
= gammaBindTexture
;
431 functions
->DeleteTexture
= gammaDeleteTexture
;
432 functions
->TexParameter
= gammaTexParameter
;
433 functions
->IsTextureResident
= gammaIsTextureResident
;