/*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
+ * frame buffer texture by Gary Wong <gtw@gnu.org>
*/
DUP(brw, gl_fragment_program_state, FragmentProgram);
}
-static void install_attribs( struct brw_context *brw )
+static void install_vertex_attribs( struct brw_context *brw )
{
- INSTALL(brw, Color, _NEW_COLOR);
- INSTALL(brw, Depth, _NEW_DEPTH);
- INSTALL(brw, Fog, _NEW_FOG);
INSTALL(brw, Hint, _NEW_HINT);
INSTALL(brw, Light, _NEW_LIGHT);
INSTALL(brw, Line, _NEW_LINE);
INSTALL(brw, Point, _NEW_POINT);
INSTALL(brw, Polygon, _NEW_POLYGON);
- INSTALL(brw, Scissor, _NEW_SCISSOR);
- INSTALL(brw, Stencil, _NEW_STENCIL);
- INSTALL(brw, Texture, _NEW_TEXTURE);
INSTALL(brw, Transform, _NEW_TRANSFORM);
INSTALL(brw, Viewport, _NEW_VIEWPORT);
INSTALL(brw, VertexProgram, _NEW_PROGRAM);
+}
+
+static void install_fragment_attribs( struct brw_context *brw )
+{
+ INSTALL(brw, Color, _NEW_COLOR);
+ INSTALL(brw, Depth, _NEW_DEPTH);
+ INSTALL(brw, Fog, _NEW_FOG);
+ INSTALL(brw, Scissor, _NEW_SCISSOR);
+ INSTALL(brw, Stencil, _NEW_STENCIL);
+ INSTALL(brw, Texture, _NEW_TEXTURE);
INSTALL(brw, FragmentProgram, _NEW_PROGRAM);
}
"MOV result.color, fragment.color;\n"
"END\n";
+static const char *fp_tex_prog =
+ "!!ARBfp1.0\n"
+ "TEMP a;\n"
+ "ADD a, fragment.position, program.local[0];\n"
+ "MUL a, a, program.local[1];\n"
+ "TEX result.color, a, texture[0], 2D;\n"
+ "MOV result.depth.z, fragment.position;\n"
+ "END\n";
+
/* Derived values of importance:
*
* FragmentProgram->_Current
brw->metaops.fp = (struct gl_fragment_program *)
ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 1 );
+ brw->metaops.fp_tex = (struct gl_fragment_program *)
+ ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 1 );
+
brw->metaops.vp = (struct gl_vertex_program *)
ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 1 );
fp_prog, strlen(fp_prog),
brw->metaops.fp);
+ _mesa_parse_arb_fragment_program(ctx, GL_FRAGMENT_PROGRAM_ARB,
+ fp_tex_prog, strlen(fp_tex_prog),
+ brw->metaops.fp_tex);
+
_mesa_parse_arb_vertex_program(ctx, GL_VERTEX_PROGRAM_ARB,
vp_prog, strlen(vp_prog),
brw->metaops.vp);
static void meta_no_texture( struct intel_context *intel )
{
- /* Nothing to do */
+ struct brw_context *brw = brw_context(&intel->ctx);
+
+ brw->metaops.attribs.FragmentProgram->_Current = brw->metaops.fp;
+
+ brw->metaops.attribs.Texture->CurrentUnit = 0;
+ brw->metaops.attribs.Texture->_EnabledUnits = 0;
+ brw->metaops.attribs.Texture->_EnabledCoordUnits = 0;
+ brw->metaops.attribs.Texture->Unit[ 0 ].Enabled = 0;
+ brw->metaops.attribs.Texture->Unit[ 0 ]._ReallyEnabled = 0;
+
+ brw->state.dirty.mesa |= _NEW_TEXTURE | _NEW_PROGRAM;
+}
+
+static void meta_frame_buffer_texture( struct intel_context *intel,
+ GLint xoff, GLint yoff )
+{
+ struct brw_context *brw = brw_context(&intel->ctx);
+ struct intel_region *region = intel_drawbuf_region( intel );
+
+ INSTALL(brw, FragmentProgram, _NEW_PROGRAM);
+
+ brw->metaops.attribs.FragmentProgram->_Current = brw->metaops.fp_tex;
+ /* This is unfortunate, but seems to be necessary, since later on we
+ will end up calling _mesa_load_state_parameters to lookup the
+ local params (below), and that will want to look in ctx.FragmentProgram
+ instead of brw->attribs.FragmentProgram. */
+ intel->ctx.FragmentProgram.Current = brw->metaops.fp_tex;
+
+ brw->metaops.fp_tex->Base.LocalParams[ 0 ][ 0 ] = xoff;
+ brw->metaops.fp_tex->Base.LocalParams[ 0 ][ 1 ] = yoff;
+ brw->metaops.fp_tex->Base.LocalParams[ 0 ][ 2 ] = 0.0;
+ brw->metaops.fp_tex->Base.LocalParams[ 0 ][ 3 ] = 0.0;
+ brw->metaops.fp_tex->Base.LocalParams[ 1 ][ 0 ] =
+ 1.0 / region->pitch;
+ brw->metaops.fp_tex->Base.LocalParams[ 1 ][ 1 ] =
+ -1.0 / region->height;
+ brw->metaops.fp_tex->Base.LocalParams[ 1 ][ 2 ] = 0.0;
+ brw->metaops.fp_tex->Base.LocalParams[ 1 ][ 3 ] = 1.0;
+
+ brw->metaops.attribs.Texture->CurrentUnit = 0;
+ brw->metaops.attribs.Texture->_EnabledUnits = 1;
+ brw->metaops.attribs.Texture->_EnabledCoordUnits = 1;
+ brw->metaops.attribs.Texture->Unit[ 0 ].Enabled = TEXTURE_2D_BIT;
+ brw->metaops.attribs.Texture->Unit[ 0 ]._ReallyEnabled = TEXTURE_2D_BIT;
+ brw->metaops.attribs.Texture->Unit[ 0 ].Current2D =
+ intel->frame_buffer_texobj;
+ brw->metaops.attribs.Texture->Unit[ 0 ]._Current =
+ intel->frame_buffer_texobj;
+
+ brw->state.dirty.mesa |= _NEW_TEXTURE | _NEW_PROGRAM;
}
}
-static void install_meta_state( struct intel_context *intel )
+static void install_meta_state( struct intel_context *intel,
+ GLenum state )
{
GLcontext *ctx = &intel->ctx;
struct brw_context *brw = brw_context(ctx);
init_metaops_state(brw);
}
- install_attribs(brw);
+ install_vertex_attribs(brw);
+ if( state == META_FULL )
+ install_fragment_attribs(brw);
+
meta_no_texture(&brw->intel);
meta_flat_shade(&brw->intel);
brw->metaops.restore_draw_mask = ctx->DrawBuffer->_ColorDrawBufferMask[0];
+ brw->metaops.restore_fp = ctx->FragmentProgram.Current;
/* This works without adjusting refcounts. Fix later?
*/
restore_attribs(brw);
ctx->DrawBuffer->_ColorDrawBufferMask[0] = brw->metaops.restore_draw_mask;
+ ctx->FragmentProgram.Current = brw->metaops.restore_fp;
brw->state.draw_region = brw->metaops.saved_draw_region;
brw->state.depth_region = brw->metaops.saved_depth_region;
brw->intel.vtbl.meta_depth_replace = meta_depth_replace;
brw->intel.vtbl.meta_color_mask = meta_color_mask;
brw->intel.vtbl.meta_no_texture = meta_no_texture;
+ brw->intel.vtbl.meta_frame_buffer_texture = meta_frame_buffer_texture;
brw->intel.vtbl.meta_draw_region = meta_draw_region;
brw->intel.vtbl.meta_draw_quad = meta_draw_quad;
ctx->Driver.DeleteBuffer( ctx, brw->metaops.vbo );
/* ctx->Driver.DeleteProgram( ctx, brw->metaops.fp ); */
+/* ctx->Driver.DeleteProgram( ctx, brw->metaops.fp_tex ); */
/* ctx->Driver.DeleteProgram( ctx, brw->metaops.vp ); */
}
if (ctx->NewState)
_mesa_update_state(ctx);
- /* Could do logicop with the blitter:
- */
return !(ctx->_ImageTransferState ||
ctx->RenderMode != GL_RENDER ||
ctx->Color.AlphaEnabled ||
return GL_TRUE;
}
+/**
+ * CopyPixels with metaops. We can support (most) fragment options that way.
+ */
+static GLboolean
+do_meta_copypixels(GLcontext * ctx,
+ GLint srcx, GLint srcy,
+ GLsizei width, GLsizei height,
+ GLint dstx, GLint dsty, GLenum type)
+{
+ struct intel_context *intel = intel_context(ctx);
+
+ /* We're going to cheat and use texturing to get the source region
+ * duplicated. Trying to cope with the case where texturing is
+ * already applied to fragments would be messy (and it's an unusual
+ * thing to want anyway), so we leave that to swrast.
+ *
+ * We don't want to worry about any case other than GL_COLOR, either
+ * (though we could, with a bit more work).
+ *
+ * PixelMap, PixelTransfer, PixelZoom etc. could also be handled with
+ * a bit more intelligence in metaops.
+ */
+ if( ctx->_ImageTransferState ||
+ ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F ||
+ ctx->RenderMode != GL_RENDER ||
+ ctx->Texture._EnabledUnits ||
+ ctx->FragmentProgram._Enabled ||
+ type != GL_COLOR )
+ return GL_FALSE;
+
+ /* We don't yet handle copying between two different buffers (which
+ * would really only require filling out a new surface state for
+ * the source instead of aliasing the draw one). Nor do we handle
+ * overlapping source/dest rectangles (since I assume there is no
+ * way to force the hardware to guarantee the drawing order that
+ * the GL specifies -- if so, the fastest approach might be to use
+ * the blitter to copy the source to a temporary surface and then
+ * map that back onto the destination). Of course, overlapping
+ * areas in different buffers would be fine.
+ */
+ if( ctx->Color.DrawBuffer[0] != ctx->ReadBuffer->ColorReadBuffer ||
+ ( abs( srcx - dstx ) < width && abs( srcy - dsty ) < height ) )
+ return GL_FALSE;
+
+ intel->vtbl.install_meta_state( intel, META_VERTEX_ONLY );
+
+ intel->vtbl.meta_frame_buffer_texture( intel, srcx - dstx, srcy - dsty );
+
+ intel->vtbl.meta_draw_quad( intel,
+ dstx, dstx + width,
+ dsty, dsty + height,
+ ctx->Current.RasterPos[ 2 ],
+ 0, 0, 0, 0, 0.0, 0.0, 0.0, 0.0 );
+
+ intel->vtbl.leave_meta_state( intel );
+
+ return GL_TRUE;
+}
+
void
intelCopyPixels(GLcontext * ctx,
GLint srcx, GLint srcy,
if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type))
return;
+ if (INTEL_DEBUG & DEBUG_PIXEL)
+ _mesa_printf("fallback to do_meta_copypixels\n");
+
+ if (do_meta_copypixels(ctx, srcx, srcy, width, height, destx, desty, type))
+ return;
+
if (INTEL_DEBUG & DEBUG_PIXEL)
_mesa_printf("fallback to _swrast_CopyPixels\n");