Add back a mostly-correct glFinish for GEM and fake.

The right solution would probably be keeping a list of regions which have been
rendered to.
This commit is contained in:
Eric Anholt 2008-05-19 15:42:00 -07:00
parent 76286bc76c
commit 6cefae5354
5 changed files with 49 additions and 4 deletions

View file

@ -127,6 +127,12 @@ dri_bo_get_subdata(dri_bo *bo, unsigned long offset,
return 0;
}
void
dri_bo_wait_rendering(dri_bo *bo)
{
bo->bufmgr->bo_wait_rendering(bo);
}
void
dri_bufmgr_destroy(dri_bufmgr *bufmgr)
{

View file

@ -127,6 +127,14 @@ struct _dri_bufmgr {
int (*bo_get_subdata) (dri_bo *bo, unsigned long offset,
unsigned long size, void *data);
/**
* Waits for rendering to an object by the GPU to have completed.
*
* This is not required for any access to the BO by bo_map, bo_subdata, etc.
* It is merely a way for the driver to implement glFinish.
*/
void (*bo_wait_rendering) (dri_bo *bo);
/**
* Tears down the buffer manager instance.
*/
@ -192,6 +200,7 @@ int dri_bo_subdata(dri_bo *bo, unsigned long offset,
unsigned long size, const void *data);
int dri_bo_get_subdata(dri_bo *bo, unsigned long offset,
unsigned long size, void *data);
void dri_bo_wait_rendering(dri_bo *bo);
void dri_bufmgr_set_debug(dri_bufmgr *bufmgr, GLboolean enable_debug);
void dri_bufmgr_destroy(dri_bufmgr *bufmgr);

View file

@ -533,10 +533,13 @@ dri_bufmgr_fake_wait_idle(dri_bufmgr_fake *bufmgr_fake)
}
/**
* Wait for execution pending on a buffer
* Wait for rendering to a buffer to complete.
*
* It is assumed that the bathcbuffer which performed the rendering included
* the necessary flushing.
*/
static void
dri_bufmgr_fake_bo_wait_idle(dri_bo *bo)
dri_fake_bo_wait_rendering(dri_bo *bo)
{
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
@ -757,7 +760,7 @@ dri_fake_bo_map(dri_bo *bo, GLboolean write_enable)
if (!(bo_fake->flags & BM_NO_FENCE_SUBDATA) &&
bo_fake->block->fenced) {
dri_bufmgr_fake_bo_wait_idle(bo);
dri_fake_bo_wait_rendering(bo);
}
bo->virtual = bo_fake->block->virtual;
@ -1157,6 +1160,7 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual,
bufmgr_fake->bufmgr.bo_unreference = dri_fake_bo_unreference;
bufmgr_fake->bufmgr.bo_map = dri_fake_bo_map;
bufmgr_fake->bufmgr.bo_unmap = dri_fake_bo_unmap;
bufmgr_fake->bufmgr.bo_wait_rendering = dri_fake_bo_wait_rendering;
bufmgr_fake->bufmgr.destroy = dri_fake_destroy;
bufmgr_fake->bufmgr.emit_reloc = dri_fake_emit_reloc;
bufmgr_fake->bufmgr.process_relocs = dri_fake_process_relocs;

View file

@ -595,6 +595,26 @@ dri_gem_bo_get_subdata (dri_bo *bo, unsigned long offset,
return 0;
}
static void
dri_gem_bo_wait_rendering(dri_bo *bo)
{
dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
struct drm_gem_set_domain set_domain;
int ret;
set_domain.handle = bo_gem->gem_handle;
set_domain.read_domains = DRM_GEM_DOMAIN_CPU;
set_domain.write_domain = 0;
ret = ioctl (bufmgr_gem->fd, DRM_IOCTL_GEM_SET_DOMAIN, &set_domain);
if (ret != 0) {
fprintf (stderr, "%s:%d: Error setting memory domains %d (%08x %08x): %s .\n",
__FILE__, __LINE__,
bo_gem->gem_handle, set_domain.read_domains, set_domain.write_domain,
strerror (errno));
}
}
static void
dri_bufmgr_gem_destroy(dri_bufmgr *bufmgr)
{
@ -827,6 +847,7 @@ intel_bufmgr_gem_init(int fd, int batch_size)
bufmgr_gem->bufmgr.bo_unmap = dri_gem_bo_unmap;
bufmgr_gem->bufmgr.bo_subdata = dri_gem_bo_subdata;
bufmgr_gem->bufmgr.bo_get_subdata = dri_gem_bo_get_subdata;
bufmgr_gem->bufmgr.bo_wait_rendering = dri_gem_bo_wait_rendering;
bufmgr_gem->bufmgr.destroy = dri_bufmgr_gem_destroy;
bufmgr_gem->bufmgr.emit_reloc = dri_gem_emit_reloc;
bufmgr_gem->bufmgr.process_relocs = dri_gem_process_reloc;

View file

@ -375,7 +375,12 @@ intelFinish(GLcontext * ctx)
intelFlush(ctx);
for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
/* XXX: Wait on buffer idle */
struct intel_renderbuffer *irb;
irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]);
if (irb->region)
dri_bo_wait_rendering(irb->region->buffer);
}
if (fb->_DepthBuffer) {
/* XXX: Wait on buffer idle */