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;
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;
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;
memset(&clip, 0, sizeof(clip));
- clip.thread0.grf_reg_count = align(key->total_grf, 16) / 16 - 1;
/* reloc */
clip.thread0.kernel_start_pointer = 0;
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;
/* Create new:
*/
ret = clip_unit_create_from_key(brw, &key,
+ reloc,
&brw->clip.state_bo);
if (ret)
return ret;
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;
brw->curbe.curbe_offset,
BRW_DATA_OTHER,
bufsz,
- buf);
+ buf,
+ NULL, 0);
}
brw_add_validated_bo(brw, brw->curbe.curbe_bo);
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;
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;
}
{
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;
}
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;
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;
/* 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:
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;
}
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;
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,
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);
* 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
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;
}
/* 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);
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;
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;
}
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)
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,
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;
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;
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);
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);
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);
/**
* 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);
}
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);
*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);
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;
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;
}
{
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;
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;
}
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
};
+/* 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 */
+}
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,
{
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 */
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;
}
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;
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;
*/
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;
}
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;
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;
}
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;
}
{
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.
*/
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;
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;
}
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;
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;
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;
}
#define MAX_VRAM (128*1024*1024)
+#define MAX_DUMPS 128
+
+
+
extern int brw_disasm (FILE *file,
const struct brw_instruction *inst,
unsigned count );
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;
}