diff options
Diffstat (limited to 'src/gallium/winsys')
-rw-r--r-- | src/gallium/winsys/r600/drm/evergreen_hw_context.c | 19 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/r600.c | 5 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/r600_bo.c | 18 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/r600_drm.c | 74 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/r600_hw_context.c | 93 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/r600_priv.h | 14 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/r600d.h | 1 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/radeon_bo.c | 74 | ||||
-rw-r--r-- | src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c | 15 | ||||
-rw-r--r-- | src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h | 11 | ||||
-rw-r--r-- | src/gallium/winsys/sw/xlib/xlib_sw_winsys.c | 306 |
11 files changed, 414 insertions, 216 deletions
diff --git a/src/gallium/winsys/r600/drm/evergreen_hw_context.c b/src/gallium/winsys/r600/drm/evergreen_hw_context.c index 1355b079450..7f21b53ace0 100644 --- a/src/gallium/winsys/r600/drm/evergreen_hw_context.c +++ b/src/gallium/winsys/r600/drm/evergreen_hw_context.c @@ -613,6 +613,13 @@ int evergreen_context_init(struct r600_context *ctx, struct radeon *radeon) r = -ENOMEM; goto out_err; } + /* save 16dwords space for fence mecanism */ + ctx->pm4_ndwords -= 16; + + r = r600_context_init_fence(ctx); + if (r) { + goto out_err; + } /* init dirty list */ LIST_INITHEAD(&ctx->dirty); @@ -633,7 +640,7 @@ static inline void evergreen_context_pipe_state_set_resource(struct r600_context block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY); r600_bo_reference(ctx->radeon, &block->reloc[1].bo, NULL); r600_bo_reference(ctx->radeon , &block->reloc[2].bo, NULL); - LIST_DEL(&block->list); + LIST_DELINIT(&block->list); return; } block->reg[0] = state->regs[0].value; @@ -688,7 +695,7 @@ static inline void evergreen_context_pipe_state_set_sampler(struct r600_context block = range->blocks[CTX_BLOCK_ID(ctx, offset)]; if (state == NULL) { block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY); - LIST_DEL(&block->list); + LIST_DELINIT(&block->list); return; } block->reg[0] = state->regs[0].value; @@ -712,7 +719,7 @@ static inline void evergreen_context_pipe_state_set_sampler_border(struct r600_c block = range->blocks[CTX_BLOCK_ID(ctx, fake_offset)]; if (state == NULL) { block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY); - LIST_DEL(&block->list); + LIST_DELINIT(&block->list); return; } if (state->nregs <= 3) { @@ -755,7 +762,8 @@ void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *dr struct r600_bo *cb[12]; struct r600_bo *db; unsigned ndwords = 9, flush; - struct r600_block *dirty_block; + struct r600_block *dirty_block = NULL; + struct r600_block *next_block; if (draw->indices) { ndwords = 13; @@ -810,10 +818,9 @@ void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *dr } /* enough room to copy packet */ - LIST_FOR_EACH_ENTRY(dirty_block,&ctx->dirty,list) { + LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &ctx->dirty,list) { r600_context_block_emit_dirty(ctx, dirty_block); } - LIST_INITHEAD(&ctx->dirty); /* draw packet */ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_INDEX_TYPE, 0); diff --git a/src/gallium/winsys/r600/drm/r600.c b/src/gallium/winsys/r600/drm/r600.c index 496547ca994..0a4d2e791db 100644 --- a/src/gallium/winsys/r600/drm/r600.c +++ b/src/gallium/winsys/r600/drm/r600.c @@ -40,6 +40,11 @@ enum chip_class r600_get_family_class(struct radeon *radeon) return radeon->chip_class; } +struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon) +{ + return &radeon->tiling_info; +} + static int r600_get_device(struct radeon *r600) { struct drm_radeon_info info; diff --git a/src/gallium/winsys/r600/drm/r600_bo.c b/src/gallium/winsys/r600/drm/r600_bo.c index 9498f3a82ea..7d54ff18fc2 100644 --- a/src/gallium/winsys/r600/drm/r600_bo.c +++ b/src/gallium/winsys/r600/drm/r600_bo.c @@ -26,7 +26,9 @@ #include <pipe/p_compiler.h> #include <pipe/p_screen.h> #include <pipebuffer/pb_bufmgr.h> +#include "radeon_drm.h" #include "r600_priv.h" +#include "r600d.h" struct r600_bo *r600_bo(struct radeon *radeon, unsigned size, unsigned alignment, unsigned usage) @@ -55,7 +57,7 @@ struct r600_bo *r600_bo(struct radeon *radeon, } struct r600_bo *r600_bo_handle(struct radeon *radeon, - unsigned handle) + unsigned handle, unsigned *array_mode) { struct r600_bo *ws_bo = calloc(1, sizeof(struct r600_bo)); struct radeon_bo *bo; @@ -68,6 +70,20 @@ struct r600_bo *r600_bo_handle(struct radeon *radeon, bo = radeon_bo_pb_get_bo(ws_bo->pb); ws_bo->size = bo->size; pipe_reference_init(&ws_bo->reference, 1); + + radeon_bo_get_tiling_flags(radeon, bo, &ws_bo->tiling_flags, + &ws_bo->kernel_pitch); + if (array_mode) { + if (ws_bo->tiling_flags) { + if (ws_bo->tiling_flags & RADEON_TILING_MICRO) + *array_mode = V_0280A0_ARRAY_1D_TILED_THIN1; + if ((ws_bo->tiling_flags & (RADEON_TILING_MICRO | RADEON_TILING_MACRO)) == + (RADEON_TILING_MICRO | RADEON_TILING_MACRO)) + *array_mode = V_0280A0_ARRAY_2D_TILED_THIN1; + } else { + *array_mode = 0; + } + } return ws_bo; } diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c index 5f175a4df98..60c2f51fac0 100644 --- a/src/gallium/winsys/r600/drm/r600_drm.c +++ b/src/gallium/winsys/r600/drm/r600_drm.c @@ -37,6 +37,9 @@ #include "xf86drm.h" #include "radeon_drm.h" +#ifndef RADEON_INFO_TILING_CONFIG +#define RADEON_INFO_TILING_CONFIG 0x6 +#endif static int radeon_get_device(struct radeon *radeon) { struct drm_radeon_info info; @@ -50,6 +53,61 @@ static int radeon_get_device(struct radeon *radeon) return r; } +static int radeon_drm_get_tiling(struct radeon *radeon) +{ + struct drm_radeon_info info; + int r; + uint32_t tiling_config; + + info.request = RADEON_INFO_TILING_CONFIG; + info.value = (uintptr_t)&tiling_config; + r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info, + sizeof(struct drm_radeon_info)); + + if (r) + return 0; + + switch ((tiling_config & 0xe) >> 1) { + case 0: + radeon->tiling_info.num_channels = 1; + break; + case 1: + radeon->tiling_info.num_channels = 2; + break; + case 2: + radeon->tiling_info.num_channels = 4; + break; + case 3: + radeon->tiling_info.num_channels = 8; + break; + default: + return -EINVAL; + } + + switch ((tiling_config & 0x30) >> 4) { + case 0: + radeon->tiling_info.num_banks = 4; + break; + case 1: + radeon->tiling_info.num_banks = 8; + break; + default: + return -EINVAL; + + } + switch ((tiling_config & 0xc0) >> 6) { + case 0: + radeon->tiling_info.group_bytes = 256; + break; + case 1: + radeon->tiling_info.group_bytes = 512; + break; + default: + return -EINVAL; + } + return 0; +} + struct radeon *radeon_new(int fd, unsigned device) { struct radeon *radeon; @@ -157,6 +215,10 @@ struct radeon *radeon_new(int fd, unsigned device) break; } + if (radeon->chip_class == R600 || radeon->chip_class == R700) { + if (radeon_drm_get_tiling(radeon)) + return NULL; + } radeon->kman = radeon_bo_pbmgr_create(radeon); if (!radeon->kman) return NULL; @@ -179,9 +241,15 @@ struct radeon *radeon_decref(struct radeon *radeon) return NULL; } - radeon->cman->destroy(radeon->cman); - radeon->kman->destroy(radeon->kman); - drmClose(radeon->fd); + if (radeon->cman) + radeon->cman->destroy(radeon->cman); + + if (radeon->kman) + radeon->kman->destroy(radeon->kman); + + if (radeon->fd >= 0) + drmClose(radeon->fd); + free(radeon); return NULL; } diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index b379499f060..2521ff96473 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -41,6 +41,45 @@ #define GROUP_FORCE_NEW_BLOCK 0 +int r600_context_init_fence(struct r600_context *ctx) +{ + ctx->fence = 1; + ctx->fence_bo = r600_bo(ctx->radeon, 4096, 0, 0); + if (ctx->fence_bo == NULL) { + return -ENOMEM; + } + ctx->cfence = r600_bo_map(ctx->radeon, ctx->fence_bo, PB_USAGE_UNSYNCHRONIZED, NULL); + *ctx->cfence = 0; + LIST_INITHEAD(&ctx->fenced_bo); + return 0; +} + +static void INLINE r600_context_update_fenced_list(struct r600_context *ctx) +{ + for (int i = 0; i < ctx->creloc; i++) { + if (!LIST_IS_EMPTY(&ctx->bo[i]->fencedlist)) + LIST_DELINIT(&ctx->bo[i]->fencedlist); + LIST_ADDTAIL(&ctx->bo[i]->fencedlist, &ctx->fenced_bo); + ctx->bo[i]->fence = ctx->fence; + ctx->bo[i]->ctx = ctx; + } +} + +static void INLINE r600_context_fence_wraparound(struct r600_context *ctx, unsigned fence) +{ + struct radeon_bo *bo = NULL; + struct radeon_bo *tmp; + + LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &ctx->fenced_bo, fencedlist) { + if (bo->fence <= *ctx->cfence) { + LIST_DELINIT(&bo->fencedlist); + bo->fence = 0; + } else { + bo->fence = fence; + } + } +} + int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg, unsigned nreg) { struct r600_block *block; @@ -87,6 +126,8 @@ int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg, block->reg = &block->pm4[block->pm4_ndwords]; block->pm4_ndwords += n; block->nreg = n; + LIST_INITHEAD(&block->list); + for (j = 0; j < n; j++) { if (reg[i+j].need_bo) { block->nbo++; @@ -572,6 +613,9 @@ void r600_context_fini(struct r600_context *ctx) } free(ctx->reloc); free(ctx->pm4); + if (ctx->fence_bo) { + r600_bo_reference(ctx->radeon, &ctx->fence_bo, NULL); + } memset(ctx, 0, sizeof(struct r600_context)); } @@ -691,6 +735,13 @@ int r600_context_init(struct r600_context *ctx, struct radeon *radeon) r = -ENOMEM; goto out_err; } + /* save 16dwords space for fence mecanism */ + ctx->pm4_ndwords -= 16; + + r = r600_context_init_fence(ctx); + if (r) { + goto out_err; + } /* init dirty list */ LIST_INITHEAD(&ctx->dirty); @@ -781,7 +832,7 @@ static inline void r600_context_pipe_state_set_resource(struct r600_context *ctx block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY); r600_bo_reference(ctx->radeon, &block->reloc[1].bo, NULL); r600_bo_reference(ctx->radeon , &block->reloc[2].bo, NULL); - LIST_DEL(&block->list); + LIST_DELINIT(&block->list); return; } block->reg[0] = state->regs[0].value; @@ -835,7 +886,7 @@ static inline void r600_context_pipe_state_set_sampler(struct r600_context *ctx, block = range->blocks[CTX_BLOCK_ID(ctx, offset)]; if (state == NULL) { block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY); - LIST_DEL(&block->list); + LIST_DELINIT(&block->list); return; } block->reg[0] = state->regs[0].value; @@ -858,7 +909,7 @@ static inline void r600_context_pipe_state_set_sampler_border(struct r600_contex block = range->blocks[CTX_BLOCK_ID(ctx, offset)]; if (state == NULL) { block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY); - LIST_DEL(&block->list); + LIST_DELINIT(&block->list); return; } if (state->nregs <= 3) { @@ -917,7 +968,8 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw) struct r600_bo *cb[8]; struct r600_bo *db; unsigned ndwords = 9; - struct r600_block *dirty_block; + struct r600_block *dirty_block = NULL; + struct r600_block *next_block; if (draw->indices) { ndwords = 13; @@ -970,10 +1022,9 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw) } /* enough room to copy packet */ - LIST_FOR_EACH_ENTRY(dirty_block,&ctx->dirty,list) { + LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &ctx->dirty,list) { r600_context_block_emit_dirty(ctx, dirty_block); } - LIST_INITHEAD(&ctx->dirty); /* draw packet */ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_INDEX_TYPE, 0); @@ -1019,6 +1070,7 @@ void r600_context_flush(struct r600_context *ctx) struct drm_radeon_cs drmib; struct drm_radeon_cs_chunk chunks[2]; uint64_t chunk_array[2]; + unsigned fence; int r; if (!ctx->pm4_cdwords) @@ -1028,6 +1080,18 @@ void r600_context_flush(struct r600_context *ctx) r600_context_queries_suspend(ctx); radeon_bo_pbmgr_flush_maps(ctx->radeon->kman); + + /* emit fence */ + ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE_EOP, 4); + ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT | (5 << 8); + ctx->pm4[ctx->pm4_cdwords++] = 0; + ctx->pm4[ctx->pm4_cdwords++] = (1 << 29) | (0 << 24); + ctx->pm4[ctx->pm4_cdwords++] = ctx->fence; + ctx->pm4[ctx->pm4_cdwords++] = 0; + ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0); + ctx->pm4[ctx->pm4_cdwords++] = 0; + r600_context_bo_reloc(ctx, &ctx->pm4[ctx->pm4_cdwords - 1], ctx->fence_bo); + #if 1 /* emit cs */ drmib.num_chunks = 2; @@ -1043,8 +1107,18 @@ void r600_context_flush(struct r600_context *ctx) r = drmCommandWriteRead(ctx->radeon->fd, DRM_RADEON_CS, &drmib, sizeof(struct drm_radeon_cs)); #endif + + r600_context_update_fenced_list(ctx); + + fence = ctx->fence + 1; + if (fence < ctx->fence) { + /* wrap around */ + fence = 1; + r600_context_fence_wraparound(ctx, fence); + } + ctx->fence = fence; + /* restart */ - radeon_bo_fencelist(ctx->radeon, ctx->bo, ctx->creloc); for (int i = 0; i < ctx->creloc; i++) { ctx->bo[i]->reloc = NULL; ctx->bo[i]->last_flush = 0; @@ -1062,8 +1136,9 @@ void r600_context_flush(struct r600_context *ctx) */ for (int i = 0; i < ctx->nblocks; i++) { if (ctx->blocks[i]->status & R600_BLOCK_STATUS_ENABLED) { - if(!(ctx->blocks[i]->status & R600_BLOCK_STATUS_DIRTY)) + if(!(ctx->blocks[i]->status & R600_BLOCK_STATUS_DIRTY)) { LIST_ADDTAIL(&ctx->blocks[i]->list,&ctx->dirty); + } ctx->pm4_dirty_cdwords += ctx->blocks[i]->pm4_ndwords + ctx->blocks[i]->pm4_flush_ndwords; ctx->blocks[i]->status |= R600_BLOCK_STATUS_DIRTY; } @@ -1243,7 +1318,7 @@ struct r600_query *r600_context_query_create(struct r600_context *ctx, unsigned void r600_context_query_destroy(struct r600_context *ctx, struct r600_query *query) { r600_bo_reference(ctx->radeon, &query->buffer, NULL); - LIST_DEL(&query->list); + LIST_DELINIT(&query->list); free(query); } diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h index ea2cf347785..b5bd7bd92c1 100644 --- a/src/gallium/winsys/r600/drm/r600_priv.h +++ b/src/gallium/winsys/r600/drm/r600_priv.h @@ -42,6 +42,7 @@ struct radeon { enum chip_class chip_class; struct pb_manager *kman; /* kernel bo manager */ struct pb_manager *cman; /* cached bo manager */ + struct r600_tiling_info tiling_info; }; struct radeon *r600_new(int fd, unsigned device); @@ -64,9 +65,9 @@ struct radeon_bo { unsigned map_count; void *data; struct list_head fencedlist; + unsigned fence; + struct r600_context *ctx; boolean shared; - int64_t last_busy; - boolean set_busy; struct r600_reloc *reloc; unsigned reloc_id; unsigned last_flush; @@ -76,6 +77,8 @@ struct r600_bo { struct pipe_reference reference; struct pb_buffer *pb; unsigned size; + unsigned tiling_flags; + unsigned kernel_pitch; }; @@ -94,7 +97,10 @@ int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo); int radeon_bo_busy(struct radeon *radeon, struct radeon_bo *bo, uint32_t *domain); void radeon_bo_pbmgr_flush_maps(struct pb_manager *_mgr); int radeon_bo_fencelist(struct radeon *radeon, struct radeon_bo **bolist, uint32_t num_bo); - +int radeon_bo_get_tiling_flags(struct radeon *radeon, + struct radeon_bo *bo, + uint32_t *tiling_flags, + uint32_t *pitch); /* radeon_bo_pb.c */ struct radeon_bo *radeon_bo_pb_get_bo(struct pb_buffer *_buf); @@ -103,6 +109,7 @@ struct pb_buffer *radeon_bo_pb_create_buffer_from_handle(struct pb_manager *_mgr uint32_t handle); /* r600_hw_context.c */ +int r600_context_init_fence(struct r600_context *ctx); void r600_context_bo_reloc(struct r600_context *ctx, u32 *pm4, struct r600_bo *rbo); void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags, unsigned flush_mask, struct r600_bo *rbo); @@ -161,6 +168,7 @@ static inline void r600_context_block_emit_dirty(struct r600_context *ctx, struc memcpy(&ctx->pm4[ctx->pm4_cdwords], block->pm4, block->pm4_ndwords * 4); ctx->pm4_cdwords += block->pm4_ndwords; block->status ^= R600_BLOCK_STATUS_DIRTY; + LIST_DELINIT(&block->list); } static inline int radeon_bo_map(struct radeon *radeon, struct radeon_bo *bo) diff --git a/src/gallium/winsys/r600/drm/r600d.h b/src/gallium/winsys/r600/drm/r600d.h index ccc9ffaf8e3..d91f7737af3 100644 --- a/src/gallium/winsys/r600/drm/r600d.h +++ b/src/gallium/winsys/r600/drm/r600d.h @@ -91,6 +91,7 @@ #define PKT3_SET_CTL_CONST 0x6F #define PKT3_SURFACE_BASE_UPDATE 0x73 +#define EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT 0x14 #define EVENT_TYPE_ZPASS_DONE 0x15 #define EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT 0x16 diff --git a/src/gallium/winsys/r600/drm/radeon_bo.c b/src/gallium/winsys/r600/drm/radeon_bo.c index 42a23f0ab8f..9d664b7e537 100644 --- a/src/gallium/winsys/r600/drm/radeon_bo.c +++ b/src/gallium/winsys/r600/drm/radeon_bo.c @@ -32,7 +32,6 @@ #include "r600_priv.h" #include "xf86drm.h" #include "radeon_drm.h" -#include "util/u_time.h" static int radeon_bo_fixed_map(struct radeon *radeon, struct radeon_bo *bo) { @@ -128,7 +127,6 @@ struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle, return bo; } - static void radeon_bo_destroy(struct radeon *radeon, struct radeon_bo *bo) { struct drm_gem_close args; @@ -158,8 +156,14 @@ int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo) struct drm_radeon_gem_wait_idle args; int ret; - if (LIST_IS_EMPTY(&bo->fencedlist) && !bo->shared) + if (!bo->fence && !bo->shared) + return 0; + + if (bo->fence <= *bo->ctx->cfence) { + LIST_DELINIT(&bo->fencedlist); + bo->fence = 0; return 0; + } /* Zero out args to make valgrind happy */ memset(&args, 0, sizeof(args)); @@ -171,22 +175,20 @@ int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo) return ret; } -#define BO_BUSY_BACKOFF 10000 - int radeon_bo_busy(struct radeon *radeon, struct radeon_bo *bo, uint32_t *domain) { struct drm_radeon_gem_busy args; int ret; - int64_t now; - - now = os_time_get(); - if (LIST_IS_EMPTY(&bo->fencedlist) && !bo->shared) - return 0; - - if (bo->set_busy && (now - bo->last_busy < BO_BUSY_BACKOFF)) - return -EBUSY; - bo->set_busy = FALSE; + if (!bo->shared) { + if (!bo->fence) + return 0; + if (bo->fence <= *bo->ctx->cfence) { + LIST_DELINIT(&bo->fencedlist); + bo->fence = 0; + return 0; + } + } memset(&args, 0, sizeof(args)); args.handle = bo->handle; @@ -195,37 +197,25 @@ int radeon_bo_busy(struct radeon *radeon, struct radeon_bo *bo, uint32_t *domain ret = drmCommandWriteRead(radeon->fd, DRM_RADEON_GEM_BUSY, &args, sizeof(args)); - if (ret == 0) { - struct radeon_bo *entry, *tent; - LIST_FOR_EACH_ENTRY_SAFE(entry, tent, &bo->fencedlist, fencedlist) { - LIST_DELINIT(&entry->fencedlist); - } - } else { - bo->set_busy = TRUE; - bo->last_busy = now; - } *domain = args.domain; return ret; } -int radeon_bo_fencelist(struct radeon *radeon, struct radeon_bo **bolist, - uint32_t num_bo) +int radeon_bo_get_tiling_flags(struct radeon *radeon, + struct radeon_bo *bo, + uint32_t *tiling_flags, + uint32_t *pitch) { - struct radeon_bo *first; - int i; - - first = bolist[0]; - - if (!LIST_IS_EMPTY(&first->fencedlist)) - LIST_DELINIT(&first->fencedlist); - - LIST_INITHEAD(&first->fencedlist); - - for (i = 1; i < num_bo; i++) { - if (!LIST_IS_EMPTY(&bolist[i]->fencedlist)) - LIST_DELINIT(&bolist[i]->fencedlist); - - LIST_ADDTAIL(&bolist[i]->fencedlist, &first->fencedlist); - } - return 0; + struct drm_radeon_gem_get_tiling args; + int ret; + + args.handle = bo->handle; + ret = drmCommandWriteRead(radeon->fd, DRM_RADEON_GEM_GET_TILING, + &args, sizeof(args)); + if (ret) + return ret; + + *tiling_flags = args.tiling_flags; + *pitch = args.pitch; + return ret; } diff --git a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c index 3a76098b655..bc2623e7b77 100644 --- a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c +++ b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c @@ -272,7 +272,7 @@ wsw_destroy(struct sw_winsys *ws) } struct sw_winsys * -wrapper_sw_winsys_warp_pipe_screen(struct pipe_screen *screen) +wrapper_sw_winsys_wrap_pipe_screen(struct pipe_screen *screen) { struct wrapper_sw_winsys *wsw = CALLOC_STRUCT(wrapper_sw_winsys); @@ -304,3 +304,16 @@ err_free: err: return NULL; } + +struct pipe_screen * +wrapper_sw_winsys_dewrap_pipe_screen(struct sw_winsys *ws) +{ + struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws); + struct pipe_screen *screen = wsw->screen; + + wsw->pipe->destroy(wsw->pipe); + /* don't destroy the screen its needed later on */ + + FREE(wsw); + return screen; +} diff --git a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h index b5c25a3c50f..ae0196c432c 100644 --- a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h +++ b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h @@ -30,6 +30,15 @@ struct sw_winsys; struct pipe_screen; -struct sw_winsys *wrapper_sw_winsys_warp_pipe_screen(struct pipe_screen *screen); +/* + * Wrap a pipe screen. + */ +struct sw_winsys *wrapper_sw_winsys_wrap_pipe_screen(struct pipe_screen *screen); + +/* + * Destroy the sw_winsys and return the wrapped pipe_screen. + * Not destroying it as sw_winsys::destroy does. + */ +struct pipe_screen *wrapper_sw_winsys_dewrap_pipe_screen(struct sw_winsys *sw_winsys); #endif diff --git a/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c b/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c index b78f537c125..3aef8daa423 100644 --- a/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c +++ b/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c @@ -54,7 +54,7 @@ DEBUG_GET_ONCE_BOOL_OPTION(xlib_no_shm, "XLIB_NO_SHM", FALSE) * Display target for Xlib winsys. * Low-level OS/window system memory buffer */ -struct xm_displaytarget +struct xlib_displaytarget { enum pipe_format format; unsigned width; @@ -75,7 +75,7 @@ struct xm_displaytarget Drawable drawable; XShmSegmentInfo shminfo; - int shm; + Bool shm; /** Using shared memory images? */ }; @@ -85,19 +85,16 @@ struct xm_displaytarget struct xlib_sw_winsys { struct sw_winsys base; - - - Display *display; }; /** Cast wrapper */ -static INLINE struct xm_displaytarget * -xm_displaytarget( struct sw_displaytarget *dt ) +static INLINE struct xlib_displaytarget * +xlib_displaytarget(struct sw_displaytarget *dt) { - return (struct xm_displaytarget *)dt; + return (struct xlib_displaytarget *) dt; } @@ -105,22 +102,23 @@ xm_displaytarget( struct sw_displaytarget *dt ) * X Shared Memory Image extension code */ -static volatile int mesaXErrorFlag = 0; +static volatile int XErrorFlag = 0; /** * Catches potential Xlib errors. */ static int -mesaHandleXError(Display *dpy, XErrorEvent *event) +handle_xerror(Display *dpy, XErrorEvent *event) { (void) dpy; (void) event; - mesaXErrorFlag = 1; + XErrorFlag = 1; return 0; } -static char *alloc_shm(struct xm_displaytarget *buf, unsigned size) +static char * +alloc_shm(struct xlib_displaytarget *buf, unsigned size) { XShmSegmentInfo *const shminfo = & buf->shminfo; @@ -144,10 +142,10 @@ static char *alloc_shm(struct xm_displaytarget *buf, unsigned size) /** - * Allocate a shared memory XImage back buffer for the given XMesaBuffer. + * Allocate a shared memory XImage back buffer for the given display target. */ static void -alloc_shm_ximage(struct xm_displaytarget *xm_dt, +alloc_shm_ximage(struct xlib_displaytarget *xlib_dt, struct xlib_drawable *xmb, unsigned width, unsigned height) { @@ -159,51 +157,54 @@ alloc_shm_ximage(struct xm_displaytarget *xm_dt, */ int (*old_handler)(Display *, XErrorEvent *); - xm_dt->tempImage = XShmCreateImage(xm_dt->display, + xlib_dt->tempImage = XShmCreateImage(xlib_dt->display, xmb->visual, xmb->depth, ZPixmap, NULL, - &xm_dt->shminfo, + &xlib_dt->shminfo, width, height); - if (xm_dt->tempImage == NULL) { - xm_dt->shm = 0; + if (xlib_dt->tempImage == NULL) { + xlib_dt->shm = False; return; } - mesaXErrorFlag = 0; - old_handler = XSetErrorHandler(mesaHandleXError); + XErrorFlag = 0; + old_handler = XSetErrorHandler(handle_xerror); /* This may trigger the X protocol error we're ready to catch: */ - XShmAttach(xm_dt->display, &xm_dt->shminfo); - XSync(xm_dt->display, False); + XShmAttach(xlib_dt->display, &xlib_dt->shminfo); + XSync(xlib_dt->display, False); - if (mesaXErrorFlag) { + if (XErrorFlag) { /* we are on a remote display, this error is normal, don't print it */ - XFlush(xm_dt->display); - mesaXErrorFlag = 0; - XDestroyImage(xm_dt->tempImage); - xm_dt->tempImage = NULL; - xm_dt->shm = 0; + XFlush(xlib_dt->display); + XErrorFlag = 0; + XDestroyImage(xlib_dt->tempImage); + xlib_dt->tempImage = NULL; + xlib_dt->shm = False; (void) XSetErrorHandler(old_handler); return; } - xm_dt->shm = 1; + xlib_dt->shm = True; } static void -alloc_ximage(struct xm_displaytarget *xm_dt, +alloc_ximage(struct xlib_displaytarget *xlib_dt, struct xlib_drawable *xmb, unsigned width, unsigned height) { - if (xm_dt->shm) { - alloc_shm_ximage(xm_dt, xmb, width, height); - return; + /* try allocating a shared memory image first */ + if (xlib_dt->shm) { + alloc_shm_ximage(xlib_dt, xmb, width, height); + if (xlib_dt->tempImage) + return; /* success */ } - xm_dt->tempImage = XCreateImage(xm_dt->display, + /* try regular (non-shared memory) image */ + xlib_dt->tempImage = XCreateImage(xlib_dt->display, xmb->visual, xmb->depth, ZPixmap, 0, @@ -212,9 +213,9 @@ alloc_ximage(struct xm_displaytarget *xm_dt, } static boolean -xm_is_displaytarget_format_supported( struct sw_winsys *ws, - unsigned tex_usage, - enum pipe_format format ) +xlib_is_displaytarget_format_supported(struct sw_winsys *ws, + unsigned tex_usage, + enum pipe_format format) { /* TODO: check visuals or other sensible thing here */ return TRUE; @@ -222,61 +223,67 @@ xm_is_displaytarget_format_supported( struct sw_winsys *ws, static void * -xm_displaytarget_map(struct sw_winsys *ws, - struct sw_displaytarget *dt, - unsigned flags) +xlib_displaytarget_map(struct sw_winsys *ws, + struct sw_displaytarget *dt, + unsigned flags) { - struct xm_displaytarget *xm_dt = xm_displaytarget(dt); - xm_dt->mapped = xm_dt->data; - return xm_dt->mapped; + struct xlib_displaytarget *xlib_dt = xlib_displaytarget(dt); + xlib_dt->mapped = xlib_dt->data; + return xlib_dt->mapped; } + static void -xm_displaytarget_unmap(struct sw_winsys *ws, - struct sw_displaytarget *dt) +xlib_displaytarget_unmap(struct sw_winsys *ws, + struct sw_displaytarget *dt) { - struct xm_displaytarget *xm_dt = xm_displaytarget(dt); - xm_dt->mapped = NULL; + struct xlib_displaytarget *xlib_dt = xlib_displaytarget(dt); + xlib_dt->mapped = NULL; } + static void -xm_displaytarget_destroy(struct sw_winsys *ws, - struct sw_displaytarget *dt) +xlib_displaytarget_destroy(struct sw_winsys *ws, + struct sw_displaytarget *dt) { - struct xm_displaytarget *xm_dt = xm_displaytarget(dt); + struct xlib_displaytarget *xlib_dt = xlib_displaytarget(dt); - if (xm_dt->data) { - if (xm_dt->shminfo.shmid >= 0) { - shmdt(xm_dt->shminfo.shmaddr); - shmctl(xm_dt->shminfo.shmid, IPC_RMID, 0); + if (xlib_dt->data) { + if (xlib_dt->shminfo.shmid >= 0) { + shmdt(xlib_dt->shminfo.shmaddr); + shmctl(xlib_dt->shminfo.shmid, IPC_RMID, 0); - xm_dt->shminfo.shmid = -1; - xm_dt->shminfo.shmaddr = (char *) -1; + xlib_dt->shminfo.shmid = -1; + xlib_dt->shminfo.shmaddr = (char *) -1; + + xlib_dt->data = NULL; + if (xlib_dt->tempImage) + xlib_dt->tempImage->data = NULL; } else { - FREE(xm_dt->data); - if (xm_dt->tempImage && xm_dt->tempImage->data == xm_dt->data) { - xm_dt->tempImage->data = NULL; + FREE(xlib_dt->data); + if (xlib_dt->tempImage && xlib_dt->tempImage->data == xlib_dt->data) { + xlib_dt->tempImage->data = NULL; } - xm_dt->data = NULL; + xlib_dt->data = NULL; } } - if (xm_dt->tempImage) { - XDestroyImage(xm_dt->tempImage); - xm_dt->tempImage = NULL; + if (xlib_dt->tempImage) { + XDestroyImage(xlib_dt->tempImage); + xlib_dt->tempImage = NULL; } - if (xm_dt->gc) - XFreeGC(xm_dt->display, xm_dt->gc); + if (xlib_dt->gc) + XFreeGC(xlib_dt->display, xlib_dt->gc); - FREE(xm_dt); + FREE(xlib_dt); } /** * Display/copy the image in the surface into the X window specified - * by the XMesaBuffer. + * by the display target. */ static void xlib_sw_display(struct xlib_drawable *xlib_drawable, @@ -284,8 +291,8 @@ xlib_sw_display(struct xlib_drawable *xlib_drawable, { static boolean no_swap = 0; static boolean firsttime = 1; - struct xm_displaytarget *xm_dt = xm_displaytarget(dt); - Display *display = xm_dt->display; + struct xlib_displaytarget *xlib_dt = xlib_displaytarget(dt); + Display *display = xlib_dt->display; XImage *ximage; if (firsttime) { @@ -296,74 +303,74 @@ xlib_sw_display(struct xlib_drawable *xlib_drawable, if (no_swap) return; - if (xm_dt->drawable != xlib_drawable->drawable) { - if (xm_dt->gc) { - XFreeGC( display, xm_dt->gc ); - xm_dt->gc = NULL; + if (xlib_dt->drawable != xlib_drawable->drawable) { + if (xlib_dt->gc) { + XFreeGC(display, xlib_dt->gc); + xlib_dt->gc = NULL; } - if (xm_dt->tempImage) { - XDestroyImage( xm_dt->tempImage ); - xm_dt->tempImage = NULL; + if (xlib_dt->tempImage) { + XDestroyImage(xlib_dt->tempImage); + xlib_dt->tempImage = NULL; } - xm_dt->drawable = xlib_drawable->drawable; + xlib_dt->drawable = xlib_drawable->drawable; } - if (xm_dt->tempImage == NULL) { - assert(util_format_get_blockwidth(xm_dt->format) == 1); - assert(util_format_get_blockheight(xm_dt->format) == 1); - alloc_ximage(xm_dt, xlib_drawable, - xm_dt->stride / util_format_get_blocksize(xm_dt->format), - xm_dt->height); - if (!xm_dt->tempImage) + if (xlib_dt->tempImage == NULL) { + assert(util_format_get_blockwidth(xlib_dt->format) == 1); + assert(util_format_get_blockheight(xlib_dt->format) == 1); + alloc_ximage(xlib_dt, xlib_drawable, + xlib_dt->stride / util_format_get_blocksize(xlib_dt->format), + xlib_dt->height); + if (!xlib_dt->tempImage) return; } - if (xm_dt->gc == NULL) { - xm_dt->gc = XCreateGC( display, xlib_drawable->drawable, 0, NULL ); - XSetFunction( display, xm_dt->gc, GXcopy ); + if (xlib_dt->gc == NULL) { + xlib_dt->gc = XCreateGC(display, xlib_drawable->drawable, 0, NULL); + XSetFunction(display, xlib_dt->gc, GXcopy); } - if (xm_dt->shm) - { - ximage = xm_dt->tempImage; - ximage->data = xm_dt->data; + if (xlib_dt->shm) { + ximage = xlib_dt->tempImage; + ximage->data = xlib_dt->data; /* _debug_printf("XSHM\n"); */ - XShmPutImage(xm_dt->display, xlib_drawable->drawable, xm_dt->gc, - ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height, False); + XShmPutImage(xlib_dt->display, xlib_drawable->drawable, xlib_dt->gc, + ximage, 0, 0, 0, 0, xlib_dt->width, xlib_dt->height, False); } else { /* display image in Window */ - ximage = xm_dt->tempImage; - ximage->data = xm_dt->data; + ximage = xlib_dt->tempImage; + ximage->data = xlib_dt->data; /* check that the XImage has been previously initialized */ assert(ximage->format); assert(ximage->bitmap_unit); /* update XImage's fields */ - ximage->width = xm_dt->width; - ximage->height = xm_dt->height; - ximage->bytes_per_line = xm_dt->stride; + ximage->width = xlib_dt->width; + ximage->height = xlib_dt->height; + ximage->bytes_per_line = xlib_dt->stride; /* _debug_printf("XPUT\n"); */ - XPutImage(xm_dt->display, xlib_drawable->drawable, xm_dt->gc, - ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height); + XPutImage(xlib_dt->display, xlib_drawable->drawable, xlib_dt->gc, + ximage, 0, 0, 0, 0, xlib_dt->width, xlib_dt->height); } - XFlush(xm_dt->display); + XFlush(xlib_dt->display); } + /** * Display/copy the image in the surface into the X window specified - * by the XMesaBuffer. + * by the display target. */ static void -xm_displaytarget_display(struct sw_winsys *ws, - struct sw_displaytarget *dt, - void *context_private) +xlib_displaytarget_display(struct sw_winsys *ws, + struct sw_displaytarget *dt, + void *context_private) { struct xlib_drawable *xlib_drawable = (struct xlib_drawable *)context_private; xlib_sw_display(xlib_drawable, dt); @@ -371,57 +378,57 @@ xm_displaytarget_display(struct sw_winsys *ws, static struct sw_displaytarget * -xm_displaytarget_create(struct sw_winsys *winsys, - unsigned tex_usage, - enum pipe_format format, - unsigned width, unsigned height, - unsigned alignment, - unsigned *stride) +xlib_displaytarget_create(struct sw_winsys *winsys, + unsigned tex_usage, + enum pipe_format format, + unsigned width, unsigned height, + unsigned alignment, + unsigned *stride) { - struct xm_displaytarget *xm_dt; + struct xlib_displaytarget *xlib_dt; unsigned nblocksy, size; - xm_dt = CALLOC_STRUCT(xm_displaytarget); - if(!xm_dt) - goto no_xm_dt; + xlib_dt = CALLOC_STRUCT(xlib_displaytarget); + if (!xlib_dt) + goto no_xlib_dt; - xm_dt->display = ((struct xlib_sw_winsys *)winsys)->display; - xm_dt->format = format; - xm_dt->width = width; - xm_dt->height = height; + xlib_dt->display = ((struct xlib_sw_winsys *)winsys)->display; + xlib_dt->format = format; + xlib_dt->width = width; + xlib_dt->height = height; nblocksy = util_format_get_nblocksy(format, height); - xm_dt->stride = align(util_format_get_stride(format, width), alignment); - size = xm_dt->stride * nblocksy; + xlib_dt->stride = align(util_format_get_stride(format, width), alignment); + size = xlib_dt->stride * nblocksy; if (!debug_get_option_xlib_no_shm()) { - xm_dt->data = alloc_shm(xm_dt, size); - if (xm_dt->data) { - xm_dt->shm = TRUE; + xlib_dt->data = alloc_shm(xlib_dt, size); + if (xlib_dt->data) { + xlib_dt->shm = True; } } - if(!xm_dt->data) { - xm_dt->data = align_malloc(size, alignment); - if(!xm_dt->data) + if (!xlib_dt->data) { + xlib_dt->data = align_malloc(size, alignment); + if (!xlib_dt->data) goto no_data; } - *stride = xm_dt->stride; - return (struct sw_displaytarget *)xm_dt; + *stride = xlib_dt->stride; + return (struct sw_displaytarget *)xlib_dt; no_data: - FREE(xm_dt); -no_xm_dt: + FREE(xlib_dt); +no_xlib_dt: return NULL; } static struct sw_displaytarget * -xm_displaytarget_from_handle(struct sw_winsys *winsys, - const struct pipe_resource *templet, - struct winsys_handle *whandle, - unsigned *stride) +xlib_displaytarget_from_handle(struct sw_winsys *winsys, + const struct pipe_resource *templet, + struct winsys_handle *whandle, + unsigned *stride) { assert(0); return NULL; @@ -429,9 +436,9 @@ xm_displaytarget_from_handle(struct sw_winsys *winsys, static boolean -xm_displaytarget_get_handle(struct sw_winsys *winsys, - struct sw_displaytarget *dt, - struct winsys_handle *whandle) +xlib_displaytarget_get_handle(struct sw_winsys *winsys, + struct sw_displaytarget *dt, + struct winsys_handle *whandle) { assert(0); return FALSE; @@ -439,14 +446,14 @@ xm_displaytarget_get_handle(struct sw_winsys *winsys, static void -xm_destroy( struct sw_winsys *ws ) +xlib_destroy(struct sw_winsys *ws) { FREE(ws); } struct sw_winsys * -xlib_create_sw_winsys( Display *display ) +xlib_create_sw_winsys(Display *display) { struct xlib_sw_winsys *ws; @@ -455,19 +462,18 @@ xlib_create_sw_winsys( Display *display ) return NULL; ws->display = display; - ws->base.destroy = xm_destroy; + ws->base.destroy = xlib_destroy; - ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported; + ws->base.is_displaytarget_format_supported = xlib_is_displaytarget_format_supported; - ws->base.displaytarget_create = xm_displaytarget_create; - ws->base.displaytarget_from_handle = xm_displaytarget_from_handle; - ws->base.displaytarget_get_handle = xm_displaytarget_get_handle; - ws->base.displaytarget_map = xm_displaytarget_map; - ws->base.displaytarget_unmap = xm_displaytarget_unmap; - ws->base.displaytarget_destroy = xm_displaytarget_destroy; + ws->base.displaytarget_create = xlib_displaytarget_create; + ws->base.displaytarget_from_handle = xlib_displaytarget_from_handle; + ws->base.displaytarget_get_handle = xlib_displaytarget_get_handle; + ws->base.displaytarget_map = xlib_displaytarget_map; + ws->base.displaytarget_unmap = xlib_displaytarget_unmap; + ws->base.displaytarget_destroy = xlib_displaytarget_destroy; - ws->base.displaytarget_display = xm_displaytarget_display; + ws->base.displaytarget_display = xlib_displaytarget_display; return &ws->base; } - |