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