summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/i965
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2009-11-05 22:43:36 +0000
committerKeith Whitwell <[email protected]>2009-11-05 22:43:36 +0000
commit4c196ed7a8e06933d11b96ac520afa39252fc5c7 (patch)
treed32fea2784830e7695c071104a461eb853da638f /src/gallium/drivers/i965
parent3763457892c2d0c654c0eca7585e4d3a863f7714 (diff)
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.
Diffstat (limited to 'src/gallium/drivers/i965')
-rw-r--r--src/gallium/drivers/i965/brw_cc.c27
-rw-r--r--src/gallium/drivers/i965/brw_clip_state.c35
-rw-r--r--src/gallium/drivers/i965/brw_context.h4
-rw-r--r--src/gallium/drivers/i965/brw_curbe.c3
-rw-r--r--src/gallium/drivers/i965/brw_gs_state.c36
-rw-r--r--src/gallium/drivers/i965/brw_sf_state.c73
-rw-r--r--src/gallium/drivers/i965/brw_state.h16
-rw-r--r--src/gallium/drivers/i965/brw_state_cache.c81
-rw-r--r--src/gallium/drivers/i965/brw_vs_state.c28
-rw-r--r--src/gallium/drivers/i965/brw_vs_surface_state.c69
-rw-r--r--src/gallium/drivers/i965/brw_winsys.h28
-rw-r--r--src/gallium/drivers/i965/brw_wm_constant_buffer.c25
-rw-r--r--src/gallium/drivers/i965/brw_wm_sampler_state.c27
-rw-r--r--src/gallium/drivers/i965/brw_wm_state.c61
-rw-r--r--src/gallium/drivers/i965/brw_wm_surface_state.c70
15 files changed, 302 insertions, 281 deletions
diff --git a/src/gallium/drivers/i965/brw_cc.c b/src/gallium/drivers/i965/brw_cc.c
index 78d83929e0b..94e2c99c3ef 100644
--- a/src/gallium/drivers/i965/brw_cc.c
+++ b/src/gallium/drivers/i965/brw_cc.c
@@ -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;
diff --git a/src/gallium/drivers/i965/brw_clip_state.c b/src/gallium/drivers/i965/brw_clip_state.c
index 157e6edf198..3f2b9701e60 100644
--- a/src/gallium/drivers/i965/brw_clip_state.c
+++ b/src/gallium/drivers/i965/brw_clip_state.c
@@ -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;
diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h
index 177fe2172de..67fad0d9a57 100644
--- a/src/gallium/drivers/i965/brw_context.h
+++ b/src/gallium/drivers/i965/brw_context.h
@@ -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;
diff --git a/src/gallium/drivers/i965/brw_curbe.c b/src/gallium/drivers/i965/brw_curbe.c
index ca7774a7cc2..0a5cfcc7cfc 100644
--- a/src/gallium/drivers/i965/brw_curbe.c
+++ b/src/gallium/drivers/i965/brw_curbe.c
@@ -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);
diff --git a/src/gallium/drivers/i965/brw_gs_state.c b/src/gallium/drivers/i965/brw_gs_state.c
index 36a99fd0e97..1b0de17aec1 100644
--- a/src/gallium/drivers/i965/brw_gs_state.c
+++ b/src/gallium/drivers/i965/brw_gs_state.c
@@ -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;
diff --git a/src/gallium/drivers/i965/brw_sf_state.c b/src/gallium/drivers/i965/brw_sf_state.c
index 689483b4bc7..a911482149c 100644
--- a/src/gallium/drivers/i965/brw_sf_state.c
+++ b/src/gallium/drivers/i965/brw_sf_state.c
@@ -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;
diff --git a/src/gallium/drivers/i965/brw_state.h b/src/gallium/drivers/i965/brw_state.h
index e219a1d8701..97710abec3c 100644
--- a/src/gallium/drivers/i965/brw_state.h
+++ b/src/gallium/drivers/i965/brw_state.h
@@ -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);
diff --git a/src/gallium/drivers/i965/brw_state_cache.c b/src/gallium/drivers/i965/brw_state_cache.c
index f8369d31ec1..16b643ceb28 100644
--- a/src/gallium/drivers/i965/brw_state_cache.c
+++ b/src/gallium/drivers/i965/brw_state_cache.c
@@ -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);
diff --git a/src/gallium/drivers/i965/brw_vs_state.c b/src/gallium/drivers/i965/brw_vs_state.c
index a5b30eba473..0b44f39f4d3 100644
--- a/src/gallium/drivers/i965/brw_vs_state.c
+++ b/src/gallium/drivers/i965/brw_vs_state.c
@@ -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;
diff --git a/src/gallium/drivers/i965/brw_vs_surface_state.c b/src/gallium/drivers/i965/brw_vs_surface_state.c
index b12df0ec038..aaf2a44f61e 100644
--- a/src/gallium/drivers/i965/brw_vs_surface_state.c
+++ b/src/gallium/drivers/i965/brw_vs_surface_state.c
@@ -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;
- }
- else {
- GLuint data_size = BRW_VS_MAX_SURF * sizeof(GLuint);
- uint32_t *data = malloc(data_size);
- int i;
-
- 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;
- }
- }
+ static GLuint data[BRW_VS_MAX_SURF]; /* always zero */
+ struct brw_winsys_reloc reloc[BRW_VS_MAX_SURF];
+ int i;
- FREE(data);
- return PIPE_OK;
+ /* 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]);
}
+
+ 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;
+
+ FREE(data);
+ return PIPE_OK;
#else
return PIPE_OK;
#endif
diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h
index e72b928b064..2da660a1e6e 100644
--- a/src/gallium/drivers/i965/brw_winsys.h
+++ b/src/gallium/drivers/i965/brw_winsys.h
@@ -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,
diff --git a/src/gallium/drivers/i965/brw_wm_constant_buffer.c b/src/gallium/drivers/i965/brw_wm_constant_buffer.c
index 14568265dd0..6434c6acf73 100644
--- a/src/gallium/drivers/i965/brw_wm_constant_buffer.c
+++ b/src/gallium/drivers/i965/brw_wm_constant_buffer.c
@@ -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;
}
diff --git a/src/gallium/drivers/i965/brw_wm_sampler_state.c b/src/gallium/drivers/i965/brw_wm_sampler_state.c
index 174836b39da..4e99ac703a9 100644
--- a/src/gallium/drivers/i965/brw_wm_sampler_state.c
+++ b/src/gallium/drivers/i965/brw_wm_sampler_state.c
@@ -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;
}
diff --git a/src/gallium/drivers/i965/brw_wm_state.c b/src/gallium/drivers/i965/brw_wm_state.c
index 56789ce7a41..d8e88237ce0 100644
--- a/src/gallium/drivers/i965/brw_wm_state.c
+++ b/src/gallium/drivers/i965/brw_wm_state.c
@@ -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;
}
diff --git a/src/gallium/drivers/i965/brw_wm_surface_state.c b/src/gallium/drivers/i965/brw_wm_surface_state.c
index ed365b03b92..f8823314337 100644
--- a/src/gallium/drivers/i965/brw_wm_surface_state.c
+++ b/src/gallium/drivers/i965/brw_wm_surface_state.c
@@ -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;
}