diff options
35 files changed, 1003 insertions, 745 deletions
diff --git a/src/gallium/drivers/i965/brw_batchbuffer.c b/src/gallium/drivers/i965/brw_batchbuffer.c index ca612e5ed0b..e5f73bd6a31 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.c +++ b/src/gallium/drivers/i965/brw_batchbuffer.c @@ -38,17 +38,17 @@ #define USE_MALLOC_BUFFER 1 #define ALWAYS_EMIT_MI_FLUSH 1 -void +enum pipe_error brw_batchbuffer_reset(struct brw_batchbuffer *batch) { - if (batch->buf) { - batch->sws->bo_unreference(batch->buf); - batch->buf = NULL; - } + enum pipe_error ret; - batch->buf = batch->sws->bo_alloc(batch->sws, - BRW_BUFFER_TYPE_BATCH, - BRW_BATCH_SIZE, 4096); + ret = batch->sws->bo_alloc( batch->sws, + BRW_BUFFER_TYPE_BATCH, + BRW_BATCH_SIZE, 4096, + &batch->buf ); + if (ret) + return ret; if (batch->malloc_buffer) batch->map = batch->malloc_buffer; @@ -59,6 +59,7 @@ brw_batchbuffer_reset(struct brw_batchbuffer *batch) batch->size = BRW_BATCH_SIZE; batch->ptr = batch->map; + return PIPE_OK; } struct brw_batchbuffer * @@ -91,7 +92,7 @@ brw_batchbuffer_free(struct brw_batchbuffer *batch) batch->map = NULL; } - batch->sws->bo_unreference(batch->buf); + bo_reference(&batch->buf, NULL); FREE(batch); } diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h index 1f04826aea6..288a9d27555 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.h +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -65,7 +65,8 @@ void _brw_batchbuffer_flush(struct brw_batchbuffer *batch, const char *file, int line); -void brw_batchbuffer_reset(struct brw_batchbuffer *batch); +enum pipe_error +brw_batchbuffer_reset(struct brw_batchbuffer *batch); /* Unlike bmBufferData, this currently requires the buffer be mapped. diff --git a/src/gallium/drivers/i965/brw_cc.c b/src/gallium/drivers/i965/brw_cc.c index 20967f01911..8e25fe85854 100644 --- a/src/gallium/drivers/i965/brw_cc.c +++ b/src/gallium/drivers/i965/brw_cc.c @@ -57,10 +57,11 @@ static void calc_sane_viewport( const struct pipe_viewport_state *vp, svp->far = 1; } -static int prepare_cc_vp( struct brw_context *brw ) +static enum pipe_error prepare_cc_vp( struct brw_context *brw ) { struct brw_cc_viewport ccv; struct sane_viewport svp; + enum pipe_error ret; memset(&ccv, 0, sizeof(ccv)); @@ -70,10 +71,12 @@ static int prepare_cc_vp( struct brw_context *brw ) ccv.min_depth = svp.near; ccv.max_depth = svp.far; - brw->sws->bo_unreference(brw->cc.vp_bo); - brw->cc.vp_bo = brw_cache_data( &brw->cache, BRW_CC_VP, &ccv, NULL, 0 ); - - return 0; + ret = brw_cache_data( &brw->cache, BRW_CC_VP, &ccv, NULL, 0, + &brw->cc.vp_bo ); + if (ret) + return ret; + + return PIPE_OK; } const struct brw_tracked_state brw_cc_vp = { @@ -123,11 +126,13 @@ cc_unit_populate_key(const struct brw_context *brw, /** * Creates the state cache entry for the given CC unit key. */ -static struct brw_winsys_buffer * -cc_unit_create_from_key(struct brw_context *brw, struct brw_cc_unit_key *key) +static enum pipe_error +cc_unit_create_from_key(struct brw_context *brw, + struct brw_cc_unit_key *key, + struct brw_winsys_buffer **bo_out) { struct brw_cc_unit_state cc; - struct brw_winsys_buffer *bo; + enum pipe_error ret; memset(&cc, 0, sizeof(cc)); @@ -143,38 +148,48 @@ cc_unit_create_from_key(struct brw_context *brw, struct brw_cc_unit_key *key) cc.cc6 = key->cc6; cc.cc7 = key->cc7; - bo = brw_upload_cache(&brw->cache, BRW_CC_UNIT, - key, sizeof(*key), - &brw->cc.vp_bo, 1, - &cc, sizeof(cc), - NULL, NULL); + ret = brw_upload_cache(&brw->cache, BRW_CC_UNIT, + key, sizeof(*key), + &brw->cc.vp_bo, 1, + &cc, sizeof(cc), + NULL, NULL, + bo_out); + if (ret) + return ret; - /* Emit CC viewport relocation */ - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_STATE, - 0, - offsetof(struct brw_cc_unit_state, cc4), - brw->cc.vp_bo); - return bo; + /* Emit CC viewport relocation */ + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_STATE, + 0, + offsetof(struct brw_cc_unit_state, cc4), + brw->cc.vp_bo); + if (ret) + return ret; + + return PIPE_OK; } static int prepare_cc_unit( struct brw_context *brw ) { struct brw_cc_unit_key key; + enum pipe_error ret; cc_unit_populate_key(brw, &key); - brw->sws->bo_unreference(brw->cc.state_bo); - brw->cc.state_bo = brw_search_cache(&brw->cache, BRW_CC_UNIT, - &key, sizeof(key), - &brw->cc.vp_bo, 1, - NULL); - - if (brw->cc.state_bo == NULL) - brw->cc.state_bo = cc_unit_create_from_key(brw, &key); + if (brw_search_cache(&brw->cache, BRW_CC_UNIT, + &key, sizeof(key), + &brw->cc.vp_bo, 1, + NULL, + &brw->cc.state_bo)) + return PIPE_OK; + + ret = cc_unit_create_from_key(brw, &key, + &brw->cc.state_bo); + if (ret) + return ret; - return 0; + return PIPE_OK; } const struct brw_tracked_state brw_cc_unit = { diff --git a/src/gallium/drivers/i965/brw_clip.c b/src/gallium/drivers/i965/brw_clip.c index 1a52fa771bf..35e1d2fdbd0 100644 --- a/src/gallium/drivers/i965/brw_clip.c +++ b/src/gallium/drivers/i965/brw_clip.c @@ -48,9 +48,12 @@ #define BACK_UNFILLED_BIT 0x2 -static void compile_clip_prog( struct brw_context *brw, - struct brw_clip_prog_key *key ) +static enum pipe_error +compile_clip_prog( struct brw_context *brw, + struct brw_clip_prog_key *key, + struct brw_winsys_buffer **bo_out ) { + enum pipe_error ret; struct brw_clip_compile c; const GLuint *program; GLuint program_size; @@ -123,31 +126,39 @@ static void compile_clip_prog( struct brw_context *brw, break; default: assert(0); - return; + return PIPE_ERROR_BAD_INPUT; } /* get the program */ - program = brw_get_program(&c.func, &program_size); + ret = brw_get_program(&c.func, &program, &program_size); + if (ret) + return ret; /* Upload */ - brw->sws->bo_unreference(brw->clip.prog_bo); - brw->clip.prog_bo = brw_upload_cache( &brw->cache, - BRW_CLIP_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->clip.prog_data ); + ret = brw_upload_cache( &brw->cache, + BRW_CLIP_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + &brw->clip.prog_data, + bo_out ); + if (ret) + return ret; + + return PIPE_OK; } /* Calculate interpolants for triangle and line rasterization. */ -static int upload_clip_prog(struct brw_context *brw) +static enum pipe_error +upload_clip_prog(struct brw_context *brw) { + enum pipe_error ret; struct brw_clip_prog_key key; /* Populate the key, starting from the almost-complete version from @@ -166,15 +177,22 @@ static int upload_clip_prog(struct brw_context *brw) /* PIPE_NEW_CLIP */ key.nr_userclip = brw->curr.ucp.nr; - brw->sws->bo_unreference(brw->clip.prog_bo); - brw->clip.prog_bo = brw_search_cache(&brw->cache, BRW_CLIP_PROG, - &key, sizeof(key), - NULL, 0, - &brw->clip.prog_data); - if (brw->clip.prog_bo == NULL) - compile_clip_prog( brw, &key ); + /* Already cached? + */ + if (brw_search_cache(&brw->cache, BRW_CLIP_PROG, + &key, sizeof(key), + NULL, 0, + &brw->clip.prog_data, + &brw->clip.prog_bo)) + return PIPE_OK; + + /* Compile new program: + */ + ret = compile_clip_prog( brw, &key, &brw->clip.prog_bo ); + if (ret) + return ret; - return 0; + return PIPE_OK; } diff --git a/src/gallium/drivers/i965/brw_clip_state.c b/src/gallium/drivers/i965/brw_clip_state.c index 6f8309fea92..d4e3c43c61a 100644 --- a/src/gallium/drivers/i965/brw_clip_state.c +++ b/src/gallium/drivers/i965/brw_clip_state.c @@ -72,12 +72,13 @@ clip_unit_populate_key(struct brw_context *brw, struct brw_clip_unit_key *key) key->depth_clamp = 0; // XXX: add this to gallium: ctx->Transform.DepthClamp; } -static struct brw_winsys_buffer * +static enum pipe_error clip_unit_create_from_key(struct brw_context *brw, - struct brw_clip_unit_key *key) + struct brw_clip_unit_key *key, + struct brw_winsys_buffer **bo_out) { struct brw_clip_unit_state clip; - struct brw_winsys_buffer *bo; + enum pipe_error ret; memset(&clip, 0, sizeof(clip)); @@ -141,39 +142,50 @@ clip_unit_create_from_key(struct brw_context *brw, clip.viewport_ymin = -1; clip.viewport_ymax = 1; - bo = brw_upload_cache(&brw->cache, BRW_CLIP_UNIT, - key, sizeof(*key), - &brw->clip.prog_bo, 1, - &clip, sizeof(clip), - NULL, NULL); + ret = brw_upload_cache(&brw->cache, BRW_CLIP_UNIT, + key, sizeof(*key), + &brw->clip.prog_bo, 1, + &clip, sizeof(clip), + NULL, NULL, + bo_out); + if (ret) + return ret; /* Emit clip program relocation */ assert(brw->clip.prog_bo); - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_STATE, - clip.thread0.grf_reg_count << 1, - offsetof(struct brw_clip_unit_state, thread0), - brw->clip.prog_bo); - - return bo; + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_STATE, + clip.thread0.grf_reg_count << 1, + offsetof(struct brw_clip_unit_state, thread0), + brw->clip.prog_bo); + if (ret) + return ret; + + return PIPE_OK; } static int upload_clip_unit( struct brw_context *brw ) { struct brw_clip_unit_key key; + enum pipe_error ret; clip_unit_populate_key(brw, &key); - brw->sws->bo_unreference(brw->clip.state_bo); - brw->clip.state_bo = brw_search_cache(&brw->cache, BRW_CLIP_UNIT, - &key, sizeof(key), - &brw->clip.prog_bo, 1, - NULL); - if (brw->clip.state_bo == NULL) { - brw->clip.state_bo = clip_unit_create_from_key(brw, &key); - } + if (brw_search_cache(&brw->cache, BRW_CLIP_UNIT, + &key, sizeof(key), + &brw->clip.prog_bo, 1, + NULL, + &brw->clip.state_bo)) + return PIPE_OK; + + /* Create new: + */ + ret = clip_unit_create_from_key(brw, &key, + &brw->clip.state_bo); + if (ret) + return ret; - return 0; + return PIPE_OK; } const struct brw_tracked_state brw_clip_unit = { diff --git a/src/gallium/drivers/i965/brw_context.c b/src/gallium/drivers/i965/brw_context.c index aaf7d1834ea..2cee7a7a3cf 100644 --- a/src/gallium/drivers/i965/brw_context.c +++ b/src/gallium/drivers/i965/brw_context.c @@ -72,29 +72,33 @@ static void brw_destroy_context( struct pipe_context *pipe ) brw->curr.fb.nr_cbufs = 0; pipe_surface_reference(&brw->curr.fb.zsbuf, NULL); - brw->sws->bo_unreference(brw->curbe.curbe_bo); - brw->sws->bo_unreference(brw->vs.prog_bo); - brw->sws->bo_unreference(brw->vs.state_bo); - brw->sws->bo_unreference(brw->vs.bind_bo); - brw->sws->bo_unreference(brw->gs.prog_bo); - brw->sws->bo_unreference(brw->gs.state_bo); - brw->sws->bo_unreference(brw->clip.prog_bo); - brw->sws->bo_unreference(brw->clip.state_bo); - brw->sws->bo_unreference(brw->clip.vp_bo); - brw->sws->bo_unreference(brw->sf.prog_bo); - brw->sws->bo_unreference(brw->sf.state_bo); - brw->sws->bo_unreference(brw->sf.vp_bo); + bo_reference(&brw->curbe.curbe_bo, NULL); + bo_reference(&brw->vs.prog_bo, NULL); + bo_reference(&brw->vs.state_bo, NULL); + bo_reference(&brw->vs.bind_bo, NULL); + bo_reference(&brw->gs.prog_bo, NULL); + bo_reference(&brw->gs.state_bo, NULL); + bo_reference(&brw->clip.prog_bo, NULL); + bo_reference(&brw->clip.state_bo, NULL); + bo_reference(&brw->clip.vp_bo, NULL); + bo_reference(&brw->sf.prog_bo, NULL); + bo_reference(&brw->sf.state_bo, NULL); + bo_reference(&brw->sf.vp_bo, NULL); + for (i = 0; i < BRW_MAX_TEX_UNIT; i++) - brw->sws->bo_unreference(brw->wm.sdc_bo[i]); - brw->sws->bo_unreference(brw->wm.bind_bo); + bo_reference(&brw->wm.sdc_bo[i], NULL); + + bo_reference(&brw->wm.bind_bo, NULL); + for (i = 0; i < BRW_WM_MAX_SURF; i++) - brw->sws->bo_unreference(brw->wm.surf_bo[i]); - brw->sws->bo_unreference(brw->wm.sampler_bo); - brw->sws->bo_unreference(brw->wm.prog_bo); - brw->sws->bo_unreference(brw->wm.state_bo); - brw->sws->bo_unreference(brw->cc.prog_bo); - brw->sws->bo_unreference(brw->cc.state_bo); - brw->sws->bo_unreference(brw->cc.vp_bo); + bo_reference(&brw->wm.surf_bo[i], NULL); + + bo_reference(&brw->wm.sampler_bo, NULL); + bo_reference(&brw->wm.prog_bo, NULL); + bo_reference(&brw->wm.state_bo, NULL); + bo_reference(&brw->cc.prog_bo, NULL); + bo_reference(&brw->cc.state_bo, NULL); + bo_reference(&brw->cc.vp_bo, NULL); } diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h index 09d34615c74..580251d2f12 100644 --- a/src/gallium/drivers/i965/brw_context.h +++ b/src/gallium/drivers/i965/brw_context.h @@ -744,7 +744,7 @@ struct brw_context * brw_queryobj.c */ void brw_init_query(struct brw_context *brw); -void brw_prepare_query_begin(struct brw_context *brw); +enum pipe_error brw_prepare_query_begin(struct brw_context *brw); void brw_emit_query_begin(struct brw_context *brw); void brw_emit_query_end(struct brw_context *brw); diff --git a/src/gallium/drivers/i965/brw_curbe.c b/src/gallium/drivers/i965/brw_curbe.c index 1e2e232204e..ca7774a7cc2 100644 --- a/src/gallium/drivers/i965/brw_curbe.c +++ b/src/gallium/drivers/i965/brw_curbe.c @@ -160,10 +160,11 @@ static GLfloat fixed_plane[6][4] = { * cache mechanism, but maybe would benefit from a comparison against * the current uploaded set of constants. */ -static int prepare_curbe_buffer(struct brw_context *brw) +static enum pipe_error prepare_curbe_buffer(struct brw_context *brw) { const GLuint sz = brw->curbe.total_size; const GLuint bufsz = sz * 16 * sizeof(GLfloat); + enum pipe_error ret; GLfloat *buf; GLuint i; @@ -267,17 +268,20 @@ static int prepare_curbe_buffer(struct brw_context *brw) (brw->curbe.need_new_bo || brw->curbe.curbe_next_offset + bufsz > brw->curbe.curbe_bo->size)) { - brw->sws->bo_unreference(brw->curbe.curbe_bo); - brw->curbe.curbe_bo = NULL; + bo_reference(&brw->curbe.curbe_bo, NULL); } if (brw->curbe.curbe_bo == NULL) { /* Allocate a single page for CURBE entries for this batchbuffer. * They're generally around 64b. */ - brw->curbe.curbe_bo = brw->sws->bo_alloc(brw->sws, - BRW_BUFFER_TYPE_CURBE, - 4096, 1 << 6); + ret = brw->sws->bo_alloc(brw->sws, + BRW_BUFFER_TYPE_CURBE, + 4096, 1 << 6, + &brw->curbe.curbe_bo); + if (ret) + return ret; + brw->curbe.curbe_next_offset = 0; } @@ -313,7 +317,7 @@ static int prepare_curbe_buffer(struct brw_context *brw) return 0; } -static int emit_curbe_buffer(struct brw_context *brw) +static enum pipe_error emit_curbe_buffer(struct brw_context *brw) { GLuint sz = brw->curbe.total_size; diff --git a/src/gallium/drivers/i965/brw_draw.c b/src/gallium/drivers/i965/brw_draw.c index 6d6b1c7c5c3..88cb31ad546 100644 --- a/src/gallium/drivers/i965/brw_draw.c +++ b/src/gallium/drivers/i965/brw_draw.c @@ -280,6 +280,5 @@ void brw_draw_cleanup( struct brw_context *brw ) u_upload_destroy( brw->vb.upload_vertex ); u_upload_destroy( brw->vb.upload_index ); - brw->sws->bo_unreference(brw->ib.bo); - brw->ib.bo = NULL; + bo_reference(&brw->ib.bo, NULL); } diff --git a/src/gallium/drivers/i965/brw_draw_upload.c b/src/gallium/drivers/i965/brw_draw_upload.c index 4fa7d549ebd..188605a0c12 100644 --- a/src/gallium/drivers/i965/brw_draw_upload.c +++ b/src/gallium/drivers/i965/brw_draw_upload.c @@ -251,9 +251,8 @@ static int brw_prepare_vertices(struct brw_context *brw) brw->vb.vb[i].vertex_count = (vb->stride == 0 ? 1 : (bo->size - offset) / vb->stride); - brw->sws->bo_unreference(brw->vb.vb[i].bo); - brw->vb.vb[i].bo = bo; - brw->sws->bo_reference(brw->vb.vb[i].bo); + + bo_reference( &brw->vb.vb[i].bo, bo ); /* Don't need to retain this reference. We have a reference on * the underlying winsys buffer: @@ -417,6 +416,7 @@ const struct brw_tracked_state brw_vertices = { static int brw_prepare_indices(struct brw_context *brw) { struct pipe_buffer *index_buffer = brw->curr.index_buffer; + struct pipe_buffer *upload_buf = NULL; struct brw_winsys_buffer *bo = NULL; GLuint offset; GLuint index_size; @@ -438,7 +438,6 @@ static int brw_prepare_indices(struct brw_context *brw) /* Turn userbuffer into a proper hardware buffer? */ if (brw_buffer_is_user_buffer(index_buffer)) { - struct pipe_buffer *upload_buf; ret = u_upload_buffer( brw->vb.upload_index, 0, @@ -450,8 +449,6 @@ static int brw_prepare_indices(struct brw_context *brw) return ret; bo = brw_buffer(upload_buf)->bo; - brw->sws->bo_reference(bo); - pipe_buffer_reference( &upload_buf, NULL ); /* XXX: annotate the userbuffer with the upload information so * that successive calls don't get re-uploaded. @@ -459,8 +456,6 @@ static int brw_prepare_indices(struct brw_context *brw) } else { bo = brw_buffer(index_buffer)->bo; - brw->sws->bo_reference(bo); - ib_size = bo->size; offset = 0; } @@ -486,15 +481,12 @@ static int brw_prepare_indices(struct brw_context *brw) if (brw->ib.bo != bo || brw->ib.size != ib_size) { - brw->sws->bo_unreference(brw->ib.bo); - brw->ib.bo = bo; + bo_reference(&brw->ib.bo, bo); brw->ib.size = ib_size; brw->state.dirty.brw |= BRW_NEW_INDEX_BUFFER; } - else { - brw->sws->bo_unreference(bo); - } + pipe_buffer_reference( &upload_buf, NULL ); brw_add_validated_bo(brw, brw->ib.bo); return 0; } diff --git a/src/gallium/drivers/i965/brw_eu.c b/src/gallium/drivers/i965/brw_eu.c index de43b14512d..a8fcb5f97eb 100644 --- a/src/gallium/drivers/i965/brw_eu.c +++ b/src/gallium/drivers/i965/brw_eu.c @@ -118,16 +118,23 @@ void brw_init_compile( struct brw_context *brw, struct brw_compile *p ) } -const GLuint *brw_get_program( struct brw_compile *p, - GLuint *sz ) +enum pipe_error brw_get_program( struct brw_compile *p, + const GLuint **data, + GLuint *sz ) { GLuint i; for (i = 0; i < 8; i++) brw_NOP(p); + /* Is the generated program malformed for some reason? + */ + if (p->error) + return PIPE_ERROR_BAD_INPUT; + *sz = p->nr_insn * sizeof(struct brw_instruction); - return (const GLuint *)p->store; + *data = (const GLuint *)p->store; + return PIPE_OK; } diff --git a/src/gallium/drivers/i965/brw_eu.h b/src/gallium/drivers/i965/brw_eu.h index 7bddc3859ca..565f4ef1c59 100644 --- a/src/gallium/drivers/i965/brw_eu.h +++ b/src/gallium/drivers/i965/brw_eu.h @@ -34,6 +34,7 @@ #define BRW_EU_H #include "util/u_debug.h" +#include "pipe/p_error.h" #include "brw_structs.h" #include "brw_defines.h" @@ -132,6 +133,8 @@ struct brw_compile { struct brw_eu_label *first_label; /**< linked list of labels */ struct brw_eu_call *first_call; /**< linked list of CALs */ + + boolean error; }; @@ -772,7 +775,10 @@ void brw_set_predicate_control( struct brw_compile *p, GLuint pc ); void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional ); void brw_init_compile( struct brw_context *, struct brw_compile *p ); -const GLuint *brw_get_program( struct brw_compile *p, GLuint *sz ); + +enum pipe_error brw_get_program( struct brw_compile *p, + const GLuint **program, + GLuint *sz ); /* Helpers for regular instructions: diff --git a/src/gallium/drivers/i965/brw_gs.c b/src/gallium/drivers/i965/brw_gs.c index 693d8bfdf8d..ce77be24f60 100644 --- a/src/gallium/drivers/i965/brw_gs.c +++ b/src/gallium/drivers/i965/brw_gs.c @@ -40,10 +40,12 @@ -static void compile_gs_prog( struct brw_context *brw, - struct brw_gs_prog_key *key ) +static enum pipe_error compile_gs_prog( struct brw_context *brw, + struct brw_gs_prog_key *key, + struct brw_winsys_buffer **bo_out ) { struct brw_gs_compile c; + enum pipe_error ret; const GLuint *program; GLuint program_size; @@ -57,9 +59,9 @@ static void compile_gs_prog( struct brw_context *brw, c.nr_attrs = c.key.nr_attrs; if (BRW_IS_IGDNG(brw)) - c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */ + c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */ else - c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */ + c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */ c.nr_bytes = c.nr_regs * REG_SIZE; @@ -93,40 +95,47 @@ static void compile_gs_prog( struct brw_context *brw, if (key->hint_gs_always) brw_gs_lines( &c ); else { - return; + return PIPE_OK; } break; case PIPE_PRIM_TRIANGLES: if (key->hint_gs_always) brw_gs_tris( &c ); else { - return; + return PIPE_OK; } break; case PIPE_PRIM_POINTS: if (key->hint_gs_always) brw_gs_points( &c ); else { - return; + return PIPE_OK; } - break; + break; default: - return; + assert(0); + return PIPE_ERROR_BAD_INPUT; } /* get the program */ - program = brw_get_program(&c.func, &program_size); + ret = brw_get_program(&c.func, &program, &program_size); + if (ret) + return ret; /* Upload */ - brw->sws->bo_unreference(brw->gs.prog_bo); - brw->gs.prog_bo = brw_upload_cache( &brw->cache, BRW_GS_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->gs.prog_data ); + ret = brw_upload_cache( &brw->cache, BRW_GS_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + &brw->gs.prog_data, + bo_out ); + if (ret) + return ret; + + return PIPE_OK; } static const unsigned gs_prim[PIPE_PRIM_MAX] = { @@ -166,6 +175,8 @@ static void populate_key( struct brw_context *brw, static int prepare_gs_prog(struct brw_context *brw) { struct brw_gs_prog_key key; + enum pipe_error ret; + /* Populate the key: */ populate_key(brw, &key); @@ -175,17 +186,21 @@ static int prepare_gs_prog(struct brw_context *brw) brw->gs.prog_active = key.need_gs_prog; } - if (brw->gs.prog_active) { - brw->sws->bo_unreference(brw->gs.prog_bo); - brw->gs.prog_bo = brw_search_cache(&brw->cache, BRW_GS_PROG, - &key, sizeof(key), - NULL, 0, - &brw->gs.prog_data); - if (brw->gs.prog_bo == NULL) - compile_gs_prog( brw, &key ); - } + if (!brw->gs.prog_active) + return PIPE_OK; + + if (brw_search_cache(&brw->cache, BRW_GS_PROG, + &key, sizeof(key), + NULL, 0, + &brw->gs.prog_data, + &brw->gs.prog_bo)) + return PIPE_OK; + + ret = compile_gs_prog( brw, &key, &brw->gs.prog_bo ); + if (ret) + return ret; - return 0; + return PIPE_OK; } diff --git a/src/gallium/drivers/i965/brw_gs_state.c b/src/gallium/drivers/i965/brw_gs_state.c index f27f886a651..18a66da538e 100644 --- a/src/gallium/drivers/i965/brw_gs_state.c +++ b/src/gallium/drivers/i965/brw_gs_state.c @@ -69,11 +69,13 @@ gs_unit_populate_key(struct brw_context *brw, struct brw_gs_unit_key *key) key->urb_size = brw->urb.vsize; } -static struct brw_winsys_buffer * -gs_unit_create_from_key(struct brw_context *brw, struct brw_gs_unit_key *key) +static enum pipe_error +gs_unit_create_from_key(struct brw_context *brw, + struct brw_gs_unit_key *key, + struct brw_winsys_buffer **bo_out) { struct brw_gs_unit_state gs; - struct brw_winsys_buffer *bo; + enum pipe_error ret; memset(&gs, 0, sizeof(gs)); @@ -104,40 +106,46 @@ gs_unit_create_from_key(struct brw_context *brw, struct brw_gs_unit_key *key) if (BRW_DEBUG & DEBUG_STATS) gs.thread4.stats_enable = 1; - bo = brw_upload_cache(&brw->cache, BRW_GS_UNIT, - key, sizeof(*key), - &brw->gs.prog_bo, 1, - &gs, sizeof(gs), - NULL, NULL); + ret = brw_upload_cache(&brw->cache, BRW_GS_UNIT, + key, sizeof(*key), + &brw->gs.prog_bo, 1, + &gs, sizeof(gs), + NULL, NULL, + bo_out); + if (ret) + return ret; if (key->prog_active) { /* Emit GS program relocation */ - brw->sws->bo_emit_reloc(bo, + brw->sws->bo_emit_reloc(*bo_out, BRW_USAGE_STATE, gs.thread0.grf_reg_count << 1, offsetof(struct brw_gs_unit_state, thread0), brw->gs.prog_bo); } - return bo; + return PIPE_OK; } -static int prepare_gs_unit(struct brw_context *brw) +static enum pipe_error prepare_gs_unit(struct brw_context *brw) { struct brw_gs_unit_key key; + enum pipe_error ret; gs_unit_populate_key(brw, &key); - brw->sws->bo_unreference(brw->gs.state_bo); - brw->gs.state_bo = brw_search_cache(&brw->cache, BRW_GS_UNIT, - &key, sizeof(key), - &brw->gs.prog_bo, 1, - NULL); - if (brw->gs.state_bo == NULL) { - brw->gs.state_bo = gs_unit_create_from_key(brw, &key); - } + if (brw_search_cache(&brw->cache, BRW_GS_UNIT, + &key, sizeof(key), + &brw->gs.prog_bo, 1, + NULL, + &brw->gs.state_bo)) + return PIPE_OK; + + ret = gs_unit_create_from_key(brw, &key, &brw->gs.state_bo); + if (ret) + return ret; - return 0; + return PIPE_OK; } const struct brw_tracked_state brw_gs_unit = { diff --git a/src/gallium/drivers/i965/brw_pipe_query.c b/src/gallium/drivers/i965/brw_pipe_query.c index 3370ebd2626..6a011737879 100644 --- a/src/gallium/drivers/i965/brw_pipe_query.c +++ b/src/gallium/drivers/i965/brw_pipe_query.c @@ -72,8 +72,7 @@ brw_query_get_result(struct pipe_context *pipe, } brw->sws->bo_unmap(query->bo); - brw->sws->bo_unreference(query->bo); - query->bo = NULL; + bo_reference(&query->bo, NULL); } *result = query->result; @@ -100,10 +99,9 @@ brw_query_create(struct pipe_context *pipe, unsigned type ) static void brw_query_destroy(struct pipe_context *pipe, struct pipe_query *q) { - struct brw_context *brw = brw_context(pipe); struct brw_query_object *query = (struct brw_query_object *)q; - brw->sws->bo_unreference(query->bo); + bo_reference(&query->bo, NULL); FREE(query); } @@ -114,9 +112,8 @@ brw_query_begin(struct pipe_context *pipe, struct pipe_query *q) struct brw_query_object *query = (struct brw_query_object *)q; /* Reset our driver's tracking of query state. */ - brw->sws->bo_unreference(query->bo); + bo_reference(&query->bo, NULL); query->result = 0; - query->bo = NULL; query->first_index = -1; query->last_index = -1; @@ -139,8 +136,7 @@ brw_query_end(struct pipe_context *pipe, struct pipe_query *q) brw_emit_query_end(brw); brw_context_flush( brw ); - brw->sws->bo_unreference(brw->query.bo); - brw->query.bo = NULL; + bo_reference(&brw->query.bo, NULL); } remove_from_list(query); @@ -153,24 +149,30 @@ brw_query_end(struct pipe_context *pipe, struct pipe_query *q) */ /** Called to set up the query BO and account for its aperture space */ -void +enum pipe_error brw_prepare_query_begin(struct brw_context *brw) { + enum pipe_error ret; + /* Skip if we're not doing any queries. */ if (is_empty_list(&brw->query.active_head)) - return; + return PIPE_OK; /* Get a new query BO if we're going to need it. */ if (brw->query.bo == NULL || brw->query.index * 2 + 1 >= 4096 / sizeof(uint64_t)) { - brw->sws->bo_unreference(brw->query.bo); - brw->query.bo = NULL; - brw->query.bo = brw->sws->bo_alloc(brw->sws, BRW_BUFFER_TYPE_QUERY, 4096, 1); + ret = brw->sws->bo_alloc(brw->sws, BRW_BUFFER_TYPE_QUERY, 4096, 1, + &brw->query.bo); + if (ret) + return ret; + brw->query.index = 0; } brw_add_validated_bo(brw, brw->query.bo); + + return PIPE_OK; } /** Called just before primitive drawing to get a beginning PS_DEPTH_COUNT. */ @@ -213,8 +215,7 @@ brw_emit_query_begin(struct brw_context *brw) FALSE, &tmp ); - brw->sws->bo_reference(brw->query.bo); - query->bo = brw->query.bo; + bo_reference( &query->bo, brw->query.bo ); query->first_index = brw->query.index; } query->last_index = brw->query.index; diff --git a/src/gallium/drivers/i965/brw_pipe_shader.c b/src/gallium/drivers/i965/brw_pipe_shader.c index 2833f2bce02..662c43c3e5f 100644 --- a/src/gallium/drivers/i965/brw_pipe_shader.c +++ b/src/gallium/drivers/i965/brw_pipe_shader.c @@ -146,10 +146,9 @@ fail: static void brw_delete_fs_state( struct pipe_context *pipe, void *prog ) { - struct brw_context *brw = brw_context(pipe); struct brw_fragment_shader *fs = (struct brw_fragment_shader *)prog; - brw->sws->bo_unreference(fs->const_buffer); + bo_reference(&fs->const_buffer, NULL); FREE( (void *)fs->tokens ); FREE( fs ); } diff --git a/src/gallium/drivers/i965/brw_pipe_vertex.c b/src/gallium/drivers/i965/brw_pipe_vertex.c index 97e9a236883..73bba5b0881 100644 --- a/src/gallium/drivers/i965/brw_pipe_vertex.c +++ b/src/gallium/drivers/i965/brw_pipe_vertex.c @@ -56,7 +56,7 @@ brw_pipe_vertex_cleanup( struct brw_context *brw ) */ #if 0 for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - brw->sws->bo_unreference(brw->vb.inputs[i].bo); + bo_reference(&brw->vb.inputs[i].bo, NULL); brw->vb.inputs[i].bo = NULL; } #endif diff --git a/src/gallium/drivers/i965/brw_screen_buffers.c b/src/gallium/drivers/i965/brw_screen_buffers.c index ba54740225c..7ae386ffb34 100644 --- a/src/gallium/drivers/i965/brw_screen_buffers.c +++ b/src/gallium/drivers/i965/brw_screen_buffers.c @@ -43,15 +43,11 @@ brw_buffer_unmap( struct pipe_screen *screen, static void brw_buffer_destroy( struct pipe_buffer *buffer ) { - struct brw_screen *bscreen = brw_screen( buffer->screen ); - struct brw_winsys_screen *sws = bscreen->sws; struct brw_buffer *buf = brw_buffer( buffer ); assert(!p_atomic_read(&buffer->reference.count)); - if (buf->bo) - sws->bo_unreference(buf->bo); - + bo_reference(&buf->bo, NULL); FREE(buf); } @@ -66,6 +62,7 @@ brw_buffer_create(struct pipe_screen *screen, struct brw_winsys_screen *sws = bscreen->sws; struct brw_buffer *buf; unsigned buffer_type; + enum pipe_error ret; buf = CALLOC_STRUCT(brw_buffer); if (!buf) @@ -101,10 +98,11 @@ brw_buffer_create(struct pipe_screen *screen, break; } - buf->bo = sws->bo_alloc( sws, - buffer_type, - size, - alignment ); + ret = sws->bo_alloc( sws, buffer_type, + size, alignment, + &buf->bo ); + if (ret != PIPE_OK) + return NULL; return &buf->base; } diff --git a/src/gallium/drivers/i965/brw_screen_surface.c b/src/gallium/drivers/i965/brw_screen_surface.c index 1c408e9f2e5..21a7382873f 100644 --- a/src/gallium/drivers/i965/brw_screen_surface.c +++ b/src/gallium/drivers/i965/brw_screen_surface.c @@ -150,9 +150,7 @@ static struct brw_surface *create_in_place_view( struct brw_screen *brw_screen, surface->pitch = tex->pitch; surface->tiling = tex->tiling; - surface->bo = tex->bo; - brw_screen->sws->bo_reference(surface->bo); - + bo_reference( &surface->bo, tex->bo ); pipe_texture_reference( &surface->base.texture, &tex->base ); surface->ss.ss0.surface_format = tex->ss.ss0.surface_format; @@ -244,11 +242,10 @@ static struct pipe_surface *brw_get_tex_surface(struct pipe_screen *screen, static void brw_tex_surface_destroy( struct pipe_surface *surf ) { struct brw_surface *surface = brw_surface(surf); - struct brw_screen *screen = brw_screen(surf->texture->screen); /* Unreference texture, shared buffer: */ - screen->sws->bo_unreference(surface->bo); + bo_reference(&surface->bo, NULL); pipe_texture_reference( &surface->base.texture, NULL ); diff --git a/src/gallium/drivers/i965/brw_screen_texture.c b/src/gallium/drivers/i965/brw_screen_texture.c index ba6dc7dfdee..355abf0b898 100644 --- a/src/gallium/drivers/i965/brw_screen_texture.c +++ b/src/gallium/drivers/i965/brw_screen_texture.c @@ -187,6 +187,7 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen, struct brw_screen *bscreen = brw_screen(screen); struct brw_texture *tex; enum brw_buffer_type buffer_type; + enum pipe_error ret; tex = CALLOC_STRUCT(brw_texture); if (tex == NULL) @@ -235,10 +236,13 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen, buffer_type = BRW_BUFFER_TYPE_TEXTURE; } - tex->bo = bscreen->sws->bo_alloc( bscreen->sws, - buffer_type, - tex->pitch * tex->total_height * tex->cpp, - 64 ); + ret = bscreen->sws->bo_alloc( bscreen->sws, + buffer_type, + tex->pitch * tex->total_height * tex->cpp, + 64, + &tex->bo ); + if (ret) + goto fail; tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW; tex->ss.ss0.surface_type = translate_tex_target(tex->base.target); @@ -289,7 +293,7 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen, return &tex->base; fail: - bscreen->sws->bo_unreference(tex->bo); + bo_reference(&tex->bo, NULL); FREE(tex); return NULL; } @@ -306,7 +310,8 @@ static struct pipe_texture *brw_texture_blanket(struct pipe_screen *screen, static void brw_texture_destroy(struct pipe_texture *pt) { - //bscreen->sws->bo_unreference(tex->bo); + struct brw_texture *tex = brw_texture(pt); + bo_reference(&tex->bo, NULL); FREE(pt); } diff --git a/src/gallium/drivers/i965/brw_sf.c b/src/gallium/drivers/i965/brw_sf.c index 013d839e37d..24d1015bbd5 100644 --- a/src/gallium/drivers/i965/brw_sf.c +++ b/src/gallium/drivers/i965/brw_sf.c @@ -40,9 +40,11 @@ #include "brw_sf.h" #include "brw_state.h" -static void compile_sf_prog( struct brw_context *brw, - struct brw_sf_prog_key *key ) +static enum pipe_error compile_sf_prog( struct brw_context *brw, + struct brw_sf_prog_key *key, + struct brw_winsys_buffer **bo_out ) { + enum pipe_error ret; struct brw_sf_compile c; const GLuint *program; GLuint program_size; @@ -87,28 +89,35 @@ static void compile_sf_prog( struct brw_context *brw, break; default: assert(0); - return; + return PIPE_ERROR_BAD_INPUT; } /* get the program */ - program = brw_get_program(&c.func, &program_size); + ret = brw_get_program(&c.func, &program, &program_size); + if (ret) + return ret; /* Upload */ - brw->sws->bo_unreference(brw->sf.prog_bo); - brw->sf.prog_bo = brw_upload_cache( &brw->cache, BRW_SF_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->sf.prog_data ); + ret = brw_upload_cache( &brw->cache, BRW_SF_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + &brw->sf.prog_data, + bo_out); + if (ret) + return ret; + + return PIPE_OK; } /* Calculate interpolants for triangle and line rasterization. */ -static int upload_sf_prog(struct brw_context *brw) +static enum pipe_error upload_sf_prog(struct brw_context *brw) { + enum pipe_error ret; struct brw_sf_prog_key key; memset(&key, 0, sizeof(key)); @@ -161,15 +170,18 @@ static int upload_sf_prog(struct brw_context *brw) PIPE_WINDING_CCW); } - brw->sws->bo_unreference(brw->sf.prog_bo); - brw->sf.prog_bo = brw_search_cache(&brw->cache, BRW_SF_PROG, - &key, sizeof(key), - NULL, 0, - &brw->sf.prog_data); - if (brw->sf.prog_bo == NULL) - compile_sf_prog( brw, &key ); + if (brw_search_cache(&brw->cache, BRW_SF_PROG, + &key, sizeof(key), + NULL, 0, + &brw->sf.prog_data, + &brw->sf.prog_bo)) + return PIPE_OK; - return 0; + ret = compile_sf_prog( brw, &key, &brw->sf.prog_bo ); + if (ret) + return ret; + + return PIPE_OK; } diff --git a/src/gallium/drivers/i965/brw_sf_state.c b/src/gallium/drivers/i965/brw_sf_state.c index 31343ff2459..f030f26c19f 100644 --- a/src/gallium/drivers/i965/brw_sf_state.c +++ b/src/gallium/drivers/i965/brw_sf_state.c @@ -39,11 +39,12 @@ #include "brw_debug.h" #include "brw_pipe_rast.h" -static int upload_sf_vp(struct brw_context *brw) +static enum pipe_error upload_sf_vp(struct brw_context *brw) { const struct pipe_viewport_state *vp = &brw->curr.vp; const struct pipe_scissor_state *scissor = &brw->curr.scissor; struct brw_sf_viewport sfv; + enum pipe_error ret; memset(&sfv, 0, sizeof(sfv)); @@ -61,10 +62,12 @@ static int upload_sf_vp(struct brw_context *brw) sfv.scissor.ymin = scissor->miny; sfv.scissor.ymax = scissor->maxy; /* -1 ?? */ - brw->sws->bo_unreference(brw->sf.vp_bo); - brw->sf.vp_bo = brw_cache_data( &brw->cache, BRW_SF_VP, &sfv, NULL, 0 ); + ret = brw_cache_data( &brw->cache, BRW_SF_VP, &sfv, NULL, 0, + &brw->sf.vp_bo ); + if (ret) + return ret; - return 0; + return PIPE_OK; } const struct brw_tracked_state brw_sf_vp = { @@ -128,12 +131,13 @@ sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key) rast->point_size_max); } -static struct brw_winsys_buffer * +static enum pipe_error sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key, - struct brw_winsys_buffer **reloc_bufs) + struct brw_winsys_buffer **reloc_bufs, + struct brw_winsys_buffer **bo_out) { struct brw_sf_unit_state sf; - struct brw_winsys_buffer *bo; + enum pipe_error ret; int chipset_max_threads; memset(&sf, 0, sizeof(sf)); @@ -273,51 +277,65 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key, sf.sf6.dest_org_hbias = 0x0; } - bo = brw_upload_cache(&brw->cache, BRW_SF_UNIT, - key, sizeof(*key), - reloc_bufs, 2, - &sf, sizeof(sf), - NULL, NULL); + ret = brw_upload_cache(&brw->cache, BRW_SF_UNIT, + key, sizeof(*key), + reloc_bufs, 2, + &sf, sizeof(sf), + NULL, NULL, + bo_out); + if (ret) + return ret; /* STATE_PREFETCH command description describes this state as being * something loaded through the GPE (L2 ISC), so it's INSTRUCTION domain. */ /* Emit SF program relocation */ - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_STATE, - sf.thread0.grf_reg_count << 1, - offsetof(struct brw_sf_unit_state, thread0), - brw->sf.prog_bo); + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_STATE, + sf.thread0.grf_reg_count << 1, + offsetof(struct brw_sf_unit_state, thread0), + brw->sf.prog_bo); + if (ret) + return ret; - /* Emit SF viewport relocation */ - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_STATE, - sf.sf5.front_winding | (sf.sf5.viewport_transform << 1), - offsetof(struct brw_sf_unit_state, sf5), - brw->sf.vp_bo); - return bo; + /* Emit SF viewport relocation */ + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_STATE, + sf.sf5.front_winding | (sf.sf5.viewport_transform << 1), + offsetof(struct brw_sf_unit_state, sf5), + brw->sf.vp_bo); + if (ret) + return ret; + + return PIPE_OK; } -static int upload_sf_unit( struct brw_context *brw ) +static enum pipe_error upload_sf_unit( struct brw_context *brw ) { struct brw_sf_unit_key key; struct brw_winsys_buffer *reloc_bufs[2]; + enum pipe_error ret; sf_unit_populate_key(brw, &key); reloc_bufs[0] = brw->sf.prog_bo; reloc_bufs[1] = brw->sf.vp_bo; - brw->sws->bo_unreference(brw->sf.state_bo); - brw->sf.state_bo = brw_search_cache(&brw->cache, BRW_SF_UNIT, - &key, sizeof(key), - reloc_bufs, 2, - NULL); - if (brw->sf.state_bo == NULL) { - brw->sf.state_bo = sf_unit_create_from_key(brw, &key, reloc_bufs); - } - return 0; + if (brw_search_cache(&brw->cache, BRW_SF_UNIT, + &key, sizeof(key), + reloc_bufs, 2, + NULL, + &brw->sf.state_bo)) + return PIPE_OK; + + + ret = sf_unit_create_from_key(brw, &key, reloc_bufs, + &brw->sf.state_bo); + if (ret) + return ret; + + return PIPE_OK; } const struct brw_tracked_state brw_sf_unit = { diff --git a/src/gallium/drivers/i965/brw_state.h b/src/gallium/drivers/i965/brw_state.h index 94d2cb6f829..e219a1d8701 100644 --- a/src/gallium/drivers/i965/brw_state.h +++ b/src/gallium/drivers/i965/brw_state.h @@ -44,8 +44,8 @@ brw_add_validated_bo(struct brw_context *brw, struct brw_winsys_buffer *bo) assert(brw->state.validated_bo_count < Elements(brw->state.validated_bos)); if (bo != NULL) { - brw->sws->bo_reference(bo); - brw->state.validated_bos[brw->state.validated_bo_count++] = bo; + bo_reference( &brw->state.validated_bos[brw->state.validated_bo_count++], + bo ); } } @@ -106,37 +106,42 @@ void brw_destroy_state(struct brw_context *brw); /*********************************************************************** * brw_state_cache.c */ -struct brw_winsys_buffer *brw_cache_data(struct brw_cache *cache, - enum brw_cache_id cache_id, - const void *data, - struct brw_winsys_buffer **reloc_bufs, - GLuint nr_reloc_bufs); - -struct brw_winsys_buffer *brw_cache_data_sz(struct brw_cache *cache, - enum brw_cache_id cache_id, - const void *data, - GLuint data_size, - struct brw_winsys_buffer **reloc_bufs, - GLuint nr_reloc_bufs); - -struct brw_winsys_buffer *brw_upload_cache( struct brw_cache *cache, - enum brw_cache_id cache_id, - const void *key, - GLuint key_sz, - struct brw_winsys_buffer **reloc_bufs, - GLuint nr_reloc_bufs, - const void *data, - GLuint data_sz, - const void *aux, - void *aux_return ); - -struct brw_winsys_buffer *brw_search_cache( struct brw_cache *cache, - enum brw_cache_id cache_id, - const void *key, - GLuint key_size, - struct brw_winsys_buffer **reloc_bufs, - GLuint nr_reloc_bufs, - void *aux_return); +enum pipe_error brw_cache_data(struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *data, + struct brw_winsys_buffer **reloc_bufs, + GLuint nr_reloc_bufs, + struct brw_winsys_buffer **bo_out ); + +enum pipe_error brw_cache_data_sz(struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *data, + GLuint data_size, + struct brw_winsys_buffer **reloc_bufs, + GLuint nr_reloc_bufs, + struct brw_winsys_buffer **bo_out); + +enum pipe_error brw_upload_cache( struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *key, + GLuint key_sz, + struct brw_winsys_buffer **reloc_bufs, + GLuint nr_reloc_bufs, + const void *data, + GLuint data_sz, + const void *aux, + void *aux_return , + struct brw_winsys_buffer **bo_out); + +boolean brw_search_cache( struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *key, + GLuint key_size, + struct brw_winsys_buffer **reloc_bufs, + GLuint nr_reloc_bufs, + void *aux_return, + struct brw_winsys_buffer **bo_out); + void brw_state_cache_check_size( struct brw_context *brw ); void brw_init_caches( struct brw_context *brw ); diff --git a/src/gallium/drivers/i965/brw_state_cache.c b/src/gallium/drivers/i965/brw_state_cache.c index cbd1f02d77d..f8369d31ec1 100644 --- a/src/gallium/drivers/i965/brw_state_cache.c +++ b/src/gallium/drivers/i965/brw_state_cache.c @@ -109,9 +109,8 @@ update_cache_last(struct brw_cache *cache, enum brw_cache_id cache_id, if (bo == cache->last_bo[cache_id]) return; /* no change */ - cache->sws->bo_unreference(cache->last_bo[cache_id]); - cache->last_bo[cache_id] = bo; - cache->sws->bo_reference(cache->last_bo[cache_id]); + bo_reference( &cache->last_bo[cache_id], bo ); + cache->brw->state.dirty.cache |= 1 << cache_id; } @@ -174,14 +173,15 @@ rehash(struct brw_cache *cache) /** * Returns the buffer object matching cache_id and key, or NULL. */ -struct brw_winsys_buffer * +boolean brw_search_cache(struct brw_cache *cache, enum brw_cache_id cache_id, const void *key, GLuint key_size, struct brw_winsys_buffer **reloc_bufs, GLuint nr_reloc_bufs, - void *aux_return) + void *aux_return, + struct brw_winsys_buffer **bo_out) { struct brw_cache_item *item; GLuint hash = hash_key(key, key_size, reloc_bufs, nr_reloc_bufs); @@ -189,20 +189,20 @@ brw_search_cache(struct brw_cache *cache, item = search_cache(cache, cache_id, hash, key, key_size, reloc_bufs, nr_reloc_bufs); - if (item == NULL) - return NULL; - - if (aux_return) - *(void **)aux_return = (void *)((char *)item->key + item->key_size); - - update_cache_last(cache, cache_id, item->bo); - - cache->sws->bo_reference(item->bo); - return item->bo; + if (item) { + if (aux_return) + *(void **)aux_return = (void *)((char *)item->key + item->key_size); + + update_cache_last(cache, cache_id, item->bo); + bo_reference(bo_out, item->bo); + return TRUE; + } + + return FALSE; } -struct brw_winsys_buffer * +enum pipe_error brw_upload_cache( struct brw_cache *cache, enum brw_cache_id cache_id, const void *key, @@ -212,14 +212,15 @@ brw_upload_cache( struct brw_cache *cache, const void *data, GLuint data_size, const void *aux, - void *aux_return ) + void *aux_return, + struct brw_winsys_buffer **bo_out) { struct brw_cache_item *item = CALLOC_STRUCT(brw_cache_item); GLuint hash = hash_key(key, key_size, reloc_bufs, nr_reloc_bufs); GLuint relocs_size = nr_reloc_bufs * sizeof(struct brw_winsys_buffer *); GLuint aux_size = cache->aux_size[cache_id]; + enum pipe_error ret; void *tmp; - struct brw_winsys_buffer *bo; int i; /* Create the buffer object to contain the data. For now, use a @@ -227,9 +228,12 @@ brw_upload_cache( struct brw_cache *cache, * may want to take advantage of hardware distinctions between * these various entities. */ - bo = cache->sws->bo_alloc(cache->sws, - cache->buffer_type, - data_size, 1 << 6); + ret = cache->sws->bo_alloc(cache->sws, + cache->buffer_type, + data_size, 1 << 6, + bo_out); + if (ret) + return ret; /* Set up the memory containing the key, aux_data, and reloc_bufs */ @@ -240,7 +244,7 @@ brw_upload_cache( struct brw_cache *cache, memcpy((char *)tmp + key_size + aux_size, reloc_bufs, relocs_size); for (i = 0; i < nr_reloc_bufs; i++) { if (reloc_bufs[i] != NULL) - cache->sws->bo_reference(reloc_bufs[i]); + p_atomic_inc(&reloc_bufs[i]->reference.count); } item->cache_id = cache_id; @@ -249,9 +253,7 @@ brw_upload_cache( struct brw_cache *cache, item->key_size = key_size; item->reloc_bufs = (struct brw_winsys_buffer **)((char *)tmp + key_size + aux_size); item->nr_reloc_bufs = nr_reloc_bufs; - - item->bo = bo; - cache->sws->bo_reference(bo); + bo_reference( &item->bo, *bo_out ); item->data_size = data_size; if (cache->n_items > cache->size * 1.5) @@ -273,28 +275,28 @@ brw_upload_cache( struct brw_cache *cache, data_size, cache_id); /* Copy data to the buffer */ - cache->sws->bo_subdata(bo, + cache->sws->bo_subdata(item->bo, cache_id, 0, data_size, data); - update_cache_last(cache, cache_id, bo); + update_cache_last(cache, cache_id, item->bo); - return bo; + return PIPE_OK; } /** * This doesn't really work with aux data. Use search/upload instead */ -struct brw_winsys_buffer * +enum pipe_error brw_cache_data_sz(struct brw_cache *cache, enum brw_cache_id cache_id, const void *data, GLuint data_size, struct brw_winsys_buffer **reloc_bufs, - GLuint nr_reloc_bufs) + GLuint nr_reloc_bufs, + struct brw_winsys_buffer **bo_out) { - struct brw_winsys_buffer *bo; struct brw_cache_item *item; GLuint hash = hash_key(data, data_size, reloc_bufs, nr_reloc_bufs); @@ -302,17 +304,17 @@ brw_cache_data_sz(struct brw_cache *cache, reloc_bufs, nr_reloc_bufs); if (item) { update_cache_last(cache, cache_id, item->bo); - cache->sws->bo_reference(item->bo); - return item->bo; - } - bo = brw_upload_cache(cache, cache_id, - data, data_size, - reloc_bufs, nr_reloc_bufs, - data, data_size, - NULL, NULL); + bo_reference(bo_out, item->bo); + return PIPE_OK; + } - return bo; + return brw_upload_cache(cache, cache_id, + data, data_size, + reloc_bufs, nr_reloc_bufs, + data, data_size, + NULL, NULL, + bo_out); } @@ -323,15 +325,16 @@ brw_cache_data_sz(struct brw_cache *cache, * better to use, as the potentially changing offsets in the data-used-as-key * will result in excessive cache misses. */ -struct brw_winsys_buffer * +enum pipe_error brw_cache_data(struct brw_cache *cache, enum brw_cache_id cache_id, const void *data, struct brw_winsys_buffer **reloc_bufs, - GLuint nr_reloc_bufs) + GLuint nr_reloc_bufs, + struct brw_winsys_buffer **bo_out) { return brw_cache_data_sz(cache, cache_id, data, cache->key_size[cache_id], - reloc_bufs, nr_reloc_bufs); + reloc_bufs, nr_reloc_bufs, bo_out); } @@ -506,11 +509,13 @@ brw_clear_cache(struct brw_context *brw, struct brw_cache *cache) int j; next = c->next; + for (j = 0; j < c->nr_reloc_bufs; j++) - brw->sws->bo_unreference(c->reloc_bufs[j]); - brw->sws->bo_unreference(c->bo); - free((void *)c->key); - free(c); + bo_reference(&c->reloc_bufs[j], NULL); + + bo_reference(&c->bo, NULL); + FREE((void *)c->key); + FREE(c); } cache->items[i] = NULL; } @@ -551,10 +556,12 @@ brw_state_cache_bo_delete(struct brw_cache *cache, struct brw_winsys_buffer *bo) *prev = c->next; for (j = 0; j < c->nr_reloc_bufs; j++) - cache->sws->bo_unreference(c->reloc_bufs[j]); - cache->sws->bo_unreference(c->bo); - free((void *)c->key); - free(c); + bo_reference(&c->reloc_bufs[j], NULL); + + bo_reference(&c->bo, NULL); + + FREE((void *)c->key); + FREE(c); cache->n_items--; } else { prev = &c->next; @@ -590,10 +597,10 @@ brw_destroy_cache(struct brw_context *brw, struct brw_cache *cache) brw_clear_cache(brw, cache); for (i = 0; i < BRW_MAX_CACHE; i++) { - brw->sws->bo_unreference(cache->last_bo[i]); - free(cache->name[i]); + bo_reference(&cache->last_bo[i], NULL); + FREE(cache->name[i]); } - free(cache->items); + FREE(cache->items); cache->items = NULL; cache->size = 0; } diff --git a/src/gallium/drivers/i965/brw_state_upload.c b/src/gallium/drivers/i965/brw_state_upload.c index a71af4d2b91..fdcdd59129f 100644 --- a/src/gallium/drivers/i965/brw_state_upload.c +++ b/src/gallium/drivers/i965/brw_state_upload.c @@ -140,8 +140,7 @@ brw_clear_validated_bos(struct brw_context *brw) /* Clear the last round of validated bos */ for (i = 0; i < brw->state.validated_bo_count; i++) { - brw->sws->bo_unreference(brw->state.validated_bos[i]); - brw->state.validated_bos[i] = NULL; + bo_reference(&brw->state.validated_bos[i], NULL); } brw->state.validated_bo_count = 0; } diff --git a/src/gallium/drivers/i965/brw_vs.c b/src/gallium/drivers/i965/brw_vs.c index 26a28114d98..966940ceacb 100644 --- a/src/gallium/drivers/i965/brw_vs.c +++ b/src/gallium/drivers/i965/brw_vs.c @@ -39,10 +39,12 @@ -static void do_vs_prog( struct brw_context *brw, - struct brw_vertex_shader *vp, - struct brw_vs_prog_key *key ) +static enum pipe_error do_vs_prog( struct brw_context *brw, + struct brw_vertex_shader *vp, + struct brw_vs_prog_key *key, + struct brw_winsys_buffer **bo_out) { + enum pipe_error ret; GLuint program_size; const GLuint *program; struct brw_vs_compile c; @@ -66,22 +68,29 @@ static void do_vs_prog( struct brw_context *brw, /* get the program */ - program = brw_get_program(&c.func, &program_size); - - brw->sws->bo_unreference(brw->vs.prog_bo); - brw->vs.prog_bo = brw_upload_cache( &brw->cache, BRW_VS_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->vs.prog_data ); + ret = brw_get_program(&c.func, &program, &program_size); + if (ret) + return ret; + + ret = brw_upload_cache( &brw->cache, BRW_VS_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + &brw->vs.prog_data, + bo_out); + if (ret) + return ret; + + return PIPE_OK; } -static int brw_upload_vs_prog(struct brw_context *brw) +static enum pipe_error brw_upload_vs_prog(struct brw_context *brw) { struct brw_vs_prog_key key; struct brw_vertex_shader *vp = brw->curr.vertex_shader; + enum pipe_error ret; memset(&key, 0, sizeof(key)); @@ -95,15 +104,18 @@ static int brw_upload_vs_prog(struct brw_context *brw) /* Make an early check for the key. */ - brw->sws->bo_unreference(brw->vs.prog_bo); - brw->vs.prog_bo = brw_search_cache(&brw->cache, BRW_VS_PROG, - &key, sizeof(key), - NULL, 0, - &brw->vs.prog_data); - if (brw->vs.prog_bo == NULL) - do_vs_prog(brw, vp, &key); - - return 0; + if (brw_search_cache(&brw->cache, BRW_VS_PROG, + &key, sizeof(key), + NULL, 0, + &brw->vs.prog_data, + &brw->vs.prog_bo)) + return PIPE_OK; + + ret = do_vs_prog(brw, vp, &key, &brw->vs.prog_bo); + if (ret) + return ret; + + return PIPE_OK; } diff --git a/src/gallium/drivers/i965/brw_vs_state.c b/src/gallium/drivers/i965/brw_vs_state.c index 26d5d005faa..22a4d7f01b9 100644 --- a/src/gallium/drivers/i965/brw_vs_state.c +++ b/src/gallium/drivers/i965/brw_vs_state.c @@ -78,11 +78,13 @@ vs_unit_populate_key(struct brw_context *brw, struct brw_vs_unit_key *key) } } -static struct brw_winsys_buffer * -vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key) +static enum pipe_error +vs_unit_create_from_key(struct brw_context *brw, + struct brw_vs_unit_key *key, + struct brw_winsys_buffer **bo_out) { + enum pipe_error ret; struct brw_vs_unit_state vs; - struct brw_winsys_buffer *bo; int chipset_max_threads; memset(&vs, 0, sizeof(vs)); @@ -141,38 +143,46 @@ vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key) */ vs.vs6.vs_enable = 1; - bo = brw_upload_cache(&brw->cache, BRW_VS_UNIT, - key, sizeof(*key), - &brw->vs.prog_bo, 1, - &vs, sizeof(vs), - NULL, NULL); + ret = brw_upload_cache(&brw->cache, BRW_VS_UNIT, + key, sizeof(*key), + &brw->vs.prog_bo, 1, + &vs, sizeof(vs), + NULL, NULL, + bo_out); + if (ret) + return ret; /* Emit VS program relocation */ - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_STATE, - vs.thread0.grf_reg_count << 1, - offsetof(struct brw_vs_unit_state, thread0), - brw->vs.prog_bo); - - return bo; + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_STATE, + vs.thread0.grf_reg_count << 1, + offsetof(struct brw_vs_unit_state, thread0), + brw->vs.prog_bo); + if (ret) + return ret; + + return PIPE_OK; } static int prepare_vs_unit(struct brw_context *brw) { struct brw_vs_unit_key key; + enum pipe_error ret; vs_unit_populate_key(brw, &key); - brw->sws->bo_unreference(brw->vs.state_bo); - brw->vs.state_bo = brw_search_cache(&brw->cache, BRW_VS_UNIT, - &key, sizeof(key), - &brw->vs.prog_bo, 1, - NULL); - if (brw->vs.state_bo == NULL) { - brw->vs.state_bo = vs_unit_create_from_key(brw, &key); - } + if (brw_search_cache(&brw->cache, BRW_VS_UNIT, + &key, sizeof(key), + &brw->vs.prog_bo, 1, + NULL, + &brw->vs.state_bo)) + return PIPE_OK; + + ret = vs_unit_create_from_key(brw, &key, &brw->vs.state_bo); + if (ret) + return ret; - return 0; + return PIPE_OK; } const struct brw_tracked_state brw_vs_unit = { diff --git a/src/gallium/drivers/i965/brw_vs_surface_state.c b/src/gallium/drivers/i965/brw_vs_surface_state.c index 32fb9b2a8b9..b12df0ec038 100644 --- a/src/gallium/drivers/i965/brw_vs_surface_state.c +++ b/src/gallium/drivers/i965/brw_vs_surface_state.c @@ -83,22 +83,23 @@ brw_update_vs_constant_surface( struct brw_context *brw, { struct brw_surface_key key; struct pipe_buffer *cb = brw->curr.vs_constants; + enum pipe_error ret; assert(surf == 0); /* If we're in this state update atom, we need to update VS constants, so * free the old buffer and create a new one for the new contents. */ - brw->sws->bo_unreference(vp->const_buffer); - vp->const_buffer = brw_vs_update_constant_buffer(brw); + ret = brw_vs_update_constant_buffer(brw, &vp->const_buffer); + if (ret) + return ret; /* If there's no constant buffer, then no surface BO is needed to point at * it. */ - if (vp->const_buffer == 0) { - drm_intel_bo_unreference(brw->vs.surf_bo[surf]); - brw->vs.surf_bo[surf] = NULL; - return; + if (vp->const_buffer == NULL) { + bo_reference(brw->vs.surf_bo[surf], NULL); + return PIPE_OK; } memset(&key, 0, sizeof(key)); @@ -118,15 +119,20 @@ brw_update_vs_constant_surface( struct brw_context *brw, key.width, key.height, key.depth, key.cpp, key.pitch); */ - drm_intel_bo_unreference(brw->vs.surf_bo[surf]); - brw->vs.surf_bo[surf] = brw_search_cache(&brw->surface_cache, - BRW_SS_SURFACE, - &key, sizeof(key), - &key.bo, key.bo ? 1 : 0, - NULL); - if (brw->vs.surf_bo[surf] == NULL) { - brw->vs.surf_bo[surf] = brw_create_constant_surface(brw, &key); - } + if (brw_search_cache(&brw->surface_cache, + BRW_SS_SURFACE, + &key, sizeof(key), + &key.bo, key.bo ? 1 : 0, + NULL, + &brw->vs.surf_bo[surf])) + return PIPE_OK; + + ret = brw_create_constant_surface(brw, &key + &brw->vs.surf_bo[surf]); + if (ret) + return ret; + + return PIPE_OK; } #endif @@ -134,18 +140,20 @@ brw_update_vs_constant_surface( struct brw_context *brw, /** * Constructs the binding table for the VS surface state. */ -static struct brw_winsys_buffer * -brw_vs_get_binding_table(struct brw_context *brw) +static enum pipe_error +brw_vs_get_binding_table(struct brw_context *brw, + struct brw_winsys_buffer **bo_out) { #if 0 - struct brw_winsys_buffer *bind_bo; - - bind_bo = brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND, - NULL, 0, - brw->vs.surf_bo, BRW_VS_MAX_SURF, - NULL); - - if (bind_bo == NULL) { + if (brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND, + NULL, 0, + brw->vs.surf_bo, BRW_VS_MAX_SURF, + NULL, + bo_out)) + { + return PIPE_OK; + } + else { GLuint data_size = BRW_VS_MAX_SURF * sizeof(GLuint); uint32_t *data = malloc(data_size); int i; @@ -156,11 +164,14 @@ brw_vs_get_binding_table(struct brw_context *brw) else data[i] = 0; - bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND, - NULL, 0, - brw->vs.surf_bo, BRW_VS_MAX_SURF, - data, data_size, - NULL, NULL); + ret = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND, + NULL, 0, + brw->vs.surf_bo, BRW_VS_MAX_SURF, + data, data_size, + NULL, NULL, + bo_out); + if (ret) + return ret; /* Emit binding table relocations to surface state */ for (i = 0; i < BRW_VS_MAX_SURF; i++) { @@ -168,18 +179,19 @@ brw_vs_get_binding_table(struct brw_context *brw) /* The presumed offsets were set in the data values for * brw_upload_cache. */ - drm_intel_bo_emit_reloc(bind_bo, i * 4, - brw->vs.surf_bo[i], 0, - BRW_USAGE_STATE); + ret = sws->bo_emit_reloc(*bo_out, i * 4, + brw->vs.surf_bo[i], 0, + BRW_USAGE_STATE); + if (ret) + return ret; } } - free(data); + FREE(data); + return PIPE_OK; } - - return bind_bo; #else - return NULL; + return PIPE_OK; #endif } @@ -190,8 +202,10 @@ brw_vs_get_binding_table(struct brw_context *brw) * to be updated, and produces BRW_NEW_NR_VS_SURFACES for the VS unit and * CACHE_NEW_SURF_BIND for the binding table upload. */ -static int prepare_vs_surfaces(struct brw_context *brw ) +static enum pipe_error prepare_vs_surfaces(struct brw_context *brw ) { + enum pipe_error ret; + #if 0 int i; int nr_surfaces = 0; @@ -215,11 +229,12 @@ static int prepare_vs_surfaces(struct brw_context *brw ) * just slightly increases our working set size. */ if (brw->vs.nr_surfaces != 0) { - brw->sws->bo_unreference(brw->vs.bind_bo); - brw->vs.bind_bo = brw_vs_get_binding_table(brw); + ret = brw_vs_get_binding_table(brw, &brw->vs.bind_bo); + if (ret) + return ret; } - return 0; + return PIPE_OK; } const struct brw_tracked_state brw_vs_surfaces = { diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h index d941fbcebee..f61c541ad15 100644 --- a/src/gallium/drivers/i965/brw_winsys.h +++ b/src/gallium/drivers/i965/brw_winsys.h @@ -28,6 +28,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_error.h" +#include "pipe/p_refcnt.h" struct brw_winsys; struct pipe_fence_handle; @@ -36,10 +37,13 @@ struct pipe_fence_handle; */ #define BRW_BATCH_SIZE (32*1024) +struct brw_winsys_screen; /* Need a tiny bit of information inside the abstract buffer struct: */ struct brw_winsys_buffer { + struct pipe_reference reference; + struct brw_winsys_screen *sws; unsigned *offset; unsigned size; }; @@ -105,6 +109,10 @@ enum brw_buffer_data_type { BRW_DATA_MAX }; + + + + struct brw_winsys_screen { @@ -116,33 +124,33 @@ struct brw_winsys_screen { /** * Create a buffer. */ - struct brw_winsys_buffer *(*bo_alloc)( struct brw_winsys_screen *sws, - enum brw_buffer_type type, - unsigned size, - unsigned alignment ); + enum pipe_error (*bo_alloc)( struct brw_winsys_screen *sws, + enum brw_buffer_type type, + unsigned size, + unsigned alignment, + struct brw_winsys_buffer **bo_out ); - /* Reference and unreference buffers: + /* Destroy a buffer when our refcount goes to zero: */ - void (*bo_reference)( struct brw_winsys_buffer *buffer ); - void (*bo_unreference)( struct brw_winsys_buffer *buffer ); + void (*bo_destroy)( struct brw_winsys_buffer *buffer ); /* delta -- added to b2->offset, and written into buffer * offset -- location above value is written to within buffer */ - int (*bo_emit_reloc)( struct brw_winsys_buffer *buffer, - enum brw_buffer_usage usage, - unsigned delta, - unsigned offset, - struct brw_winsys_buffer *b2); + enum pipe_error (*bo_emit_reloc)( struct brw_winsys_buffer *buffer, + enum brw_buffer_usage usage, + unsigned delta, + unsigned offset, + struct brw_winsys_buffer *b2); - int (*bo_exec)( struct brw_winsys_buffer *buffer, - unsigned bytes_used ); + enum pipe_error (*bo_exec)( struct brw_winsys_buffer *buffer, + unsigned bytes_used ); - int (*bo_subdata)(struct brw_winsys_buffer *buffer, - enum brw_buffer_data_type data_type, - size_t offset, - size_t size, - const void *data); + enum pipe_error (*bo_subdata)(struct brw_winsys_buffer *buffer, + enum brw_buffer_data_type data_type, + size_t offset, + size_t size, + const void *data); boolean (*bo_is_busy)(struct brw_winsys_buffer *buffer); boolean (*bo_references)(struct brw_winsys_buffer *a, @@ -175,6 +183,16 @@ struct brw_winsys_screen { }; +static INLINE void +bo_reference(struct brw_winsys_buffer **ptr, struct brw_winsys_buffer *buf) +{ + struct brw_winsys_buffer *old_buf = *ptr; + + if (pipe_reference((struct pipe_reference **)ptr, &buf->reference)) + old_buf->sws->bo_destroy(old_buf); +} + + /** * Create brw pipe_screen. */ diff --git a/src/gallium/drivers/i965/brw_wm.c b/src/gallium/drivers/i965/brw_wm.c index 815ae8c51aa..93f90bf3298 100644 --- a/src/gallium/drivers/i965/brw_wm.c +++ b/src/gallium/drivers/i965/brw_wm.c @@ -137,30 +137,26 @@ brw_wm_linear_shader_emit(struct brw_context *brw, struct brw_wm_compile *c) * Depending on the instructions used (i.e. flow control instructions) * we'll use one of two code generators. */ -static int do_wm_prog( struct brw_context *brw, - struct brw_fragment_shader *fp, - struct brw_wm_prog_key *key) +static enum pipe_error do_wm_prog( struct brw_context *brw, + struct brw_fragment_shader *fp, + struct brw_wm_prog_key *key, + struct brw_winsys_buffer **bo_out) { + enum pipe_error ret; struct brw_wm_compile *c; const GLuint *program; GLuint program_size; - c = brw->wm.compile_data; - if (c == NULL) { - brw->wm.compile_data = calloc(1, sizeof(*brw->wm.compile_data)); - c = brw->wm.compile_data; - if (c == NULL) { - /* Ouch - big out of memory problem. Can't continue - * without triggering a segfault, no way to signal, - * so just return. - */ + if (brw->wm.compile_data == NULL) { + brw->wm.compile_data = MALLOC(sizeof(*brw->wm.compile_data)); + if (!brw->wm.compile_data) return PIPE_ERROR_OUT_OF_MEMORY; - } - } else { - memset(c, 0, sizeof(*brw->wm.compile_data)); } - memcpy(&c->key, key, sizeof(*key)); + c = brw->wm.compile_data; + memset(c, 0, sizeof *c); + + c->key = *key; c->fp = fp; c->env_param = NULL; /*brw->intel.ctx.FragmentProgram.Parameters;*/ @@ -190,17 +186,21 @@ static int do_wm_prog( struct brw_context *brw, /* get the program */ - program = brw_get_program(&c->func, &program_size); - - brw->sws->bo_unreference(brw->wm.prog_bo); - brw->wm.prog_bo = brw_upload_cache( &brw->cache, BRW_WM_PROG, - &c->key, sizeof(c->key), - NULL, 0, - program, program_size, - &c->prog_data, - &brw->wm.prog_data ); - - return 0; + ret = brw_get_program(&c->func, &program, &program_size); + if (ret) + return ret; + + ret = brw_upload_cache( &brw->cache, BRW_WM_PROG, + &c->key, sizeof(c->key), + NULL, 0, + program, program_size, + &c->prog_data, + &brw->wm.prog_data, + bo_out ); + if (ret) + return ret; + + return PIPE_OK; } @@ -267,24 +267,28 @@ static void brw_wm_populate_key( struct brw_context *brw, } -static int brw_prepare_wm_prog(struct brw_context *brw) +static enum pipe_error brw_prepare_wm_prog(struct brw_context *brw) { struct brw_wm_prog_key key; struct brw_fragment_shader *fs = brw->curr.fragment_shader; + enum pipe_error ret; brw_wm_populate_key(brw, &key); /* Make an early check for the key. */ - brw->sws->bo_unreference(brw->wm.prog_bo); - brw->wm.prog_bo = brw_search_cache(&brw->cache, BRW_WM_PROG, - &key, sizeof(key), - NULL, 0, - &brw->wm.prog_data); - if (brw->wm.prog_bo == NULL) - return do_wm_prog(brw, fs, &key); - - return 0; + if (brw_search_cache(&brw->cache, BRW_WM_PROG, + &key, sizeof(key), + NULL, 0, + &brw->wm.prog_data, + &brw->wm.prog_bo)) + return PIPE_OK; + + ret = do_wm_prog(brw, fs, &key, &brw->wm.prog_bo); + if (ret) + return ret; + + return PIPE_OK; } diff --git a/src/gallium/drivers/i965/brw_wm_constant_buffer.c b/src/gallium/drivers/i965/brw_wm_constant_buffer.c index 50ecef29a41..14568265dd0 100644 --- a/src/gallium/drivers/i965/brw_wm_constant_buffer.c +++ b/src/gallium/drivers/i965/brw_wm_constant_buffer.c @@ -6,12 +6,14 @@ * Create the constant buffer surface. Vertex/fragment shader constants will be * read from this buffer with Data Port Read instructions/messages. */ -struct brw_winsys_buffer * +enum pipe_error brw_create_constant_surface( struct brw_context *brw, - struct brw_surface_key *key ) + struct brw_surface_key *key, + struct brw_winsys_buffer **bo_out ) { const GLint w = key->width - 1; struct brw_winsys_buffer *bo; + enum pipe_error ret; memset(&surf, 0, sizeof(surf)); @@ -28,22 +30,27 @@ brw_create_constant_surface( struct brw_context *brw, surf.ss3.pitch = (key->pitch * key->cpp) - 1; /* ignored?? */ brw_set_surface_tiling(&surf, key->tiling); /* tiling now allowed */ - bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE, - key, sizeof(*key), - &key->bo, key->bo ? 1 : 0, - &surf, sizeof(surf), - NULL, NULL); + ret = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE, + key, sizeof(*key), + &key->bo, key->bo ? 1 : 0, + &surf, sizeof(surf), + NULL, NULL, + &bo_out); + if (ret) + return ret; if (key->bo) { /* Emit relocation to surface contents */ - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_SAMPLER, - 0, - offsetof(struct brw_surface_state, ss1), - key->bo); + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_SAMPLER, + 0, + offsetof(struct brw_surface_state, ss1), + key->bo); + if (ret) + return ret; } - return bo; + return PIPE_OK; } @@ -52,7 +59,7 @@ brw_create_constant_surface( struct brw_context *brw, * Update the surface state for a WM constant buffer. * The constant buffer will be (re)allocated here if needed. */ -static void +static enum pipe_error brw_update_wm_constant_surface( struct brw_context *brw, GLuint surf) { @@ -60,20 +67,21 @@ brw_update_wm_constant_surface( struct brw_context *brw, struct brw_fragment_shader *fp = brw->curr.fragment_shader; struct pipe_buffer *cbuf = brw->curr.fragment_constants; int pitch = cbuf->size / (4 * sizeof(float)); + enum pipe_error ret; /* If we're in this state update atom, we need to update WM constants, so * free the old buffer and create a new one for the new contents. */ - brw->sws->bo_unreference(fp->const_buffer); - fp->const_buffer = brw_wm_update_constant_buffer(brw); + ret = brw_wm_update_constant_buffer(brw, &fp->const_buffer); + if (ret) + return ret; /* If there's no constant buffer, then no surface BO is needed to point at * it. */ if (cbuf == NULL) { - drm_intel_bo_unreference(brw->wm.surf_bo[surf]); - brw->wm.surf_bo[surf] = NULL; - return; + bo_reference(&brw->wm.surf_bo[surf], NULL); + return PIPE_OK; } memset(&key, 0, sizeof(key)); @@ -97,16 +105,20 @@ brw_update_wm_constant_surface( struct brw_context *brw, key.width, key.height, key.depth, key.cpp, key.pitch); */ - brw->sws->bo_unreference(brw->wm.surf_bo[surf]); - brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache, - BRW_SS_SURFACE, - &key, sizeof(key), - &key.bo, 1, - NULL); - if (brw->wm.surf_bo[surf] == NULL) { - brw->wm.surf_bo[surf] = brw_create_constant_surface(brw, &key); - } + if (brw_search_cache(&brw->surface_cache, + BRW_SS_SURFACE, + &key, sizeof(key), + &key.bo, 1, + NULL, + &brw->wm.surf_bo[surf])) + return PIPE_OK; + + ret = brw_create_constant_surface(brw, &key, &brw->wm.surf_bo[surf]); + if (ret) + return ret; + brw->state.dirty.brw |= BRW_NEW_WM_SURFACES; + return PIPE_OK; } /** @@ -117,28 +129,33 @@ brw_update_wm_constant_surface( struct brw_context *brw, * BRW_NEW_WM_SURFACES to get picked up by brw_prepare_wm_surfaces for * inclusion in the binding table. */ -static void prepare_wm_constant_surface(struct brw_context *brw ) +static enum pipe_error prepare_wm_constant_surface(struct brw_context *brw ) { struct brw_fragment_program *fp = (struct brw_fragment_program *) brw->fragment_program; GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER; - drm_intel_bo_unreference(fp->const_buffer); - fp->const_buffer = brw_wm_update_constant_buffer(brw); + ret = brw_wm_update_constant_buffer(brw, + &fp->const_buffer); + if (ret) + return ret; /* If there's no constant buffer, then no surface BO is needed to point at * it. */ if (fp->const_buffer == 0) { if (brw->wm.surf_bo[surf] != NULL) { - drm_intel_bo_unreference(brw->wm.surf_bo[surf]); - brw->wm.surf_bo[surf] = NULL; + bo_reference(&brw->wm.surf_bo[surf], NULL); brw->state.dirty.brw |= BRW_NEW_WM_SURFACES; } - return; + return PIPE_OK; } - brw_update_wm_constant_surface(ctx, surf); + ret = brw_update_wm_constant_surface(ctx, surf); + if (ret) + return ret; + + return PIPE_OK } const struct brw_tracked_state brw_wm_constant_surface = { diff --git a/src/gallium/drivers/i965/brw_wm_sampler_state.c b/src/gallium/drivers/i965/brw_wm_sampler_state.c index 2fddb4ad897..2861aa979fe 100644 --- a/src/gallium/drivers/i965/brw_wm_sampler_state.c +++ b/src/gallium/drivers/i965/brw_wm_sampler_state.c @@ -43,16 +43,22 @@ -static struct brw_winsys_buffer * +static enum pipe_error upload_default_color( struct brw_context *brw, - const GLfloat *color ) + const GLfloat *color, + struct brw_winsys_buffer **bo_out ) { struct brw_sampler_default_color sdc; + enum pipe_error ret; COPY_4V(sdc.color, color); - return brw_cache_data( &brw->cache, BRW_SAMPLER_DEFAULT_COLOR, &sdc, - NULL, 0 ); + ret = brw_cache_data( &brw->cache, BRW_SAMPLER_DEFAULT_COLOR, &sdc, + NULL, 0, bo_out ); + if (ret) + return ret; + + return PIPE_OK; } @@ -111,9 +117,10 @@ brw_wm_sampler_populate_key(struct brw_context *brw, } -static void +static enum pipe_error brw_wm_sampler_update_default_colors(struct brw_context *brw) { + enum pipe_error ret; int nr = MIN2(brw->curr.num_textures, brw->curr.num_samplers); int i; @@ -121,8 +128,7 @@ brw_wm_sampler_update_default_colors(struct brw_context *brw) for (i = 0; i < nr; i++) { const struct brw_texture *tex = brw_texture(brw->curr.texture[i]); const struct brw_sampler *sampler = brw->curr.sampler[i]; - - brw->sws->bo_unreference(brw->wm.sdc_bo[i]); + const float *bc; if (pf_is_depth_or_stencil(tex->base.format)) { float bordercolor[4] = { @@ -131,15 +137,25 @@ brw_wm_sampler_update_default_colors(struct brw_context *brw) sampler->border_color[0], sampler->border_color[0] }; - /* GL specs that border color for depth textures is taken from the - * R channel, while the hardware uses A. Spam R into all the - * channels for safety. - */ - brw->wm.sdc_bo[i] = upload_default_color(brw, bordercolor); - } else { - brw->wm.sdc_bo[i] = upload_default_color(brw, sampler->border_color); + + bc = bordercolor; + } + else { + bc = sampler->border_color; } + + /* GL specs that border color for depth textures is taken from the + * R channel, while the hardware uses A. Spam R into all the + * channels for safety. + */ + ret = upload_default_color(brw, + bc, + &brw->wm.sdc_bo[i]); + if (ret) + return ret; } + + return PIPE_OK; } @@ -149,6 +165,7 @@ brw_wm_sampler_update_default_colors(struct brw_context *brw) static int upload_wm_samplers( struct brw_context *brw ) { struct wm_sampler_key key; + enum pipe_error ret; int i; brw_wm_sampler_update_default_colors(brw); @@ -159,35 +176,40 @@ static int upload_wm_samplers( struct brw_context *brw ) brw->state.dirty.cache |= CACHE_NEW_SAMPLER; } - brw->sws->bo_unreference(brw->wm.sampler_bo); - brw->wm.sampler_bo = NULL; - if (brw->wm.sampler_count == 0) - return 0; + if (brw->wm.sampler_count == 0) { + bo_reference(&brw->wm.sampler_bo, NULL); + return PIPE_OK; + } - brw->wm.sampler_bo = brw_search_cache(&brw->cache, BRW_SAMPLER, - &key, sizeof(key), - brw->wm.sdc_bo, key.sampler_count, - NULL); + if (brw_search_cache(&brw->cache, BRW_SAMPLER, + &key, sizeof(key), + brw->wm.sdc_bo, key.sampler_count, + NULL, + &brw->wm.sampler_bo)) + return PIPE_OK; /* If we didnt find it in the cache, compute the state and put it in the * cache. */ - if (brw->wm.sampler_bo == NULL) { - brw->wm.sampler_bo = brw_upload_cache(&brw->cache, BRW_SAMPLER, - &key, sizeof(key), - brw->wm.sdc_bo, key.sampler_count, - &key.sampler, sizeof(key.sampler), - NULL, NULL); - - /* Emit SDC relocations */ - for (i = 0; i < key.sampler_count; i++) { - brw->sws->bo_emit_reloc(brw->wm.sampler_bo, - BRW_USAGE_SAMPLER, - 0, - i * sizeof(struct brw_sampler_state) + - offsetof(struct brw_sampler_state, ss2), - brw->wm.sdc_bo[i]); - } + ret = brw_upload_cache(&brw->cache, BRW_SAMPLER, + &key, sizeof(key), + brw->wm.sdc_bo, key.sampler_count, + &key.sampler, sizeof(key.sampler), + NULL, NULL, + &brw->wm.sampler_bo); + if (ret) + return ret; + + /* Emit SDC relocations */ + for (i = 0; i < key.sampler_count; i++) { + ret = brw->sws->bo_emit_reloc(brw->wm.sampler_bo, + BRW_USAGE_SAMPLER, + 0, + i * sizeof(struct brw_sampler_state) + + offsetof(struct brw_sampler_state, ss2), + brw->wm.sdc_bo[i]); + if (ret) + return ret; } return 0; diff --git a/src/gallium/drivers/i965/brw_wm_state.c b/src/gallium/drivers/i965/brw_wm_state.c index ccbb647bcd0..86dc10540d7 100644 --- a/src/gallium/drivers/i965/brw_wm_state.c +++ b/src/gallium/drivers/i965/brw_wm_state.c @@ -138,12 +138,13 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key) /** * Setup wm hardware state. See page 225 of Volume 2 */ -static struct brw_winsys_buffer * +static enum pipe_error wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key, - struct brw_winsys_buffer **reloc_bufs) + struct brw_winsys_buffer **reloc_bufs, + struct brw_winsys_buffer **bo_out) { struct brw_wm_unit_state wm; - struct brw_winsys_buffer *bo; + enum pipe_error ret; memset(&wm, 0, sizeof(wm)); @@ -222,45 +223,56 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key, if (BRW_DEBUG & DEBUG_STATS || key->stats_wm) wm.wm4.stats_enable = 1; - bo = brw_upload_cache(&brw->cache, BRW_WM_UNIT, - key, sizeof(*key), - reloc_bufs, 3, - &wm, sizeof(wm), - NULL, NULL); + ret = brw_upload_cache(&brw->cache, BRW_WM_UNIT, + key, sizeof(*key), + reloc_bufs, 3, + &wm, sizeof(wm), + NULL, NULL, + bo_out); + if (ret) + return ret; /* Emit WM program relocation */ - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_STATE, - wm.thread0.grf_reg_count << 1, - offsetof(struct brw_wm_unit_state, thread0), - brw->wm.prog_bo); + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_STATE, + wm.thread0.grf_reg_count << 1, + offsetof(struct brw_wm_unit_state, thread0), + brw->wm.prog_bo); + if (ret) + return ret; /* Emit scratch space relocation */ if (key->total_scratch != 0) { - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_SCRATCH, - wm.thread2.per_thread_scratch_space, - offsetof(struct brw_wm_unit_state, thread2), - brw->wm.scratch_bo); + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_SCRATCH, + wm.thread2.per_thread_scratch_space, + offsetof(struct brw_wm_unit_state, thread2), + brw->wm.scratch_bo); + if (ret) + return ret; } /* Emit sampler state relocation */ if (key->sampler_count != 0) { - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_STATE, - wm.wm4.stats_enable | (wm.wm4.sampler_count << 2), - offsetof(struct brw_wm_unit_state, wm4), - brw->wm.sampler_bo); + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_STATE, + wm.wm4.stats_enable | (wm.wm4.sampler_count << 2), + offsetof(struct brw_wm_unit_state, wm4), + brw->wm.sampler_bo); + if (ret) + return ret; } - return bo; + return PIPE_OK; } -static int upload_wm_unit( struct brw_context *brw ) +static enum pipe_error upload_wm_unit( struct brw_context *brw ) { struct brw_wm_unit_key key; struct brw_winsys_buffer *reloc_bufs[3]; + enum pipe_error ret; + wm_unit_populate_key(brw, &key); /* Allocate the necessary scratch space if we haven't already. Don't @@ -271,15 +283,19 @@ static int upload_wm_unit( struct brw_context *brw ) if (key.total_scratch) { GLuint total = key.total_scratch * key.max_threads; - if (brw->wm.scratch_bo && total > brw->wm.scratch_bo->size) { - brw->sws->bo_unreference(brw->wm.scratch_bo); - brw->wm.scratch_bo = NULL; - } + /* Do we need a new buffer: + */ + if (brw->wm.scratch_bo && total > brw->wm.scratch_bo->size) + bo_reference(&brw->wm.scratch_bo, NULL); + if (brw->wm.scratch_bo == NULL) { - brw->wm.scratch_bo = brw->sws->bo_alloc(brw->sws, - BRW_BUFFER_TYPE_SHADER_SCRATCH, - total, - 4096); + ret = brw->sws->bo_alloc(brw->sws, + BRW_BUFFER_TYPE_SHADER_SCRATCH, + total, + 4096, + &brw->wm.scratch_bo); + if (ret) + return ret; } } @@ -287,16 +303,19 @@ static int upload_wm_unit( struct brw_context *brw ) reloc_bufs[1] = brw->wm.scratch_bo; reloc_bufs[2] = brw->wm.sampler_bo; - brw->sws->bo_unreference(brw->wm.state_bo); - brw->wm.state_bo = brw_search_cache(&brw->cache, BRW_WM_UNIT, - &key, sizeof(key), - reloc_bufs, 3, - NULL); - if (brw->wm.state_bo == NULL) { - brw->wm.state_bo = wm_unit_create_from_key(brw, &key, reloc_bufs); - } + if (brw_search_cache(&brw->cache, BRW_WM_UNIT, + &key, sizeof(key), + reloc_bufs, 3, + NULL, + &brw->wm.state_bo)) + return PIPE_OK; + + ret = wm_unit_create_from_key(brw, &key, reloc_bufs, + &brw->wm.state_bo); + if (ret) + return ret; - return 0; + return PIPE_OK; } const struct brw_tracked_state brw_wm_unit = { diff --git a/src/gallium/drivers/i965/brw_wm_surface_state.c b/src/gallium/drivers/i965/brw_wm_surface_state.c index b055dde20cf..e5d03299677 100644 --- a/src/gallium/drivers/i965/brw_wm_surface_state.c +++ b/src/gallium/drivers/i965/brw_wm_surface_state.c @@ -40,31 +40,40 @@ -static void +static enum pipe_error brw_update_texture_surface( struct brw_context *brw, struct brw_texture *tex, - GLuint surf ) + struct brw_winsys_buffer **bo_out) { - brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache, - BRW_SS_SURFACE, - &tex->ss, sizeof tex->ss, - &tex->bo, 1, - NULL); - - if (brw->wm.surf_bo[surf] == NULL) { - brw->wm.surf_bo[surf] = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE, - &tex->ss, sizeof tex->ss, - &tex->bo, 1, - &tex->ss, sizeof tex->ss, - NULL, NULL); + enum pipe_error ret; + + if (brw_search_cache(&brw->surface_cache, + BRW_SS_SURFACE, + &tex->ss, sizeof tex->ss, + &tex->bo, 1, + NULL, + bo_out)) + return PIPE_OK; + + ret = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE, + &tex->ss, sizeof tex->ss, + &tex->bo, 1, + &tex->ss, sizeof tex->ss, + NULL, NULL, + bo_out); + if (ret) + return ret; - /* Emit relocation to surface contents */ - brw->sws->bo_emit_reloc(brw->wm.surf_bo[surf], - BRW_USAGE_SAMPLER, - 0, - offsetof(struct brw_surface_state, ss1), - tex->bo); - } + /* Emit relocation to surface contents */ + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_SAMPLER, + 0, + offsetof(struct brw_surface_state, ss1), + tex->bo); + if (ret) + return ret; + + return PIPE_OK; } @@ -79,13 +88,14 @@ brw_update_texture_surface( struct brw_context *brw, * While it is only used for the front/back buffer currently, it should be * usable for further buffers when doing ARB_draw_buffer support. */ -static void -brw_update_renderbuffer_surface(struct brw_context *brw, - struct brw_surface *surface, - unsigned int unit) +static enum pipe_error +brw_update_render_surface(struct brw_context *brw, + struct brw_surface *surface, + struct brw_winsys_buffer **bo_out) { struct brw_surf_ss0 blend_ss0 = brw->curr.blend->ss0; struct brw_surface_state ss; + enum pipe_error ret; /* Surfaces are potentially shared between contexts, so can't * scribble the in-place ss0 value in the surface. @@ -98,30 +108,35 @@ brw_update_renderbuffer_surface(struct brw_context *brw, ss.ss0.writedisable_red = blend_ss0.writedisable_red; ss.ss0.writedisable_alpha = blend_ss0.writedisable_alpha; - brw->sws->bo_unreference(brw->wm.surf_bo[unit]); - brw->wm.surf_bo[unit] = brw_search_cache(&brw->surface_cache, - BRW_SS_SURFACE, - &ss, sizeof(ss), - &surface->bo, 1, - NULL); - - if (brw->wm.surf_bo[unit] == NULL) { - - brw->wm.surf_bo[unit] = brw_upload_cache(&brw->surface_cache, - BRW_SS_SURFACE, - &ss, sizeof ss, - &surface->bo, 1, - &ss, sizeof ss, - NULL, NULL); + if (brw_search_cache(&brw->surface_cache, + BRW_SS_SURFACE, + &ss, sizeof(ss), + &surface->bo, 1, + NULL, + bo_out)) + return PIPE_OK; + + ret = brw_upload_cache(&brw->surface_cache, + BRW_SS_SURFACE, + &ss, sizeof ss, + &surface->bo, 1, + &ss, sizeof ss, + NULL, NULL, + bo_out); + if (ret) + return ret; /* XXX: we will only be rendering to this surface: */ - brw->sws->bo_emit_reloc(brw->wm.surf_bo[unit], - BRW_USAGE_RENDER_TARGET, - ss.ss1.base_addr - surface->bo->offset[0], /* XXX */ - offsetof(struct brw_surface_state, ss1), - surface->bo); - } + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_RENDER_TARGET, + ss.ss1.base_addr - surface->bo->offset[0], /* XXX */ + offsetof(struct brw_surface_state, ss1), + surface->bo); + if (ret) + return ret; + + return PIPE_OK; } @@ -129,60 +144,60 @@ brw_update_renderbuffer_surface(struct brw_context *brw, * Constructs the binding table for the WM surface state, which maps unit * numbers to surface state objects. */ -static struct brw_winsys_buffer * -brw_wm_get_binding_table(struct brw_context *brw) +static enum pipe_error +brw_wm_get_binding_table(struct brw_context *brw, + struct brw_winsys_buffer **bo_out ) { - struct brw_winsys_buffer *bind_bo; + enum pipe_error ret; + uint32_t data[BRW_WM_MAX_SURF]; + GLuint data_size = brw->wm.nr_surfaces * sizeof data[0]; + int i; assert(brw->wm.nr_surfaces <= BRW_WM_MAX_SURF); + assert(brw->wm.nr_surfaces > 0); /* Note there is no key for this search beyond the values in the * relocation array: */ - bind_bo = brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND, - NULL, 0, - brw->wm.surf_bo, brw->wm.nr_surfaces, - NULL); - - if (bind_bo == NULL) { - uint32_t data[BRW_WM_MAX_SURF]; - GLuint data_size = brw->wm.nr_surfaces * sizeof data[0]; - int i; - - for (i = 0; i < brw->wm.nr_surfaces; i++) - data[i] = brw->wm.surf_bo[i]->offset[0]; - - bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND, - NULL, 0, - brw->wm.surf_bo, brw->wm.nr_surfaces, - data, data_size, - NULL, NULL); - - /* Emit binding table relocations to surface state */ - for (i = 0; i < brw->wm.nr_surfaces; i++) { - brw->sws->bo_emit_reloc(bind_bo, - BRW_USAGE_STATE, - 0, - i * sizeof(GLuint), - brw->wm.surf_bo[i]); - } + if (brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND, + NULL, 0, + brw->wm.surf_bo, + brw->wm.nr_surfaces, + NULL, + bo_out)) + return PIPE_OK; + + for (i = 0; i < brw->wm.nr_surfaces; i++) + data[i] = brw->wm.surf_bo[i]->offset[0]; + + ret = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND, + NULL, 0, + brw->wm.surf_bo, brw->wm.nr_surfaces, + data, data_size, + NULL, NULL, + bo_out); + if (ret) + return ret; + + /* Emit binding table relocations to surface state */ + for (i = 0; i < brw->wm.nr_surfaces; i++) { + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_STATE, + 0, + i * sizeof(GLuint), + brw->wm.surf_bo[i]); + if (ret) + return ret; } - return bind_bo; + return PIPE_OK; } -static int prepare_wm_surfaces(struct brw_context *brw ) +static enum pipe_error prepare_wm_surfaces(struct brw_context *brw ) { - GLuint i; + enum pipe_error ret; int nr_surfaces = 0; - - /* Unreference old buffers - */ - for (i = 0; i < brw->wm.nr_surfaces; i++) { - brw->sws->bo_unreference(brw->wm.surf_bo[i]); - brw->wm.surf_bo[i] = NULL; - } - + GLuint i; /* PIPE_NEW_COLOR_BUFFERS | PIPE_NEW_BLEND * @@ -192,38 +207,51 @@ static int prepare_wm_surfaces(struct brw_context *brw ) * XXX: no color buffer case */ for (i = 0; i < brw->curr.fb.nr_cbufs; i++) { - brw_update_renderbuffer_surface(brw, - brw_surface(brw->curr.fb.cbufs[i]), - nr_surfaces++); + ret = brw_update_render_surface(brw, + brw_surface(brw->curr.fb.cbufs[i]), + &brw->wm.surf_bo[nr_surfaces++]); + if (ret) + return ret; } /* PIPE_NEW_TEXTURE */ for (i = 0; i < brw->curr.num_textures; i++) { - brw_update_texture_surface(brw, - brw_texture(brw->curr.texture[i]), - nr_surfaces++); + ret = brw_update_texture_surface(brw, + brw_texture(brw->curr.texture[i]), + &brw->wm.surf_bo[nr_surfaces++]); + if (ret) + return ret; } /* PIPE_NEW_FRAGMENT_CONSTANTS */ #if 0 if (brw->curr.fragment_constants) { - brw_update_fragment_constant_surface(brw, - brw->curr.fragment_constants, - nr_surfaces++); + ret = brw_update_fragment_constant_surface(brw, + brw->curr.fragment_constants, + &brw->wm.surf_bo[nr_surfaces++]); + if (ret) + return ret; } #endif if (brw->wm.nr_surfaces != nr_surfaces) { + + /* Unreference any left-over old buffers + */ + for (i = nr_surfaces; i < brw->wm.nr_surfaces; i++) + bo_reference(&brw->wm.surf_bo[i], NULL); + brw->wm.nr_surfaces = nr_surfaces; brw->state.dirty.brw |= BRW_NEW_NR_WM_SURFACES; } - brw->sws->bo_unreference(brw->wm.bind_bo); - brw->wm.bind_bo = brw_wm_get_binding_table(brw); + ret = brw_wm_get_binding_table(brw, &brw->wm.bind_bo); + if (ret) + return ret; - return 0; + return PIPE_OK; } const struct brw_tracked_state brw_wm_surfaces = { diff --git a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c index b1edca818a1..fc465d7c143 100644 --- a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c +++ b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c @@ -134,11 +134,12 @@ const char *data_types[BRW_DATA_MAX] = }; -static struct brw_winsys_buffer * +static enum pipe_error xlib_brw_bo_alloc( struct brw_winsys_screen *sws, - enum brw_buffer_type type, - unsigned size, - unsigned alignment ) + enum brw_buffer_type type, + unsigned size, + unsigned alignment, + struct brw_winsys_buffer **bo_out ) { struct xlib_brw_winsys *xbw = xlib_brw_winsys(sws); struct xlib_brw_buffer *buf; @@ -148,12 +149,13 @@ xlib_brw_bo_alloc( struct brw_winsys_screen *sws, buf = CALLOC_STRUCT(xlib_brw_buffer); if (!buf) - return NULL; + return PIPE_ERROR_OUT_OF_MEMORY; + + pipe_reference_init(&buf->base.reference, 1); buf->offset = align(xbw->offset, alignment); buf->type = type; buf->virtual = MALLOC(size); - buf->cheesy_refcount = 1; buf->base.offset = &buf->offset; /* hmm, cheesy */ buf->base.size = size; @@ -161,36 +163,25 @@ xlib_brw_bo_alloc( struct brw_winsys_screen *sws, if (xbw->offset > MAX_VRAM) goto err; - return &buf->base; + /* XXX: possibly rentrant call to bo_destroy: + */ + bo_reference(bo_out, &buf->base); + return PIPE_OK; err: assert(0); + FREE(buf->virtual); FREE(buf); - return NULL; -} - -static void -xlib_brw_bo_reference( struct brw_winsys_buffer *buffer ) -{ - struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer); - - buf->cheesy_refcount++; + return PIPE_ERROR_OUT_OF_MEMORY; } static void -xlib_brw_bo_unreference( struct brw_winsys_buffer *buffer ) +xlib_brw_bo_destroy( struct brw_winsys_buffer *buffer ) { struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer); - /* As a special favor in this call only, buffer is allowed to be - * NULL: - */ - if (buffer == NULL) - return; - - if (--buf->cheesy_refcount == 0) { - FREE(buffer); - } + FREE(buf->virtual); + FREE(buf); } static int @@ -378,8 +369,7 @@ xlib_create_brw_winsys_screen( void ) ws->base.destroy = xlib_brw_winsys_destroy; ws->base.bo_alloc = xlib_brw_bo_alloc; - ws->base.bo_reference = xlib_brw_bo_reference; - ws->base.bo_unreference = xlib_brw_bo_unreference; + ws->base.bo_destroy = xlib_brw_bo_destroy; ws->base.bo_emit_reloc = xlib_brw_bo_emit_reloc; ws->base.bo_exec = xlib_brw_bo_exec; ws->base.bo_subdata = xlib_brw_bo_subdata; |