diff options
author | Keith Whitwell <[email protected]> | 2009-11-05 13:57:05 +0000 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2009-11-05 14:01:37 +0000 |
commit | c796aed5ddad011d66e631c4cafdbf779e73f213 (patch) | |
tree | d8a510233b281c9d6a0690632948f10a03819a84 /src/gallium/drivers/i965/brw_sf.c | |
parent | 31b8b1dd36d9f07a7893a89ee985d83c4d0bb95b (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_sf.c')
-rw-r--r-- | src/gallium/drivers/i965/brw_sf.c | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/src/gallium/drivers/i965/brw_sf.c b/src/gallium/drivers/i965/brw_sf.c index 013d839e37d..24d1015bbd5 100644 --- a/src/gallium/drivers/i965/brw_sf.c +++ b/src/gallium/drivers/i965/brw_sf.c @@ -40,9 +40,11 @@ #include "brw_sf.h" #include "brw_state.h" -static void compile_sf_prog( struct brw_context *brw, - struct brw_sf_prog_key *key ) +static enum pipe_error compile_sf_prog( struct brw_context *brw, + struct brw_sf_prog_key *key, + struct brw_winsys_buffer **bo_out ) { + enum pipe_error ret; struct brw_sf_compile c; const GLuint *program; GLuint program_size; @@ -87,28 +89,35 @@ static void compile_sf_prog( struct brw_context *brw, break; default: assert(0); - return; + return PIPE_ERROR_BAD_INPUT; } /* get the program */ - program = brw_get_program(&c.func, &program_size); + ret = brw_get_program(&c.func, &program, &program_size); + if (ret) + return ret; /* Upload */ - brw->sws->bo_unreference(brw->sf.prog_bo); - brw->sf.prog_bo = brw_upload_cache( &brw->cache, BRW_SF_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->sf.prog_data ); + ret = brw_upload_cache( &brw->cache, BRW_SF_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + &brw->sf.prog_data, + bo_out); + if (ret) + return ret; + + return PIPE_OK; } /* Calculate interpolants for triangle and line rasterization. */ -static int upload_sf_prog(struct brw_context *brw) +static enum pipe_error upload_sf_prog(struct brw_context *brw) { + enum pipe_error ret; struct brw_sf_prog_key key; memset(&key, 0, sizeof(key)); @@ -161,15 +170,18 @@ static int upload_sf_prog(struct brw_context *brw) PIPE_WINDING_CCW); } - brw->sws->bo_unreference(brw->sf.prog_bo); - brw->sf.prog_bo = brw_search_cache(&brw->cache, BRW_SF_PROG, - &key, sizeof(key), - NULL, 0, - &brw->sf.prog_data); - if (brw->sf.prog_bo == NULL) - compile_sf_prog( brw, &key ); + if (brw_search_cache(&brw->cache, BRW_SF_PROG, + &key, sizeof(key), + NULL, 0, + &brw->sf.prog_data, + &brw->sf.prog_bo)) + return PIPE_OK; - return 0; + ret = compile_sf_prog( brw, &key, &brw->sf.prog_bo ); + if (ret) + return ret; + + return PIPE_OK; } |