8 #include "simple_list.h"
12 #include "texformat.h"
14 #include "swrast/swrast.h"
17 #include "gamma_context.h"
22 * Compute the 'S2.4' lod bias factor from the floating point OpenGL bias.
25 static GLuint
gammaComputeLodBias(GLfloat bias
)
31 static void gammaSetTexWrapping(gammaTextureObjectPtr t
,
32 GLenum wraps
, GLenum wrapt
)
34 uint32_t t1
= t
->TextureAddressMode
;
35 uint32_t t2
= t
->TextureReadMode
;
37 t1
&= ~(TAM_SWrap_Mask
| TAM_TWrap_Mask
);
38 t2
&= ~(TRM_UWrap_Mask
| TRM_VWrap_Mask
);
40 if (wraps
!= GL_CLAMP
) {
41 t1
|= TAM_SWrap_Repeat
;
42 t2
|= TRM_UWrap_Repeat
;
45 if (wrapt
!= GL_CLAMP
) {
46 t1
|= TAM_TWrap_Repeat
;
47 t2
|= TRM_VWrap_Repeat
;
50 t
->TextureAddressMode
= t1
;
51 t
->TextureReadMode
= t2
;
55 static void gammaSetTexFilter(gammaContextPtr gmesa
,
56 gammaTextureObjectPtr t
,
57 GLenum minf
, GLenum magf
,
60 uint32_t t1
= t
->TextureAddressMode
;
61 uint32_t t2
= t
->TextureReadMode
;
63 t2
&= ~(TRM_Mag_Mask
| TRM_Min_Mask
);
68 t2
&= ~TRM_MipMapEnable
;
69 t2
|= TRM_Min_Nearest
;
73 t2
&= ~TRM_MipMapEnable
;
76 case GL_NEAREST_MIPMAP_NEAREST
:
77 t2
|= TRM_Min_NearestMMNearest
;
79 case GL_LINEAR_MIPMAP_NEAREST
:
80 t2
|= TRM_Min_LinearMMNearest
;
82 case GL_NEAREST_MIPMAP_LINEAR
:
83 t2
|= TRM_Min_NearestMMLinear
;
85 case GL_LINEAR_MIPMAP_LINEAR
:
86 t2
|= TRM_Min_LinearMMLinear
;
94 t2
|= TRM_Mag_Nearest
;
103 t
->TextureAddressMode
= t1
;
104 t
->TextureReadMode
= t2
;
108 static void gammaSetTexBorderColor(gammaContextPtr gmesa
,
109 gammaTextureObjectPtr t
,
112 t
->TextureBorderColor
= PACK_COLOR_8888(color
[0], color
[1], color
[2], color
[3]);
116 static void gammaTexParameter( GLcontext
*ctx
, GLenum target
,
117 struct gl_texture_object
*tObj
,
118 GLenum pname
, const GLfloat
*params
)
120 gammaContextPtr gmesa
= GAMMA_CONTEXT(ctx
);
121 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
) tObj
->DriverData
;
125 /* Can't do the update now as we don't know whether to flush
126 * vertices or not. Setting gmesa->new_state means that
127 * gammaUpdateTextureState() will be called before any triangles are
128 * rendered. If a statechange has occurred, it will be detected at
129 * that point, and buffered vertices flushed.
132 case GL_TEXTURE_MIN_FILTER
:
133 case GL_TEXTURE_MAG_FILTER
:
135 GLfloat bias
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].LodBias
;
136 gammaSetTexFilter( gmesa
, t
, tObj
->MinFilter
, tObj
->MagFilter
, bias
);
140 case GL_TEXTURE_WRAP_S
:
141 case GL_TEXTURE_WRAP_T
:
142 gammaSetTexWrapping( t
, tObj
->WrapS
, tObj
->WrapT
);
145 case GL_TEXTURE_BORDER_COLOR
:
146 gammaSetTexBorderColor( gmesa
, t
, tObj
->_BorderChan
);
149 case GL_TEXTURE_BASE_LEVEL
:
150 case GL_TEXTURE_MAX_LEVEL
:
151 case GL_TEXTURE_MIN_LOD
:
152 case GL_TEXTURE_MAX_LOD
:
153 /* This isn't the most efficient solution but there doesn't appear to
154 * be a nice alternative for Radeon. Since there's no LOD clamping,
155 * we just have to rely on loading the right subset of mipmap levels
156 * to simulate a clamped LOD.
158 gammaSwapOutTexObj( gmesa
, t
);
165 if (t
== gmesa
->CurrentTexObj
[0])
166 gmesa
->dirty
|= GAMMA_UPLOAD_TEX0
;
169 if (t
== gmesa
->CurrentTexObj
[1]) {
170 gmesa
->dirty
|= GAMMA_UPLOAD_TEX1
;
176 static void gammaTexEnv( GLcontext
*ctx
, GLenum target
,
177 GLenum pname
, const GLfloat
*param
)
179 gammaContextPtr gmesa
= GAMMA_CONTEXT( ctx
);
180 GLuint unit
= ctx
->Texture
.CurrentUnit
;
182 /* Only one env color. Need a fallback if env colors are different
183 * and texture setup references env color in both units.
186 case GL_TEXTURE_ENV_COLOR
: {
187 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
188 GLfloat
*fc
= texUnit
->EnvColor
;
189 GLuint r
, g
, b
, a
, col
;
190 CLAMPED_FLOAT_TO_UBYTE(r
, fc
[0]);
191 CLAMPED_FLOAT_TO_UBYTE(g
, fc
[1]);
192 CLAMPED_FLOAT_TO_UBYTE(b
, fc
[2]);
193 CLAMPED_FLOAT_TO_UBYTE(a
, fc
[3]);
202 case GL_TEXTURE_ENV_MODE
:
203 gmesa
->TexEnvImageFmt
[unit
] = 0; /* force recalc of env state */
206 case GL_TEXTURE_LOD_BIAS_EXT
:
209 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[unit
]._Current
;
210 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
) tObj
->DriverData
;
212 /* XXX Looks like there's something missing here */
223 static void gammaTexImage1D( GLcontext
*ctx
, GLenum target
, GLint level
,
224 GLint internalFormat
,
225 GLint width
, GLint border
,
226 GLenum format
, GLenum type
,
227 const GLvoid
*pixels
,
228 const struct gl_pixelstore_attrib
*pack
,
229 struct gl_texture_object
*texObj
,
230 struct gl_texture_image
*texImage
)
232 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
) texObj
->DriverData
;
234 gammaSwapOutTexObj( GAMMA_CONTEXT(ctx
), t
);
236 _mesa_store_teximage1d( ctx
, target
, level
, internalFormat
,
237 width
, border
, format
, type
,
238 pixels
, pack
, texObj
, texImage
);
243 static void gammaTexSubImage1D( GLcontext
*ctx
,
248 GLenum format
, GLenum type
,
249 const GLvoid
*pixels
,
250 const struct gl_pixelstore_attrib
*pack
,
251 struct gl_texture_object
*texObj
,
252 struct gl_texture_image
*texImage
)
254 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
) texObj
->DriverData
;
256 gammaSwapOutTexObj( GAMMA_CONTEXT(ctx
), t
);
258 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
259 format
, type
, pixels
, pack
, texObj
,
264 static void gammaTexImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
265 GLint internalFormat
,
266 GLint width
, GLint height
, GLint border
,
267 GLenum format
, GLenum type
, const GLvoid
*pixels
,
268 const struct gl_pixelstore_attrib
*packing
,
269 struct gl_texture_object
*texObj
,
270 struct gl_texture_image
*texImage
)
272 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
) texObj
->DriverData
;
274 gammaSwapOutTexObj( GAMMA_CONTEXT(ctx
), t
);
276 _mesa_store_teximage2d( ctx
, target
, level
, internalFormat
,
277 width
, height
, border
, format
, type
,
278 pixels
, packing
, texObj
, texImage
);
281 static void gammaTexSubImage2D( GLcontext
*ctx
,
284 GLint xoffset
, GLint yoffset
,
285 GLsizei width
, GLsizei height
,
286 GLenum format
, GLenum type
,
287 const GLvoid
*pixels
,
288 const struct gl_pixelstore_attrib
*packing
,
289 struct gl_texture_object
*texObj
,
290 struct gl_texture_image
*texImage
)
292 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
) texObj
->DriverData
;
294 gammaSwapOutTexObj( GAMMA_CONTEXT(ctx
), t
);
296 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
297 height
, format
, type
, pixels
, packing
, texObj
,
301 static void gammaBindTexture( GLcontext
*ctx
, GLenum target
,
302 struct gl_texture_object
*tObj
)
304 gammaContextPtr gmesa
= GAMMA_CONTEXT( ctx
);
305 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
) tObj
->DriverData
;
308 GLfloat bias
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].LodBias
;
309 t
= CALLOC_STRUCT(gamma_texture_object_t
);
311 /* Initialize non-image-dependent parts of the state:
315 t
->TextureAddressMode
= TextureAddressModeEnable
| TAM_Operation_3D
|
316 TAM_DY_Enable
| TAM_LODEnable
;
317 t
->TextureReadMode
= TextureReadModeEnable
| TRM_PrimaryCacheEnable
|
318 TRM_MipMapEnable
| TRM_BorderClamp
| TRM_Border
;
319 t
->TextureColorMode
= TextureColorModeEnable
;
320 t
->TextureFilterMode
= TextureFilterModeEnable
;
322 if (target
== GL_TEXTURE_2D
) {
323 t
->TextureAddressMode
|= TAM_TexMapType_2D
;
324 t
->TextureReadMode
|= TRM_TexMapType_2D
;
326 else if (target
== GL_TEXTURE_1D
) {
327 t
->TextureAddressMode
|= TAM_TexMapType_1D
;
328 t
->TextureReadMode
|= TRM_TexMapType_1D
;
331 t
->TextureColorMode
= TextureColorModeEnable
;
333 t
->TextureFilterMode
= TextureFilterModeEnable
;
335 #ifdef MESA_LITTLE_ENDIAN
336 t
->TextureFormat
= (TF_LittleEndian
|
338 t
->TextureFormat
= (TF_BigEndian
|
343 t
->dirty_images
= ~0;
345 tObj
->DriverData
= t
;
346 make_empty_list( t
);
348 gammaSetTexWrapping( t
, tObj
->WrapS
, tObj
->WrapT
);
349 gammaSetTexFilter( gmesa
, t
, tObj
->MinFilter
, tObj
->MagFilter
, bias
);
350 gammaSetTexBorderColor( gmesa
, t
, tObj
->_BorderChan
);
354 static void gammaDeleteTexture( GLcontext
*ctx
, struct gl_texture_object
*tObj
)
356 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
)tObj
->DriverData
;
359 gammaContextPtr gmesa
= GAMMA_CONTEXT( ctx
);
362 GAMMA_FIREVERTICES( gmesa
);
364 gammaDestroyTexObj( gmesa
, t
);
365 tObj
->DriverData
= 0;
367 /* Free mipmap images and the texture object itself */
368 _mesa_delete_texture_object(ctx
, tObj
);
371 static GLboolean
gammaIsTextureResident( GLcontext
*ctx
,
372 struct gl_texture_object
*tObj
)
374 gammaTextureObjectPtr t
= (gammaTextureObjectPtr
)tObj
->DriverData
;
375 return t
&& t
->MemBlock
;
380 * Allocate a new texture object.
381 * Called via ctx->Driver.NewTextureObject.
382 * Note: this function will be called during context creation to
383 * allocate the default texture objects.
384 * Note: we could use containment here to 'derive' the driver-specific
385 * texture object from the core mesa gl_texture_object. Not done at this time.
387 static struct gl_texture_object
*
388 gammaNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
390 struct gl_texture_object
*obj
;
391 obj
= _mesa_new_texture_object(ctx
, name
, target
);
396 void gammaInitTextureObjects( GLcontext
*ctx
)
398 struct gl_texture_object
*texObj
;
399 GLuint tmp
= ctx
->Texture
.CurrentUnit
;
401 ctx
->Texture
.CurrentUnit
= 0;
403 texObj
= ctx
->Texture
.Unit
[0].Current1D
;
404 gammaBindTexture( ctx
, GL_TEXTURE_1D
, texObj
);
406 texObj
= ctx
->Texture
.Unit
[0].Current2D
;
407 gammaBindTexture( ctx
, GL_TEXTURE_2D
, texObj
);
410 ctx
->Texture
.CurrentUnit
= 1;
412 texObj
= ctx
->Texture
.Unit
[1].Current1D
;
413 gammaBindTexture( ctx
, GL_TEXTURE_1D
, texObj
);
415 texObj
= ctx
->Texture
.Unit
[1].Current2D
;
416 gammaBindTexture( ctx
, GL_TEXTURE_2D
, texObj
);
419 ctx
->Texture
.CurrentUnit
= tmp
;
423 void gammaDDInitTextureFuncs( struct dd_function_table
*functions
)
425 functions
->TexEnv
= gammaTexEnv
;
426 functions
->TexImage2D
= gammaTexImage2D
;
427 functions
->TexSubImage2D
= gammaTexSubImage2D
;
428 functions
->BindTexture
= gammaBindTexture
;
429 functions
->DeleteTexture
= gammaDeleteTexture
;
430 functions
->TexParameter
= gammaTexParameter
;
431 functions
->IsTextureResident
= gammaIsTextureResident
;