summaryrefslogtreecommitdiffstats
path: root/src/gallium/winsys
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys')
-rw-r--r--src/gallium/winsys/r600/drm/evergreen_hw_context.c19
-rw-r--r--src/gallium/winsys/r600/drm/r600.c5
-rw-r--r--src/gallium/winsys/r600/drm/r600_bo.c18
-rw-r--r--src/gallium/winsys/r600/drm/r600_drm.c74
-rw-r--r--src/gallium/winsys/r600/drm/r600_hw_context.c93
-rw-r--r--src/gallium/winsys/r600/drm/r600_priv.h14
-rw-r--r--src/gallium/winsys/r600/drm/r600d.h1
-rw-r--r--src/gallium/winsys/r600/drm/radeon_bo.c74
-rw-r--r--src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c15
-rw-r--r--src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h11
-rw-r--r--src/gallium/winsys/sw/xlib/xlib_sw_winsys.c306
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;
}
-