summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-06-10 23:45:51 -0700
committerEric Anholt <eric@anholt.net>2010-06-11 00:15:59 -0700
commit178414eba402f9087ea505e7ef19f1becdd7a36d (patch)
treedc5d5e33be05ec830d971bc4129226fbb0d26cf5
parent73de09f265cb1c66d70fd9eb92021882bfbbbef6 (diff)
i965: Remove caching of surface state objects.
It turns out that computing a 56 byte key to look up a 20-byte object out of a hash table was some sort of a bad idea. Whoops. before: [ # ] backend test min(s) median(s) stddev. count [ 0] gl firefox-talos-gfx 37.799 38.203 0.39% 6/6 after: [ 0] gl firefox-talos-gfx 34.761 34.784 0.17% 5/6
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h7
-rw-r--r--src/mesa/drivers/dri/i965/brw_state.h7
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_cache.c22
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_upload.c1
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_surface_state.c33
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c391
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.c6
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.c13
8 files changed, 192 insertions, 288 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 86b86fde9a7..7fbffbeb030 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -302,7 +302,6 @@ enum brw_cache_id {
BRW_CLIP_VP,
BRW_CLIP_UNIT,
BRW_CLIP_PROG,
- BRW_SS_SURFACE,
BRW_MAX_CACHE
};
@@ -376,7 +375,6 @@ struct brw_tracked_state {
#define CACHE_NEW_CLIP_VP (1<<BRW_CLIP_VP)
#define CACHE_NEW_CLIP_UNIT (1<<BRW_CLIP_UNIT)
#define CACHE_NEW_CLIP_PROG (1<<BRW_CLIP_PROG)
-#define CACHE_NEW_SURFACE (1<<BRW_SS_SURFACE)
struct brw_cached_batch_item {
struct header *header;
@@ -463,8 +461,7 @@ struct brw_context
int validated_bo_count;
} state;
- struct brw_cache cache; /** non-surface items */
- struct brw_cache surface_cache; /* surface items */
+ struct brw_cache cache;
struct brw_cached_batch_item *cached_batch_items;
struct {
@@ -599,6 +596,7 @@ struct brw_context
drm_intel_bo *bind_bo;
uint32_t bind_bo_offset;
drm_intel_bo *surf_bo[BRW_VS_MAX_SURF];
+ uint32_t surf_offset[BRW_VS_MAX_SURF];
GLuint nr_surfaces;
} vs;
@@ -652,6 +650,7 @@ struct brw_context
drm_intel_bo *bind_bo;
uint32_t bind_bo_offset;
drm_intel_bo *surf_bo[BRW_WM_MAX_SURF];
+ uint32_t surf_offset[BRW_WM_MAX_SURF];
drm_intel_bo *prog_bo;
drm_intel_bo *state_bo;
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 68fd7d4f807..577c70ac8df 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -195,8 +195,9 @@ void *brw_state_batch(struct brw_context *brw,
uint32_t *out_offset);
/* brw_wm_surface_state.c */
-drm_intel_bo *
-brw_create_constant_surface( struct brw_context *brw,
- struct brw_surface_key *key );
+void brw_create_constant_surface(struct brw_context *brw,
+ struct brw_surface_key *key,
+ drm_intel_bo **out_bo,
+ uint32_t *out_offset);
#endif
diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c
index 45f1088f4aa..c19ea85e746 100644
--- a/src/mesa/drivers/dri/i965/brw_state_cache.c
+++ b/src/mesa/drivers/dri/i965/brw_state_cache.c
@@ -396,28 +396,10 @@ brw_init_non_surface_cache(struct brw_context *brw)
brw_init_cache_id(cache, "DEPTH_STENCIL_STATE", BRW_DEPTH_STENCIL_STATE);
}
-
-static void
-brw_init_surface_cache(struct brw_context *brw)
-{
- struct brw_cache *cache = &brw->surface_cache;
-
- cache->brw = brw;
-
- cache->size = 7;
- cache->n_items = 0;
- cache->items = (struct brw_cache_item **)
- calloc(1, cache->size * sizeof(struct brw_cache_item));
-
- brw_init_cache_id(cache, "SS_SURFACE", BRW_SS_SURFACE);
-}
-
-
void
brw_init_caches(struct brw_context *brw)
{
brw_init_non_surface_cache(brw);
- brw_init_surface_cache(brw);
}
@@ -498,9 +480,6 @@ brw_state_cache_check_size(struct brw_context *brw)
*/
if (brw->cache.n_items > 1000)
brw_clear_cache(brw, &brw->cache);
-
- if (brw->surface_cache.n_items > 1000)
- brw_clear_cache(brw, &brw->surface_cache);
}
@@ -527,5 +506,4 @@ void
brw_destroy_caches(struct brw_context *brw)
{
brw_destroy_cache(brw, &brw->cache);
- brw_destroy_cache(brw, &brw->surface_cache);
}
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index e345dbcf5b7..fac57c935fe 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -297,7 +297,6 @@ static struct dirty_bit_map cache_bits[] = {
DEFINE_BIT(CACHE_NEW_CLIP_VP),
DEFINE_BIT(CACHE_NEW_CLIP_UNIT),
DEFINE_BIT(CACHE_NEW_CLIP_PROG),
- DEFINE_BIT(CACHE_NEW_SURFACE),
{0, 0, 0}
};
diff --git a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
index d946756af70..611d77d1f74 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
@@ -139,41 +139,25 @@ brw_update_vs_constant_surface( GLcontext *ctx,
key.width, key.height, key.depth, key.cpp, key.pitch);
*/
- drm_intel_bo_unreference(brw->vs.surf_bo[surf]);
- brw->vs.surf_bo[surf] = brw_search_cache(&brw->surface_cache,
- BRW_SS_SURFACE,
- &key, sizeof(key),
- &key.bo, 1,
- NULL);
- if (brw->vs.surf_bo[surf] == NULL) {
- brw->vs.surf_bo[surf] = brw_create_constant_surface(brw, &key);
- }
+ brw_create_constant_surface(brw, &key, &brw->vs.surf_bo[surf],
+ &brw->vs.surf_offset[surf]);
}
static void
prepare_vs_surfaces(struct brw_context *brw)
{
- GLcontext *ctx = &brw->intel.ctx;
- int i;
int nr_surfaces = 0;
- brw_update_vs_constant_surface(ctx, SURF_INDEX_VERT_CONST_BUFFER);
-
- for (i = 0; i < BRW_VS_MAX_SURF; i++) {
- if (brw->vs.surf_bo[i] != NULL) {
- nr_surfaces = i + 1;
- }
+ if (brw->vs.const_bo) {
+ brw_add_validated_bo(brw, brw->vs.const_bo);
+ nr_surfaces = 1;
}
if (brw->vs.nr_surfaces != nr_surfaces) {
brw->state.dirty.brw |= BRW_NEW_NR_VS_SURFACES;
brw->vs.nr_surfaces = nr_surfaces;
}
-
- for (i = 0; i < BRW_VS_MAX_SURF; i++) {
- brw_add_validated_bo(brw, brw->vs.surf_bo[i]);
- }
}
/**
@@ -185,6 +169,7 @@ prepare_vs_surfaces(struct brw_context *brw)
*/
static void upload_vs_surfaces(struct brw_context *brw)
{
+ GLcontext *ctx = &brw->intel.ctx;
uint32_t *bind;
int i;
@@ -198,6 +183,8 @@ static void upload_vs_surfaces(struct brw_context *brw)
return;
}
+ brw_update_vs_constant_surface(ctx, SURF_INDEX_VERT_CONST_BUFFER);
+
/* Might want to calculate nr_surfaces first, to avoid taking up so much
* space for the binding table. (once we have vs samplers)
*/
@@ -209,9 +196,9 @@ static void upload_vs_surfaces(struct brw_context *brw)
if (brw->vs.surf_bo[i]) {
drm_intel_bo_emit_reloc(brw->vs.bind_bo,
brw->vs.bind_bo_offset + i * sizeof(uint32_t),
- brw->vs.surf_bo[i], 0,
+ brw->vs.surf_bo[i], brw->vs.surf_offset[i],
I915_GEM_DOMAIN_INSTRUCTION, 0);
- bind[i] = brw->vs.surf_bo[i]->offset;
+ bind[i] = brw->vs.surf_bo[i]->offset + brw->vs.surf_offset[i];
} else {
bind[i] = 0;
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index ba6a6258f57..7e683bd5421 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -196,36 +196,40 @@ brw_set_surface_tiling(struct brw_surface_state *surf, uint32_t tiling)
}
}
-static drm_intel_bo *
-brw_create_texture_surface( struct brw_context *brw,
- struct brw_surface_key *key )
+static void
+brw_update_texture_surface( GLcontext *ctx, GLuint unit )
{
+ struct brw_context *brw = brw_context(ctx);
+ struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
+ struct intel_texture_object *intelObj = intel_texture_object(tObj);
+ struct gl_texture_image *firstImage = tObj->Image[0][intelObj->firstLevel];
+ const GLuint surf_index = SURF_INDEX_TEXTURE(unit);
struct brw_surface_state surf;
- drm_intel_bo *bo;
+ void *map;
memset(&surf, 0, sizeof(surf));
surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
- surf.ss0.surface_type = translate_tex_target(key->target);
- surf.ss0.surface_format = translate_tex_format(key->format,
- key->internal_format,
- key->depthmode);
+ surf.ss0.surface_type = translate_tex_target(tObj->Target);
+ surf.ss0.surface_format = translate_tex_format(firstImage->TexFormat,
+ firstImage->InternalFormat,
+ tObj->DepthMode);
/* This is ok for all textures with channel width 8bit or less:
*/
/* surf.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
- surf.ss1.base_addr = key->bo->offset; /* reloc */
+ surf.ss1.base_addr = intelObj->mt->region->buffer->offset; /* reloc */
- surf.ss2.mip_count = key->last_level - key->first_level;
- surf.ss2.width = key->width - 1;
- surf.ss2.height = key->height - 1;
- brw_set_surface_tiling(&surf, key->tiling);
- surf.ss3.pitch = (key->pitch * key->cpp) - 1;
- surf.ss3.depth = key->depth - 1;
+ surf.ss2.mip_count = intelObj->lastLevel - intelObj->firstLevel;
+ surf.ss2.width = firstImage->Width - 1;
+ surf.ss2.height = firstImage->Height - 1;
+ brw_set_surface_tiling(&surf, intelObj->mt->region->tiling);
+ surf.ss3.pitch = (intelObj->mt->region->pitch * intelObj->mt->cpp) - 1;
+ surf.ss3.depth = firstImage->Depth - 1;
surf.ss4.min_lod = 0;
- if (key->target == GL_TEXTURE_CUBE_MAP) {
+ if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
surf.ss0.cube_pos_x = 1;
surf.ss0.cube_pos_y = 1;
surf.ss0.cube_pos_z = 1;
@@ -234,71 +238,32 @@ brw_create_texture_surface( struct brw_context *brw,
surf.ss0.cube_neg_z = 1;
}
- bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
- key, sizeof(*key),
- &key->bo, 1,
- &surf, sizeof(surf));
+ map = brw_state_batch(brw, sizeof(surf), 32,
+ &brw->wm.surf_bo[surf_index],
+ &brw->wm.surf_offset[surf_index]);
+ memcpy(map, &surf, sizeof(surf));
/* Emit relocation to surface contents */
- drm_intel_bo_emit_reloc(bo, offsetof(struct brw_surface_state, ss1),
- key->bo, 0,
+ drm_intel_bo_emit_reloc(brw->wm.surf_bo[surf_index],
+ brw->wm.surf_offset[surf_index] +
+ offsetof(struct brw_surface_state, ss1),
+ intelObj->mt->region->buffer, 0,
I915_GEM_DOMAIN_SAMPLER, 0);
-
- return bo;
}
-static void
-brw_update_texture_surface( GLcontext *ctx, GLuint unit )
-{
- struct brw_context *brw = brw_context(ctx);
- struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
- struct intel_texture_object *intelObj = intel_texture_object(tObj);
- struct gl_texture_image *firstImage = tObj->Image[0][intelObj->firstLevel];
- struct brw_surface_key key;
- const GLuint surf = SURF_INDEX_TEXTURE(unit);
-
- memset(&key, 0, sizeof(key));
-
- key.format = firstImage->TexFormat;
- key.internal_format = firstImage->InternalFormat;
- key.pitch = intelObj->mt->region->pitch;
- key.depth = firstImage->Depth;
- key.bo = intelObj->mt->region->buffer;
- key.offset = 0;
-
- key.target = tObj->Target;
- key.depthmode = tObj->DepthMode;
- key.first_level = intelObj->firstLevel;
- key.last_level = intelObj->lastLevel;
- key.width = firstImage->Width;
- key.height = firstImage->Height;
- key.cpp = intelObj->mt->cpp;
- key.tiling = intelObj->mt->region->tiling;
-
- drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
- brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache,
- BRW_SS_SURFACE,
- &key, sizeof(key),
- &key.bo, 1,
- NULL);
- if (brw->wm.surf_bo[surf] == NULL) {
- brw->wm.surf_bo[surf] = brw_create_texture_surface(brw, &key);
- }
-}
-
-
-
/**
* Create the constant buffer surface. Vertex/fragment shader constants will be
* read from this buffer with Data Port Read instructions/messages.
*/
-drm_intel_bo *
-brw_create_constant_surface( struct brw_context *brw,
- struct brw_surface_key *key )
+void
+brw_create_constant_surface(struct brw_context *brw,
+ struct brw_surface_key *key,
+ drm_intel_bo **out_bo,
+ uint32_t *out_offset)
{
const GLint w = key->width - 1;
struct brw_surface_state surf;
- drm_intel_bo *bo;
+ void *map;
memset(&surf, 0, sizeof(surf));
@@ -314,21 +279,18 @@ brw_create_constant_surface( struct brw_context *brw,
surf.ss3.depth = (w >> 20) & 0x7f; /* bits 26:20 of size or width */
surf.ss3.pitch = (key->pitch * key->cpp) - 1; /* ignored?? */
brw_set_surface_tiling(&surf, key->tiling); /* tiling now allowed */
-
- bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
- key, sizeof(*key),
- &key->bo, 1,
- &surf, sizeof(surf));
+
+ map = brw_state_batch(brw, sizeof(surf), 32, out_bo, out_offset);
+ memcpy(map, &surf, sizeof(surf));
/* Emit relocation to surface contents. Section 5.1.1 of the gen4
* bspec ("Data Cache") says that the data cache does not exist as
* a separate cache and is just the sampler cache.
*/
- drm_intel_bo_emit_reloc(bo, offsetof(struct brw_surface_state, ss1),
+ drm_intel_bo_emit_reloc(*out_bo, (*out_offset +
+ offsetof(struct brw_surface_state, ss1)),
key->bo, 0,
I915_GEM_DOMAIN_SAMPLER, 0);
-
- return bo;
}
/* Creates a new WM constant buffer reflecting the current fragment program's
@@ -381,10 +343,21 @@ const struct brw_tracked_state brw_wm_constants = {
* The constant buffer will be (re)allocated here if needed.
*/
static void
-brw_update_wm_constant_surface( GLcontext *ctx,
- GLuint surf)
+prepare_wm_constant_surface(GLcontext *ctx)
{
- struct brw_context *brw = brw_context(ctx);
+}
+
+/**
+ * Updates surface / buffer for fragment shader constant buffer, if
+ * one is required.
+ *
+ * This consumes the state updates for the constant buffer, and produces
+ * BRW_NEW_WM_SURFACES to get picked up by brw_prepare_wm_surfaces for
+ * inclusion in the binding table.
+ */
+static void upload_wm_constant_surface(struct brw_context *brw )
+{
+ GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER;
struct brw_surface_key key;
struct brw_fragment_program *fp =
(struct brw_fragment_program *) brw->fragment_program;
@@ -394,9 +367,12 @@ brw_update_wm_constant_surface( GLcontext *ctx,
/* If there's no constant buffer, then no surface BO is needed to point at
* it.
*/
- if (brw->wm.const_bo == NULL) {
- drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
- brw->wm.surf_bo[surf] = NULL;
+ if (brw->wm.const_bo == 0) {
+ if (brw->wm.surf_bo[surf] != NULL) {
+ drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
+ brw->wm.surf_bo[surf] = NULL;
+ brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
+ }
return;
}
@@ -418,53 +394,19 @@ brw_update_wm_constant_surface( GLcontext *ctx,
key.width, key.height, key.depth, key.cpp, key.pitch);
*/
- drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
- brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache,
- BRW_SS_SURFACE,
- &key, sizeof(key),
- &key.bo, 1,
- NULL);
- if (brw->wm.surf_bo[surf] == NULL) {
- brw->wm.surf_bo[surf] = brw_create_constant_surface(brw, &key);
- }
+ brw_create_constant_surface(brw, &key, &brw->wm.surf_bo[surf],
+ &brw->wm.surf_offset[surf]);
brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
}
-/**
- * Updates surface / buffer for fragment shader constant buffer, if
- * one is required.
- *
- * This consumes the state updates for the constant buffer, and produces
- * BRW_NEW_WM_SURFACES to get picked up by brw_prepare_wm_surfaces for
- * inclusion in the binding table.
- */
-static void prepare_wm_constant_surface(struct brw_context *brw )
-{
- GLcontext *ctx = &brw->intel.ctx;
- GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER;
-
- /* If there's no constant buffer, then no surface BO is needed to point at
- * it.
- */
- if (brw->wm.const_bo == 0) {
- if (brw->wm.surf_bo[surf] != NULL) {
- drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
- brw->wm.surf_bo[surf] = NULL;
- brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
- }
- return;
- }
-
- brw_update_wm_constant_surface(ctx, surf);
-}
-
const struct brw_tracked_state brw_wm_constant_surface = {
.dirty = {
.mesa = 0,
- .brw = (BRW_NEW_WM_CONSTBUF),
+ .brw = (BRW_NEW_WM_CONSTBUF |
+ BRW_NEW_BATCH),
.cache = 0
},
- .prepare = prepare_wm_constant_surface,
+ .emit = upload_wm_constant_surface,
};
@@ -493,6 +435,8 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
uint32_t draw_x;
uint32_t draw_y;
} key;
+ struct brw_surface_state surf;
+ void *map;
memset(&key, 0, sizeof(key));
@@ -559,87 +503,120 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
(ctx->Color.BlendEnabled & (1 << unit)));
}
- drm_intel_bo_unreference(brw->wm.surf_bo[unit]);
- brw->wm.surf_bo[unit] = brw_search_cache(&brw->surface_cache,
- BRW_SS_SURFACE,
- &key, sizeof(key),
- &region_bo, 1,
- NULL);
-
- if (brw->wm.surf_bo[unit] == NULL) {
- struct brw_surface_state surf;
-
- memset(&surf, 0, sizeof(surf));
+ memset(&surf, 0, sizeof(surf));
- surf.ss0.surface_format = key.surface_format;
- surf.ss0.surface_type = key.surface_type;
- if (key.tiling == I915_TILING_NONE) {
- surf.ss1.base_addr = (key.draw_x + key.draw_y * key.pitch) * key.cpp;
+ surf.ss0.surface_format = key.surface_format;
+ surf.ss0.surface_type = key.surface_type;
+ if (key.tiling == I915_TILING_NONE) {
+ surf.ss1.base_addr = (key.draw_x + key.draw_y * key.pitch) * key.cpp;
+ } else {
+ uint32_t tile_base, tile_x, tile_y;
+ uint32_t pitch = key.pitch * key.cpp;
+
+ if (key.tiling == I915_TILING_X) {
+ tile_x = key.draw_x % (512 / key.cpp);
+ tile_y = key.draw_y % 8;
+ tile_base = ((key.draw_y / 8) * (8 * pitch));
+ tile_base += (key.draw_x - tile_x) / (512 / key.cpp) * 4096;
} else {
- uint32_t tile_base, tile_x, tile_y;
- uint32_t pitch = key.pitch * key.cpp;
-
- if (key.tiling == I915_TILING_X) {
- tile_x = key.draw_x % (512 / key.cpp);
- tile_y = key.draw_y % 8;
- tile_base = ((key.draw_y / 8) * (8 * pitch));
- tile_base += (key.draw_x - tile_x) / (512 / key.cpp) * 4096;
- } else {
- /* Y */
- tile_x = key.draw_x % (128 / key.cpp);
- tile_y = key.draw_y % 32;
- tile_base = ((key.draw_y / 32) * (32 * pitch));
- tile_base += (key.draw_x - tile_x) / (128 / key.cpp) * 4096;
- }
- assert(brw->has_surface_tile_offset || (tile_x == 0 && tile_y == 0));
- assert(tile_x % 4 == 0);
- assert(tile_y % 2 == 0);
- /* Note that the low bits of these fields are missing, so
- * there's the possibility of getting in trouble.
- */
- surf.ss1.base_addr = tile_base;
- surf.ss5.x_offset = tile_x / 4;
- surf.ss5.y_offset = tile_y / 2;
+ /* Y */
+ tile_x = key.draw_x % (128 / key.cpp);
+ tile_y = key.draw_y % 32;
+ tile_base = ((key.draw_y / 32) * (32 * pitch));
+ tile_base += (key.draw_x - tile_x) / (128 / key.cpp) * 4096;
}
- if (region_bo != NULL)
- surf.ss1.base_addr += region_bo->offset; /* reloc */
-
- surf.ss2.width = key.width - 1;
- surf.ss2.height = key.height - 1;
- brw_set_surface_tiling(&surf, key.tiling);
- surf.ss3.pitch = (key.pitch * key.cpp) - 1;
-
- if (intel->gen < 6) {
- /* _NEW_COLOR */
- surf.ss0.color_blend = key.color_blend;
- surf.ss0.writedisable_red = !key.color_mask[0];
- surf.ss0.writedisable_green = !key.color_mask[1];
- surf.ss0.writedisable_blue = !key.color_mask[2];
- surf.ss0.writedisable_alpha = !key.color_mask[3];
+ assert(brw->has_surface_tile_offset || (tile_x == 0 && tile_y == 0));
+ assert(tile_x % 4 == 0);
+ assert(tile_y % 2 == 0);
+ /* Note that the low bits of these fields are missing, so
+ * there's the possibility of getting in trouble.
+ */
+ surf.ss1.base_addr = tile_base;
+ surf.ss5.x_offset = tile_x / 4;
+ surf.ss5.y_offset = tile_y / 2;
+ }
+ if (region_bo != NULL)
+ surf.ss1.base_addr += region_bo->offset; /* reloc */
+
+ surf.ss2.width = key.width - 1;
+ surf.ss2.height = key.height - 1;
+ brw_set_surface_tiling(&surf, key.tiling);
+ surf.ss3.pitch = (key.pitch * key.cpp) - 1;
+
+ if (intel->gen < 6) {
+ /* _NEW_COLOR */
+ surf.ss0.color_blend = key.color_blend;
+ surf.ss0.writedisable_red = !key.color_mask[0];
+ surf.ss0.writedisable_green = !key.color_mask[1];
+ surf.ss0.writedisable_blue = !key.color_mask[2];
+ surf.ss0.writedisable_alpha = !key.color_mask[3];
+ }
+
+ map = brw_state_batch(brw, sizeof(surf), 32,
+ &brw->wm.surf_bo[unit],
+ &brw->wm.surf_offset[unit]);
+ memcpy(map, &surf, sizeof(surf));
+
+ if (region_bo != NULL) {
+ drm_intel_bo_emit_reloc(brw->wm.surf_bo[unit],
+ brw->wm.surf_offset[unit] +
+ offsetof(struct brw_surface_state, ss1),
+ region_bo,
+ surf.ss1.base_addr - region_bo->offset,
+ I915_GEM_DOMAIN_RENDER,
+ I915_GEM_DOMAIN_RENDER);
+ }
+}
+
+static void
+prepare_wm_surfaces(struct brw_context *brw)
+{
+ GLcontext *ctx = &brw->intel.ctx;
+ int i;
+ int nr_surfaces = 0;
+
+ if (ctx->DrawBuffer->_NumColorDrawBuffers >= 1) {
+ for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
+ struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+ struct intel_region *region = irb ? irb->region : NULL;
+
+ brw_add_validated_bo(brw, region->buffer);
+ nr_surfaces = SURF_INDEX_DRAW(i) + 1;
}
+ }
+
+ if (brw->wm.const_bo) {
+ brw_add_validated_bo(brw, brw->wm.const_bo);
+ nr_surfaces = SURF_INDEX_FRAG_CONST_BUFFER + 1;
+ }
+
+ for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
+ const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
+ struct gl_texture_object *tObj = texUnit->_Current;
+ struct intel_texture_object *intelObj = intel_texture_object(tObj);
- /* Key size will never match key size for textures, so we're safe. */
- brw->wm.surf_bo[unit] = brw_upload_cache(&brw->surface_cache,
- BRW_SS_SURFACE,
- &key, sizeof(key),
- &region_bo, 1,
- &surf, sizeof(surf));
- if (region_bo != NULL) {
- /* We might sample from it, and we might render to it, so flag
- * them both. We might be able to figure out from other state
- * a more restrictive relocation to emit.
- */
- drm_intel_bo_emit_reloc(brw->wm.surf_bo[unit],
- offsetof(struct brw_surface_state, ss1),
- region_bo,
- surf.ss1.base_addr - region_bo->offset,
- I915_GEM_DOMAIN_RENDER,
- I915_GEM_DOMAIN_RENDER);
+ if (texUnit->_ReallyEnabled) {
+ brw_add_validated_bo(brw, intelObj->mt->region->buffer);
+ nr_surfaces = SURF_INDEX_TEXTURE(i) + 1;
}
}
+
+ /* Have to update this in our prepare, since the unit's prepare
+ * relies on it.
+ */
+ if (brw->wm.nr_surfaces != nr_surfaces) {
+ brw->wm.nr_surfaces = nr_surfaces;
+ brw->state.dirty.brw |= BRW_NEW_NR_WM_SURFACES;
+ }
}
-static void prepare_wm_surfaces(struct brw_context *brw )
+/**
+ * Constructs the set of surface state objects pointed to by the
+ * binding table.
+ */
+static void
+upload_wm_surfaces(struct brw_context *brw)
{
GLcontext *ctx = &brw->intel.ctx;
GLuint i;
@@ -682,20 +659,9 @@ const struct brw_tracked_state brw_wm_surfaces = {
.cache = 0
},
.prepare = prepare_wm_surfaces,
+ .emit = upload_wm_surfaces,
};
-static void
-brw_wm_prepare_binding_table(struct brw_context *brw)
-{
- int i;
-
- for (i = 0; i < BRW_WM_MAX_SURF; i++) {
- if (brw->wm.surf_bo[i]) {
- brw_add_validated_bo(brw, brw->wm.surf_bo[i]);
- }
- }
-}
-
/**
* Constructs the binding table for the WM surface state, which maps unit
* numbers to surface state objects.
@@ -704,7 +670,7 @@ static void
brw_wm_upload_binding_table(struct brw_context *brw)
{
uint32_t *bind;
- int i, nr_surfaces = 0;
+ int i;
/* Might want to calculate nr_surfaces first, to avoid taking up so much
* space for the binding table.
@@ -717,20 +683,14 @@ brw_wm_upload_binding_table(struct brw_context *brw)
if (brw->wm.surf_bo[i]) {
drm_intel_bo_emit_reloc(brw->wm.bind_bo,
brw->wm.bind_bo_offset + i * sizeof(uint32_t),
- brw->wm.surf_bo[i], 0,
+ brw->wm.surf_bo[i], brw->wm.surf_offset[i],
I915_GEM_DOMAIN_INSTRUCTION, 0);
- bind[i] = brw->wm.surf_bo[i]->offset;
- nr_surfaces = i + 1;
+ bind[i] = brw->wm.surf_bo[i]->offset + brw->wm.surf_offset[i];
} else {
bind[i] = 0;
}
}
- if (brw->wm.nr_surfaces != nr_surfaces) {
- brw->wm.nr_surfaces = nr_surfaces;
- brw->state.dirty.brw |= BRW_NEW_NR_WM_SURFACES;
- }
-
brw->state.dirty.brw |= BRW_NEW_BINDING_TABLE;
}
@@ -741,6 +701,5 @@ const struct brw_tracked_state brw_wm_binding_table = {
BRW_NEW_WM_SURFACES),
.cache = 0
},
- .prepare = brw_wm_prepare_binding_table,
.emit = brw_wm_upload_binding_table,
};
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index 8f61f1f5b24..d95de877b5a 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -296,12 +296,6 @@ intel_renderbuffer_set_region(struct intel_context *intel,
old = rb->region;
rb->region = NULL;
intel_region_reference(&rb->region, region);
-#ifndef I915
- if (old) {
- brw_state_cache_bo_delete(&brw_context(&intel->ctx)->surface_cache,
- old->buffer);
- }
-#endif
intel_region_release(&old);
}
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index 71ef7a8e39b..41b658648e2 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -203,19 +203,6 @@ intel_miptree_release(struct intel_context *intel,
DBG("%s deleting %p\n", __FUNCTION__, *mt);
-#ifndef I915
- /* Free up cached binding tables holding a reference on our buffer, to
- * avoid excessive memory consumption.
- *
- * This isn't as aggressive as we could be, as we'd like to do
- * it from any time we free the last ref on a region. But intel_region.c
- * is context-agnostic. Perhaps our constant state cache should be, as
- * well.
- */
- brw_state_cache_bo_delete(&brw_context(&intel->ctx)->surface_cache,
- (*mt)->region->buffer);
-#endif
-
intel_region_release(&((*mt)->region));
for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {