gallium: Change pipe->flush() interface to optionally return a fence.

The cell driver still uses an internal CELL_FLUSH_WAIT flag, in the long run
proper fencing should be implemented for it.
This commit is contained in:
Michel Dänzer 2008-03-26 09:36:40 +00:00
parent e55dccd0bf
commit 4abe1eb980
28 changed files with 128 additions and 84 deletions

View File

@ -935,7 +935,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
4, /* verts */
2); /* attribs/vert */
pipe->flush(pipe, PIPE_FLUSH_WAIT);
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
/* need to signal that the texture has changed _after_ rendering to it */
pipe->texture_update(pipe, pt, face, (1 << dstLevel));

View File

@ -35,12 +35,19 @@
void
cell_flush(struct pipe_context *pipe, unsigned flags)
cell_flush(struct pipe_context *pipe, unsigned flags,
struct pipe_fence_handle **fence)
{
struct cell_context *cell = cell_context(pipe);
if (fence) {
*fence = NULL;
/* XXX: Implement real fencing */
flags |= CELL_FLUSH_WAIT;
}
if (flags & PIPE_FLUSH_SWAPBUFFERS)
flags |= PIPE_FLUSH_WAIT;
flags |= CELL_FLUSH_WAIT;
draw_flush( cell->draw );
cell_flush_int(pipe, flags);
@ -58,7 +65,7 @@ cell_flush_int(struct pipe_context *pipe, unsigned flags)
ASSERT(!flushing);
flushing = TRUE;
if (flags & PIPE_FLUSH_WAIT) {
if (flags & CELL_FLUSH_WAIT) {
uint64_t *cmd = (uint64_t *) cell_batch_alloc(cell, sizeof(uint64_t));
*cmd = CELL_CMD_FINISH;
}
@ -72,7 +79,7 @@ cell_flush_int(struct pipe_context *pipe, unsigned flags)
}
#endif
if (flags & PIPE_FLUSH_WAIT) {
if (flags & CELL_FLUSH_WAIT) {
/* Wait for ack */
for (i = 0; i < cell->num_spus; i++) {
uint k = wait_mbox_message(cell_global.spe_contexts[i]);

View File

@ -29,8 +29,11 @@
#ifndef CELL_FLUSH
#define CELL_FLUSH
#define CELL_FLUSH_WAIT 0x80000000
extern void
cell_flush(struct pipe_context *pipe, unsigned flags);
cell_flush(struct pipe_context *pipe, unsigned flags,
struct pipe_fence_handle **fence);
extern void
cell_flush_int(struct pipe_context *pipe, unsigned flags);

View File

@ -243,7 +243,7 @@ cell_vbuf_draw(struct vbuf_render *vbr,
#if 0
/* helpful for debug */
cell_flush_int(&cell->pipe, PIPE_FLUSH_WAIT);
cell_flush_int(&cell->pipe, CELL_FLUSH_WAIT);
#endif
}

View File

@ -133,7 +133,7 @@ cell_vertex_shader_queue_flush(struct draw_context *draw)
vs->num_elts = n;
send_mbox_message(cell_global.spe_contexts[0], CELL_CMD_VS_EXECUTE);
cell_flush_int(& cell->pipe, PIPE_FLUSH_WAIT);
cell_flush_int(& cell->pipe, CELL_FLUSH_WAIT);
}
draw->vs.post_nr = draw->vs.queue_nr;

View File

@ -69,7 +69,7 @@ static boolean failover_draw_elements( struct pipe_context *pipe,
start,
count )) {
failover->hw->flush( failover->hw, ~0 );
failover->hw->flush( failover->hw, ~0, NULL );
failover->mode = FO_SW;
}
}
@ -92,7 +92,7 @@ static boolean failover_draw_elements( struct pipe_context *pipe,
* intervening flush. Unlikely to be much performance impact to
* this:
*/
failover->sw->flush( failover->sw, ~0 );
failover->sw->flush( failover->sw, ~0, NULL );
}
return TRUE;

View File

@ -44,9 +44,9 @@
#define ADVANCE_BATCH()
#define FLUSH_BATCH() do { \
#define FLUSH_BATCH(fence) do { \
if (0) i915_dump_batchbuffer( i915 ); \
i915->winsys->batch_flush( i915->winsys ); \
i915->winsys->batch_flush( i915->winsys, fence ); \
i915->batch_start = NULL; \
i915->hardware_dirty = ~0; \
} while (0)

View File

@ -70,7 +70,7 @@ i915_fill_blit(struct i915_context *i915,
if (!BEGIN_BATCH(6, 1)) {
FLUSH_BATCH();
FLUSH_BATCH(NULL);
assert(BEGIN_BATCH(6, 1));
}
OUT_BATCH(CMD);
@ -145,7 +145,7 @@ i915_copy_blit( struct i915_context *i915,
if (!BEGIN_BATCH(8, 2)) {
FLUSH_BATCH();
FLUSH_BATCH(NULL);
assert(BEGIN_BATCH(8, 2));
}
OUT_BATCH(CMD);

View File

@ -37,11 +37,9 @@
#include "i915_batch.h"
/**
* In future we may want a fence-like interface instead of finish.
*/
static void i915_flush( struct pipe_context *pipe,
unsigned flags )
unsigned flags,
struct pipe_fence_handle **fence )
{
struct i915_context *i915 = i915_context(pipe);
@ -60,7 +58,7 @@ static void i915_flush( struct pipe_context *pipe,
flush |= FLUSH_MAP_CACHE;
if (!BEGIN_BATCH(1, 0)) {
FLUSH_BATCH();
FLUSH_BATCH(NULL);
assert(BEGIN_BATCH(1, 0));
}
OUT_BATCH( flush );
@ -69,11 +67,7 @@ static void i915_flush( struct pipe_context *pipe,
/* If there are no flags, just flush pending commands to hardware:
*/
FLUSH_BATCH();
if (flags & PIPE_FLUSH_WAIT) {
i915->winsys->batch_finish(i915->winsys);
}
FLUSH_BATCH(fence);
}

View File

@ -140,7 +140,7 @@ emit_prim( struct draw_stage *stage,
assert(vertex_size >= 12); /* never smaller than 12 bytes */
if (!BEGIN_BATCH( 1 + nr * vertex_size / 4, 0 )) {
FLUSH_BATCH();
FLUSH_BATCH(NULL);
/* Make sure state is re-emitted after a flush:
*/

View File

@ -161,7 +161,7 @@ i915_vbuf_render_draw( struct vbuf_render *render,
i915_emit_hardware_state( i915 );
if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
FLUSH_BATCH();
FLUSH_BATCH(NULL);
/* Make sure state is re-emitted after a flush:
*/

View File

@ -115,7 +115,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
#endif
if(!BEGIN_BATCH(dwords, relocs)) {
FLUSH_BATCH();
FLUSH_BATCH(NULL);
assert(BEGIN_BATCH(dwords, relocs));
}

View File

@ -56,6 +56,7 @@ extern "C" {
*/
struct pipe_buffer;
struct pipe_fence_handle;
struct pipe_winsys;
struct pipe_screen;
@ -103,8 +104,8 @@ struct i915_winsys {
unsigned access_flags,
unsigned delta );
void (*batch_flush)( struct i915_winsys *sws );
void (*batch_finish)( struct i915_winsys *sws );
void (*batch_flush)( struct i915_winsys *sws,
struct pipe_fence_handle **fence );
};
#define I915_BUFFER_ACCESS_WRITE 0x1

View File

@ -36,14 +36,11 @@
#include "brw_batch.h"
/**
* In future we may want a fence-like interface instead of finish.
*/
static void brw_flush( struct pipe_context *pipe,
unsigned flags )
unsigned flags,
struct pipe_fence_handle **fence )
{
struct brw_context *brw = brw_context(pipe);
struct pipe_fence_handle *fence;
/* Do we need to emit an MI_FLUSH command to flush the hardware
* caches?
@ -65,11 +62,7 @@ static void brw_flush( struct pipe_context *pipe,
/* If there are no flags, just flush pending commands to hardware:
*/
FLUSH_BATCH( &fence );
if (flags & PIPE_FLUSH_WAIT) {
// brw->winsys->wait_fence(brw->winsys, fence);
}
FLUSH_BATCH( fence );
}

View File

@ -40,13 +40,10 @@
#include "sp_winsys.h"
/* There will be actual work to do here. In future we may want a
* fence-like interface instead of finish, and perhaps flush will take
* flags to indicate what type of flush is required.
*/
void
softpipe_flush( struct pipe_context *pipe,
unsigned flags )
unsigned flags,
struct pipe_fence_handle **fence )
{
struct softpipe_context *softpipe = softpipe_context(pipe);
uint i;
@ -72,5 +69,8 @@ softpipe_flush( struct pipe_context *pipe,
* to unmap surfaces when flushing.
*/
softpipe_unmap_surfaces(softpipe);
if (fence)
*fence = NULL;
}

View File

@ -29,7 +29,9 @@
#define SP_FLUSH_H
struct pipe_context;
struct pipe_fence_handle;
void softpipe_flush(struct pipe_context *pipe, unsigned flags );
void softpipe_flush(struct pipe_context *pipe, unsigned flags,
struct pipe_fence_handle **fence);
#endif

View File

@ -37,7 +37,7 @@ extern "C" {
struct pipe_screen;
struct pipe_fence_handle;
struct pipe_state_cache;
/* Opaque driver handles:
@ -202,7 +202,8 @@ struct pipe_context {
/* Flush rendering:
*/
void (*flush)( struct pipe_context *pipe,
unsigned flags );
unsigned flags,
struct pipe_fence_handle **fence );
};

View File

@ -201,8 +201,7 @@ enum pipe_texture_target {
*/
#define PIPE_FLUSH_RENDER_CACHE 0x1
#define PIPE_FLUSH_TEXTURE_CACHE 0x2
#define PIPE_FLUSH_WAIT 0x4
#define PIPE_FLUSH_SWAPBUFFERS 0x8
#define PIPE_FLUSH_SWAPBUFFERS 0x4
/**

View File

@ -228,7 +228,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
assert(intel); /* should never be null */
if (intel) {
st_flush(intel->st, PIPE_FLUSH_WAIT);
st_finish(intel->st);
intel_batchbuffer_free(intel->batch);
@ -256,7 +256,7 @@ GLboolean
intelUnbindContext(__DRIcontextPrivate * driContextPriv)
{
struct intel_context *intel = intel_context(driContextPriv);
st_flush(intel->st, 0x0);
st_flush(intel->st, PIPE_FLUSH_RENDER_CACHE, NULL);
/* XXX make_current(NULL)? */
return GL_TRUE;
}

View File

@ -39,12 +39,14 @@
#include "intel_winsys.h"
#include "pipe/p_util.h"
#include "pipe/p_winsys.h"
#include "i915simple/i915_winsys.h"
#include "i915simple/i915_screen.h"
struct intel_i915_winsys {
struct i915_winsys winsys; /**< batch buffer funcs */
struct pipe_winsys *pws;
struct intel_context *intel;
};
@ -112,22 +114,25 @@ static void intel_i915_batch_reloc( struct i915_winsys *sws,
static void intel_i915_batch_flush( struct i915_winsys *sws )
static void intel_i915_batch_flush( struct i915_winsys *sws,
struct pipe_fence_handle **fence )
{
struct intel_context *intel = intel_i915_winsys(sws)->intel;
struct intel_i915_winsys *iws = intel_i915_winsys(sws);
struct intel_context *intel = iws->intel;
union {
struct _DriFenceObject *dri;
struct pipe_fence_handle *pipe;
} fu;
fu.dri = intel_batchbuffer_flush( intel->batch );
if (fu.dri)
iws->pws->fence_reference(iws->pws, fence, fu.pipe);
intel_batchbuffer_flush( intel->batch );
// if (0) intel_i915_batch_wait_idle( sws );
}
static void intel_i915_batch_finish( struct i915_winsys *sws )
{
struct intel_context *intel = intel_i915_winsys(sws)->intel;
intel_batchbuffer_finish( intel->batch );
}
/**
* Create i915 hardware rendering context.
*/
@ -145,7 +150,7 @@ intel_create_i915simple( struct intel_context *intel,
iws->winsys.batch_dword = intel_i915_batch_dword;
iws->winsys.batch_reloc = intel_i915_batch_reloc;
iws->winsys.batch_flush = intel_i915_batch_flush;
iws->winsys.batch_finish = intel_i915_batch_finish;
iws->pws = winsys;
iws->intel = intel;
screen = i915_create_screen(winsys, intel->intelScreen->deviceID);

View File

@ -570,6 +570,33 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
}
/*
* Fence functions - basically nothing to do, as we don't create any actual
* fence objects.
*/
static void
xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence)
{
}
static int
xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
unsigned flag)
{
return 0;
}
static int
xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
unsigned flag)
{
return 0;
}
/**
* Return pointer to a pipe_winsys object.
@ -603,6 +630,10 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis)
ws->base.surface_alloc_storage = xm_surface_alloc_storage;
ws->base.surface_release = xm_surface_release;
ws->fence_reference = xm_fence_reference;
ws->fence_signalled = xm_fence_signalled;
ws->fence_finish = xm_fence_finish;
ws->base.flush_frontbuffer = xm_flush_frontbuffer;
ws->base.printf = xm_printf;
ws->base.get_name = xm_get_name;

View File

@ -214,7 +214,7 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value)
const GLint height = ctx->DrawBuffer->_Ymax - ypos;
/* make sure color bufs aren't cached */
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE);
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
switch (op) {
case GL_ADD:

View File

@ -737,7 +737,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
GLint skipPixels;
ubyte *stmap;
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE);
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
/* map the stencil buffer */
stmap = pipe_surface_map(ps);
@ -952,7 +952,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
enum pipe_format srcFormat, texFormat;
/* make sure rendering has completed */
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE);
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
st_validate_state(st);

View File

@ -366,7 +366,7 @@ st_finish_render_texture(GLcontext *ctx,
assert(strb);
ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE);
ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
/*
printf("FINISH RENDER TO TEXTURE surf=%p\n", strb->surface);

View File

@ -43,19 +43,21 @@
#include "pipe/p_winsys.h"
void st_flush( struct st_context *st, uint pipeFlushFlags )
void st_flush( struct st_context *st, uint pipeFlushFlags,
struct pipe_fence_handle **fence )
{
FLUSH_VERTICES(st->ctx, 0);
st->pipe->flush( st->pipe, pipeFlushFlags );
st->pipe->flush( st->pipe, pipeFlushFlags, fence );
}
static void st_gl_flush( struct st_context *st, uint pipeFlushFlags )
static void st_gl_flush( struct st_context *st, uint pipeFlushFlags,
struct pipe_fence_handle **fence )
{
GLframebuffer *fb = st->ctx->DrawBuffer;
FLUSH_VERTICES(st->ctx, 0);
st_flush( st, pipeFlushFlags, fence );
if (!fb)
return;
@ -80,15 +82,6 @@ static void st_gl_flush( struct st_context *st, uint pipeFlushFlags )
= st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
struct pipe_surface *front_surf = strb->surface;
/* If we aren't rendering to the frontbuffer, this is a noop.
* This should be uncontroversial for glFlush, though people may
* feel more strongly about glFinish.
*
* Additionally, need to make sure that the frontbuffer_dirty
* flag really gets set on frontbuffer rendering.
*/
st->pipe->flush( st->pipe, pipeFlushFlags );
/* Hook for copying "fake" frontbuffer if necessary:
*/
st->pipe->winsys->flush_frontbuffer( st->pipe->winsys, front_surf,
@ -103,7 +96,18 @@ static void st_gl_flush( struct st_context *st, uint pipeFlushFlags )
*/
static void st_glFlush(GLcontext *ctx)
{
st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE);
st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
}
void st_finish( struct st_context *st )
{
struct pipe_fence_handle *fence;
st_gl_flush(st, PIPE_FLUSH_RENDER_CACHE, &fence);
st->pipe->winsys->fence_finish(st->pipe->winsys, fence, 0);
st->pipe->winsys->fence_reference(st->pipe->winsys, &fence, NULL);
}
@ -112,7 +116,7 @@ static void st_glFlush(GLcontext *ctx)
*/
static void st_glFinish(GLcontext *ctx)
{
st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_WAIT);
st_finish( ctx->st );
}

View File

@ -160,7 +160,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
return;
/* make sure rendering has completed */
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE);
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
if (format == GL_STENCIL_INDEX) {
st_read_stencil_pixels(ctx, x, y, width, height, type, pack, dest);

View File

@ -186,7 +186,8 @@ st_notify_swapbuffers(struct st_framebuffer *stfb)
if (ctx && ctx->DrawBuffer == &stfb->Base) {
st_flush( ctx->st,
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_SWAPBUFFERS);
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_SWAPBUFFERS,
NULL );
}
}

View File

@ -45,6 +45,7 @@
struct st_context;
struct st_framebuffer;
struct pipe_context;
struct pipe_fence_handle;
struct pipe_surface;
@ -78,7 +79,9 @@ void st_make_current(struct st_context *st,
struct st_framebuffer *draw,
struct st_framebuffer *read);
void st_flush( struct st_context *st, uint pipeFlushFlags );
void st_flush( struct st_context *st, uint pipeFlushFlags,
struct pipe_fence_handle **fence );
void st_finish( struct st_context *st );
void st_notify_swapbuffers(struct st_framebuffer *stfb);
void st_notify_swapbuffers_complete(struct st_framebuffer *stfb);