i965g: add lots of error checks and early returns
Any allocation that may fail should be checked, and propogate the error upwards. At the highest level we will flush batch and retry. This is an alternate strategy to what the original DRI driver did of attempting to flush batch from the lowest levels (eg inside BEGIN_BATCH). The trouble with that strategy was that flushes could occur at unexpected times, and additionally there was a need for a wierd notification mechanism to propogate the 'lost context' state back up to higher levels. Propogating the errors directly gives us a lot of flexibility how to deal with these states, at the expense of a lot more checking in the code. Will add some sanity checks later to make sure that out-of-memory conditions are properly escalated and not lost halfway up the stack.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
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 bo;
|
||||
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_search_cache(&brw->cache, BRW_CC_UNIT,
|
||||
&key, sizeof(key),
|
||||
&brw->cc.vp_bo, 1,
|
||||
NULL,
|
||||
&brw->cc.state_bo))
|
||||
return PIPE_OK;
|
||||
|
||||
if (brw->cc.state_bo == NULL)
|
||||
brw->cc.state_bo = cc_unit_create_from_key(brw, &key);
|
||||
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 = {
|
||||
|
||||
@@ -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;
|
||||
|
||||
return 0;
|
||||
/* Compile new program:
|
||||
*/
|
||||
ret = compile_clip_prog( brw, &key, &brw->clip.prog_bo );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
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 bo;
|
||||
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 = {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
return 0;
|
||||
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 PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
return 0;
|
||||
ret = gs_unit_create_from_key(brw, &key, &brw->gs.state_bo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
const struct brw_tracked_state brw_gs_unit = {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
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 = {
|
||||
|
||||
@@ -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);
|
||||
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 );
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
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 );
|
||||
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);
|
||||
|
||||
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);
|
||||
void brw_state_cache_check_size( struct brw_context *brw );
|
||||
|
||||
void brw_init_caches( struct brw_context *brw );
|
||||
|
||||
@@ -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_reference(bo_out, item->bo);
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
bo = brw_upload_cache(cache, cache_id,
|
||||
data, data_size,
|
||||
reloc_bufs, nr_reloc_bufs,
|
||||
data, data_size,
|
||||
NULL, NULL);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
ret = brw_get_program(&c.func, &program, &program_size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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_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);
|
||||
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;
|
||||
|
||||
return 0;
|
||||
ret = do_vs_prog(brw, vp, &key, &brw->vs.prog_bo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
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 bo;
|
||||
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;
|
||||
|
||||
return 0;
|
||||
ret = vs_unit_create_from_key(brw, &key, &brw->vs.state_bo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
const struct brw_tracked_state brw_vs_unit = {
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
ret = brw_get_program(&c->func, &program, &program_size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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 );
|
||||
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 0;
|
||||
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);
|
||||
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;
|
||||
|
||||
return 0;
|
||||
ret = do_wm_prog(brw, fs, &key, &brw->wm.prog_bo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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);
|
||||
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++) {
|
||||
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]);
|
||||
}
|
||||
/* 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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
return 0;
|
||||
ret = wm_unit_create_from_key(brw, &key, reloc_bufs,
|
||||
&brw->wm.state_bo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
const struct brw_tracked_state brw_wm_unit = {
|
||||
|
||||
@@ -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);
|
||||
enum pipe_error ret;
|
||||
|
||||
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);
|
||||
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 (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;
|
||||
|
||||
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];
|
||||
|
||||
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;
|
||||
|
||||
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]);
|
||||
}
|
||||
/* 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 = {
|
||||
|
||||
@@ -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;
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
static void
|
||||
xlib_brw_bo_reference( struct brw_winsys_buffer *buffer )
|
||||
xlib_brw_bo_destroy( struct brw_winsys_buffer *buffer )
|
||||
{
|
||||
struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
|
||||
|
||||
buf->cheesy_refcount++;
|
||||
}
|
||||
|
||||
static void
|
||||
xlib_brw_bo_unreference( 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;
|
||||
|
||||
Reference in New Issue
Block a user