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

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/i915tex/i830_vtbl.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:
 
1
/**************************************************************************
 
2
 * 
 
3
 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
 
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
 
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:
 
13
 * 
 
14
 * The above copyright notice and this permission notice (including the
 
15
 * next paragraph) shall be included in all copies or substantial portions
 
16
 * of the Software.
 
17
 * 
 
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.
 
25
 * 
 
26
 **************************************************************************/
 
27
 
 
28
 
 
29
#include "i830_context.h"
 
30
#include "i830_reg.h"
 
31
#include "intel_batchbuffer.h"
 
32
#include "intel_regions.h"
 
33
#include "tnl/t_context.h"
 
34
#include "tnl/t_vertex.h"
 
35
 
 
36
#define FILE_DEBUG_FLAG DEBUG_STATE
 
37
 
 
38
static GLboolean i830_check_vertex_size(struct intel_context *intel,
 
39
                                        GLuint expected);
 
40
 
 
41
#define SZ_TO_HW(sz)  ((sz-2)&0x3)
 
42
#define EMIT_SZ(sz)   (EMIT_1F + (sz) - 1)
 
43
#define EMIT_ATTR( ATTR, STYLE, V0 )                                    \
 
44
do {                                                                    \
 
45
   intel->vertex_attrs[intel->vertex_attr_count].attrib = (ATTR);       \
 
46
   intel->vertex_attrs[intel->vertex_attr_count].format = (STYLE);      \
 
47
   intel->vertex_attr_count++;                                          \
 
48
   v0 |= V0;                                                            \
 
49
} while (0)
 
50
 
 
51
#define EMIT_PAD( N )                                                   \
 
52
do {                                                                    \
 
53
   intel->vertex_attrs[intel->vertex_attr_count].attrib = 0;            \
 
54
   intel->vertex_attrs[intel->vertex_attr_count].format = EMIT_PAD;     \
 
55
   intel->vertex_attrs[intel->vertex_attr_count].offset = (N);          \
 
56
   intel->vertex_attr_count++;                                          \
 
57
} while (0)
 
58
 
 
59
 
 
60
#define VRTX_TEX_SET_FMT(n, x)          ((x)<<((n)*2))
 
61
#define TEXBIND_SET(n, x)               ((x)<<((n)*4))
 
62
 
 
63
static void
 
64
i830_render_start(struct intel_context *intel)
 
65
{
 
66
   GLcontext *ctx = &intel->ctx;
 
67
   struct i830_context *i830 = i830_context(ctx);
 
68
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
69
   struct vertex_buffer *VB = &tnl->vb;
 
70
   DECLARE_RENDERINPUTS(index_bitset);
 
71
   GLuint v0 = _3DSTATE_VFT0_CMD;
 
72
   GLuint v2 = _3DSTATE_VFT1_CMD;
 
73
   GLuint mcsb1 = 0;
 
74
 
 
75
   RENDERINPUTS_COPY(index_bitset, tnl->render_inputs_bitset);
 
76
 
 
77
   /* Important:
 
78
    */
 
79
   VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
 
80
   intel->vertex_attr_count = 0;
 
81
 
 
82
   /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
 
83
    * build up a hardware vertex.
 
84
    */
 
85
   if (RENDERINPUTS_TEST_RANGE(index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX)) {
 
86
      EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VFT0_XYZW);
 
87
      intel->coloroffset = 4;
 
88
   }
 
89
   else {
 
90
      EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, VFT0_XYZ);
 
91
      intel->coloroffset = 3;
 
92
   }
 
93
 
 
94
   if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_POINTSIZE)) {
 
95
      EMIT_ATTR(_TNL_ATTRIB_POINTSIZE, EMIT_1F, VFT0_POINT_WIDTH);
 
96
   }
 
97
 
 
98
   EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VFT0_DIFFUSE);
 
99
 
 
100
   intel->specoffset = 0;
 
101
   if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_COLOR1) ||
 
102
       RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_FOG)) {
 
103
      if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_COLOR1)) {
 
104
         intel->specoffset = intel->coloroffset + 1;
 
105
         EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VFT0_SPEC);
 
106
      }
 
107
      else
 
108
         EMIT_PAD(3);
 
109
 
 
110
      if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_FOG))
 
111
         EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, VFT0_SPEC);
 
112
      else
 
113
         EMIT_PAD(1);
 
114
   }
 
115
 
 
116
   if (RENDERINPUTS_TEST_RANGE(index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX)) {
 
117
      int i, count = 0;
 
118
 
 
119
      for (i = 0; i < I830_TEX_UNITS; i++) {
 
120
         if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_TEX(i))) {
 
121
            GLuint sz = VB->TexCoordPtr[i]->size;
 
122
            GLuint emit;
 
123
            GLuint mcs = (i830->state.Tex[i][I830_TEXREG_MCS] &
 
124
                          ~TEXCOORDTYPE_MASK);
 
125
 
 
126
            switch (sz) {
 
127
            case 1:
 
128
            case 2:
 
129
               emit = EMIT_2F;
 
130
               sz = 2;
 
131
               mcs |= TEXCOORDTYPE_CARTESIAN;
 
132
               break;
 
133
            case 3:
 
134
               emit = EMIT_3F;
 
135
               sz = 3;
 
136
               mcs |= TEXCOORDTYPE_VECTOR;
 
137
               break;
 
138
            case 4:
 
139
               emit = EMIT_3F_XYW;
 
140
               sz = 3;
 
141
               mcs |= TEXCOORDTYPE_HOMOGENEOUS;
 
142
               break;
 
143
            default:
 
144
               continue;
 
145
            };
 
146
 
 
147
 
 
148
            EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, emit, 0);
 
149
            v2 |= VRTX_TEX_SET_FMT(count, SZ_TO_HW(sz));
 
150
            mcsb1 |= (count + 8) << (i * 4);
 
151
 
 
152
            if (mcs != i830->state.Tex[i][I830_TEXREG_MCS]) {
 
153
               I830_STATECHANGE(i830, I830_UPLOAD_TEX(i));
 
154
               i830->state.Tex[i][I830_TEXREG_MCS] = mcs;
 
155
            }
 
156
 
 
157
            count++;
 
158
         }
 
159
      }
 
160
 
 
161
      v0 |= VFT0_TEX_COUNT(count);
 
162
   }
 
163
 
 
164
   /* Only need to change the vertex emit code if there has been a
 
165
    * statechange to a new hardware vertex format:
 
166
    */
 
167
   if (v0 != i830->state.Ctx[I830_CTXREG_VF] ||
 
168
       v2 != i830->state.Ctx[I830_CTXREG_VF2] ||
 
169
       mcsb1 != i830->state.Ctx[I830_CTXREG_MCSB1] ||
 
170
       !RENDERINPUTS_EQUAL(index_bitset, i830->last_index_bitset)) {
 
171
      int k;
 
172
 
 
173
      I830_STATECHANGE(i830, I830_UPLOAD_CTX);
 
174
 
 
175
      /* Must do this *after* statechange, so as not to affect
 
176
       * buffered vertices reliant on the old state:
 
177
       */
 
178
      intel->vertex_size =
 
179
         _tnl_install_attrs(ctx,
 
180
                            intel->vertex_attrs,
 
181
                            intel->vertex_attr_count,
 
182
                            intel->ViewportMatrix.m, 0);
 
183
 
 
184
      intel->vertex_size >>= 2;
 
185
 
 
186
      i830->state.Ctx[I830_CTXREG_VF] = v0;
 
187
      i830->state.Ctx[I830_CTXREG_VF2] = v2;
 
188
      i830->state.Ctx[I830_CTXREG_MCSB1] = mcsb1;
 
189
      RENDERINPUTS_COPY(i830->last_index_bitset, index_bitset);
 
190
 
 
191
      k = i830_check_vertex_size(intel, intel->vertex_size);
 
192
      assert(k);
 
193
   }
 
194
}
 
195
 
 
196
static void
 
197
i830_reduced_primitive_state(struct intel_context *intel, GLenum rprim)
 
198
{
 
199
   struct i830_context *i830 = i830_context(&intel->ctx);
 
200
   GLuint st1 = i830->state.Stipple[I830_STPREG_ST1];
 
201
 
 
202
   st1 &= ~ST1_ENABLE;
 
203
 
 
204
   switch (rprim) {
 
205
   case GL_TRIANGLES:
 
206
      if (intel->ctx.Polygon.StippleFlag && intel->hw_stipple)
 
207
         st1 |= ST1_ENABLE;
 
208
      break;
 
209
   case GL_LINES:
 
210
   case GL_POINTS:
 
211
   default:
 
212
      break;
 
213
   }
 
214
 
 
215
   i830->intel.reduced_primitive = rprim;
 
216
 
 
217
   if (st1 != i830->state.Stipple[I830_STPREG_ST1]) {
 
218
      INTEL_FIREVERTICES(intel);
 
219
 
 
220
      I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE);
 
221
      i830->state.Stipple[I830_STPREG_ST1] = st1;
 
222
   }
 
223
}
 
224
 
 
225
/* Pull apart the vertex format registers and figure out how large a
 
226
 * vertex is supposed to be. 
 
227
 */
 
228
static GLboolean
 
229
i830_check_vertex_size(struct intel_context *intel, GLuint expected)
 
230
{
 
231
   struct i830_context *i830 = i830_context(&intel->ctx);
 
232
   int vft0 = i830->current->Ctx[I830_CTXREG_VF];
 
233
   int vft1 = i830->current->Ctx[I830_CTXREG_VF2];
 
234
   int nrtex = (vft0 & VFT0_TEX_COUNT_MASK) >> VFT0_TEX_COUNT_SHIFT;
 
235
   int i, sz = 0;
 
236
 
 
237
   switch (vft0 & VFT0_XYZW_MASK) {
 
238
   case VFT0_XY:
 
239
      sz = 2;
 
240
      break;
 
241
   case VFT0_XYZ:
 
242
      sz = 3;
 
243
      break;
 
244
   case VFT0_XYW:
 
245
      sz = 3;
 
246
      break;
 
247
   case VFT0_XYZW:
 
248
      sz = 4;
 
249
      break;
 
250
   default:
 
251
      fprintf(stderr, "no xyzw specified\n");
 
252
      return 0;
 
253
   }
 
254
 
 
255
   if (vft0 & VFT0_SPEC)
 
256
      sz++;
 
257
   if (vft0 & VFT0_DIFFUSE)
 
258
      sz++;
 
259
   if (vft0 & VFT0_DEPTH_OFFSET)
 
260
      sz++;
 
261
   if (vft0 & VFT0_POINT_WIDTH)
 
262
      sz++;
 
263
 
 
264
   for (i = 0; i < nrtex; i++) {
 
265
      switch (vft1 & VFT1_TEX0_MASK) {
 
266
      case TEXCOORDFMT_2D:
 
267
         sz += 2;
 
268
         break;
 
269
      case TEXCOORDFMT_3D:
 
270
         sz += 3;
 
271
         break;
 
272
      case TEXCOORDFMT_4D:
 
273
         sz += 4;
 
274
         break;
 
275
      case TEXCOORDFMT_1D:
 
276
         sz += 1;
 
277
         break;
 
278
      }
 
279
      vft1 >>= VFT1_TEX1_SHIFT;
 
280
   }
 
281
 
 
282
   if (sz != expected)
 
283
      fprintf(stderr, "vertex size mismatch %d/%d\n", sz, expected);
 
284
 
 
285
   return sz == expected;
 
286
}
 
287
 
 
288
static void
 
289
i830_emit_invarient_state(struct intel_context *intel)
 
290
{
 
291
   BATCH_LOCALS;
 
292
 
 
293
   BEGIN_BATCH(40, 0);
 
294
 
 
295
   OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
 
296
   OUT_BATCH(0);
 
297
 
 
298
   OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD);
 
299
   OUT_BATCH(0);
 
300
 
 
301
   OUT_BATCH(_3DSTATE_DFLT_Z_CMD);
 
302
   OUT_BATCH(0);
 
303
 
 
304
   OUT_BATCH(_3DSTATE_FOG_MODE_CMD);
 
305
   OUT_BATCH(FOGFUNC_ENABLE |
 
306
             FOG_LINEAR_CONST | FOGSRC_INDEX_Z | ENABLE_FOG_DENSITY);
 
307
   OUT_BATCH(0);
 
308
   OUT_BATCH(0);
 
309
 
 
310
 
 
311
   OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD |
 
312
             MAP_UNIT(0) |
 
313
             DISABLE_TEX_STREAM_BUMP |
 
314
             ENABLE_TEX_STREAM_COORD_SET |
 
315
             TEX_STREAM_COORD_SET(0) |
 
316
             ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(0));
 
317
   OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD |
 
318
             MAP_UNIT(1) |
 
319
             DISABLE_TEX_STREAM_BUMP |
 
320
             ENABLE_TEX_STREAM_COORD_SET |
 
321
             TEX_STREAM_COORD_SET(1) |
 
322
             ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(1));
 
323
   OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD |
 
324
             MAP_UNIT(2) |
 
325
             DISABLE_TEX_STREAM_BUMP |
 
326
             ENABLE_TEX_STREAM_COORD_SET |
 
327
             TEX_STREAM_COORD_SET(2) |
 
328
             ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(2));
 
329
   OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD |
 
330
             MAP_UNIT(3) |
 
331
             DISABLE_TEX_STREAM_BUMP |
 
332
             ENABLE_TEX_STREAM_COORD_SET |
 
333
             TEX_STREAM_COORD_SET(3) |
 
334
             ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(3));
 
335
 
 
336
   OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM);
 
337
   OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(0));
 
338
   OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM);
 
339
   OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(1));
 
340
   OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM);
 
341
   OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(2));
 
342
   OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM);
 
343
   OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3));
 
344
 
 
345
   OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
 
346
             ENABLE_POINT_RASTER_RULE |
 
347
             OGL_POINT_RASTER_RULE |
 
348
             ENABLE_LINE_STRIP_PROVOKE_VRTX |
 
349
             ENABLE_TRI_FAN_PROVOKE_VRTX |
 
350
             ENABLE_TRI_STRIP_PROVOKE_VRTX |
 
351
             LINE_STRIP_PROVOKE_VRTX(1) |
 
352
             TRI_FAN_PROVOKE_VRTX(2) | TRI_STRIP_PROVOKE_VRTX(2));
 
353
 
 
354
   OUT_BATCH(_3DSTATE_VERTEX_TRANSFORM);
 
355
   OUT_BATCH(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE);
 
356
 
 
357
   OUT_BATCH(_3DSTATE_W_STATE_CMD);
 
358
   OUT_BATCH(MAGIC_W_STATE_DWORD1);
 
359
   OUT_BATCH(0x3f800000 /* 1.0 in IEEE float */ );
 
360
 
 
361
 
 
362
   OUT_BATCH(_3DSTATE_COLOR_FACTOR_CMD);
 
363
   OUT_BATCH(0x80808080);       /* .5 required in alpha for GL_DOT3_RGBA_EXT */
 
364
 
 
365
   ADVANCE_BATCH();
 
366
}
 
367
 
 
368
 
 
369
#define emit( intel, state, size )                      \
 
370
do {                                                    \
 
371
   int k;                                               \
 
372
   BEGIN_BATCH(size / sizeof(GLuint), 0);               \
 
373
   for (k = 0 ; k < size / sizeof(GLuint) ; k++) {      \
 
374
      if (0) _mesa_printf("  0x%08x\n", state[k]);              \
 
375
      OUT_BATCH(state[k]);                              \
 
376
   }                                                    \
 
377
   ADVANCE_BATCH();                                     \
 
378
} while (0)
 
379
 
 
380
static GLuint
 
381
get_state_size(struct i830_hw_state *state)
 
382
{
 
383
   GLuint dirty = state->active & ~state->emitted;
 
384
   GLuint sz = 0;
 
385
   GLuint i;
 
386
 
 
387
   if (dirty & I830_UPLOAD_INVARIENT)
 
388
      sz += 40 * sizeof(int);
 
389
 
 
390
   if (dirty & I830_UPLOAD_CTX)
 
391
      sz += sizeof(state->Ctx);
 
392
 
 
393
   if (dirty & I830_UPLOAD_BUFFERS)
 
394
      sz += sizeof(state->Buffer);
 
395
 
 
396
   if (dirty & I830_UPLOAD_STIPPLE)
 
397
      sz += sizeof(state->Stipple);
 
398
 
 
399
   for (i = 0; i < I830_TEX_UNITS; i++) {
 
400
      if ((dirty & I830_UPLOAD_TEX(i)))
 
401
         sz += sizeof(state->Tex[i]);
 
402
 
 
403
      if (dirty & I830_UPLOAD_TEXBLEND(i))
 
404
         sz += state->TexBlendWordsUsed[i] * 4;
 
405
   }
 
406
 
 
407
   return sz;
 
408
}
 
409
 
 
410
 
 
411
/* Push the state into the sarea and/or texture memory.
 
412
 */
 
413
static void
 
414
i830_emit_state(struct intel_context *intel)
 
415
{
 
416
   struct i830_context *i830 = i830_context(&intel->ctx);
 
417
   struct i830_hw_state *state = i830->current;
 
418
   int i;
 
419
   GLuint dirty;
 
420
   BATCH_LOCALS;
 
421
 
 
422
   /* We don't hold the lock at this point, so want to make sure that
 
423
    * there won't be a buffer wrap.  
 
424
    *
 
425
    * It might be better to talk about explicit places where
 
426
    * scheduling is allowed, rather than assume that it is whenever a
 
427
    * batchbuffer fills up.
 
428
    */
 
429
   intel_batchbuffer_require_space(intel->batch, get_state_size(state), 0);
 
430
 
 
431
   /* Do this here as we may have flushed the batchbuffer above,
 
432
    * causing more state to be dirty!
 
433
    */
 
434
   dirty = state->active & ~state->emitted;
 
435
 
 
436
   if (dirty & I830_UPLOAD_INVARIENT) {
 
437
      DBG("I830_UPLOAD_INVARIENT:\n");
 
438
      i830_emit_invarient_state(intel);
 
439
   }
 
440
 
 
441
   if (dirty & I830_UPLOAD_CTX) {
 
442
      DBG("I830_UPLOAD_CTX:\n");
 
443
      emit(i830, state->Ctx, sizeof(state->Ctx));
 
444
 
 
445
   }
 
446
 
 
447
   if (dirty & I830_UPLOAD_BUFFERS) {
 
448
      DBG("I830_UPLOAD_BUFFERS:\n");
 
449
      BEGIN_BATCH(I830_DEST_SETUP_SIZE + 2, 0);
 
450
      OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR0]);
 
451
      OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR1]);
 
452
      OUT_RELOC(state->draw_region->buffer,
 
453
                DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
 
454
                DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
 
455
                state->draw_region->draw_offset);
 
456
 
 
457
      if (state->depth_region) {
 
458
         OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR0]);
 
459
         OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR1]);
 
460
         OUT_RELOC(state->depth_region->buffer,
 
461
                   DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
 
462
                   DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
 
463
                   state->depth_region->draw_offset);
 
464
      }
 
465
 
 
466
      OUT_BATCH(state->Buffer[I830_DESTREG_DV0]);
 
467
      OUT_BATCH(state->Buffer[I830_DESTREG_DV1]);
 
468
      OUT_BATCH(state->Buffer[I830_DESTREG_SENABLE]);
 
469
      OUT_BATCH(state->Buffer[I830_DESTREG_SR0]);
 
470
      OUT_BATCH(state->Buffer[I830_DESTREG_SR1]);
 
471
      OUT_BATCH(state->Buffer[I830_DESTREG_SR2]);
 
472
      ADVANCE_BATCH();
 
473
   }
 
474
   
 
475
   if (dirty & I830_UPLOAD_STIPPLE) {
 
476
      DBG("I830_UPLOAD_STIPPLE:\n");
 
477
      emit(i830, state->Stipple, sizeof(state->Stipple));
 
478
   }
 
479
 
 
480
   for (i = 0; i < I830_TEX_UNITS; i++) {
 
481
      if ((dirty & I830_UPLOAD_TEX(i))) {
 
482
         DBG("I830_UPLOAD_TEX(%d):\n", i);
 
483
 
 
484
         BEGIN_BATCH(I830_TEX_SETUP_SIZE + 1, 0);
 
485
         OUT_BATCH(state->Tex[i][I830_TEXREG_TM0LI]);
 
486
 
 
487
         if (state->tex_buffer[i]) {
 
488
            OUT_RELOC(state->tex_buffer[i],
 
489
                      DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
 
490
                      DRM_BO_MASK_MEM | DRM_BO_FLAG_READ,
 
491
                      state->tex_offset[i] | TM0S0_USE_FENCE);
 
492
         }
 
493
         else {
 
494
            assert(i == 0);
 
495
            assert(state == &i830->meta);
 
496
            OUT_BATCH(0);
 
497
         }
 
498
 
 
499
         OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S1]);
 
500
         OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S2]);
 
501
         OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S3]);
 
502
         OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S4]);
 
503
         OUT_BATCH(state->Tex[i][I830_TEXREG_MCS]);
 
504
         OUT_BATCH(state->Tex[i][I830_TEXREG_CUBE]);
 
505
      }
 
506
 
 
507
      if (dirty & I830_UPLOAD_TEXBLEND(i)) {
 
508
         DBG("I830_UPLOAD_TEXBLEND(%d): %d words\n", i,
 
509
             state->TexBlendWordsUsed[i]);
 
510
         emit(i830, state->TexBlend[i], state->TexBlendWordsUsed[i] * 4);
 
511
      }
 
512
   }
 
513
 
 
514
   state->emitted |= dirty;
 
515
}
 
516
 
 
517
static void
 
518
i830_destroy_context(struct intel_context *intel)
 
519
{
 
520
   _tnl_free_vertices(&intel->ctx);
 
521
}
 
522
 
 
523
 
 
524
void
 
525
i830_state_draw_region(struct intel_context *intel,
 
526
                       struct i830_hw_state *state,
 
527
                       struct intel_region *color_region,
 
528
                       struct intel_region *depth_region)
 
529
{
 
530
   struct i830_context *i830 = i830_context(&intel->ctx);
 
531
   GLuint value;
 
532
 
 
533
   ASSERT(state == &i830->state || state == &i830->meta);
 
534
 
 
535
   if (state->draw_region != color_region) {
 
536
      intel_region_release(&state->draw_region);
 
537
      intel_region_reference(&state->draw_region, color_region);
 
538
   }
 
539
   if (state->depth_region != depth_region) {
 
540
      intel_region_release(&state->depth_region);
 
541
      intel_region_reference(&state->depth_region, depth_region);
 
542
   }
 
543
 
 
544
   /*
 
545
    * Set stride/cpp values
 
546
    */
 
547
   if (color_region) {
 
548
      state->Buffer[I830_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
 
549
      state->Buffer[I830_DESTREG_CBUFADDR1] =
 
550
         (BUF_3D_ID_COLOR_BACK |
 
551
          BUF_3D_PITCH(color_region->pitch * color_region->cpp) |
 
552
          BUF_3D_USE_FENCE);
 
553
   }
 
554
 
 
555
   if (depth_region) {
 
556
      state->Buffer[I830_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
 
557
      state->Buffer[I830_DESTREG_DBUFADDR1] =
 
558
         (BUF_3D_ID_DEPTH |
 
559
          BUF_3D_PITCH(depth_region->pitch * depth_region->cpp) |
 
560
          BUF_3D_USE_FENCE);
 
561
   }
 
562
 
 
563
   /*
 
564
    * Compute/set I830_DESTREG_DV1 value
 
565
    */
 
566
   value = (DSTORG_HORT_BIAS(0x8) |     /* .5 */
 
567
            DSTORG_VERT_BIAS(0x8) | DEPTH_IS_Z);    /* .5 */
 
568
            
 
569
   if (color_region && color_region->cpp == 4) {
 
570
      value |= DV_PF_8888;
 
571
   }
 
572
   else {
 
573
      value |= DV_PF_565;
 
574
   }
 
575
   if (depth_region && depth_region->cpp == 4) {
 
576
      value |= DEPTH_FRMT_24_FIXED_8_OTHER;
 
577
   }
 
578
   else {
 
579
      value |= DEPTH_FRMT_16_FIXED;
 
580
   }
 
581
   state->Buffer[I830_DESTREG_DV1] = value;
 
582
 
 
583
   I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS);
 
584
 
 
585
 
 
586
}
 
587
 
 
588
 
 
589
static void
 
590
i830_set_draw_region(struct intel_context *intel,
 
591
                     struct intel_region *color_region,
 
592
                     struct intel_region *depth_region)
 
593
{
 
594
   struct i830_context *i830 = i830_context(&intel->ctx);
 
595
   i830_state_draw_region(intel, &i830->state, color_region, depth_region);
 
596
}
 
597
 
 
598
#if 0
 
599
static void
 
600
i830_update_color_z_regions(intelContextPtr intel,
 
601
                            const intelRegion * colorRegion,
 
602
                            const intelRegion * depthRegion)
 
603
{
 
604
   i830ContextPtr i830 = I830_CONTEXT(intel);
 
605
 
 
606
   i830->state.Buffer[I830_DESTREG_CBUFADDR1] =
 
607
      (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(colorRegion->pitch) |
 
608
       BUF_3D_USE_FENCE);
 
609
   i830->state.Buffer[I830_DESTREG_CBUFADDR2] = colorRegion->offset;
 
610
 
 
611
   i830->state.Buffer[I830_DESTREG_DBUFADDR1] =
 
612
      (BUF_3D_ID_DEPTH | BUF_3D_PITCH(depthRegion->pitch) | BUF_3D_USE_FENCE);
 
613
   i830->state.Buffer[I830_DESTREG_DBUFADDR2] = depthRegion->offset;
 
614
}
 
615
#endif
 
616
 
 
617
 
 
618
/* This isn't really handled at the moment.
 
619
 */
 
620
static void
 
621
i830_lost_hardware(struct intel_context *intel)
 
622
{
 
623
   struct i830_context *i830 = i830_context(&intel->ctx);
 
624
   i830->state.emitted = 0;
 
625
}
 
626
 
 
627
 
 
628
 
 
629
static GLuint
 
630
i830_flush_cmd(void)
 
631
{
 
632
   return MI_FLUSH | FLUSH_MAP_CACHE;
 
633
}
 
634
 
 
635
 
 
636
static void 
 
637
i830_assert_not_dirty( struct intel_context *intel )
 
638
{
 
639
   struct i830_context *i830 = i830_context(&intel->ctx);
 
640
   struct i830_hw_state *state = i830->current;
 
641
   GLuint dirty = state->active & ~state->emitted;
 
642
   assert(!dirty);
 
643
}
 
644
 
 
645
 
 
646
void
 
647
i830InitVtbl(struct i830_context *i830)
 
648
{
 
649
   i830->intel.vtbl.check_vertex_size = i830_check_vertex_size;
 
650
   i830->intel.vtbl.destroy = i830_destroy_context;
 
651
   i830->intel.vtbl.emit_state = i830_emit_state;
 
652
   i830->intel.vtbl.lost_hardware = i830_lost_hardware;
 
653
   i830->intel.vtbl.reduced_primitive_state = i830_reduced_primitive_state;
 
654
   i830->intel.vtbl.set_draw_region = i830_set_draw_region;
 
655
   i830->intel.vtbl.update_texture_state = i830UpdateTextureState;
 
656
   i830->intel.vtbl.flush_cmd = i830_flush_cmd;
 
657
   i830->intel.vtbl.render_start = i830_render_start;
 
658
   i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty;
 
659
}