mesa: added "main/" prefix to includes, remove some -I paths from Makefile.template
[mesa.git] / src / mesa / drivers / dri / i915 / i830_metaops.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 "main/glheader.h"
29 #include "main/enums.h"
30 #include "main/mtypes.h"
31 #include "main/macros.h"
32 #include "utils.h"
33
34 #include "intel_screen.h"
35 #include "intel_batchbuffer.h"
36 #include "intel_regions.h"
37
38 #include "i830_context.h"
39 #include "i830_reg.h"
40
41 /* A large amount of state doesn't need to be uploaded.
42 */
43 #define ACTIVE (I830_UPLOAD_INVARIENT | \
44 I830_UPLOAD_CTX | \
45 I830_UPLOAD_BUFFERS | \
46 I830_UPLOAD_STIPPLE | \
47 I830_UPLOAD_TEXBLEND(0) | \
48 I830_UPLOAD_TEX(0))
49
50
51 #define SET_STATE( i830, STATE ) \
52 do { \
53 i830->current->emitted &= ~ACTIVE; \
54 i830->current = &i830->STATE; \
55 i830->current->emitted &= ~ACTIVE; \
56 } while (0)
57
58
59 static void
60 set_no_stencil_write(struct intel_context *intel)
61 {
62 struct i830_context *i830 = i830_context(&intel->ctx);
63
64 /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE )
65 */
66 i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST;
67 i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE;
68 i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST;
69 i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE;
70
71 i830->meta.emitted &= ~I830_UPLOAD_CTX;
72 }
73
74 static void
75 set_no_depth_write(struct intel_context *intel)
76 {
77 struct i830_context *i830 = i830_context(&intel->ctx);
78
79 /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE )
80 */
81 i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK;
82 i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK;
83 i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST;
84 i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE;
85
86 i830->meta.emitted &= ~I830_UPLOAD_CTX;
87 }
88
89 /* Set depth unit to replace.
90 */
91 static void
92 set_depth_replace(struct intel_context *intel)
93 {
94 struct i830_context *i830 = i830_context(&intel->ctx);
95
96 /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE )
97 * ctx->Driver.DepthMask( ctx, GL_TRUE )
98 */
99 i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK;
100 i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK;
101 i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST;
102 i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE;
103
104 /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS )
105 */
106 i830->meta.Ctx[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK;
107 i830->meta.Ctx[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC |
108 DEPTH_TEST_FUNC
109 (COMPAREFUNC_ALWAYS));
110
111 i830->meta.emitted &= ~I830_UPLOAD_CTX;
112 }
113
114
115 /* Set stencil unit to replace always with the reference value.
116 */
117 static void
118 set_stencil_replace(struct intel_context *intel,
119 GLuint s_mask, GLuint s_clear)
120 {
121 struct i830_context *i830 = i830_context(&intel->ctx);
122
123 /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE )
124 */
125 i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST;
126 i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE;
127
128 /* ctx->Driver.StencilMask( ctx, s_mask )
129 */
130 i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK;
131 i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK |
132 STENCIL_WRITE_MASK((s_mask &
133 0xff)));
134
135 /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE )
136 */
137 i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK);
138 i830->meta.Ctx[I830_CTXREG_STENCILTST] |=
139 (ENABLE_STENCIL_PARMS |
140 STENCIL_FAIL_OP(STENCILOP_REPLACE) |
141 STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE) |
142 STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE));
143
144 /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_clear, ~0 )
145 */
146 i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK;
147 i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK |
148 STENCIL_TEST_MASK(0xff));
149
150 i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK |
151 ENABLE_STENCIL_TEST_FUNC_MASK);
152 i830->meta.Ctx[I830_CTXREG_STENCILTST] |=
153 (ENABLE_STENCIL_REF_VALUE |
154 ENABLE_STENCIL_TEST_FUNC |
155 STENCIL_REF_VALUE((s_clear & 0xff)) |
156 STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS));
157
158
159
160 i830->meta.emitted &= ~I830_UPLOAD_CTX;
161 }
162
163
164 static void
165 set_color_mask(struct intel_context *intel, GLboolean state)
166 {
167 struct i830_context *i830 = i830_context(&intel->ctx);
168
169 const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) |
170 (1 << WRITEMASK_GREEN_SHIFT) |
171 (1 << WRITEMASK_BLUE_SHIFT) |
172 (1 << WRITEMASK_ALPHA_SHIFT));
173
174 i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~mask;
175
176 if (state) {
177 i830->meta.Ctx[I830_CTXREG_ENABLES_2] |=
178 (i830->state.Ctx[I830_CTXREG_ENABLES_2] & mask);
179 }
180
181 i830->meta.emitted &= ~I830_UPLOAD_CTX;
182 }
183
184 /* Installs a one-stage passthrough texture blend pipeline. Is there
185 * more that can be done to turn off texturing?
186 */
187 static void
188 set_no_texture(struct intel_context *intel)
189 {
190 struct i830_context *i830 = i830_context(&intel->ctx);
191 static const struct gl_tex_env_combine_state comb = {
192 GL_NONE, GL_NONE,
193 {GL_TEXTURE, 0, 0,}, {GL_TEXTURE, 0, 0,},
194 {GL_SRC_COLOR, 0, 0}, {GL_SRC_ALPHA, 0, 0},
195 0, 0, 0, 0
196 };
197
198 i830->meta.TexBlendWordsUsed[0] =
199 i830SetTexEnvCombine(i830, &comb, 0, TEXBLENDARG_TEXEL0,
200 i830->meta.TexBlend[0], NULL);
201
202 i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE;
203 i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0);
204 }
205
206 /* Set up a single element blend stage for 'replace' texturing with no
207 * funny ops.
208 */
209 static void
210 set_texture_blend_replace(struct intel_context *intel)
211 {
212 struct i830_context *i830 = i830_context(&intel->ctx);
213 static const struct gl_tex_env_combine_state comb = {
214 GL_REPLACE, GL_REPLACE,
215 {GL_TEXTURE, GL_TEXTURE, GL_TEXTURE,}, {GL_TEXTURE, GL_TEXTURE,
216 GL_TEXTURE,},
217 {GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR}, {GL_SRC_ALPHA, GL_SRC_ALPHA,
218 GL_SRC_ALPHA},
219 0, 0, 1, 1
220 };
221
222 i830->meta.TexBlendWordsUsed[0] =
223 i830SetTexEnvCombine(i830, &comb, 0, TEXBLENDARG_TEXEL0,
224 i830->meta.TexBlend[0], NULL);
225
226 i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE;
227 i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0);
228
229 /* fprintf(stderr, "%s: TexBlendWordsUsed[0]: %d\n", */
230 /* __FUNCTION__, i830->meta.TexBlendWordsUsed[0]); */
231 }
232
233
234
235 /* Set up an arbitary piece of memory as a rectangular texture
236 * (including the front or back buffer).
237 */
238 static GLboolean
239 set_tex_rect_source(struct intel_context *intel,
240 dri_bo *buffer,
241 GLuint offset,
242 GLuint pitch, GLuint height, GLenum format, GLenum type)
243 {
244 struct i830_context *i830 = i830_context(&intel->ctx);
245 GLuint *setup = i830->meta.Tex[0];
246 GLint numLevels = 1;
247 GLuint textureFormat;
248 GLuint cpp;
249
250 /* A full implementation of this would do the upload through
251 * glTexImage2d, and get all the conversion operations at that
252 * point. We are restricted, but still at least have access to the
253 * fragment program swizzle.
254 */
255 switch (format) {
256 case GL_BGRA:
257 switch (type) {
258 case GL_UNSIGNED_INT_8_8_8_8_REV:
259 case GL_UNSIGNED_BYTE:
260 textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888);
261 cpp = 4;
262 break;
263 default:
264 return GL_FALSE;
265 }
266 break;
267 case GL_RGBA:
268 switch (type) {
269 case GL_UNSIGNED_INT_8_8_8_8_REV:
270 case GL_UNSIGNED_BYTE:
271 textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888);
272 cpp = 4;
273 break;
274 default:
275 return GL_FALSE;
276 }
277 break;
278 case GL_BGR:
279 switch (type) {
280 case GL_UNSIGNED_SHORT_5_6_5_REV:
281 textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565);
282 cpp = 2;
283 break;
284 default:
285 return GL_FALSE;
286 }
287 break;
288 case GL_RGB:
289 switch (type) {
290 case GL_UNSIGNED_SHORT_5_6_5:
291 textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565);
292 cpp = 2;
293 break;
294 default:
295 return GL_FALSE;
296 }
297 break;
298
299 default:
300 return GL_FALSE;
301 }
302
303 i830->meta.tex_buffer[0] = buffer;
304 i830->meta.tex_offset[0] = offset;
305
306 setup[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
307 (LOAD_TEXTURE_MAP0 << 0) | 4);
308 setup[I830_TEXREG_TM0S1] = (((height - 1) << TM0S1_HEIGHT_SHIFT) |
309 ((pitch - 1) << TM0S1_WIDTH_SHIFT) |
310 textureFormat);
311 setup[I830_TEXREG_TM0S2] =
312 (((((pitch * cpp) / 4) -
313 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK);
314
315 setup[I830_TEXREG_TM0S3] =
316 ((((numLevels -
317 1) *
318 4) << TM0S3_MIN_MIP_SHIFT) | (FILTER_NEAREST <<
319 TM0S3_MIN_FILTER_SHIFT) |
320 (MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT) | (FILTER_NEAREST <<
321 TM0S3_MAG_FILTER_SHIFT));
322
323 setup[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(0));
324
325 setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD |
326 MAP_UNIT(0) |
327 ENABLE_TEXCOORD_PARAMS |
328 TEXCOORDS_ARE_IN_TEXELUNITS |
329 TEXCOORDTYPE_CARTESIAN |
330 ENABLE_ADDR_V_CNTL |
331 TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) |
332 ENABLE_ADDR_U_CNTL |
333 TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP));
334
335 i830->meta.emitted &= ~I830_UPLOAD_TEX(0);
336 return GL_TRUE;
337 }
338
339
340 static void
341 set_vertex_format(struct intel_context *intel)
342 {
343 struct i830_context *i830 = i830_context(&intel->ctx);
344 i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD |
345 VFT0_TEX_COUNT(1) |
346 VFT0_DIFFUSE | VFT0_XYZ);
347 i830->meta.Ctx[I830_CTXREG_VF2] = (_3DSTATE_VFT1_CMD |
348 VFT1_TEX0_FMT(TEXCOORDFMT_2D) |
349 VFT1_TEX1_FMT(TEXCOORDFMT_2D) |
350 VFT1_TEX2_FMT(TEXCOORDFMT_2D) |
351 VFT1_TEX3_FMT(TEXCOORDFMT_2D));
352 i830->meta.emitted &= ~I830_UPLOAD_CTX;
353 }
354
355
356 static void
357 meta_import_pixel_state(struct intel_context *intel)
358 {
359 struct i830_context *i830 = i830_context(&intel->ctx);
360
361 i830->meta.Ctx[I830_CTXREG_STATE1] = i830->state.Ctx[I830_CTXREG_STATE1];
362 i830->meta.Ctx[I830_CTXREG_STATE2] = i830->state.Ctx[I830_CTXREG_STATE2];
363 i830->meta.Ctx[I830_CTXREG_STATE3] = i830->state.Ctx[I830_CTXREG_STATE3];
364 i830->meta.Ctx[I830_CTXREG_STATE4] = i830->state.Ctx[I830_CTXREG_STATE4];
365 i830->meta.Ctx[I830_CTXREG_STATE5] = i830->state.Ctx[I830_CTXREG_STATE5];
366 i830->meta.Ctx[I830_CTXREG_IALPHAB] = i830->state.Ctx[I830_CTXREG_IALPHAB];
367 i830->meta.Ctx[I830_CTXREG_STENCILTST] =
368 i830->state.Ctx[I830_CTXREG_STENCILTST];
369 i830->meta.Ctx[I830_CTXREG_ENABLES_1] =
370 i830->state.Ctx[I830_CTXREG_ENABLES_1];
371 i830->meta.Ctx[I830_CTXREG_ENABLES_2] =
372 i830->state.Ctx[I830_CTXREG_ENABLES_2];
373 i830->meta.Ctx[I830_CTXREG_AA] = i830->state.Ctx[I830_CTXREG_AA];
374 i830->meta.Ctx[I830_CTXREG_FOGCOLOR] =
375 i830->state.Ctx[I830_CTXREG_FOGCOLOR];
376 i830->meta.Ctx[I830_CTXREG_BLENDCOLOR0] =
377 i830->state.Ctx[I830_CTXREG_BLENDCOLOR0];
378 i830->meta.Ctx[I830_CTXREG_BLENDCOLOR1] =
379 i830->state.Ctx[I830_CTXREG_BLENDCOLOR1];
380 i830->meta.Ctx[I830_CTXREG_MCSB0] = i830->state.Ctx[I830_CTXREG_MCSB0];
381 i830->meta.Ctx[I830_CTXREG_MCSB1] = i830->state.Ctx[I830_CTXREG_MCSB1];
382
383
384 i830->meta.Ctx[I830_CTXREG_STATE3] &= ~CULLMODE_MASK;
385 i830->meta.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE;
386 i830->meta.emitted &= ~I830_UPLOAD_CTX;
387
388
389 i830->meta.Buffer[I830_DESTREG_SENABLE] =
390 i830->state.Buffer[I830_DESTREG_SENABLE];
391 i830->meta.Buffer[I830_DESTREG_SR1] = i830->state.Buffer[I830_DESTREG_SR1];
392 i830->meta.Buffer[I830_DESTREG_SR2] = i830->state.Buffer[I830_DESTREG_SR2];
393 i830->meta.emitted &= ~I830_UPLOAD_BUFFERS;
394 }
395
396
397
398 /* Select between front and back draw buffers.
399 */
400 static void
401 meta_draw_region(struct intel_context *intel,
402 struct intel_region *color_region,
403 struct intel_region *depth_region)
404 {
405 struct i830_context *i830 = i830_context(&intel->ctx);
406
407 i830_state_draw_region(intel, &i830->meta, color_region, depth_region);
408 }
409
410
411 /* Operations where the 3D engine is decoupled temporarily from the
412 * current GL state and used for other purposes than simply rendering
413 * incoming triangles.
414 */
415 static void
416 install_meta_state(struct intel_context *intel)
417 {
418 struct i830_context *i830 = i830_context(&intel->ctx);
419 memcpy(&i830->meta, &i830->initial, sizeof(i830->meta));
420
421 i830->meta.active = ACTIVE;
422 i830->meta.emitted = 0;
423
424 SET_STATE(i830, meta);
425 set_vertex_format(intel);
426 set_no_texture(intel);
427 }
428
429 static void
430 leave_meta_state(struct intel_context *intel)
431 {
432 struct i830_context *i830 = i830_context(&intel->ctx);
433 intel_region_release(&i830->meta.draw_region);
434 intel_region_release(&i830->meta.depth_region);
435 /* intel_region_release(intel, &i830->meta.tex_region[0]); */
436 SET_STATE(i830, state);
437 }
438
439
440
441 void
442 i830InitMetaFuncs(struct i830_context *i830)
443 {
444 i830->intel.vtbl.install_meta_state = install_meta_state;
445 i830->intel.vtbl.leave_meta_state = leave_meta_state;
446 i830->intel.vtbl.meta_no_depth_write = set_no_depth_write;
447 i830->intel.vtbl.meta_no_stencil_write = set_no_stencil_write;
448 i830->intel.vtbl.meta_stencil_replace = set_stencil_replace;
449 i830->intel.vtbl.meta_depth_replace = set_depth_replace;
450 i830->intel.vtbl.meta_color_mask = set_color_mask;
451 i830->intel.vtbl.meta_no_texture = set_no_texture;
452 i830->intel.vtbl.meta_texture_blend_replace = set_texture_blend_replace;
453 i830->intel.vtbl.meta_tex_rect_source = set_tex_rect_source;
454 i830->intel.vtbl.meta_draw_region = meta_draw_region;
455 i830->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state;
456 }