1 /**************************************************************************
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
36 #include "tnl/t_context.h"
37 #include "tnl/t_vertex.h"
39 #include "intel_batchbuffer.h"
42 #include "i915_context.h"
44 static void i915_render_start( intelContextPtr intel
)
46 GLcontext
*ctx
= &intel
->ctx
;
47 i915ContextPtr i915
= I915_CONTEXT(intel
);
49 if (ctx
->FragmentProgram
._Active
)
50 i915ValidateFragmentProgram( i915
);
52 i915ValidateTextureProgram( i915
);
56 static void i915_reduced_primitive_state( intelContextPtr intel
,
59 i915ContextPtr i915
= I915_CONTEXT(intel
);
60 GLuint st1
= i915
->state
.Stipple
[I915_STPREG_ST1
];
66 if (intel
->ctx
.Polygon
.StippleFlag
&&
76 i915
->intel
.reduced_primitive
= rprim
;
78 if (st1
!= i915
->state
.Stipple
[I915_STPREG_ST1
]) {
79 I915_STATECHANGE(i915
, I915_UPLOAD_STIPPLE
);
80 i915
->state
.Stipple
[I915_STPREG_ST1
] = st1
;
85 /* Pull apart the vertex format registers and figure out how large a
86 * vertex is supposed to be.
88 static GLboolean
i915_check_vertex_size( intelContextPtr intel
,
91 i915ContextPtr i915
= I915_CONTEXT(intel
);
92 int lis2
= i915
->current
->Ctx
[I915_CTXREG_LIS2
];
93 int lis4
= i915
->current
->Ctx
[I915_CTXREG_LIS4
];
96 switch (lis4
& S4_VFMT_XYZW_MASK
) {
97 case S4_VFMT_XY
: sz
= 2; break;
98 case S4_VFMT_XYZ
: sz
= 3; break;
99 case S4_VFMT_XYW
: sz
= 3; break;
100 case S4_VFMT_XYZW
: sz
= 4; break;
102 fprintf(stderr
, "no xyzw specified\n");
106 if (lis4
& S4_VFMT_SPEC_FOG
) sz
++;
107 if (lis4
& S4_VFMT_COLOR
) sz
++;
108 if (lis4
& S4_VFMT_DEPTH_OFFSET
) sz
++;
109 if (lis4
& S4_VFMT_POINT_WIDTH
) sz
++;
110 if (lis4
& S4_VFMT_FOG_PARAM
) sz
++;
112 for (i
= 0 ; i
< 8 ; i
++) {
113 switch (lis2
& S2_TEXCOORD_FMT0_MASK
) {
114 case TEXCOORDFMT_2D
: sz
+= 2; break;
115 case TEXCOORDFMT_3D
: sz
+= 3; break;
116 case TEXCOORDFMT_4D
: sz
+= 4; break;
117 case TEXCOORDFMT_1D
: sz
+= 1; break;
118 case TEXCOORDFMT_2D_16
: sz
+= 1; break;
119 case TEXCOORDFMT_4D_16
: sz
+= 2; break;
120 case TEXCOORDFMT_NOT_PRESENT
: break;
122 fprintf(stderr
, "bad texcoord fmt %d\n", i
);
125 lis2
>>= S2_TEXCOORD_FMT1_SHIFT
;
129 fprintf(stderr
, "vertex size mismatch %d/%d\n", sz
, expected
);
131 return sz
== expected
;
135 static void i915_emit_invarient_state( intelContextPtr intel
)
141 OUT_BATCH(_3DSTATE_AA_CMD
|
142 AA_LINE_ECAAR_WIDTH_ENABLE
|
143 AA_LINE_ECAAR_WIDTH_1_0
|
144 AA_LINE_REGION_WIDTH_ENABLE
|
145 AA_LINE_REGION_WIDTH_1_0
);
147 OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD
);
150 OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD
);
153 OUT_BATCH(_3DSTATE_DFLT_Z_CMD
);
156 /* Don't support texture crossbar yet */
157 OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS
|
167 OUT_BATCH(_3DSTATE_RASTER_RULES_CMD
|
168 ENABLE_POINT_RASTER_RULE
|
169 OGL_POINT_RASTER_RULE
|
170 ENABLE_LINE_STRIP_PROVOKE_VRTX
|
171 ENABLE_TRI_FAN_PROVOKE_VRTX
|
172 LINE_STRIP_PROVOKE_VRTX(1) |
173 TRI_FAN_PROVOKE_VRTX(2) |
174 ENABLE_TEXKILL_3D_4D
|
177 /* Need to initialize this to zero.
179 OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1
|
185 OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD
|
186 DISABLE_SCISSOR_RECT
);
188 OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD
);
192 OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE
);
194 OUT_BATCH(_3DSTATE_LOAD_INDIRECT
| 0); /* disable indirect state */
198 /* Don't support twosided stencil yet */
199 OUT_BATCH(_3DSTATE_BACKFACE_STENCIL_OPS
|
200 BFO_ENABLE_STENCIL_TWO_SIDE
|
207 #define emit( intel, state, size ) \
210 BEGIN_BATCH( (size) / sizeof(GLuint)); \
211 for (k = 0 ; k < (size) / sizeof(GLuint) ; k++) \
212 OUT_BATCH((state)[k]); \
217 /* Push the state into the sarea and/or texture memory.
219 static void i915_emit_state( intelContextPtr intel
)
221 i915ContextPtr i915
= I915_CONTEXT(intel
);
222 struct i915_hw_state
*state
= i915
->current
;
227 /* More to workaround the multitex hang - if one texture unit state
228 * is modified, emit all texture units.
230 dirty
= state
->active
& ~state
->emitted
;
231 if (dirty
& I915_UPLOAD_TEX_ALL
)
232 state
->emitted
&= ~I915_UPLOAD_TEX_ALL
;
233 dirty
= state
->active
& ~state
->emitted
;
237 fprintf(stderr
, "%s dirty: %x\n", __FUNCTION__
, dirty
);
239 if (dirty
& I915_UPLOAD_CTX
) {
240 if (VERBOSE
) fprintf(stderr
, "I915_UPLOAD_CTX:\n");
241 emit( i915
, state
->Ctx
, sizeof(state
->Ctx
) );
244 if (dirty
& I915_UPLOAD_BUFFERS
) {
245 if (VERBOSE
) fprintf(stderr
, "I915_UPLOAD_BUFFERS:\n");
246 emit( i915
, state
->Buffer
, sizeof(state
->Buffer
) );
249 if (dirty
& I915_UPLOAD_STIPPLE
) {
250 if (VERBOSE
) fprintf(stderr
, "I915_UPLOAD_STIPPLE:\n");
251 emit( i915
, state
->Stipple
, sizeof(state
->Stipple
) );
254 if (dirty
& I915_UPLOAD_FOG
) {
255 if (VERBOSE
) fprintf(stderr
, "I915_UPLOAD_FOG:\n");
256 emit( i915
, state
->Fog
, sizeof(state
->Fog
) );
259 /* Combine all the dirty texture state into a single command to
260 * avoid lockups on I915 hardware.
262 if (dirty
& I915_UPLOAD_TEX_ALL
) {
265 for (i
= 0; i
< I915_TEX_UNITS
; i
++)
266 if (dirty
& I915_UPLOAD_TEX(i
))
270 OUT_BATCH(_3DSTATE_MAP_STATE
| (3*nr
));
271 OUT_BATCH((dirty
& I915_UPLOAD_TEX_ALL
) >> I915_UPLOAD_TEX_0_SHIFT
);
272 for (i
= 0 ; i
< I915_TEX_UNITS
; i
++)
273 if (dirty
& I915_UPLOAD_TEX(i
)) {
274 OUT_BATCH(state
->Tex
[i
][I915_TEXREG_MS2
]);
275 OUT_BATCH(state
->Tex
[i
][I915_TEXREG_MS3
]);
276 OUT_BATCH(state
->Tex
[i
][I915_TEXREG_MS4
]);
281 OUT_BATCH(_3DSTATE_SAMPLER_STATE
| (3*nr
));
282 OUT_BATCH((dirty
& I915_UPLOAD_TEX_ALL
) >> I915_UPLOAD_TEX_0_SHIFT
);
283 for (i
= 0 ; i
< I915_TEX_UNITS
; i
++)
284 if (dirty
& I915_UPLOAD_TEX(i
)) {
285 OUT_BATCH(state
->Tex
[i
][I915_TEXREG_SS2
]);
286 OUT_BATCH(state
->Tex
[i
][I915_TEXREG_SS3
]);
287 OUT_BATCH(state
->Tex
[i
][I915_TEXREG_SS4
]);
292 if (dirty
& I915_UPLOAD_CONSTANTS
) {
293 if (VERBOSE
) fprintf(stderr
, "I915_UPLOAD_CONSTANTS:\n");
294 emit( i915
, state
->Constant
, state
->ConstantSize
* sizeof(GLuint
) );
297 if (dirty
& I915_UPLOAD_PROGRAM
) {
298 if (VERBOSE
) fprintf(stderr
, "I915_UPLOAD_PROGRAM:\n");
300 assert((state
->Program
[0] & 0x1ff)+2 == state
->ProgramSize
);
302 emit( i915
, state
->Program
, state
->ProgramSize
* sizeof(GLuint
) );
304 i915_disassemble_program( state
->Program
, state
->ProgramSize
);
307 state
->emitted
|= dirty
;
310 static void i915_destroy_context( intelContextPtr intel
)
312 _tnl_free_vertices(&intel
->ctx
);
315 static void i915_set_draw_offset( intelContextPtr intel
, int offset
)
317 i915ContextPtr i915
= I915_CONTEXT(intel
);
318 I915_STATECHANGE( i915
, I915_UPLOAD_BUFFERS
);
319 i915
->state
.Buffer
[I915_DESTREG_CBUFADDR2
] = offset
;
322 static void i915_lost_hardware( intelContextPtr intel
)
324 I915_CONTEXT(intel
)->state
.emitted
= 0;
327 static void i915_emit_flush( intelContextPtr intel
)
332 OUT_BATCH( MI_FLUSH
| FLUSH_MAP_CACHE
| FLUSH_RENDER_CACHE
);
338 void i915InitVtbl( i915ContextPtr i915
)
340 i915
->intel
.vtbl
.alloc_tex_obj
= i915AllocTexObj
;
341 i915
->intel
.vtbl
.check_vertex_size
= i915_check_vertex_size
;
342 i915
->intel
.vtbl
.clear_with_tris
= i915ClearWithTris
;
343 i915
->intel
.vtbl
.destroy
= i915_destroy_context
;
344 i915
->intel
.vtbl
.emit_invarient_state
= i915_emit_invarient_state
;
345 i915
->intel
.vtbl
.emit_state
= i915_emit_state
;
346 i915
->intel
.vtbl
.lost_hardware
= i915_lost_hardware
;
347 i915
->intel
.vtbl
.reduced_primitive_state
= i915_reduced_primitive_state
;
348 i915
->intel
.vtbl
.render_start
= i915_render_start
;
349 i915
->intel
.vtbl
.set_draw_offset
= i915_set_draw_offset
;
350 i915
->intel
.vtbl
.update_texture_state
= i915UpdateTextureState
;
351 i915
->intel
.vtbl
.emit_flush
= i915_emit_flush
;