summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2008-04-17 17:17:23 +1000
committerDave Airlie <airlied@panoply-rh.(none)>2008-04-18 11:57:38 +1000
commit008653ac55776d6b1c6d1627ad20937aa1c4dbda (patch)
treefad31aa8394c539980437ad58642971eb8ba9ca1 /src/mesa/drivers/dri/i965/brw_wm_surface_state.c
parent08f9b190a798c9c61ae07208345d0c2b37e54d39 (diff)
i965: initial attempt at fixing the aperture overflow
Makes state emission into a 2 phase, prepare sets things up and accounts the size of all referenced buffer objects. The emit stage then actually does the batchbuffer touching for emitting the objects. There is an assert in dri_emit_reloc if a reloc occurs for a buffer that hasn't been accounted yet.
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_wm_surface_state.c')
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c75
1 files changed, 51 insertions, 24 deletions
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 c5c944f781..eff4555fdf 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -207,7 +207,7 @@ brw_create_texture_surface( struct brw_context *brw,
return bo;
}
-static void
+static int
brw_update_texture_surface( GLcontext *ctx, GLuint unit )
{
struct brw_context *brw = brw_context(ctx);
@@ -215,6 +215,7 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit )
struct intel_texture_object *intelObj = intel_texture_object(tObj);
struct gl_texture_image *firstImage = tObj->Image[0][intelObj->firstLevel];
struct brw_wm_surface_key key;
+ int ret = 0;
memset(&key, 0, sizeof(key));
key.target = tObj->Target;
@@ -229,13 +230,19 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit )
key.depth = firstImage->Depth;
key.tiled = intelObj->mt->region->tiled;
+ ret |= dri_bufmgr_check_aperture_space(key.bo);
+
dri_bo_unreference(brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS]);
brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS] = brw_search_cache(&brw->cache, BRW_SS_SURFACE,
&key, sizeof(key),
&key.bo, 1,
NULL);
- if (brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS] == NULL)
+ if (brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS] == NULL) {
brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS] = brw_create_texture_surface(brw, &key);
+ }
+
+ ret |= dri_bufmgr_check_aperture_space(brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS]);
+ return ret;
}
/**
@@ -243,12 +250,12 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit )
* While it is only used for the front/back buffer currently, it should be
* usable for further buffers when doing ARB_draw_buffer support.
*/
-static void
+static int
brw_update_region_surface(struct brw_context *brw, struct intel_region *region,
unsigned int unit, GLboolean cached)
{
dri_bo *region_bo = NULL;
-
+ int ret = 0;
struct {
unsigned int surface_type;
unsigned int surface_format;
@@ -271,6 +278,8 @@ brw_update_region_surface(struct brw_context *brw, struct intel_region *region,
key.width = region->pitch; /* XXX: not really! */
key.height = region->height;
key.cpp = region->cpp;
+
+ ret |= dri_bufmgr_check_aperture_space(region->buffer);
} else {
key.surface_type = BRW_SURFACE_NULL;
key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
@@ -331,6 +340,10 @@ brw_update_region_surface(struct brw_context *brw, struct intel_region *region,
region_bo);
}
}
+
+ ret |= dri_bufmgr_check_aperture_space(brw->wm.surf_bo[unit]);
+
+ return ret;
}
@@ -384,17 +397,24 @@ brw_wm_get_binding_table(struct brw_context *brw)
return bind_bo;
}
-static void upload_wm_surfaces(struct brw_context *brw )
+static int prepare_wm_surfaces(struct brw_context *brw )
{
GLcontext *ctx = &brw->intel.ctx;
struct intel_context *intel = &brw->intel;
- GLuint i;
+ GLuint i, ret;
+
if (brw->state.nr_draw_regions > 1) {
- for (i = 0; i < brw->state.nr_draw_regions; i++)
- brw_update_region_surface(brw, brw->state.draw_regions[i], i,
- GL_FALSE);
- }else
- brw_update_region_surface(brw, brw->state.draw_regions[0], 0, GL_TRUE);
+ for (i = 0; i < brw->state.nr_draw_regions; i++) {
+ ret = brw_update_region_surface(brw, brw->state.draw_regions[i], i,
+ GL_FALSE);
+ if (ret)
+ return ret;
+ }
+ }else {
+ ret = brw_update_region_surface(brw, brw->state.draw_regions[0], 0, GL_TRUE);
+ if (ret)
+ return ret;
+ }
brw->wm.nr_surfaces = MAX_DRAW_BUFFERS;
@@ -402,33 +422,40 @@ static void upload_wm_surfaces(struct brw_context *brw )
struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[i];
/* _NEW_TEXTURE, BRW_NEW_TEXDATA */
- if(texUnit->_ReallyEnabled &&
- texUnit->_Current == intel->frame_buffer_texobj)
- {
- dri_bo_unreference(brw->wm.surf_bo[i+MAX_DRAW_BUFFERS]);
- brw->wm.surf_bo[i+MAX_DRAW_BUFFERS] = brw->wm.surf_bo[0];
- dri_bo_reference(brw->wm.surf_bo[i+MAX_DRAW_BUFFERS]);
- brw->wm.nr_surfaces = i + MAX_DRAW_BUFFERS + 1;
- } else if (texUnit->_ReallyEnabled) {
- brw_update_texture_surface(ctx, i);
- brw->wm.nr_surfaces = i + MAX_DRAW_BUFFERS + 1;
+ if(texUnit->_ReallyEnabled) {
+ if (texUnit->_Current == intel->frame_buffer_texobj) {
+ dri_bo_unreference(brw->wm.surf_bo[i+MAX_DRAW_BUFFERS]);
+ brw->wm.surf_bo[i+MAX_DRAW_BUFFERS] = brw->wm.surf_bo[0];
+ dri_bo_reference(brw->wm.surf_bo[i+MAX_DRAW_BUFFERS]);
+ brw->wm.nr_surfaces = i + MAX_DRAW_BUFFERS + 1;
+ } else {
+ ret = brw_update_texture_surface(ctx, i);
+ brw->wm.nr_surfaces = i + MAX_DRAW_BUFFERS + 1;
+
+ if (ret)
+ return ret;
+ }
} else {
- dri_bo_unreference(brw->wm.surf_bo[i+MAX_DRAW_BUFFERS]);
- brw->wm.surf_bo[i+MAX_DRAW_BUFFERS] = NULL;
+ dri_bo_unreference(brw->wm.surf_bo[i+MAX_DRAW_BUFFERS]);
+ brw->wm.surf_bo[i+MAX_DRAW_BUFFERS] = NULL;
}
+
}
dri_bo_unreference(brw->wm.bind_bo);
brw->wm.bind_bo = brw_wm_get_binding_table(brw);
+
+ return dri_bufmgr_check_aperture_space(brw->wm.bind_bo);
}
+
const struct brw_tracked_state brw_wm_surfaces = {
.dirty = {
.mesa = _NEW_COLOR | _NEW_TEXTURE | _NEW_BUFFERS,
.brw = BRW_NEW_CONTEXT,
.cache = 0
},
- .update = upload_wm_surfaces,
+ .prepare = prepare_wm_surfaces,
};