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
.Enabled
&& ctx
->FragmentProgram
.Current
)
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
++;
111 for (i
= 0 ; i
< 8 ; i
++) {
112 switch (lis2
& S2_TEXCOORD_FMT0_MASK
) {
113 case TEXCOORDFMT_2D
: sz
+= 2; break;
114 case TEXCOORDFMT_3D
: sz
+= 3; break;
115 case TEXCOORDFMT_4D
: sz
+= 4; break;
116 case TEXCOORDFMT_1D
: sz
+= 1; break;
117 case TEXCOORDFMT_2D_16
: sz
+= 1; break;
118 case TEXCOORDFMT_4D_16
: sz
+= 2; break;
119 case TEXCOORDFMT_NOT_PRESENT
: break;
121 fprintf(stderr
, "bad texcoord fmt %d\n", i
);
124 lis2
>>= S2_TEXCOORD_FMT1_SHIFT
;
128 fprintf(stderr
, "vertex size mismatch %d/%d\n", sz
, expected
);
130 return sz
== expected
;
134 static void i915_emit_invarient_state( intelContextPtr intel
)
140 OUT_BATCH(_3DSTATE_AA_CMD
|
141 AA_LINE_ECAAR_WIDTH_ENABLE
|
142 AA_LINE_ECAAR_WIDTH_1_0
|
143 AA_LINE_REGION_WIDTH_ENABLE
|
144 AA_LINE_REGION_WIDTH_1_0
);
146 OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD
);
149 OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD
);
152 OUT_BATCH(_3DSTATE_DFLT_Z_CMD
);
155 /* Don't support texture crossbar yet */
156 OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS
|
166 OUT_BATCH(_3DSTATE_RASTER_RULES_CMD
|
167 ENABLE_POINT_RASTER_RULE
|
168 OGL_POINT_RASTER_RULE
|
169 ENABLE_LINE_STRIP_PROVOKE_VRTX
|
170 ENABLE_TRI_FAN_PROVOKE_VRTX
|
171 LINE_STRIP_PROVOKE_VRTX(1) |
172 TRI_FAN_PROVOKE_VRTX(2) |
173 ENABLE_TEXKILL_3D_4D
|
176 /* Need to initialize this to zero.
178 OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1
|
184 OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD
|
185 DISABLE_SCISSOR_RECT
);
187 OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD
);
191 OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE
);
193 OUT_BATCH(_3DSTATE_LOAD_INDIRECT
| 0); /* disable indirect state */
197 /* Don't support twosided stencil yet */
198 OUT_BATCH(_3DSTATE_BACKFACE_STENCIL_OPS
|
199 BFO_ENABLE_STENCIL_TWO_SIDE
|
206 #define emit( intel, state, size ) \
209 BEGIN_BATCH( (size) / sizeof(GLuint)); \
210 for (k = 0 ; k < (size) / sizeof(GLuint) ; k++) \
211 OUT_BATCH((state)[k]); \
216 /* Push the state into the sarea and/or texture memory.
218 static void i915_emit_state( intelContextPtr intel
)
220 i915ContextPtr i915
= I915_CONTEXT(intel
);
221 struct i915_hw_state
*state
= i915
->current
;
226 /* More to workaround the multitex hang - if one texture unit state
227 * is modified, emit all texture units.
229 dirty
= state
->active
& ~state
->emitted
;
230 if (dirty
& I915_UPLOAD_TEX_ALL
)
231 state
->emitted
&= ~I915_UPLOAD_TEX_ALL
;
232 dirty
= state
->active
& ~state
->emitted
;
236 fprintf(stderr
, "%s dirty: %x\n", __FUNCTION__
, dirty
);
238 if (dirty
& I915_UPLOAD_CTX
) {
239 if (VERBOSE
) fprintf(stderr
, "I915_UPLOAD_CTX:\n");
240 emit( i915
, state
->Ctx
, sizeof(state
->Ctx
) );
243 if (dirty
& I915_UPLOAD_BUFFERS
) {
244 if (VERBOSE
) fprintf(stderr
, "I915_UPLOAD_BUFFERS:\n");
245 emit( i915
, state
->Buffer
, sizeof(state
->Buffer
) );
248 if (dirty
& I915_UPLOAD_STIPPLE
) {
249 if (VERBOSE
) fprintf(stderr
, "I915_UPLOAD_STIPPLE:\n");
250 emit( i915
, state
->Stipple
, sizeof(state
->Stipple
) );
253 if (dirty
& I915_UPLOAD_FOG
) {
254 if (VERBOSE
) fprintf(stderr
, "I915_UPLOAD_FOG:\n");
255 emit( i915
, state
->Fog
, sizeof(state
->Fog
) );
258 /* Combine all the dirty texture state into a single command to
259 * avoid lockups on I915 hardware.
261 if (dirty
& I915_UPLOAD_TEX_ALL
) {
264 for (i
= 0; i
< I915_TEX_UNITS
; i
++)
265 if (dirty
& I915_UPLOAD_TEX(i
))
269 OUT_BATCH(_3DSTATE_MAP_STATE
| (3*nr
));
270 OUT_BATCH((dirty
& I915_UPLOAD_TEX_ALL
) >> I915_UPLOAD_TEX_0_SHIFT
);
271 for (i
= 0 ; i
< I915_TEX_UNITS
; i
++)
272 if (dirty
& I915_UPLOAD_TEX(i
)) {
273 OUT_BATCH(state
->Tex
[i
][I915_TEXREG_MS2
]);
274 OUT_BATCH(state
->Tex
[i
][I915_TEXREG_MS3
]);
275 OUT_BATCH(state
->Tex
[i
][I915_TEXREG_MS4
]);
280 OUT_BATCH(_3DSTATE_SAMPLER_STATE
| (3*nr
));
281 OUT_BATCH((dirty
& I915_UPLOAD_TEX_ALL
) >> I915_UPLOAD_TEX_0_SHIFT
);
282 for (i
= 0 ; i
< I915_TEX_UNITS
; i
++)
283 if (dirty
& I915_UPLOAD_TEX(i
)) {
284 OUT_BATCH(state
->Tex
[i
][I915_TEXREG_SS2
]);
285 OUT_BATCH(state
->Tex
[i
][I915_TEXREG_SS3
]);
286 OUT_BATCH(state
->Tex
[i
][I915_TEXREG_SS4
]);
291 if (dirty
& I915_UPLOAD_CONSTANTS
) {
292 if (VERBOSE
) fprintf(stderr
, "I915_UPLOAD_CONSTANTS:\n");
293 emit( i915
, state
->Constant
, state
->ConstantSize
* sizeof(GLuint
) );
296 if (dirty
& I915_UPLOAD_PROGRAM
) {
297 if (VERBOSE
) fprintf(stderr
, "I915_UPLOAD_PROGRAM:\n");
299 assert((state
->Program
[0] & 0x1ff)+2 == state
->ProgramSize
);
301 emit( i915
, state
->Program
, state
->ProgramSize
* sizeof(GLuint
) );
303 i915_disassemble_program( state
->Program
, state
->ProgramSize
);
306 state
->emitted
|= dirty
;
309 static void i915_destroy_context( intelContextPtr intel
)
311 _tnl_free_vertices(&intel
->ctx
);
314 static void i915_set_draw_offset( intelContextPtr intel
, int offset
)
316 i915ContextPtr i915
= I915_CONTEXT(intel
);
317 I915_STATECHANGE( i915
, I915_UPLOAD_BUFFERS
);
318 i915
->state
.Buffer
[I915_DESTREG_CBUFADDR2
] = offset
;
321 static void i915_lost_hardware( intelContextPtr intel
)
323 I915_CONTEXT(intel
)->state
.emitted
= 0;
326 static void i915_emit_flush( intelContextPtr intel
)
331 OUT_BATCH( MI_FLUSH
| FLUSH_MAP_CACHE
| FLUSH_RENDER_CACHE
);
337 void i915InitVtbl( i915ContextPtr i915
)
339 i915
->intel
.vtbl
.alloc_tex_obj
= i915AllocTexObj
;
340 i915
->intel
.vtbl
.check_vertex_size
= i915_check_vertex_size
;
341 i915
->intel
.vtbl
.clear_with_tris
= i915ClearWithTris
;
342 i915
->intel
.vtbl
.destroy
= i915_destroy_context
;
343 i915
->intel
.vtbl
.emit_invarient_state
= i915_emit_invarient_state
;
344 i915
->intel
.vtbl
.emit_state
= i915_emit_state
;
345 i915
->intel
.vtbl
.lost_hardware
= i915_lost_hardware
;
346 i915
->intel
.vtbl
.reduced_primitive_state
= i915_reduced_primitive_state
;
347 i915
->intel
.vtbl
.render_start
= i915_render_start
;
348 i915
->intel
.vtbl
.set_draw_offset
= i915_set_draw_offset
;
349 i915
->intel
.vtbl
.update_texture_state
= i915UpdateTextureState
;
350 i915
->intel
.vtbl
.emit_flush
= i915_emit_flush
;