diff options
Diffstat (limited to 'src/gallium/winsys/radeon/drm/radeon_drm_winsys.c')
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 100 |
1 files changed, 79 insertions, 21 deletions
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c index 37f6d18689d..3ac57d25b5e 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c @@ -48,22 +48,59 @@ #define RADEON_INFO_WANT_CMASK 8 #endif -/* Enable/disable feature access. Return TRUE on success. */ -static boolean radeon_set_fd_access(int fd, unsigned request, boolean enable) +/* Enable/disable feature access for one command stream. + * If enable == TRUE, return TRUE on success. + * Otherwise, return FALSE. + * + * We basically do the same thing kernel does, because we have to deal + * with multiple contexts (here command streams) backed by one winsys. */ +static boolean radeon_set_fd_access(struct radeon_drm_cs *applier, + struct radeon_drm_cs **owner, + pipe_mutex *mutex, + unsigned request, boolean enable) { struct drm_radeon_info info = {0}; unsigned value = enable ? 1 : 0; + pipe_mutex_lock(*mutex); + + /* Early exit if we are sure the request will fail. */ + if (enable) { + if (*owner) { + pipe_mutex_unlock(*mutex); + return FALSE; + } + } else { + if (*owner != applier) { + pipe_mutex_unlock(*mutex); + return FALSE; + } + } + + /* Pass through the request to the kernel. */ info.value = (unsigned long)&value; info.request = request; - - if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0) + if (drmCommandWriteRead(applier->ws->fd, DRM_RADEON_INFO, + &info, sizeof(info)) != 0) { + pipe_mutex_unlock(*mutex); return FALSE; + } - if (enable && !value) - return FALSE; + /* Update the rights in the winsys. */ + if (enable) { + if (value) { + *owner = applier; + fprintf(stderr, "radeon: Acquired Hyper-Z.\n"); + pipe_mutex_unlock(*mutex); + return TRUE; + } + } else { + *owner = NULL; + fprintf(stderr, "radeon: Released Hyper-Z.\n"); + } - return TRUE; + pipe_mutex_unlock(*mutex); + return FALSE; } /* Helper function to do the ioctls needed for setup and init. */ @@ -138,16 +175,6 @@ static void do_ioctls(struct radeon_drm_winsys *winsys) } winsys->z_pipes = target; - if (debug_get_bool_option("RADEON_HYPERZ", FALSE)) { - winsys->hyperz = radeon_set_fd_access(winsys->fd, - RADEON_INFO_WANT_HYPERZ, TRUE); - } - - if (debug_get_bool_option("RADEON_CMASK", FALSE)) { - winsys->aacompress = radeon_set_fd_access(winsys->fd, - RADEON_INFO_WANT_CMASK, TRUE); - } - retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_GEM_INFO, &gem_info, sizeof(gem_info)); if (retval) { @@ -167,6 +194,9 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws) { struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws; + pipe_mutex_destroy(ws->hyperz_owner_mutex); + pipe_mutex_destroy(ws->cmask_owner_mutex); + ws->cman->destroy(ws->cman); ws->kman->destroy(ws->kman); FREE(rws); @@ -198,14 +228,38 @@ static uint32_t radeon_get_value(struct radeon_winsys *rws, return ws->drm_major*100 + ws->drm_minor >= 206; case RADEON_VID_DRM_2_8_0: return ws->drm_major*100 + ws->drm_minor >= 208; - case RADEON_VID_CAN_HYPERZ: - return ws->hyperz; - case RADEON_VID_CAN_AACOMPRESS: - return ws->aacompress; } return 0; } +static boolean radeon_cs_request_feature(struct radeon_winsys_cs *rcs, + enum radeon_feature_id fid, + boolean enable) +{ + struct radeon_drm_cs *cs = radeon_drm_cs(rcs); + + switch (fid) { + case RADEON_FID_HYPERZ_RAM_ACCESS: + if (debug_get_bool_option("RADEON_HYPERZ", FALSE)) { + return radeon_set_fd_access(cs, &cs->ws->hyperz_owner, + &cs->ws->hyperz_owner_mutex, + RADEON_INFO_WANT_HYPERZ, enable); + } else { + return FALSE; + } + + case RADEON_FID_CMASK_RAM_ACCESS: + if (debug_get_bool_option("RADEON_CMASK", FALSE)) { + return radeon_set_fd_access(cs, &cs->ws->cmask_owner, + &cs->ws->cmask_owner_mutex, + RADEON_INFO_WANT_CMASK, enable); + } else { + return FALSE; + } + } + return FALSE; +} + struct radeon_winsys *radeon_drm_winsys_create(int fd) { struct radeon_drm_winsys *ws = CALLOC_STRUCT(radeon_drm_winsys); @@ -231,10 +285,14 @@ struct radeon_winsys *radeon_drm_winsys_create(int fd) /* Set functions. */ ws->base.destroy = radeon_winsys_destroy; ws->base.get_value = radeon_get_value; + ws->base.cs_request_feature = radeon_cs_request_feature; radeon_bomgr_init_functions(ws); radeon_drm_cs_init_functions(ws); + pipe_mutex_init(ws->hyperz_owner_mutex); + pipe_mutex_init(ws->cmask_owner_mutex); + return &ws->base; fail: |