i965g: pass relocation information in an array with bo_subdata

Makes it easier to dump as we get all of the information
about the upload in a single hit.

Opens the window to simplification in the driver if these
relocation arrays can be maintained statically rather than
being recreated whenever we check for a new upload.

Still needs some cleanup to avoid uglyness introduced with the
delta values.
This commit is contained in:
Keith Whitwell 2009-11-05 22:43:36 +00:00
parent 3763457892
commit 4c196ed7a8
16 changed files with 327 additions and 287 deletions

View File

@ -129,6 +129,7 @@ cc_unit_populate_key(const struct brw_context *brw,
static enum pipe_error
cc_unit_create_from_key(struct brw_context *brw,
struct brw_cc_unit_key *key,
struct brw_winsys_reloc *reloc,
struct brw_winsys_buffer **bo_out)
{
struct brw_cc_unit_state cc;
@ -141,50 +142,48 @@ cc_unit_create_from_key(struct brw_context *brw,
cc.cc2 = key->cc2;
cc.cc3 = key->cc3;
/* CACHE_NEW_CC_VP */
cc.cc4.cc_viewport_state_offset = 0;
cc.cc5 = key->cc5;
cc.cc6 = key->cc6;
cc.cc7 = key->cc7;
ret = brw_upload_cache(&brw->cache, BRW_CC_UNIT,
key, sizeof(*key),
&brw->cc.vp_bo, 1,
reloc, Elements(reloc),
&cc, sizeof(cc),
NULL, NULL,
bo_out);
if (ret)
return ret;
/* Emit CC viewport relocation */
ret = brw->sws->bo_emit_reloc(*bo_out,
BRW_USAGE_STATE,
0,
offsetof(struct brw_cc_unit_state, cc4),
brw->cc.vp_bo);
if (ret)
return ret;
return PIPE_OK;
}
static int prepare_cc_unit( struct brw_context *brw )
{
struct brw_cc_unit_key key;
struct brw_winsys_reloc reloc[1];
enum pipe_error ret;
cc_unit_populate_key(brw, &key);
/* CACHE_NEW_CC_VP */
make_reloc(&reloc[0],
BRW_USAGE_STATE,
0,
offsetof(struct brw_cc_unit_state, cc4),
brw->cc.vp_bo);
if (brw_search_cache(&brw->cache, BRW_CC_UNIT,
&key, sizeof(key),
&brw->cc.vp_bo, 1,
reloc, 1,
NULL,
&brw->cc.state_bo))
return PIPE_OK;
ret = cc_unit_create_from_key(brw, &key,
reloc,
&brw->cc.state_bo);
if (ret)
return ret;

View File

@ -75,6 +75,7 @@ clip_unit_populate_key(struct brw_context *brw, struct brw_clip_unit_key *key)
static enum pipe_error
clip_unit_create_from_key(struct brw_context *brw,
struct brw_clip_unit_key *key,
struct brw_winsys_reloc *reloc,
struct brw_winsys_buffer **bo_out)
{
struct brw_clip_unit_state clip;
@ -82,7 +83,6 @@ clip_unit_create_from_key(struct brw_context *brw,
memset(&clip, 0, sizeof(clip));
clip.thread0.grf_reg_count = align(key->total_grf, 16) / 16 - 1;
/* reloc */
clip.thread0.kernel_start_pointer = 0;
@ -144,36 +144,44 @@ clip_unit_create_from_key(struct brw_context *brw,
ret = brw_upload_cache(&brw->cache, BRW_CLIP_UNIT,
key, sizeof(*key),
&brw->clip.prog_bo, 1,
reloc, 1,
&clip, sizeof(clip),
NULL, NULL,
bo_out);
if (ret)
return ret;
/* Emit clip program relocation */
assert(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 PIPE_OK;
}
static int upload_clip_unit( struct brw_context *brw )
{
struct brw_clip_unit_key key;
struct brw_winsys_reloc reloc[1];
unsigned grf_reg_count;
enum pipe_error ret;
clip_unit_populate_key(brw, &key);
grf_reg_count = align(key.total_grf, 16) / 16 - 1;
/* clip program relocation
*
* XXX: these reloc structs are long lived and only need to be
* updated when the bound BO changes. Hopefully the stuff mixed in
* in the delta's is non-orthogonal.
*/
assert(brw->clip.prog_bo);
make_reloc(&reloc[0],
BRW_USAGE_STATE,
grf_reg_count << 1,
offsetof(struct brw_clip_unit_state, thread0),
brw->clip.prog_bo);
if (brw_search_cache(&brw->cache, BRW_CLIP_UNIT,
&key, sizeof(key),
&brw->clip.prog_bo, 1,
reloc, 1,
NULL,
&brw->clip.state_bo))
return PIPE_OK;
@ -181,6 +189,7 @@ static int upload_clip_unit( struct brw_context *brw )
/* Create new:
*/
ret = clip_unit_create_from_key(brw, &key,
reloc,
&brw->clip.state_bo);
if (ret)
return ret;

View File

@ -383,8 +383,8 @@ struct brw_cache_item {
GLuint hash;
GLuint key_size; /* for variable-sized keys */
const void *key;
struct brw_winsys_buffer **reloc_bufs;
GLuint nr_reloc_bufs;
struct brw_winsys_reloc *relocs;
GLuint nr_relocs;
struct brw_winsys_buffer *bo;
GLuint data_size;

View File

@ -295,7 +295,8 @@ static enum pipe_error prepare_curbe_buffer(struct brw_context *brw)
brw->curbe.curbe_offset,
BRW_DATA_OTHER,
bufsz,
buf);
buf,
NULL, 0);
}
brw_add_validated_bo(brw, brw->curbe.curbe_bo);

View File

@ -72,15 +72,18 @@ gs_unit_populate_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_reloc *reloc,
unsigned nr_reloc,
struct brw_winsys_buffer **bo_out)
{
struct brw_gs_unit_state gs;
enum pipe_error ret;
memset(&gs, 0, sizeof(gs));
/* maybe-reloc: populate the background */
gs.thread0.grf_reg_count = align(key->total_grf, 16) / 16 - 1;
/* reloc */
gs.thread0.kernel_start_pointer = 0;
gs.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
@ -108,22 +111,13 @@ gs_unit_create_from_key(struct brw_context *brw,
ret = brw_upload_cache(&brw->cache, BRW_GS_UNIT,
key, sizeof(*key),
&brw->gs.prog_bo, 1,
reloc, nr_reloc,
&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_out,
BRW_USAGE_STATE,
gs.thread0.grf_reg_count << 1,
offsetof(struct brw_gs_unit_state, thread0),
brw->gs.prog_bo);
}
return PIPE_OK;
}
@ -131,17 +125,33 @@ static enum pipe_error prepare_gs_unit(struct brw_context *brw)
{
struct brw_gs_unit_key key;
enum pipe_error ret;
struct brw_winsys_reloc reloc[1];
unsigned nr_reloc = 0;
unsigned grf_reg_count;
gs_unit_populate_key(brw, &key);
grf_reg_count = (align(key.total_grf, 16) / 16 - 1);
/* GS program relocation */
if (key.prog_active) {
make_reloc(&reloc[nr_reloc++],
BRW_USAGE_STATE,
grf_reg_count << 1,
offsetof(struct brw_gs_unit_state, thread0),
brw->gs.prog_bo);
}
if (brw_search_cache(&brw->cache, BRW_GS_UNIT,
&key, sizeof(key),
&brw->gs.prog_bo, 1,
reloc, nr_reloc,
NULL,
&brw->gs.state_bo))
return PIPE_OK;
ret = gs_unit_create_from_key(brw, &key, &brw->gs.state_bo);
ret = gs_unit_create_from_key(brw, &key,
reloc, nr_reloc,
&brw->gs.state_bo);
if (ret)
return ret;

View File

@ -132,8 +132,9 @@ sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key)
}
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,
sf_unit_create_from_key(struct brw_context *brw,
struct brw_sf_unit_key *key,
struct brw_winsys_reloc *reloc,
struct brw_winsys_buffer **bo_out)
{
struct brw_sf_unit_state sf;
@ -141,7 +142,8 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
int chipset_max_threads;
memset(&sf, 0, sizeof(sf));
sf.thread0.grf_reg_count = align(key->total_grf, 16) / 16 - 1;
sf.thread0.grf_reg_count = 0;
/* reloc */
sf.thread0.kernel_start_pointer = 0;
@ -177,18 +179,10 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
/* CACHE_NEW_SF_VP */
/* reloc */
sf.sf5.sf_viewport_state_offset = 0;
sf.sf5.viewport_transform = 1;
if (key->scissor)
sf.sf6.scissor = 1;
if (key->front_face == PIPE_WINDING_CCW)
sf.sf5.front_winding = BRW_FRONTWINDING_CCW;
else
sf.sf5.front_winding = BRW_FRONTWINDING_CW;
switch (key->cull_mode) {
case PIPE_WINDING_CCW:
case PIPE_WINDING_CW:
@ -281,34 +275,13 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
ret = brw_upload_cache(&brw->cache, BRW_SF_UNIT,
key, sizeof(*key),
reloc_bufs, 2,
reloc, 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 */
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 */
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;
}
@ -316,23 +289,47 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
static enum pipe_error upload_sf_unit( struct brw_context *brw )
{
struct brw_sf_unit_key key;
struct brw_winsys_buffer *reloc_bufs[2];
struct brw_winsys_reloc reloc[2];
unsigned total_grf;
unsigned viewport_transform;
unsigned front_winding;
enum pipe_error ret;
sf_unit_populate_key(brw, &key);
/* XXX: cut this crap and pre calculate the key:
*/
total_grf = (align(key.total_grf, 16) / 16 - 1);
viewport_transform = 1;
front_winding = (key.front_face == PIPE_WINDING_CCW ?
BRW_FRONTWINDING_CCW :
BRW_FRONTWINDING_CW);
/* Emit SF program relocation */
make_reloc(&reloc[0],
BRW_USAGE_STATE,
total_grf << 1,
offsetof(struct brw_sf_unit_state, thread0),
brw->sf.prog_bo);
/* Emit SF viewport relocation */
make_reloc(&reloc[1],
BRW_USAGE_STATE,
front_winding | (viewport_transform << 1),
offsetof(struct brw_sf_unit_state, sf5),
brw->sf.vp_bo);
reloc_bufs[0] = brw->sf.prog_bo;
reloc_bufs[1] = brw->sf.vp_bo;
if (brw_search_cache(&brw->cache, BRW_SF_UNIT,
&key, sizeof(key),
reloc_bufs, 2,
reloc, 2,
NULL,
&brw->sf.state_bo))
return PIPE_OK;
ret = sf_unit_create_from_key(brw, &key, reloc_bufs,
ret = sf_unit_create_from_key(brw, &key,
reloc,
&brw->sf.state_bo);
if (ret)
return ret;

View File

@ -109,24 +109,24 @@ void brw_destroy_state(struct brw_context *brw);
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_reloc *relocs,
GLuint nr_relocs,
struct brw_winsys_buffer **bo_out );
enum pipe_error brw_cache_data_sz(struct brw_cache *cache,
enum brw_cache_id cache_id,
const void *data,
GLuint data_size,
struct brw_winsys_buffer **reloc_bufs,
GLuint nr_reloc_bufs,
struct brw_winsys_reloc *relocs,
GLuint nr_relocs,
struct brw_winsys_buffer **bo_out);
enum pipe_error brw_upload_cache( struct brw_cache *cache,
enum brw_cache_id cache_id,
const void *key,
GLuint key_sz,
struct brw_winsys_buffer **reloc_bufs,
GLuint nr_reloc_bufs,
struct brw_winsys_reloc *relocs,
GLuint nr_relocs,
const void *data,
GLuint data_sz,
const void *aux,
@ -137,8 +137,8 @@ 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,
struct brw_winsys_reloc *relocs,
GLuint nr_relocs,
void *aux_return,
struct brw_winsys_buffer **bo_out);

View File

@ -47,7 +47,7 @@
* a safe point (unlock) we throw out all of the cache data and let it
* regenerate for the next rendering operation.
*
* The reloc_buf pointers need to be included as key data, otherwise the
* The reloc structs need to be included as key data, otherwise the
* non-unique values stuffed in the offset in key data through
* brw_cache_data() may result in successful probe for state buffers
* even when the buffer being referenced doesn't match. The result would be
@ -73,7 +73,7 @@
static GLuint
hash_key(const void *key, GLuint key_size,
struct brw_winsys_buffer **reloc_bufs, GLuint nr_reloc_bufs)
struct brw_winsys_reloc *relocs, GLuint nr_relocs)
{
GLuint *ikey = (GLuint *)key;
GLuint hash = 0, i;
@ -88,8 +88,8 @@ hash_key(const void *key, GLuint key_size,
}
/* Include the BO pointers as key data as well */
ikey = (GLuint *)reloc_bufs;
key_size = nr_reloc_bufs * sizeof(struct brw_winsys_buffer *);
ikey = (GLuint *)relocs;
key_size = nr_relocs * sizeof(struct brw_winsys_reloc);
for (i = 0; i < key_size/4; i++) {
hash ^= ikey[i];
hash = (hash << 5) | (hash >> 27);
@ -118,7 +118,7 @@ update_cache_last(struct brw_cache *cache, enum brw_cache_id cache_id,
static struct brw_cache_item *
search_cache(struct brw_cache *cache, enum brw_cache_id cache_id,
GLuint hash, const void *key, GLuint key_size,
struct brw_winsys_buffer **reloc_bufs, GLuint nr_reloc_bufs)
struct brw_winsys_reloc *relocs, GLuint nr_relocs)
{
struct brw_cache_item *c;
@ -137,9 +137,8 @@ search_cache(struct brw_cache *cache, enum brw_cache_id cache_id,
c->hash == hash &&
c->key_size == key_size &&
memcmp(c->key, key, key_size) == 0 &&
c->nr_reloc_bufs == nr_reloc_bufs &&
memcmp(c->reloc_bufs, reloc_bufs,
nr_reloc_bufs * sizeof(struct brw_winsys_buffer *)) == 0)
c->nr_relocs == nr_relocs &&
memcmp(c->relocs, relocs, nr_relocs * sizeof *relocs) == 0)
return c;
}
@ -178,16 +177,16 @@ 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,
struct brw_winsys_reloc *relocs,
GLuint nr_relocs,
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);
GLuint hash = hash_key(key, key_size, relocs, nr_relocs);
item = search_cache(cache, cache_id, hash, key, key_size,
reloc_bufs, nr_reloc_bufs);
relocs, nr_relocs);
if (item) {
if (aux_return)
@ -207,8 +206,8 @@ brw_upload_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,
struct brw_winsys_reloc *relocs,
GLuint nr_relocs,
const void *data,
GLuint data_size,
const void *aux,
@ -216,8 +215,8 @@ brw_upload_cache( struct brw_cache *cache,
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 hash = hash_key(key, key_size, relocs, nr_relocs);
GLuint relocs_size = nr_relocs * sizeof relocs[0];
GLuint aux_size = cache->aux_size[cache_id];
enum pipe_error ret;
void *tmp;
@ -236,23 +235,22 @@ brw_upload_cache( struct brw_cache *cache,
return ret;
/* Set up the memory containing the key, aux_data, and reloc_bufs */
/* Set up the memory containing the key, aux_data, and relocs */
tmp = MALLOC(key_size + aux_size + relocs_size);
memcpy(tmp, key, key_size);
memcpy((char *)tmp + key_size, aux, cache->aux_size[cache_id]);
memcpy((char *)tmp + key_size + aux_size, reloc_bufs, relocs_size);
for (i = 0; i < nr_reloc_bufs; i++) {
if (reloc_bufs[i] != NULL)
p_atomic_inc(&reloc_bufs[i]->reference.count);
memcpy((char *)tmp + key_size + aux_size, relocs, relocs_size);
for (i = 0; i < nr_relocs; i++) {
p_atomic_inc(&relocs[i].bo->reference.count);
}
item->cache_id = cache_id;
item->key = tmp;
item->hash = hash;
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->relocs = (struct brw_winsys_reloc *)((char *)tmp + key_size + aux_size);
item->nr_relocs = nr_relocs;
bo_reference( &item->bo, *bo_out );
item->data_size = data_size;
@ -275,9 +273,12 @@ brw_upload_cache( struct brw_cache *cache,
data_size, cache_id);
/* Copy data to the buffer */
cache->sws->bo_subdata(item->bo,
cache_id,
0, data_size, data);
ret = cache->sws->bo_subdata(item->bo,
cache_id,
0, data_size, data,
relocs, nr_relocs);
if (ret)
return ret;
update_cache_last(cache, cache_id, item->bo);
@ -293,15 +294,15 @@ 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_reloc *relocs,
GLuint nr_relocs,
struct brw_winsys_buffer **bo_out)
{
struct brw_cache_item *item;
GLuint hash = hash_key(data, data_size, reloc_bufs, nr_reloc_bufs);
GLuint hash = hash_key(data, data_size, relocs, nr_relocs);
item = search_cache(cache, cache_id, hash, data, data_size,
reloc_bufs, nr_reloc_bufs);
relocs, nr_relocs);
if (item) {
update_cache_last(cache, cache_id, item->bo);
@ -311,7 +312,7 @@ brw_cache_data_sz(struct brw_cache *cache,
return brw_upload_cache(cache, cache_id,
data, data_size,
reloc_bufs, nr_reloc_bufs,
relocs, nr_relocs,
data, data_size,
NULL, NULL,
bo_out);
@ -321,20 +322,22 @@ brw_cache_data_sz(struct brw_cache *cache,
/**
* Wrapper around brw_cache_data_sz using the cache_id's canonical key size.
*
* If nr_reloc_bufs is nonzero, brw_search_cache()/brw_upload_cache() would be
* If nr_relocs is nonzero, brw_search_cache()/brw_upload_cache() would be
* better to use, as the potentially changing offsets in the data-used-as-key
* will result in excessive cache misses.
*
* XXX: above is no longer true -- can we remove some code?
*/
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_reloc *relocs,
GLuint nr_relocs,
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, bo_out);
relocs, nr_relocs, bo_out);
}
@ -510,8 +513,8 @@ brw_clear_cache(struct brw_context *brw, struct brw_cache *cache)
next = c->next;
for (j = 0; j < c->nr_reloc_bufs; j++)
bo_reference(&c->reloc_bufs[j], NULL);
for (j = 0; j < c->nr_relocs; j++)
bo_reference(&c->relocs[j].bo, NULL);
bo_reference(&c->bo, NULL);
FREE((void *)c->key);
@ -555,8 +558,8 @@ 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++)
bo_reference(&c->reloc_bufs[j], NULL);
for (j = 0; j < c->nr_relocs; j++)
bo_reference(&c->relocs[j].bo, NULL);
bo_reference(&c->bo, NULL);

View File

@ -81,6 +81,7 @@ vs_unit_populate_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_reloc *reloc,
struct brw_winsys_buffer **bo_out)
{
enum pipe_error ret;
@ -145,22 +146,13 @@ vs_unit_create_from_key(struct brw_context *brw,
ret = brw_upload_cache(&brw->cache, BRW_VS_UNIT,
key, sizeof(*key),
&brw->vs.prog_bo, 1,
reloc, Elements(reloc),
&vs, sizeof(vs),
NULL, NULL,
bo_out);
if (ret)
return ret;
/* Emit VS program relocation */
ret = brw->sws->bo_emit_reloc(*bo_out,
BRW_USAGE_STATE,
vs.thread0.grf_reg_count << 1,
offsetof(struct brw_vs_unit_state, thread0),
brw->vs.prog_bo);
if (ret)
return ret;
return PIPE_OK;
}
@ -168,17 +160,29 @@ static int prepare_vs_unit(struct brw_context *brw)
{
struct brw_vs_unit_key key;
enum pipe_error ret;
struct brw_winsys_reloc reloc[1];
unsigned grf_reg_count;
vs_unit_populate_key(brw, &key);
grf_reg_count = (align(key.total_grf, 16) / 16 - 1);
/* Emit VS program relocation */
make_reloc(&reloc[0],
BRW_USAGE_STATE,
grf_reg_count << 1,
offsetof(struct brw_vs_unit_state, thread0),
brw->vs.prog_bo);
if (brw_search_cache(&brw->cache, BRW_VS_UNIT,
&key, sizeof(key),
&brw->vs.prog_bo, 1,
reloc, 1,
NULL,
&brw->vs.state_bo))
return PIPE_OK;
ret = vs_unit_create_from_key(brw, &key, &brw->vs.state_bo);
ret = vs_unit_create_from_key(brw, &key, reloc, &brw->vs.state_bo);
if (ret)
return ret;

View File

@ -65,7 +65,8 @@ brw_vs_update_constant_buffer(struct brw_context *brw)
size, 64);
/* _NEW_PROGRAM_CONSTANTS */
dri_bo_subdata(const_buffer, 0, size, params->ParameterValues);
brw->sws->bo_subdata(const_buffer, 0, size, params->ParameterValues,
NULL, 0);
return const_buffer;
}
@ -145,51 +146,31 @@ brw_vs_get_binding_table(struct brw_context *brw,
struct brw_winsys_buffer **bo_out)
{
#if 0
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;
static GLuint data[BRW_VS_MAX_SURF]; /* always zero */
struct brw_winsys_reloc reloc[BRW_VS_MAX_SURF];
int i;
/* Emit binding table relocations to surface state */
for (i = 0; i < BRW_VS_MAX_SURF; i++) {
make_reloc(&reloc[i],
BRW_USAGE_STATE,
0,
i * 4,
brw->vs.surf_bo[i]);
}
else {
GLuint data_size = BRW_VS_MAX_SURF * sizeof(GLuint);
uint32_t *data = malloc(data_size);
int i;
ret = brw_cache_data( &brw->surface_cache,
BRW_SS_SURF_BIND,
NULL, 0,
reloc, Elements(reloc),
data, sizeof data,
NULL, NULL,
bo_out);
if (ret)
return ret;
for (i = 0; i < BRW_VS_MAX_SURF; i++)
if (brw->vs.surf_bo[i])
data[i] = brw->vs.surf_bo[i]->offset;
else
data[i] = 0;
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++) {
if (brw->vs.surf_bo[i] != NULL) {
/* The presumed offsets were set in the data values for
* brw_upload_cache.
*/
ret = sws->bo_emit_reloc(*bo_out, i * 4,
brw->vs.surf_bo[i], 0,
BRW_USAGE_STATE);
if (ret)
return ret;
}
}
FREE(data);
return PIPE_OK;
}
FREE(data);
return PIPE_OK;
#else
return PIPE_OK;
#endif

View File

@ -111,6 +111,30 @@ enum brw_buffer_data_type {
};
/* Relocations to be applied with subdata in a call to sws->bo_subdata, below.
*
* Effectively this encodes:
*
* (unsigned *)(subdata + offset) = bo->offset + delta
*/
struct brw_winsys_reloc {
enum brw_buffer_usage usage; /* debug only */
unsigned delta;
unsigned offset;
struct brw_winsys_buffer *bo;
};
static INLINE void make_reloc( struct brw_winsys_reloc *reloc,
enum brw_buffer_usage usage,
unsigned delta,
unsigned offset,
struct brw_winsys_buffer *bo)
{
reloc->usage = usage;
reloc->delta = delta;
reloc->offset = offset;
reloc->bo = bo; /* Note - note taking a reference yet */
}
@ -151,7 +175,9 @@ struct brw_winsys_screen {
enum brw_buffer_data_type data_type,
size_t offset,
size_t size,
const void *data);
const void *data,
const struct brw_winsys_reloc *reloc,
unsigned nr_reloc );
boolean (*bo_is_busy)(struct brw_winsys_buffer *buffer);
boolean (*bo_references)(struct brw_winsys_buffer *a,

View File

@ -13,16 +13,24 @@ brw_create_constant_surface( struct brw_context *brw,
{
const GLint w = key->width - 1;
struct brw_winsys_buffer *bo;
struct brw_winsys_reloc reloc[1];
enum pipe_error ret;
/* Emit relocation to surface contents */
make_reloc(&reloc[0],
BRW_USAGE_SAMPLER,
0,
offsetof(struct brw_surface_state, ss1),
key->bo);
memset(&surf, 0, sizeof(surf));
surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
surf.ss0.surface_type = BRW_SURFACE_BUFFER;
surf.ss0.surface_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
assert(key->bo);
surf.ss1.base_addr = key->bo->offset; /* reloc */
surf.ss1.base_addr = 0; /* reloc */
surf.ss2.width = w & 0x7f; /* bits 6:0 of size or width */
surf.ss2.height = (w >> 7) & 0x1fff; /* bits 19:7 of size or width */
@ -32,24 +40,13 @@ brw_create_constant_surface( struct brw_context *brw,
ret = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
key, sizeof(*key),
&key->bo, key->bo ? 1 : 0,
reloc, Elements(reloc),
&surf, sizeof(surf),
NULL, NULL,
&bo_out);
if (ret)
return ret;
if (key->bo) {
/* Emit relocation to surface contents */
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 PIPE_OK;
}

View File

@ -165,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;
struct brw_winsys_reloc reloc[BRW_MAX_TEX_UNIT];
enum pipe_error ret;
int i;
@ -181,9 +182,20 @@ static int upload_wm_samplers( struct brw_context *brw )
return PIPE_OK;
}
/* Emit SDC relocations */
for (i = 0; i < key.sampler_count; i++) {
make_reloc( &reloc[i],
BRW_USAGE_SAMPLER,
0,
i * sizeof(struct brw_sampler_state) +
offsetof(struct brw_sampler_state, ss2),
brw->wm.sdc_bo[i]);
}
if (brw_search_cache(&brw->cache, BRW_SAMPLER,
&key, sizeof(key),
brw->wm.sdc_bo, key.sampler_count,
reloc, key.sampler_count,
NULL,
&brw->wm.sampler_bo))
return PIPE_OK;
@ -193,24 +205,13 @@ static int upload_wm_samplers( struct brw_context *brw )
*/
ret = brw_upload_cache(&brw->cache, BRW_SAMPLER,
&key, sizeof(key),
brw->wm.sdc_bo, key.sampler_count,
reloc, key.sampler_count,
&key.sampler, sizeof(key.sampler),
NULL, NULL,
&brw->wm.sampler_bo);
if (ret)
return ret;
/* Emit SDC relocations */
for (i = 0; i < key.sampler_count; i++) {
ret = brw->sws->bo_emit_reloc(brw->wm.sampler_bo,
BRW_USAGE_SAMPLER,
0,
i * sizeof(struct brw_sampler_state) +
offsetof(struct brw_sampler_state, ss2),
brw->wm.sdc_bo[i]);
if (ret)
return ret;
}
return 0;
}

View File

@ -144,8 +144,36 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key,
struct brw_winsys_buffer **bo_out)
{
struct brw_wm_unit_state wm;
struct brw_winsys_reloc reloc[3];
unsigned nr_reloc = 0;
enum pipe_error ret;
/* Emit WM program relocation */
make_reloc(&reloc[nr_reloc++],
BRW_USAGE_STATE,
wm.thread0.grf_reg_count << 1,
offsetof(struct brw_wm_unit_state, thread0),
brw->wm.prog_bo);
/* Emit scratch space relocation */
if (key->total_scratch != 0) {
make_reloc(&reloc[nr_reloc++],
BRW_USAGE_SCRATCH,
wm.thread2.per_thread_scratch_space,
offsetof(struct brw_wm_unit_state, thread2),
brw->wm.scratch_bo);
}
/* Emit sampler state relocation */
if (key->sampler_count != 0) {
make_reloc(&reloc[nr_reloc++],
BRW_USAGE_STATE,
wm.wm4.stats_enable | (wm.wm4.sampler_count << 2),
offsetof(struct brw_wm_unit_state, wm4),
brw->wm.sampler_bo);
}
memset(&wm, 0, sizeof(wm));
wm.thread0.grf_reg_count = align(key->total_grf, 16) / 16 - 1;
@ -220,44 +248,13 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key,
ret = brw_upload_cache(&brw->cache, BRW_WM_UNIT,
key, sizeof(*key),
reloc_bufs, 3,
reloc, nr_reloc,
&wm, sizeof(wm),
NULL, NULL,
bo_out);
if (ret)
return ret;
/* Emit WM program relocation */
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) {
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) {
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 PIPE_OK;
}

View File

@ -45,33 +45,32 @@ brw_update_texture_surface( struct brw_context *brw,
struct brw_texture *tex,
struct brw_winsys_buffer **bo_out)
{
struct brw_winsys_reloc reloc[1];
enum pipe_error ret;
/* Emit relocation to surface contents */
make_reloc(&reloc[0],
BRW_USAGE_SAMPLER,
0,
offsetof(struct brw_surface_state, ss1),
tex->bo);
if (brw_search_cache(&brw->surface_cache,
BRW_SS_SURFACE,
&tex->ss, sizeof tex->ss,
&tex->bo, 1,
reloc, Elements(reloc),
NULL,
bo_out))
return PIPE_OK;
ret = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
&tex->ss, sizeof tex->ss,
&tex->bo, 1,
reloc, Elements(reloc),
&tex->ss, sizeof tex->ss,
NULL, NULL,
bo_out);
if (ret)
return ret;
/* 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;
}
@ -95,8 +94,17 @@ brw_update_render_surface(struct brw_context *brw,
{
struct brw_surf_ss0 blend_ss0 = brw->curr.blend->ss0;
struct brw_surface_state ss;
struct brw_winsys_reloc reloc[1];
enum pipe_error ret;
/* XXX: we will only be rendering to this surface:
*/
make_reloc(&reloc[0],
BRW_USAGE_RENDER_TARGET,
0,
offsetof(struct brw_surface_state, ss1),
surface->bo);
/* Surfaces are potentially shared between contexts, so can't
* scribble the in-place ss0 value in the surface.
*/
@ -111,7 +119,7 @@ brw_update_render_surface(struct brw_context *brw,
if (brw_search_cache(&brw->surface_cache,
BRW_SS_SURFACE,
&ss, sizeof(ss),
&surface->bo, 1,
reloc, Elements(reloc),
NULL,
bo_out))
return PIPE_OK;
@ -119,23 +127,13 @@ brw_update_render_surface(struct brw_context *brw,
ret = brw_upload_cache(&brw->surface_cache,
BRW_SS_SURFACE,
&ss, sizeof ss,
&surface->bo, 1,
reloc, Elements(reloc),
&ss, sizeof ss,
NULL, NULL,
bo_out);
if (ret)
return ret;
/* XXX: we will only be rendering to this surface:
*/
ret = brw->sws->bo_emit_reloc(*bo_out,
BRW_USAGE_RENDER_TARGET,
0,
offsetof(struct brw_surface_state, ss1),
surface->bo);
if (ret)
return ret;
return PIPE_OK;
}
@ -149,6 +147,7 @@ brw_wm_get_binding_table(struct brw_context *brw,
struct brw_winsys_buffer **bo_out )
{
enum pipe_error ret;
struct brw_winsys_reloc reloc[BRW_WM_MAX_SURF];
uint32_t data[BRW_WM_MAX_SURF];
GLuint data_size = brw->wm.nr_surfaces * sizeof data[0];
int i;
@ -156,13 +155,21 @@ brw_wm_get_binding_table(struct brw_context *brw,
assert(brw->wm.nr_surfaces <= BRW_WM_MAX_SURF);
assert(brw->wm.nr_surfaces > 0);
/* Emit binding table relocations to surface state */
for (i = 0; i < brw->wm.nr_surfaces; i++) {
make_reloc(&reloc[i],
BRW_USAGE_STATE,
0,
i * sizeof(GLuint),
brw->wm.surf_bo[i]);
}
/* Note there is no key for this search beyond the values in the
* relocation array:
*/
if (brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND,
NULL, 0,
brw->wm.surf_bo,
brw->wm.nr_surfaces,
reloc, brw->wm.nr_surfaces,
NULL,
bo_out))
return PIPE_OK;
@ -175,24 +182,13 @@ brw_wm_get_binding_table(struct brw_context *brw,
ret = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND,
NULL, 0,
brw->wm.surf_bo, brw->wm.nr_surfaces,
reloc, brw->wm.nr_surfaces,
data, data_size,
NULL, NULL,
bo_out);
if (ret)
return ret;
/* Emit binding table relocations to surface state */
for (i = 0; i < brw->wm.nr_surfaces; i++) {
ret = brw->sws->bo_emit_reloc(*bo_out,
BRW_USAGE_STATE,
0,
i * sizeof(GLuint),
brw->wm.surf_bo[i]);
if (ret)
return ret;
}
return PIPE_OK;
}

View File

@ -47,6 +47,10 @@
#define MAX_VRAM (128*1024*1024)
#define MAX_DUMPS 128
extern int brw_disasm (FILE *file,
const struct brw_instruction *inst,
unsigned count );
@ -294,21 +298,36 @@ xlib_brw_bo_subdata(struct brw_winsys_buffer *buffer,
enum brw_buffer_data_type data_type,
size_t offset,
size_t size,
const void *data)
const void *data,
const struct brw_winsys_reloc *reloc,
unsigned nr_relocs)
{
struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
struct xlib_brw_winsys *xbw = xlib_brw_winsys(buffer->sws);
unsigned i;
debug_printf("%s buf %p off %d sz %d %s\n",
debug_printf("%s buf %p off %d sz %d %s relocs: %d\n",
__FUNCTION__,
(void *)buffer, offset, size, data_types[data_type]);
if (1)
dump_data( xbw, data_type, data, size );
(void *)buffer, offset, size,
data_types[data_type],
nr_relocs);
assert(buf->base.size >= offset + size);
memcpy(buf->virtual + offset, data, size);
/* Apply the relocations:
*/
for (i = 0; i < nr_relocs; i++) {
debug_printf("\treloc[%d] usage %s off %d value %x+%x\n",
i, usages[reloc[i].usage], reloc[i].offset,
xlib_brw_buffer(reloc[i].bo)->offset, reloc[i].delta);
*(unsigned *)(buf->virtual + offset + reloc[i].offset) =
xlib_brw_buffer(reloc[i].bo)->offset + reloc[i].delta;
}
if (1)
dump_data( xbw, data_type, buf->virtual + offset, size );
return 0;
}