2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4 develop this 3D driver.
6 Permission is hereby granted, free of charge, to any person obtaining
7 a 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, sublicense, 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
16 portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **********************************************************************/
29 * Keith Whitwell <keith@tungstengraphics.com>
30 * frame buffer texture by Gary Wong <gtw@gnu.org>
41 #include "shader/arbprogparse.h"
43 #include "intel_screen.h"
44 #include "intel_batchbuffer.h"
45 #include "intel_regions.h"
47 #include "brw_context.h"
48 #include "brw_defines.h"
50 #include "brw_fallback.h"
52 #define INIT(brw, STRUCT, ATTRIB) \
54 brw->attribs.ATTRIB = &ctx->ATTRIB; \
57 #define DUP(brw, STRUCT, ATTRIB) \
59 brw->metaops.attribs.ATTRIB = MALLOC_STRUCT(STRUCT); \
60 memcpy(brw->metaops.attribs.ATTRIB, \
61 brw->attribs.ATTRIB, \
62 sizeof(struct STRUCT)); \
66 #define INSTALL(brw, ATTRIB, STATE) \
68 brw->attribs.ATTRIB = brw->metaops.attribs.ATTRIB; \
69 brw->state.dirty.mesa |= STATE; \
72 #define RESTORE(brw, ATTRIB, STATE) \
74 brw->attribs.ATTRIB = &brw->intel.ctx.ATTRIB; \
75 brw->state.dirty.mesa |= STATE; \
78 static void init_attribs( struct brw_context
*brw
)
80 DUP(brw
, gl_colorbuffer_attrib
, Color
);
81 DUP(brw
, gl_depthbuffer_attrib
, Depth
);
82 DUP(brw
, gl_fog_attrib
, Fog
);
83 DUP(brw
, gl_hint_attrib
, Hint
);
84 DUP(brw
, gl_light_attrib
, Light
);
85 DUP(brw
, gl_line_attrib
, Line
);
86 DUP(brw
, gl_point_attrib
, Point
);
87 DUP(brw
, gl_polygon_attrib
, Polygon
);
88 DUP(brw
, gl_scissor_attrib
, Scissor
);
89 DUP(brw
, gl_stencil_attrib
, Stencil
);
90 DUP(brw
, gl_texture_attrib
, Texture
);
91 DUP(brw
, gl_transform_attrib
, Transform
);
92 DUP(brw
, gl_viewport_attrib
, Viewport
);
93 DUP(brw
, gl_vertex_program_state
, VertexProgram
);
94 DUP(brw
, gl_fragment_program_state
, FragmentProgram
);
97 static void install_attribs( struct brw_context
*brw
)
99 INSTALL(brw
, Color
, _NEW_COLOR
);
100 INSTALL(brw
, Depth
, _NEW_DEPTH
);
101 INSTALL(brw
, Fog
, _NEW_FOG
);
102 INSTALL(brw
, Hint
, _NEW_HINT
);
103 INSTALL(brw
, Light
, _NEW_LIGHT
);
104 INSTALL(brw
, Line
, _NEW_LINE
);
105 INSTALL(brw
, Point
, _NEW_POINT
);
106 INSTALL(brw
, Polygon
, _NEW_POLYGON
);
107 INSTALL(brw
, Scissor
, _NEW_SCISSOR
);
108 INSTALL(brw
, Stencil
, _NEW_STENCIL
);
109 INSTALL(brw
, Texture
, _NEW_TEXTURE
);
110 INSTALL(brw
, Transform
, _NEW_TRANSFORM
);
111 INSTALL(brw
, Viewport
, _NEW_VIEWPORT
);
112 INSTALL(brw
, VertexProgram
, _NEW_PROGRAM
);
113 INSTALL(brw
, FragmentProgram
, _NEW_PROGRAM
);
116 static void restore_attribs( struct brw_context
*brw
)
118 RESTORE(brw
, Color
, _NEW_COLOR
);
119 RESTORE(brw
, Depth
, _NEW_DEPTH
);
120 RESTORE(brw
, Fog
, _NEW_FOG
);
121 RESTORE(brw
, Hint
, _NEW_HINT
);
122 RESTORE(brw
, Light
, _NEW_LIGHT
);
123 RESTORE(brw
, Line
, _NEW_LINE
);
124 RESTORE(brw
, Point
, _NEW_POINT
);
125 RESTORE(brw
, Polygon
, _NEW_POLYGON
);
126 RESTORE(brw
, Scissor
, _NEW_SCISSOR
);
127 RESTORE(brw
, Stencil
, _NEW_STENCIL
);
128 RESTORE(brw
, Texture
, _NEW_TEXTURE
);
129 RESTORE(brw
, Transform
, _NEW_TRANSFORM
);
130 RESTORE(brw
, Viewport
, _NEW_VIEWPORT
);
131 RESTORE(brw
, VertexProgram
, _NEW_PROGRAM
);
132 RESTORE(brw
, FragmentProgram
, _NEW_PROGRAM
);
136 static const char *vp_prog
=
138 "MOV result.color, vertex.color;\n"
139 "MOV result.position, vertex.position;\n"
142 static const char *fp_prog
=
144 "MOV result.color, fragment.color;\n"
147 static const char *fp_tex_prog
=
150 "ADD a, fragment.position, program.local[0];\n"
151 "MUL a, a, program.local[1];\n"
152 "TEX result.color, a, texture[0], 2D;\n"
153 "MOV result.depth.z, fragment.position;\n"
156 /* Derived values of importance:
158 * FragmentProgram->_Current
159 * VertexProgram->_Enabled
160 * brw->vertex_program
161 * DrawBuffer->_ColorDrawBufferMask[0]
164 * More if drawpixels-through-texture is added.
166 static void init_metaops_state( struct brw_context
*brw
)
168 GLcontext
*ctx
= &brw
->intel
.ctx
;
170 brw
->metaops
.vbo
= ctx
->Driver
.NewBufferObject(ctx
, 1, GL_ARRAY_BUFFER_ARB
);
172 ctx
->Driver
.BufferData(ctx
,
179 brw
->metaops
.fp
= (struct gl_fragment_program
*)
180 ctx
->Driver
.NewProgram(ctx
, GL_FRAGMENT_PROGRAM_ARB
, 1 );
182 brw
->metaops
.fp_tex
= (struct gl_fragment_program
*)
183 ctx
->Driver
.NewProgram(ctx
, GL_FRAGMENT_PROGRAM_ARB
, 1 );
185 brw
->metaops
.vp
= (struct gl_vertex_program
*)
186 ctx
->Driver
.NewProgram(ctx
, GL_VERTEX_PROGRAM_ARB
, 1 );
188 _mesa_parse_arb_fragment_program(ctx
, GL_FRAGMENT_PROGRAM_ARB
,
189 fp_prog
, strlen(fp_prog
),
192 _mesa_parse_arb_fragment_program(ctx
, GL_FRAGMENT_PROGRAM_ARB
,
193 fp_tex_prog
, strlen(fp_tex_prog
),
194 brw
->metaops
.fp_tex
);
196 _mesa_parse_arb_vertex_program(ctx
, GL_VERTEX_PROGRAM_ARB
,
197 vp_prog
, strlen(vp_prog
),
200 brw
->metaops
.attribs
.VertexProgram
->Current
= brw
->metaops
.vp
;
201 brw
->metaops
.attribs
.VertexProgram
->_Enabled
= GL_TRUE
;
203 brw
->metaops
.attribs
.FragmentProgram
->_Current
= brw
->metaops
.fp
;
206 static void meta_flat_shade( struct intel_context
*intel
)
208 struct brw_context
*brw
= brw_context(&intel
->ctx
);
210 brw
->metaops
.attribs
.Light
->ShadeModel
= GL_FLAT
;
211 brw
->state
.dirty
.mesa
|= _NEW_LIGHT
;
215 static void meta_no_stencil_write( struct intel_context
*intel
)
217 struct brw_context
*brw
= brw_context(&intel
->ctx
);
219 brw
->metaops
.attribs
.Stencil
->Enabled
= GL_FALSE
;
220 brw
->metaops
.attribs
.Stencil
->WriteMask
[0] = GL_FALSE
;
221 brw
->state
.dirty
.mesa
|= _NEW_STENCIL
;
224 static void meta_no_depth_write( struct intel_context
*intel
)
226 struct brw_context
*brw
= brw_context(&intel
->ctx
);
228 brw
->metaops
.attribs
.Depth
->Test
= GL_FALSE
;
229 brw
->metaops
.attribs
.Depth
->Mask
= GL_FALSE
;
230 brw
->state
.dirty
.mesa
|= _NEW_DEPTH
;
234 static void meta_depth_replace( struct intel_context
*intel
)
236 struct brw_context
*brw
= brw_context(&intel
->ctx
);
238 /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_TRUE )
239 * ctx->Driver.DepthMask( ctx, GL_TRUE )
241 brw
->metaops
.attribs
.Depth
->Test
= GL_TRUE
;
242 brw
->metaops
.attribs
.Depth
->Mask
= GL_TRUE
;
243 brw
->state
.dirty
.mesa
|= _NEW_DEPTH
;
245 /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS )
247 brw
->metaops
.attribs
.Depth
->Func
= GL_ALWAYS
;
249 brw
->state
.dirty
.mesa
|= _NEW_DEPTH
;
253 static void meta_stencil_replace( struct intel_context
*intel
,
257 struct brw_context
*brw
= brw_context(&intel
->ctx
);
259 brw
->metaops
.attribs
.Stencil
->Enabled
= GL_TRUE
;
260 brw
->metaops
.attribs
.Stencil
->WriteMask
[0] = s_mask
;
261 brw
->metaops
.attribs
.Stencil
->ValueMask
[0] = 0xff;
262 brw
->metaops
.attribs
.Stencil
->Ref
[0] = s_clear
;
263 brw
->metaops
.attribs
.Stencil
->Function
[0] = GL_ALWAYS
;
264 brw
->metaops
.attribs
.Stencil
->FailFunc
[0] = GL_REPLACE
;
265 brw
->metaops
.attribs
.Stencil
->ZPassFunc
[0] = GL_REPLACE
;
266 brw
->metaops
.attribs
.Stencil
->ZFailFunc
[0] = GL_REPLACE
;
267 brw
->state
.dirty
.mesa
|= _NEW_STENCIL
;
271 static void meta_color_mask( struct intel_context
*intel
, GLboolean state
)
273 struct brw_context
*brw
= brw_context(&intel
->ctx
);
276 COPY_4V(brw
->metaops
.attribs
.Color
->ColorMask
,
277 brw
->intel
.ctx
.Color
.ColorMask
);
279 ASSIGN_4V(brw
->metaops
.attribs
.Color
->ColorMask
, 0, 0, 0, 0);
281 brw
->state
.dirty
.mesa
|= _NEW_COLOR
;
284 static void meta_no_texture( struct intel_context
*intel
)
286 struct brw_context
*brw
= brw_context(&intel
->ctx
);
288 brw
->metaops
.attribs
.FragmentProgram
->_Current
= brw
->metaops
.fp
;
290 brw
->metaops
.attribs
.Texture
->CurrentUnit
= 0;
291 brw
->metaops
.attribs
.Texture
->_EnabledUnits
= 0;
292 brw
->metaops
.attribs
.Texture
->_EnabledCoordUnits
= 0;
293 brw
->metaops
.attribs
.Texture
->Unit
[ 0 ].Enabled
= 0;
294 brw
->metaops
.attribs
.Texture
->Unit
[ 0 ]._ReallyEnabled
= 0;
296 brw
->state
.dirty
.mesa
|= _NEW_TEXTURE
| _NEW_PROGRAM
;
299 static void meta_texture_blend_replace(struct intel_context
*intel
)
301 struct brw_context
*brw
= brw_context(&intel
->ctx
);
303 brw
->metaops
.attribs
.Texture
->CurrentUnit
= 0;
304 brw
->metaops
.attribs
.Texture
->_EnabledUnits
= 1;
305 brw
->metaops
.attribs
.Texture
->_EnabledCoordUnits
= 1;
306 brw
->metaops
.attribs
.Texture
->Unit
[ 0 ].Enabled
= TEXTURE_2D_BIT
;
307 brw
->metaops
.attribs
.Texture
->Unit
[ 0 ]._ReallyEnabled
= TEXTURE_2D_BIT
;
308 brw
->metaops
.attribs
.Texture
->Unit
[ 0 ].Current2D
=
309 intel
->frame_buffer_texobj
;
310 brw
->metaops
.attribs
.Texture
->Unit
[ 0 ]._Current
=
311 intel
->frame_buffer_texobj
;
313 brw
->state
.dirty
.mesa
|= _NEW_TEXTURE
| _NEW_PROGRAM
;
316 static void meta_import_pixel_state(struct intel_context
*intel
)
318 struct brw_context
*brw
= brw_context(&intel
->ctx
);
320 RESTORE(brw
, Color
, _NEW_COLOR
);
321 RESTORE(brw
, Depth
, _NEW_DEPTH
);
322 RESTORE(brw
, Fog
, _NEW_FOG
);
323 RESTORE(brw
, Scissor
, _NEW_SCISSOR
);
324 RESTORE(brw
, Stencil
, _NEW_STENCIL
);
325 RESTORE(brw
, Texture
, _NEW_TEXTURE
);
326 RESTORE(brw
, FragmentProgram
, _NEW_PROGRAM
);
329 static void meta_frame_buffer_texture( struct intel_context
*intel
,
330 GLint xoff
, GLint yoff
)
332 struct brw_context
*brw
= brw_context(&intel
->ctx
);
333 struct intel_region
*region
= intel_drawbuf_region( intel
);
335 INSTALL(brw
, FragmentProgram
, _NEW_PROGRAM
);
337 brw
->metaops
.attribs
.FragmentProgram
->_Current
= brw
->metaops
.fp_tex
;
338 /* This is unfortunate, but seems to be necessary, since later on we
339 will end up calling _mesa_load_state_parameters to lookup the
340 local params (below), and that will want to look in ctx.FragmentProgram
341 instead of brw->attribs.FragmentProgram. */
342 intel
->ctx
.FragmentProgram
.Current
= brw
->metaops
.fp_tex
;
344 brw
->metaops
.fp_tex
->Base
.LocalParams
[ 0 ][ 0 ] = xoff
;
345 brw
->metaops
.fp_tex
->Base
.LocalParams
[ 0 ][ 1 ] = yoff
;
346 brw
->metaops
.fp_tex
->Base
.LocalParams
[ 0 ][ 2 ] = 0.0;
347 brw
->metaops
.fp_tex
->Base
.LocalParams
[ 0 ][ 3 ] = 0.0;
348 brw
->metaops
.fp_tex
->Base
.LocalParams
[ 1 ][ 0 ] =
350 brw
->metaops
.fp_tex
->Base
.LocalParams
[ 1 ][ 1 ] =
351 -1.0 / region
->height
;
352 brw
->metaops
.fp_tex
->Base
.LocalParams
[ 1 ][ 2 ] = 0.0;
353 brw
->metaops
.fp_tex
->Base
.LocalParams
[ 1 ][ 3 ] = 1.0;
355 brw
->state
.dirty
.mesa
|= _NEW_PROGRAM
;
359 static void meta_draw_region( struct intel_context
*intel
,
360 struct intel_region
*draw_region
,
361 struct intel_region
*depth_region
)
363 struct brw_context
*brw
= brw_context(&intel
->ctx
);
365 if (!brw
->metaops
.saved_draw_region
) {
366 brw
->metaops
.saved_draw_region
= brw
->state
.draw_region
;
367 brw
->metaops
.saved_depth_region
= brw
->state
.depth_region
;
370 brw
->state
.draw_region
= draw_region
;
371 brw
->state
.depth_region
= depth_region
;
373 brw
->state
.dirty
.mesa
|= _NEW_BUFFERS
;
377 static void meta_draw_quad(struct intel_context
*intel
,
378 GLfloat x0
, GLfloat x1
,
379 GLfloat y0
, GLfloat y1
,
381 GLubyte red
, GLubyte green
,
382 GLubyte blue
, GLubyte alpha
,
383 GLfloat s0
, GLfloat s1
,
384 GLfloat t0
, GLfloat t1
)
386 GLcontext
*ctx
= &intel
->ctx
;
387 struct brw_context
*brw
= brw_context(&intel
->ctx
);
388 struct gl_client_array pos_array
;
389 struct gl_client_array color_array
;
390 struct gl_client_array
*attribs
[VERT_ATTRIB_MAX
];
391 struct _mesa_prim prim
[1];
395 ctx
->Driver
.BufferData(ctx
,
397 sizeof(pos
) + sizeof(color
),
419 ctx
->Driver
.BufferSubData(ctx
,
431 ctx
->Driver
.BufferSubData(ctx
,
438 /* Ignoring texture coords.
441 memset(attribs
, 0, VERT_ATTRIB_MAX
* sizeof(*attribs
));
443 attribs
[VERT_ATTRIB_POS
] = &pos_array
;
444 attribs
[VERT_ATTRIB_POS
]->Ptr
= 0;
445 attribs
[VERT_ATTRIB_POS
]->Type
= GL_FLOAT
;
446 attribs
[VERT_ATTRIB_POS
]->Enabled
= 1;
447 attribs
[VERT_ATTRIB_POS
]->Size
= 3;
448 attribs
[VERT_ATTRIB_POS
]->StrideB
= 3 * sizeof(GLfloat
);
449 attribs
[VERT_ATTRIB_POS
]->Stride
= 3 * sizeof(GLfloat
);
450 attribs
[VERT_ATTRIB_POS
]->_MaxElement
= 4;
451 attribs
[VERT_ATTRIB_POS
]->Normalized
= 0;
452 attribs
[VERT_ATTRIB_POS
]->BufferObj
= brw
->metaops
.vbo
;
454 attribs
[VERT_ATTRIB_COLOR0
] = &color_array
;
455 attribs
[VERT_ATTRIB_COLOR0
]->Ptr
= (const GLubyte
*)sizeof(pos
);
456 attribs
[VERT_ATTRIB_COLOR0
]->Type
= GL_UNSIGNED_BYTE
;
457 attribs
[VERT_ATTRIB_COLOR0
]->Enabled
= 1;
458 attribs
[VERT_ATTRIB_COLOR0
]->Size
= 4;
459 attribs
[VERT_ATTRIB_COLOR0
]->StrideB
= 0;
460 attribs
[VERT_ATTRIB_COLOR0
]->Stride
= 0;
461 attribs
[VERT_ATTRIB_COLOR0
]->_MaxElement
= 1;
462 attribs
[VERT_ATTRIB_COLOR0
]->Normalized
= 1;
463 attribs
[VERT_ATTRIB_COLOR0
]->BufferObj
= brw
->metaops
.vbo
;
465 /* Just ignoring texture coordinates for now.
468 memset(prim
, 0, sizeof(*prim
));
470 prim
[0].mode
= GL_TRIANGLE_FAN
;
478 brw_draw_prims(&brw
->intel
.ctx
,
479 (const struct gl_client_array
**)attribs
,
487 static void install_meta_state( struct intel_context
*intel
)
489 GLcontext
*ctx
= &intel
->ctx
;
490 struct brw_context
*brw
= brw_context(ctx
);
492 if (!brw
->metaops
.vbo
) {
493 init_metaops_state(brw
);
496 install_attribs(brw
);
498 meta_no_texture(&brw
->intel
);
499 meta_flat_shade(&brw
->intel
);
500 brw
->metaops
.restore_draw_mask
= ctx
->DrawBuffer
->_ColorDrawBufferMask
[0];
501 brw
->metaops
.restore_fp
= ctx
->FragmentProgram
.Current
;
503 /* This works without adjusting refcounts. Fix later?
505 brw
->metaops
.saved_draw_region
= brw
->state
.draw_region
;
506 brw
->metaops
.saved_depth_region
= brw
->state
.depth_region
;
507 brw
->metaops
.active
= 1;
509 brw
->state
.dirty
.brw
|= BRW_NEW_METAOPS
;
512 static void leave_meta_state( struct intel_context
*intel
)
514 GLcontext
*ctx
= &intel
->ctx
;
515 struct brw_context
*brw
= brw_context(ctx
);
517 restore_attribs(brw
);
519 ctx
->DrawBuffer
->_ColorDrawBufferMask
[0] = brw
->metaops
.restore_draw_mask
;
520 ctx
->FragmentProgram
.Current
= brw
->metaops
.restore_fp
;
522 brw
->state
.draw_region
= brw
->metaops
.saved_draw_region
;
523 brw
->state
.depth_region
= brw
->metaops
.saved_depth_region
;
524 brw
->metaops
.saved_draw_region
= NULL
;
525 brw
->metaops
.saved_depth_region
= NULL
;
526 brw
->metaops
.active
= 0;
528 brw
->state
.dirty
.mesa
|= _NEW_BUFFERS
;
529 brw
->state
.dirty
.brw
|= BRW_NEW_METAOPS
;
534 void brw_init_metaops( struct brw_context
*brw
)
539 brw
->intel
.vtbl
.install_meta_state
= install_meta_state
;
540 brw
->intel
.vtbl
.leave_meta_state
= leave_meta_state
;
541 brw
->intel
.vtbl
.meta_no_depth_write
= meta_no_depth_write
;
542 brw
->intel
.vtbl
.meta_no_stencil_write
= meta_no_stencil_write
;
543 brw
->intel
.vtbl
.meta_stencil_replace
= meta_stencil_replace
;
544 brw
->intel
.vtbl
.meta_depth_replace
= meta_depth_replace
;
545 brw
->intel
.vtbl
.meta_color_mask
= meta_color_mask
;
546 brw
->intel
.vtbl
.meta_no_texture
= meta_no_texture
;
547 brw
->intel
.vtbl
.meta_import_pixel_state
= meta_import_pixel_state
;
548 brw
->intel
.vtbl
.meta_frame_buffer_texture
= meta_frame_buffer_texture
;
549 brw
->intel
.vtbl
.meta_draw_region
= meta_draw_region
;
550 brw
->intel
.vtbl
.meta_draw_quad
= meta_draw_quad
;
551 brw
->intel
.vtbl
.meta_texture_blend_replace
= meta_texture_blend_replace
;
552 /* brw->intel.vtbl.meta_tex_rect_source = meta_tex_rect_source; */
553 /* brw->intel.vtbl.meta_draw_format = set_draw_format; */
556 void brw_destroy_metaops( struct brw_context
*brw
)
558 GLcontext
*ctx
= &brw
->intel
.ctx
;
560 if (brw
->metaops
.vbo
)
561 ctx
->Driver
.DeleteBuffer( ctx
, brw
->metaops
.vbo
);
563 /* ctx->Driver.DeleteProgram( ctx, brw->metaops.fp ); */
564 /* ctx->Driver.DeleteProgram( ctx, brw->metaops.fp_tex ); */
565 /* ctx->Driver.DeleteProgram( ctx, brw->metaops.vp ); */