~ubuntu-branches/ubuntu/quantal/mesa/quantal

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/r200/r200_texstate.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-02-21 12:44:07 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20070221124407-rgcacs32mycrtadl
ImportĀ upstreamĀ versionĀ 6.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
71
71
#define _INVALID(f) \
72
72
    [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
73
73
#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
74
 
                             && (tx_table[f].format != 0xffffffff) )
75
 
 
76
 
static const struct {
77
 
   GLuint format, filter;
78
 
}
79
 
tx_table[] =
 
74
                             && (tx_table_le[f].format != 0xffffffff) )
 
75
 
 
76
static const struct {
 
77
   GLuint format, filter;
 
78
}
 
79
tx_table_be[] =
 
80
{
 
81
   [ MESA_FORMAT_RGBA8888 ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
 
82
   _ALPHA_REV(RGBA8888),
 
83
   _ALPHA(ARGB8888),
 
84
   _ALPHA_REV(ARGB8888),
 
85
   _INVALID(RGB888),
 
86
   _COLOR(RGB565),
 
87
   _COLOR_REV(RGB565),
 
88
   _ALPHA(ARGB4444),
 
89
   _ALPHA_REV(ARGB4444),
 
90
   _ALPHA(ARGB1555),
 
91
   _ALPHA_REV(ARGB1555),
 
92
   _ALPHA(AL88),
 
93
   _ALPHA_REV(AL88),
 
94
   _ALPHA(A8),
 
95
   _COLOR(L8),
 
96
   _ALPHA(I8),
 
97
   _INVALID(CI8),
 
98
   _YUV(YCBCR),
 
99
   _YUV(YCBCR_REV),
 
100
   _INVALID(RGB_FXT1),
 
101
   _INVALID(RGBA_FXT1),
 
102
   _COLOR(RGB_DXT1),
 
103
   _ALPHA(RGBA_DXT1),
 
104
   _ALPHA(RGBA_DXT3),
 
105
   _ALPHA(RGBA_DXT5),
 
106
};
 
107
 
 
108
static const struct {
 
109
   GLuint format, filter;
 
110
}
 
111
tx_table_le[] =
80
112
{
81
113
   _ALPHA(RGBA8888),
82
 
   _ALPHA_REV(RGBA8888),
 
114
   [ MESA_FORMAT_RGBA8888_REV ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
83
115
   _ALPHA(ARGB8888),
84
116
   _ALPHA_REV(ARGB8888),
85
117
   _INVALID(RGB888),
129
161
   GLint i, texelBytes;
130
162
   GLint numLevels;
131
163
   GLint log2Width, log2Height, log2Depth;
 
164
   const GLuint ui = 1;
 
165
   const GLubyte littleEndian = *((const GLubyte *) &ui);
132
166
 
133
167
   /* Set the hardware texture format
134
168
    */
138
172
   t->pp_txfilter &= ~R200_YUV_TO_RGB;
139
173
 
140
174
   if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) {
141
 
      t->pp_txformat |= tx_table[ baseImage->TexFormat->MesaFormat ].format;
142
 
      t->pp_txfilter |= tx_table[ baseImage->TexFormat->MesaFormat ].filter;
 
175
      if (littleEndian) {
 
176
         t->pp_txformat |= tx_table_le[ baseImage->TexFormat->MesaFormat ].format;
 
177
         t->pp_txfilter |= tx_table_le[ baseImage->TexFormat->MesaFormat ].filter;
 
178
      }
 
179
      else {
 
180
         t->pp_txformat |= tx_table_be[ baseImage->TexFormat->MesaFormat ].format;
 
181
         t->pp_txfilter |= tx_table_be[ baseImage->TexFormat->MesaFormat ].filter;
 
182
      }
143
183
   }
144
184
   else {
145
185
      _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__);
1137
1177
                                  int unit,
1138
1178
                                  r200TexObjPtr texobj )
1139
1179
{
1140
 
   GLuint *cmd = R200_DB_STATE( tex[unit] );
 
1180
/* do not use RADEON_DB_STATE to avoid stale texture caches */
 
1181
   int *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
 
1182
 
 
1183
   R200_STATECHANGE( rmesa, tex[unit] );
1141
1184
 
1142
1185
   cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
1143
1186
   cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK;
1156
1199
   }
1157
1200
 
1158
1201
   if (texobj->base.tObj->Target == GL_TEXTURE_CUBE_MAP) {
1159
 
      GLuint *cube_cmd = R200_DB_STATE( cube[unit] );
 
1202
      int *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
1160
1203
      GLuint bytesPerFace = texobj->base.totalSize / 6;
1161
1204
      ASSERT(texobj->base.totalSize % 6 == 0);
 
1205
 
 
1206
      R200_STATECHANGE( rmesa, cube[unit] );
1162
1207
      cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
1163
1208
      if (rmesa->r200Screen->drmSupportsFragShader) {
1164
1209
         /* that value is submitted twice. could change cube atom
1170
1215
      cube_cmd[CUBE_PP_CUBIC_OFFSET_F3] = texobj->pp_txoffset + 3 * bytesPerFace;
1171
1216
      cube_cmd[CUBE_PP_CUBIC_OFFSET_F4] = texobj->pp_txoffset + 4 * bytesPerFace;
1172
1217
      cube_cmd[CUBE_PP_CUBIC_OFFSET_F5] = texobj->pp_txoffset + 5 * bytesPerFace;
1173
 
      R200_DB_STATECHANGE( rmesa, &rmesa->hw.cube[unit] );
1174
1218
   }
1175
 
   R200_DB_STATECHANGE( rmesa, &rmesa->hw.tex[unit] );
1176
1219
 
1177
1220
   texobj->dirty_state &= ~(1<<unit);
1178
1221
}
1213
1256
}
1214
1257
 
1215
1258
 
 
1259
static GLuint r200_need_dis_texgen(const GLbitfield texGenEnabled,
 
1260
                                   const GLfloat *planeS,
 
1261
                                   const GLfloat *planeT,
 
1262
                                   const GLfloat *planeR,
 
1263
                                   const GLfloat *planeQ)
 
1264
{
 
1265
   GLuint needtgenable = 0;
 
1266
 
 
1267
   if (!(texGenEnabled & S_BIT)) {
 
1268
      if (((texGenEnabled & T_BIT) && planeT[0] != 0.0) ||
 
1269
         ((texGenEnabled & R_BIT) && planeR[0] != 0.0) ||
 
1270
         ((texGenEnabled & Q_BIT) && planeQ[0] != 0.0)) {
 
1271
         needtgenable |= S_BIT;
 
1272
      }
 
1273
   }
 
1274
   if (!(texGenEnabled & T_BIT)) {
 
1275
      if (((texGenEnabled & S_BIT) && planeS[1] != 0.0) ||
 
1276
         ((texGenEnabled & R_BIT) && planeR[1] != 0.0) ||
 
1277
         ((texGenEnabled & Q_BIT) && planeQ[1] != 0.0)) {
 
1278
         needtgenable |= T_BIT;
 
1279
     }
 
1280
   }
 
1281
   if (!(texGenEnabled & R_BIT)) {
 
1282
      if (((texGenEnabled & S_BIT) && planeS[2] != 0.0) ||
 
1283
         ((texGenEnabled & T_BIT) && planeT[2] != 0.0) ||
 
1284
         ((texGenEnabled & Q_BIT) && planeQ[2] != 0.0)) {
 
1285
         needtgenable |= R_BIT;
 
1286
      }
 
1287
   }
 
1288
   if (!(texGenEnabled & Q_BIT)) {
 
1289
      if (((texGenEnabled & S_BIT) && planeS[3] != 0.0) ||
 
1290
         ((texGenEnabled & T_BIT) && planeT[3] != 0.0) ||
 
1291
         ((texGenEnabled & R_BIT) && planeR[3] != 0.0)) {
 
1292
         needtgenable |= Q_BIT;
 
1293
      }
 
1294
   }
 
1295
 
 
1296
   return needtgenable;
 
1297
}
 
1298
 
 
1299
 
1216
1300
/*
1217
1301
 * Returns GL_FALSE if fallback required.  
1218
1302
 */
1282
1366
      return GL_FALSE;
1283
1367
   }
1284
1368
 
 
1369
/* we CANNOT do mixed mode if the texgen mode requires a plane where the input
 
1370
   is not enabled for texgen, since the planes are concatenated into texmat,
 
1371
   and thus the input will come from texcoord rather than tex gen equation!
 
1372
   Either fallback or just hope that those texcoords aren't really needed...
 
1373
   Assuming the former will cause lots of unnecessary fallbacks, the latter will
 
1374
   generate bogus results sometimes - it's pretty much impossible to really know
 
1375
   when a fallback is needed, depends on texmat and what sort of texture is bound
 
1376
   etc, - for now fallback if we're missing either S or T bits, there's a high
 
1377
   probability we need the texcoords in that case.
 
1378
   That's a lot of work for some obscure texgen mixed mode fixup - why oh why
 
1379
   doesn't the chip just directly accept the plane parameters :-(. */
1285
1380
   switch (mode) {
1286
 
   case GL_OBJECT_LINEAR:
 
1381
   case GL_OBJECT_LINEAR: {
 
1382
      GLuint needtgenable = r200_need_dis_texgen( texUnit->TexGenEnabled,
 
1383
                                texUnit->ObjectPlaneS, texUnit->ObjectPlaneT,
 
1384
                                texUnit->ObjectPlaneR, texUnit->ObjectPlaneQ );
 
1385
      if (needtgenable & (S_BIT | T_BIT)) {
 
1386
         if (R200_DEBUG & DEBUG_FALLBACKS)
 
1387
         fprintf(stderr, "fallback mixed texgen / obj plane, 0x%x\n",
 
1388
                 texUnit->TexGenEnabled);
 
1389
         return GL_FALSE;
 
1390
      }
 
1391
      if (needtgenable & (R_BIT)) {
 
1392
         tgcm &= ~(R200_TEXGEN_COMP_R << (unit * 4));
 
1393
      }
 
1394
      if (needtgenable & (Q_BIT)) {
 
1395
         tgcm &= ~(R200_TEXGEN_COMP_Q << (unit * 4));
 
1396
      }
 
1397
 
1287
1398
      tgi |= R200_TEXGEN_INPUT_OBJ << inputshift;
1288
1399
      set_texgen_matrix( rmesa, unit, 
1289
1400
         (texUnit->TexGenEnabled & S_BIT) ? texUnit->ObjectPlaneS : I,
1290
1401
         (texUnit->TexGenEnabled & T_BIT) ? texUnit->ObjectPlaneT : I + 4,
1291
1402
         (texUnit->TexGenEnabled & R_BIT) ? texUnit->ObjectPlaneR : I + 8,
1292
1403
         (texUnit->TexGenEnabled & Q_BIT) ? texUnit->ObjectPlaneQ : I + 12);
 
1404
      }
1293
1405
      break;
1294
1406
 
1295
 
   case GL_EYE_LINEAR:
 
1407
   case GL_EYE_LINEAR: {
 
1408
      GLuint needtgenable = r200_need_dis_texgen( texUnit->TexGenEnabled,
 
1409
                                texUnit->EyePlaneS, texUnit->EyePlaneT,
 
1410
                                texUnit->EyePlaneR, texUnit->EyePlaneQ );
 
1411
      if (needtgenable & (S_BIT | T_BIT)) {
 
1412
         if (R200_DEBUG & DEBUG_FALLBACKS)
 
1413
         fprintf(stderr, "fallback mixed texgen / eye plane, 0x%x\n",
 
1414
                 texUnit->TexGenEnabled);
 
1415
         return GL_FALSE;
 
1416
      }
 
1417
      if (needtgenable & (R_BIT)) {
 
1418
         tgcm &= ~(R200_TEXGEN_COMP_R << (unit * 4));
 
1419
      }
 
1420
      if (needtgenable & (Q_BIT)) {
 
1421
         tgcm &= ~(R200_TEXGEN_COMP_Q << (unit * 4));
 
1422
      }
1296
1423
      tgi |= R200_TEXGEN_INPUT_EYE << inputshift;
1297
 
      set_texgen_matrix( rmesa, unit, 
 
1424
      set_texgen_matrix( rmesa, unit,
1298
1425
         (texUnit->TexGenEnabled & S_BIT) ? texUnit->EyePlaneS : I,
1299
1426
         (texUnit->TexGenEnabled & T_BIT) ? texUnit->EyePlaneT : I + 4,
1300
1427
         (texUnit->TexGenEnabled & R_BIT) ? texUnit->EyePlaneR : I + 8,
1301
1428
         (texUnit->TexGenEnabled & Q_BIT) ? texUnit->EyePlaneQ : I + 12);
 
1429
      }
1302
1430
      break;
1303
1431
 
1304
1432
   case GL_REFLECTION_MAP_NV:
1305
1433
      rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1306
 
      tgi |= R200_TEXGEN_INPUT_EYE_REFLECT<<inputshift;
1307
 
      set_texgen_matrix( rmesa, unit, 
1308
 
         (texUnit->TexGenEnabled & S_BIT) ? reflect : I,
1309
 
         (texUnit->TexGenEnabled & T_BIT) ? reflect + 4 : I + 4,
1310
 
         (texUnit->TexGenEnabled & R_BIT) ? reflect + 8 : I + 8,
1311
 
         I + 12);
 
1434
      tgi |= R200_TEXGEN_INPUT_EYE_REFLECT << inputshift;
 
1435
      /* pretty weird, must only negate when lighting is enabled? */
 
1436
      if (ctx->Light.Enabled)
 
1437
         set_texgen_matrix( rmesa, unit, 
 
1438
            (texUnit->TexGenEnabled & S_BIT) ? reflect : I,
 
1439
            (texUnit->TexGenEnabled & T_BIT) ? reflect + 4 : I + 4,
 
1440
            (texUnit->TexGenEnabled & R_BIT) ? reflect + 8 : I + 8,
 
1441
            I + 12);
1312
1442
      break;
1313
1443
 
1314
1444
   case GL_NORMAL_MAP_NV: