Structure CopyPixels similarly to i915 do_texture_copypixels, to ease future unification.

This commit is contained in:
Gary Wong 2006-12-02 01:13:06 +00:00
parent e99d6746ed
commit 7a43a6b4ff
4 changed files with 147 additions and 99 deletions

View file

@ -95,26 +95,22 @@ static void init_attribs( struct brw_context *brw )
DUP(brw, gl_fragment_program_state, FragmentProgram);
}
static void install_vertex_attribs( struct brw_context *brw )
static void install_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, 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, Transform, _NEW_TRANSFORM);
INSTALL(brw, Viewport, _NEW_VIEWPORT);
INSTALL(brw, VertexProgram, _NEW_PROGRAM);
INSTALL(brw, FragmentProgram, _NEW_PROGRAM);
}
@ -301,6 +297,36 @@ static void meta_no_texture( struct intel_context *intel )
brw->state.dirty.mesa |= _NEW_TEXTURE | _NEW_PROGRAM;
}
static void meta_texture_blend_replace(struct intel_context *intel)
{
struct brw_context *brw = brw_context(&intel->ctx);
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 meta_import_pixel_state(struct intel_context *intel)
{
struct brw_context *brw = brw_context(&intel->ctx);
RESTORE(brw, Color, _NEW_COLOR);
RESTORE(brw, Depth, _NEW_DEPTH);
RESTORE(brw, Fog, _NEW_FOG);
RESTORE(brw, Scissor, _NEW_SCISSOR);
RESTORE(brw, Stencil, _NEW_STENCIL);
RESTORE(brw, Texture, _NEW_TEXTURE);
RESTORE(brw, FragmentProgram, _NEW_PROGRAM);
}
static void meta_frame_buffer_texture( struct intel_context *intel,
GLint xoff, GLint yoff )
{
@ -327,17 +353,7 @@ static void meta_frame_buffer_texture( struct intel_context *intel,
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;
brw->state.dirty.mesa |= _NEW_PROGRAM;
}
@ -486,9 +502,7 @@ static void install_meta_state( struct intel_context *intel,
init_metaops_state(brw);
}
install_vertex_attribs(brw);
if( state == META_FULL )
install_fragment_attribs(brw);
install_attribs(brw);
meta_no_texture(&brw->intel);
meta_flat_shade(&brw->intel);
@ -539,11 +553,11 @@ void brw_init_metaops( struct brw_context *brw )
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_import_pixel_state = meta_import_pixel_state;
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;
/* brw->intel.vtbl.meta_texture_blend_replace = meta_texture_blend_replace; */
brw->intel.vtbl.meta_texture_blend_replace = meta_texture_blend_replace;
/* brw->intel.vtbl.meta_tex_rect_source = meta_tex_rect_source; */
/* brw->intel.vtbl.meta_draw_format = set_draw_format; */
}

View file

@ -235,7 +235,7 @@ static void intelClearWithTris(struct intel_context *intel,
{
intel->vtbl.install_meta_state(intel, META_FULL);
intel->vtbl.install_meta_state(intel);
/* Get clear bounds after locking */
cx = ctx->DrawBuffer->_Xmin;

View file

@ -86,12 +86,6 @@ struct intel_texture_object
/* Identifiers for use with install_meta_state below */
enum
{
META_FULL, META_VERTEX_ONLY
};
struct intel_context
{
GLcontext ctx; /* the parent class */
@ -137,8 +131,7 @@ struct intel_context
/* Metaops:
*/
void (*install_meta_state)( struct intel_context *intel,
GLenum state );
void (*install_meta_state)( struct intel_context *intel );
void (*leave_meta_state)( struct intel_context *intel );
void (*meta_draw_region)( struct intel_context *intel,
@ -154,9 +147,12 @@ struct intel_context
void (*meta_depth_replace)( struct intel_context *intel );
void (*meta_texture_blend_replace) (struct intel_context * intel);
void (*meta_no_stencil_write)( struct intel_context *intel );
void (*meta_no_depth_write)( struct intel_context *intel );
void (*meta_no_texture)( struct intel_context *intel );
void (*meta_import_pixel_state) (struct intel_context * intel);
void (*meta_frame_buffer_texture)( struct intel_context *intel,
GLint xoff, GLint yoff );

View file

@ -95,7 +95,107 @@ intel_check_blit_fragment_ops(GLcontext * ctx)
ctx->Color.BlendEnabled);
}
/* Doesn't work for overlapping regions. Could do a double copy or
* just fallback.
*/
static GLboolean
do_texture_copypixels(GLcontext * ctx,
GLint srcx, GLint srcy,
GLsizei width, GLsizei height,
GLint dstx, GLint dsty, GLenum type)
{
struct intel_context *intel = intel_context(ctx);
struct intel_region *dst = intel_drawbuf_region(intel);
struct intel_region *src = copypix_src_region(intel, type);
GLenum src_format;
GLenum src_type;
DBG("%s %d,%d %dx%d --> %d,%d\n", __FUNCTION__,
srcx, srcy, width, height, dstx, dsty);
if (!src || !dst || type != GL_COLOR ||
ctx->_ImageTransferState ||
ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F ||
ctx->RenderMode != GL_RENDER ||
ctx->Texture._EnabledUnits ||
ctx->FragmentProgram._Enabled ||
src != dst )
return GL_FALSE;
/* Can't handle overlapping regions. Don't have sufficient control
* over rasterization to pull it off in-place. Punt on these for
* now.
*
* XXX: do a copy to a temporary.
*/
if (src->buffer == dst->buffer) {
drm_clip_rect_t srcbox;
drm_clip_rect_t dstbox;
drm_clip_rect_t tmp;
srcbox.x1 = srcx;
srcbox.y1 = srcy;
srcbox.x2 = srcx + width - 1;
srcbox.y2 = srcy + height - 1;
dstbox.x1 = dstx;
dstbox.y1 = dsty;
dstbox.x2 = dstx + width - 1;
dstbox.y2 = dsty + height - 1;
DBG("src %d,%d %d,%d\n", srcbox.x1, srcbox.y1, srcbox.x2, srcbox.y2);
DBG("dst %d,%d %d,%d (%dx%d) (%f,%f)\n", dstbox.x1, dstbox.y1, dstbox.x2, dstbox.y2,
width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
if (intel_intersect_cliprects(&tmp, &srcbox, &dstbox)) {
DBG("%s: regions overlap\n", __FUNCTION__);
return GL_FALSE;
}
}
intelFlush(&intel->ctx);
intel->vtbl.install_meta_state(intel);
/* Is this true? Also will need to turn depth testing on according
* to state:
*/
intel->vtbl.meta_no_stencil_write(intel);
intel->vtbl.meta_no_depth_write(intel);
/* Set the 3d engine to draw into the destination region:
*/
intel->vtbl.meta_draw_region(intel, dst, intel->depth_region);
intel->vtbl.meta_import_pixel_state(intel);
if (src->cpp == 2) {
src_format = GL_RGB;
src_type = GL_UNSIGNED_SHORT_5_6_5;
}
else {
src_format = GL_BGRA;
src_type = GL_UNSIGNED_BYTE;
}
/* Set the frontbuffer up as a large rectangular texture.
*/
intel->vtbl.meta_frame_buffer_texture( intel, srcx - dstx, srcy - dsty );
intel->vtbl.meta_texture_blend_replace(intel);
if (intel->driDrawable->numClipRects)
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 );
DBG("%s: success\n", __FUNCTION__);
return GL_TRUE;
}
/**
* CopyPixels with the blitter. Don't support zooming, pixel transfer, etc.
@ -221,65 +321,6 @@ do_blit_copypixels(GLcontext * ctx,
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,
@ -292,10 +333,7 @@ intelCopyPixels(GLcontext * ctx,
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))
if (do_texture_copypixels(ctx, srcx, srcy, width, height, destx, desty, type))
return;
if (INTEL_DEBUG & DEBUG_PIXEL)