summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/i965/brw_wm_constant_buffer.c
diff options
context:
space:
mode:
authorKeith Whitwell <keithw@vmware.com>2009-11-05 13:57:05 +0000
committerKeith Whitwell <keithw@vmware.com>2009-11-05 14:01:37 +0000
commitc796aed5ddad011d66e631c4cafdbf779e73f213 (patch)
treed8a510233b281c9d6a0690632948f10a03819a84 /src/gallium/drivers/i965/brw_wm_constant_buffer.c
parent31b8b1dd36d9f07a7893a89ee985d83c4d0bb95b (diff)
i965g: add lots of error checks and early returns
Any allocation that may fail should be checked, and propogate the error upwards. At the highest level we will flush batch and retry. This is an alternate strategy to what the original DRI driver did of attempting to flush batch from the lowest levels (eg inside BEGIN_BATCH). The trouble with that strategy was that flushes could occur at unexpected times, and additionally there was a need for a wierd notification mechanism to propogate the 'lost context' state back up to higher levels. Propogating the errors directly gives us a lot of flexibility how to deal with these states, at the expense of a lot more checking in the code. Will add some sanity checks later to make sure that out-of-memory conditions are properly escalated and not lost halfway up the stack.
Diffstat (limited to 'src/gallium/drivers/i965/brw_wm_constant_buffer.c')
-rw-r--r--src/gallium/drivers/i965/brw_wm_constant_buffer.c87
1 files changed, 52 insertions, 35 deletions
diff --git a/src/gallium/drivers/i965/brw_wm_constant_buffer.c b/src/gallium/drivers/i965/brw_wm_constant_buffer.c
index 50ecef29a4..14568265dd 100644
--- a/src/gallium/drivers/i965/brw_wm_constant_buffer.c
+++ b/src/gallium/drivers/i965/brw_wm_constant_buffer.c
@@ -6,12 +6,14 @@
* Create the constant buffer surface. Vertex/fragment shader constants will be
* read from this buffer with Data Port Read instructions/messages.
*/
-struct brw_winsys_buffer *
+enum pipe_error
brw_create_constant_surface( struct brw_context *brw,
- struct brw_surface_key *key )
+ struct brw_surface_key *key,
+ struct brw_winsys_buffer **bo_out )
{
const GLint w = key->width - 1;
struct brw_winsys_buffer *bo;
+ enum pipe_error ret;
memset(&surf, 0, sizeof(surf));
@@ -28,22 +30,27 @@ brw_create_constant_surface( struct brw_context *brw,
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, key->bo ? 1 : 0,
- &surf, sizeof(surf),
- NULL, NULL);
+ ret = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
+ key, sizeof(*key),
+ &key->bo, key->bo ? 1 : 0,
+ &surf, sizeof(surf),
+ NULL, NULL,
+ &bo_out);
+ if (ret)
+ return ret;
if (key->bo) {
/* Emit relocation to surface contents */
- brw->sws->bo_emit_reloc(bo,
- BRW_USAGE_SAMPLER,
- 0,
- offsetof(struct brw_surface_state, ss1),
- key->bo);
+ 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 bo;
+ return PIPE_OK;
}
@@ -52,7 +59,7 @@ brw_create_constant_surface( struct brw_context *brw,
* Update the surface state for a WM constant buffer.
* The constant buffer will be (re)allocated here if needed.
*/
-static void
+static enum pipe_error
brw_update_wm_constant_surface( struct brw_context *brw,
GLuint surf)
{
@@ -60,20 +67,21 @@ brw_update_wm_constant_surface( struct brw_context *brw,
struct brw_fragment_shader *fp = brw->curr.fragment_shader;
struct pipe_buffer *cbuf = brw->curr.fragment_constants;
int pitch = cbuf->size / (4 * sizeof(float));
+ enum pipe_error ret;
/* If we're in this state update atom, we need to update WM constants, so
* free the old buffer and create a new one for the new contents.
*/
- brw->sws->bo_unreference(fp->const_buffer);
- fp->const_buffer = brw_wm_update_constant_buffer(brw);
+ ret = brw_wm_update_constant_buffer(brw, &fp->const_buffer);
+ if (ret)
+ return ret;
/* If there's no constant buffer, then no surface BO is needed to point at
* it.
*/
if (cbuf == NULL) {
- drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
- brw->wm.surf_bo[surf] = NULL;
- return;
+ bo_reference(&brw->wm.surf_bo[surf], NULL);
+ return PIPE_OK;
}
memset(&key, 0, sizeof(key));
@@ -97,16 +105,20 @@ brw_update_wm_constant_surface( struct brw_context *brw,
key.width, key.height, key.depth, key.cpp, key.pitch);
*/
- brw->sws->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);
- }
+ if (brw_search_cache(&brw->surface_cache,
+ BRW_SS_SURFACE,
+ &key, sizeof(key),
+ &key.bo, 1,
+ NULL,
+ &brw->wm.surf_bo[surf]))
+ return PIPE_OK;
+
+ ret = brw_create_constant_surface(brw, &key, &brw->wm.surf_bo[surf]);
+ if (ret)
+ return ret;
+
brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
+ return PIPE_OK;
}
/**
@@ -117,28 +129,33 @@ brw_update_wm_constant_surface( struct brw_context *brw,
* 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 )
+static enum pipe_error prepare_wm_constant_surface(struct brw_context *brw )
{
struct brw_fragment_program *fp =
(struct brw_fragment_program *) brw->fragment_program;
GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER;
- drm_intel_bo_unreference(fp->const_buffer);
- fp->const_buffer = brw_wm_update_constant_buffer(brw);
+ ret = brw_wm_update_constant_buffer(brw,
+ &fp->const_buffer);
+ if (ret)
+ return ret;
/* If there's no constant buffer, then no surface BO is needed to point at
* it.
*/
if (fp->const_buffer == 0) {
if (brw->wm.surf_bo[surf] != NULL) {
- drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
- brw->wm.surf_bo[surf] = NULL;
+ bo_reference(&brw->wm.surf_bo[surf], NULL);
brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
}
- return;
+ return PIPE_OK;
}
- brw_update_wm_constant_surface(ctx, surf);
+ ret = brw_update_wm_constant_surface(ctx, surf);
+ if (ret)
+ return ret;
+
+ return PIPE_OK
}
const struct brw_tracked_state brw_wm_constant_surface = {