OSDN Git Service

Remove CVS keywords.
[android-x86/external-mesa.git] / src / mesa / drivers / dri / mach64 / mach64_texstate.c
1 /* -*- mode: c; c-basic-offset: 3 -*- */
2 /*
3  * Copyright 2000 Gareth Hughes
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * GARETH HUGHES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 /*
26  * Authors:
27  *      Gareth Hughes <gareth@valinux.com>
28  *      Leif Delgass <ldelgass@retinalburn.net>
29  *      José Fonseca <j_r_fonseca@yahoo.co.uk>
30  */
31
32 #include "glheader.h"
33 #include "imports.h"
34 #include "context.h"
35 #include "macros.h"
36 #include "texformat.h"
37
38 #include "mach64_context.h"
39 #include "mach64_ioctl.h"
40 #include "mach64_state.h"
41 #include "mach64_vb.h"
42 #include "mach64_tris.h"
43 #include "mach64_tex.h"
44
45 static void mach64SetTexImages( mach64ContextPtr mmesa,
46                               const struct gl_texture_object *tObj )
47 {
48    mach64TexObjPtr t = (mach64TexObjPtr) tObj->DriverData;
49    struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
50    int totalSize;
51
52    assert(t);
53    assert(baseImage);
54
55    if ( MACH64_DEBUG & DEBUG_VERBOSE_API )
56       fprintf( stderr, "%s( %p )\n", __FUNCTION__, tObj );
57
58    switch (baseImage->TexFormat->MesaFormat) {
59    case MESA_FORMAT_ARGB8888:
60       t->textureFormat = MACH64_DATATYPE_ARGB8888;
61       break;
62    case MESA_FORMAT_ARGB4444:
63       t->textureFormat = MACH64_DATATYPE_ARGB4444;
64       break;
65    case MESA_FORMAT_RGB565:
66       t->textureFormat = MACH64_DATATYPE_RGB565;
67       break;
68    case MESA_FORMAT_ARGB1555:
69       t->textureFormat = MACH64_DATATYPE_ARGB1555;
70       break;
71    case MESA_FORMAT_RGB332:
72       t->textureFormat = MACH64_DATATYPE_RGB332;
73       break;
74    case MESA_FORMAT_RGB888:
75       t->textureFormat = MACH64_DATATYPE_RGB8;
76       break;
77    case MESA_FORMAT_CI8:
78       t->textureFormat = MACH64_DATATYPE_CI8;
79       break;
80    case MESA_FORMAT_YCBCR:
81       t->textureFormat = MACH64_DATATYPE_YVYU422;
82       break;
83    case MESA_FORMAT_YCBCR_REV:
84       t->textureFormat = MACH64_DATATYPE_VYUY422;
85       break;
86    default:
87       _mesa_problem(mmesa->glCtx, "Bad texture format in %s", __FUNCTION__);
88    };
89
90    totalSize = ( baseImage->Height *
91                  baseImage->Width *
92                  baseImage->TexFormat->TexelBytes );
93
94    totalSize = (totalSize + 31) & ~31;
95
96    t->base.totalSize = totalSize;
97    t->base.firstLevel = tObj->BaseLevel;
98    t->base.lastLevel = tObj->BaseLevel;
99
100    /* Set the texture format */
101    if ( ( baseImage->_BaseFormat == GL_RGBA ) ||
102         ( baseImage->_BaseFormat == GL_ALPHA ) ||
103         ( baseImage->_BaseFormat == GL_LUMINANCE_ALPHA ) ) {
104       t->hasAlpha = 1;
105    } else {
106       t->hasAlpha = 0;
107    }
108
109    t->widthLog2 = baseImage->WidthLog2;
110    t->heightLog2 = baseImage->HeightLog2;
111    t->maxLog2 = baseImage->MaxLog2;
112 }
113
114 static void mach64UpdateTextureEnv( GLcontext *ctx, int unit )
115 {
116    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
117    GLint source = mmesa->tmu_source[unit];
118    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
119    const struct gl_texture_object *tObj = texUnit->_Current;
120    const GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
121    GLuint s = mmesa->setup.scale_3d_cntl;
122
123    if ( MACH64_DEBUG & DEBUG_VERBOSE_API ) {
124       fprintf( stderr, "%s( %p, %d )\n",
125                __FUNCTION__, ctx, unit );
126    }
127
128 /*                 REPLACE  MODULATE   DECAL              GL_BLEND
129  *
130  * ALPHA           C = Cf   C = Cf     undef              C = Cf
131  *                 A = At   A = AfAt                      A = AfAt
132  *
133  * LUMINANCE       C = Ct   C = CfCt   undef              C = Cf(1-Ct)+CcCt 
134  *                 A = Af   A = Af                        A = Af
135  *
136  * LUMINANCE_ALPHA C = Ct   C = CfCt   undef              C = Cf(1-Ct)+CcCt
137  *                 A = At   A = AfAt                      A = AfAt
138  *
139  * INTENSITY       C = Ct   C = CfCt   undef              C = Cf(1-Ct)+CcCt
140  *                 A = At   A = AfAt                      A = Af(1-At)+AcAt
141  *
142  * RGB             C = Ct   C = CfCt   C = Ct             C = Cf(1-Ct)+CcCt
143  *                 A = Af   A = Af     A = Af             A = Af
144  *
145  * RGBA            C = Ct   C = CfCt   C = Cf(1-At)+CtAt  C = Cf(1-Ct)+CcCt
146  *                 A = At   A = AfAt   A = Af             A = AfAt 
147  */
148
149
150    if ( unit == 0 ) {
151       s &= ~MACH64_TEX_LIGHT_FCN_MASK;
152
153       /* Set the texture environment state 
154        * Need to verify these are working correctly, but the
155        * texenv Mesa demo seems to work.
156        */
157       switch ( texUnit->EnvMode ) {
158       case GL_REPLACE:
159          switch ( format ) {
160          case GL_ALPHA:
161          case GL_LUMINANCE_ALPHA:
162          case GL_INTENSITY:
163             /* Not compliant - can't get At */
164             FALLBACK( mmesa, MACH64_FALLBACK_TEXTURE, GL_TRUE );
165             s |= MACH64_TEX_LIGHT_FCN_MODULATE;
166             break;
167          default:
168             s |= MACH64_TEX_LIGHT_FCN_REPLACE;
169          }
170          break;
171       case GL_MODULATE:
172          switch ( format ) {
173          case GL_ALPHA:
174             FALLBACK( mmesa, MACH64_FALLBACK_TEXTURE, GL_TRUE );
175             s |= MACH64_TEX_LIGHT_FCN_MODULATE;
176             break;
177          case GL_RGB:
178          case GL_LUMINANCE:
179             /* These should be compliant */
180             s |= MACH64_TEX_LIGHT_FCN_MODULATE;
181             break;
182          case GL_LUMINANCE_ALPHA:
183          case GL_INTENSITY:
184             FALLBACK( mmesa, MACH64_FALLBACK_TEXTURE, GL_TRUE );
185             s |= MACH64_TEX_LIGHT_FCN_MODULATE;
186             break;
187          case GL_RGBA:
188             /* Should fallback when blending enabled for complete compliance */
189             s |= MACH64_TEX_LIGHT_FCN_MODULATE;
190             break;
191          default:
192             s |= MACH64_TEX_LIGHT_FCN_MODULATE;
193          }
194          break;
195       case GL_DECAL:
196          switch ( format ) {
197          case GL_RGBA: 
198             s |= MACH64_TEX_LIGHT_FCN_ALPHA_DECAL;
199             break;
200          case GL_RGB:
201             s |= MACH64_TEX_LIGHT_FCN_REPLACE;
202             break;
203          case GL_ALPHA:
204          case GL_LUMINANCE_ALPHA:
205             /* undefined - disable texturing, pass fragment unmodified  */
206             /* Also, pass fragment alpha instead of texture alpha */
207             s &= ~MACH64_TEX_MAP_AEN;
208             s |= MACH64_TEXTURE_DISABLE;
209             s |= MACH64_TEX_LIGHT_FCN_MODULATE;
210             break;
211          case GL_LUMINANCE:
212          case GL_INTENSITY:
213             /* undefined - disable texturing, pass fragment unmodified  */
214             s |= MACH64_TEXTURE_DISABLE;
215             s |= MACH64_TEX_LIGHT_FCN_MODULATE;
216             break;
217          default:
218             s |= MACH64_TEX_LIGHT_FCN_MODULATE;
219          }
220          break;
221       case GL_BLEND:
222          /* GL_BLEND not supported by RagePRO, use software */
223          FALLBACK( mmesa, MACH64_FALLBACK_TEXTURE, GL_TRUE );
224          s |= MACH64_TEX_LIGHT_FCN_MODULATE;
225          break;
226       case GL_ADD:
227       case GL_COMBINE:
228          FALLBACK( mmesa, MACH64_FALLBACK_TEXTURE, GL_TRUE );
229          s |= MACH64_TEX_LIGHT_FCN_MODULATE;
230          break;
231       default:
232          s |= MACH64_TEX_LIGHT_FCN_MODULATE;
233       }
234
235       if ( mmesa->setup.scale_3d_cntl != s ) {
236          mmesa->setup.scale_3d_cntl = s;
237          mmesa->dirty |= MACH64_UPLOAD_SCALE_3D_CNTL;
238       }
239
240    } else {
241       /* blend = 0, modulate = 1 - initialize to blend */
242       mmesa->setup.tex_cntl &= ~MACH64_COMP_COMBINE_MODULATE;
243       /* Set the texture composite function for multitexturing*/
244       switch ( texUnit->EnvMode ) {
245       case GL_BLEND:
246          /* GL_BLEND not supported by RagePRO, use software */
247          FALLBACK( mmesa, MACH64_FALLBACK_TEXTURE, GL_TRUE );
248          mmesa->setup.tex_cntl |= MACH64_COMP_COMBINE_MODULATE;
249          break;
250       case GL_MODULATE:
251          /* Should fallback when blending enabled for complete compliance */
252          mmesa->setup.tex_cntl |= MACH64_COMP_COMBINE_MODULATE;
253          break;
254       case GL_REPLACE:
255          switch ( format ) {
256          case GL_ALPHA:
257             mmesa->setup.tex_cntl |= MACH64_COMP_COMBINE_MODULATE;
258             break;
259          default: /* not supported by RagePRO */
260             FALLBACK( mmesa, MACH64_FALLBACK_TEXTURE, GL_TRUE );
261             mmesa->setup.tex_cntl |= MACH64_COMP_COMBINE_MODULATE;
262          }
263          break;
264       case GL_DECAL:
265          switch ( format ) {
266          case GL_ALPHA:
267          case GL_LUMINANCE:
268          case GL_LUMINANCE_ALPHA:
269          case GL_INTENSITY:
270             /* undefined, disable compositing and pass fragment unmodified */
271             mmesa->setup.tex_cntl &= ~MACH64_TEXTURE_COMPOSITE;
272             break;
273          default: /* not supported by RagePRO */
274             FALLBACK( mmesa, MACH64_FALLBACK_TEXTURE, GL_TRUE );
275             mmesa->setup.tex_cntl |= MACH64_COMP_COMBINE_MODULATE;
276          }
277          break;
278       case GL_ADD:
279       case GL_COMBINE:
280          FALLBACK( mmesa, MACH64_FALLBACK_TEXTURE, GL_TRUE );
281          mmesa->setup.tex_cntl |= MACH64_COMP_COMBINE_MODULATE;
282          break;
283       default:
284          mmesa->setup.tex_cntl |= MACH64_COMP_COMBINE_MODULATE;
285       }
286    }
287 }
288
289
290 static void mach64UpdateTextureUnit( GLcontext *ctx, int unit )
291 {
292    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
293    int source = mmesa->tmu_source[unit];
294    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
295    const struct gl_texture_object *tObj = ctx->Texture.Unit[source]._Current;
296    mach64TexObjPtr t = tObj->DriverData;
297    GLuint d = mmesa->setup.dp_pix_width;
298    GLuint s = mmesa->setup.scale_3d_cntl;
299
300    assert(unit == 0 || unit == 1);  /* only two tex units */
301
302    if ( MACH64_DEBUG & DEBUG_VERBOSE_API ) {
303       fprintf( stderr, "%s( %p, %d ) enabled=0x%x 0x%x\n",
304                __FUNCTION__, ctx, unit, ctx->Texture.Unit[0]._ReallyEnabled,
305                ctx->Texture.Unit[1]._ReallyEnabled);
306    }
307
308    if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) {
309
310       assert(t);  /* should have driver tex data by now */
311
312       /* Fallback if there's a texture border */
313       if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) {
314          FALLBACK( mmesa, MACH64_FALLBACK_TEXTURE, GL_TRUE );
315          return;
316       }
317
318       /* Upload teximages */
319       if (t->base.dirty_images[0]) {
320          mach64SetTexImages( mmesa, tObj );
321          mmesa->dirty |= (MACH64_UPLOAD_TEX0IMAGE << unit);
322       }
323
324       /* Bind to the given texture unit */
325       mmesa->CurrentTexObj[unit] = t;
326       t->base.bound |= (1 << unit);
327
328       if ( t->base.memBlock )
329          driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */
330
331       /* register setup */
332       if ( unit == 0 ) {
333          d &= ~MACH64_SCALE_PIX_WIDTH_MASK;
334          d |= (t->textureFormat << 28);
335    
336          s &= ~(MACH64_TEXTURE_DISABLE |
337                 MACH64_TEX_CACHE_SPLIT |
338                 MACH64_TEX_BLEND_FCN_MASK |
339                 MACH64_TEX_MAP_AEN);
340    
341          if ( mmesa->multitex ) {
342             s |= MACH64_TEX_BLEND_FCN_TRILINEAR | MACH64_TEX_CACHE_SPLIT;
343          } else if ( t->BilinearMin ) {
344             s |= MACH64_TEX_BLEND_FCN_LINEAR;
345          } else {
346             s |= MACH64_TEX_BLEND_FCN_NEAREST;
347          }
348          if ( t->BilinearMag ) {
349             s |=  MACH64_BILINEAR_TEX_EN;
350          } else {
351             s &= ~MACH64_BILINEAR_TEX_EN;
352          }
353    
354          if ( t->hasAlpha ) {
355             s |= MACH64_TEX_MAP_AEN;
356          }
357    
358          mmesa->setup.tex_cntl &= ~(MACH64_TEXTURE_CLAMP_S |
359                                     MACH64_TEXTURE_CLAMP_T |
360                                     MACH64_SECONDARY_STW);
361    
362          if ( t->ClampS ) {
363             mmesa->setup.tex_cntl |= MACH64_TEXTURE_CLAMP_S;
364          }
365          if ( t->ClampT ) {
366             mmesa->setup.tex_cntl |= MACH64_TEXTURE_CLAMP_T;
367          }
368    
369          mmesa->setup.tex_size_pitch |= ((t->widthLog2  << 0) |
370                                          (t->maxLog2    << 4) |
371                                          (t->heightLog2 << 8));
372       } else {
373          
374          /* Enable texture mapping mode */
375          s &= ~MACH64_TEXTURE_DISABLE;
376    
377          d &= ~MACH64_COMPOSITE_PIX_WIDTH_MASK;
378          d |= (t->textureFormat << 4);
379    
380          mmesa->setup.tex_cntl &= ~(MACH64_COMP_ALPHA |
381                                     MACH64_SEC_TEX_CLAMP_S |
382                                     MACH64_SEC_TEX_CLAMP_T);
383          mmesa->setup.tex_cntl |= (MACH64_TEXTURE_COMPOSITE |
384                                    MACH64_SECONDARY_STW);
385    
386          if ( t->BilinearMin ) {
387             mmesa->setup.tex_cntl |= MACH64_COMP_BLEND_BILINEAR;
388          } else {
389             mmesa->setup.tex_cntl &= ~MACH64_COMP_BLEND_BILINEAR;
390          }
391          if ( t->BilinearMag ) {
392             mmesa->setup.tex_cntl |=  MACH64_COMP_FILTER_BILINEAR;
393          } else {
394             mmesa->setup.tex_cntl &= ~MACH64_COMP_FILTER_BILINEAR;
395          }
396          
397          if ( t->hasAlpha ) {
398             mmesa->setup.tex_cntl |= MACH64_COMP_ALPHA;
399          }
400          if ( t->ClampS ) {
401             mmesa->setup.tex_cntl |= MACH64_SEC_TEX_CLAMP_S;
402          }
403          if ( t->ClampT ) {
404             mmesa->setup.tex_cntl |= MACH64_SEC_TEX_CLAMP_T;
405          }
406    
407          mmesa->setup.tex_size_pitch |= ((t->widthLog2  << 16) |
408                                          (t->maxLog2    << 20) |
409                                          (t->heightLog2 << 24));
410       }
411    
412       if ( mmesa->setup.scale_3d_cntl != s ) {
413          mmesa->setup.scale_3d_cntl = s;
414          mmesa->dirty |= MACH64_UPLOAD_SCALE_3D_CNTL;
415       }
416    
417       if ( mmesa->setup.dp_pix_width != d ) {
418          mmesa->setup.dp_pix_width = d;
419          mmesa->dirty |= MACH64_UPLOAD_DP_PIX_WIDTH;
420       }  
421    }
422    else if (texUnit->_ReallyEnabled) {
423       /* 3D or cube map texture enabled - fallback */
424       FALLBACK( mmesa, MACH64_FALLBACK_TEXTURE, GL_TRUE );
425    }
426    else {
427       /* texture unit disabled */
428    }
429 }
430
431
432 /* Update the hardware texture state */
433 void mach64UpdateTextureState( GLcontext *ctx )
434 {
435    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
436
437    if ( MACH64_DEBUG & DEBUG_VERBOSE_API ) {
438       fprintf( stderr, "%s( %p ) en=0x%x 0x%x\n",
439                __FUNCTION__, ctx, ctx->Texture.Unit[0]._ReallyEnabled,
440                ctx->Texture.Unit[1]._ReallyEnabled);
441    }
442
443    /* Clear any texturing fallbacks */
444    FALLBACK( mmesa, MACH64_FALLBACK_TEXTURE, GL_FALSE );
445
446    /* Unbind any currently bound textures */
447    if ( mmesa->CurrentTexObj[0] ) mmesa->CurrentTexObj[0]->base.bound = 0;
448    if ( mmesa->CurrentTexObj[1] ) mmesa->CurrentTexObj[1]->base.bound = 0;
449    mmesa->CurrentTexObj[0] = NULL;
450    mmesa->CurrentTexObj[1] = NULL;
451
452    /* Disable all texturing until it is known to be good */
453    mmesa->setup.scale_3d_cntl  |=  MACH64_TEXTURE_DISABLE;
454    mmesa->setup.scale_3d_cntl  &= ~MACH64_TEX_MAP_AEN;
455    mmesa->setup.tex_cntl       &= ~MACH64_TEXTURE_COMPOSITE;
456
457    mmesa->setup.tex_size_pitch = 0x00000000;
458
459    mmesa->tmu_source[0] = 0;
460    mmesa->tmu_source[1] = 1;
461    mmesa->multitex = 0;
462
463    if (ctx->Texture._EnabledUnits & 0x2) {
464        /* unit 1 enabled */
465        if (ctx->Texture._EnabledUnits & 0x1) {
466           /* units 0 and 1 enabled */
467           mmesa->multitex = 1;
468           mach64UpdateTextureUnit( ctx, 0 );
469           mach64UpdateTextureEnv( ctx, 0 );
470           mach64UpdateTextureUnit( ctx, 1 );
471           mach64UpdateTextureEnv( ctx, 1 );
472        } else {
473           mmesa->tmu_source[0] = 1;
474           mmesa->tmu_source[1] = 0;
475           mach64UpdateTextureUnit( ctx, 0 );
476           mach64UpdateTextureEnv( ctx, 0 );
477        }
478    } else if (ctx->Texture._EnabledUnits & 0x1) {
479       /* only unit 0 enabled */ 
480       mach64UpdateTextureUnit( ctx, 0 );
481       mach64UpdateTextureEnv( ctx, 0 );
482    }
483
484    mmesa->dirty |= (MACH64_UPLOAD_SCALE_3D_CNTL |
485                     MACH64_UPLOAD_TEXTURE);
486 }
487
488
489 /* Due to the way we must program texture state into the Rage Pro,
490  * we must leave these calculations to the absolute last minute.
491  */
492 void mach64EmitTexStateLocked( mach64ContextPtr mmesa,
493                                mach64TexObjPtr t0,
494                                mach64TexObjPtr t1 )
495 {
496    drm_mach64_sarea_t *sarea = mmesa->sarea;
497    drm_mach64_context_regs_t *regs = &(mmesa->setup);
498
499    /* for multitex, both textures must be local or AGP */
500    if ( t0 && t1 )
501       assert(t0->heap == t1->heap);
502
503    if ( t0 ) {
504       if (t0->heap == MACH64_CARD_HEAP) {
505 #if ENABLE_PERF_BOXES
506          mmesa->c_texsrc_card++;
507 #endif
508          mmesa->setup.tex_cntl &= ~MACH64_TEX_SRC_AGP;
509       } else {
510 #if ENABLE_PERF_BOXES
511          mmesa->c_texsrc_agp++;
512 #endif
513          mmesa->setup.tex_cntl |= MACH64_TEX_SRC_AGP;
514       }
515       mmesa->setup.tex_offset = t0->bufAddr;
516    }
517
518    if ( t1 ) {
519       mmesa->setup.secondary_tex_off = t1->bufAddr;
520    }
521
522    memcpy( &sarea->context_state.tex_size_pitch, &regs->tex_size_pitch,
523            MACH64_NR_TEXTURE_REGS * sizeof(GLuint) );
524 }
525