#define USE_MALLOC_BUFFER 1
#define ALWAYS_EMIT_MI_FLUSH 1
-void
+enum pipe_error
brw_batchbuffer_reset(struct brw_batchbuffer *batch)
{
- if (batch->buf) {
- batch->sws->bo_unreference(batch->buf);
- batch->buf = NULL;
- }
+ enum pipe_error ret;
- batch->buf = batch->sws->bo_alloc(batch->sws,
- BRW_BUFFER_TYPE_BATCH,
- BRW_BATCH_SIZE, 4096);
+ ret = batch->sws->bo_alloc( batch->sws,
+ BRW_BUFFER_TYPE_BATCH,
+ BRW_BATCH_SIZE, 4096,
+ &batch->buf );
+ if (ret)
+ return ret;
if (batch->malloc_buffer)
batch->map = batch->malloc_buffer;
batch->size = BRW_BATCH_SIZE;
batch->ptr = batch->map;
+ return PIPE_OK;
}
struct brw_batchbuffer *
batch->map = NULL;
}
- batch->sws->bo_unreference(batch->buf);
+ bo_reference(&batch->buf, NULL);
FREE(batch);
}
const char *file, int line);
-void brw_batchbuffer_reset(struct brw_batchbuffer *batch);
+enum pipe_error
+brw_batchbuffer_reset(struct brw_batchbuffer *batch);
/* Unlike bmBufferData, this currently requires the buffer be mapped.
svp->far = 1;
}
-static int prepare_cc_vp( struct brw_context *brw )
+static enum pipe_error prepare_cc_vp( struct brw_context *brw )
{
struct brw_cc_viewport ccv;
struct sane_viewport svp;
+ enum pipe_error ret;
memset(&ccv, 0, sizeof(ccv));
ccv.min_depth = svp.near;
ccv.max_depth = svp.far;
- brw->sws->bo_unreference(brw->cc.vp_bo);
- brw->cc.vp_bo = brw_cache_data( &brw->cache, BRW_CC_VP, &ccv, NULL, 0 );
-
- return 0;
+ ret = brw_cache_data( &brw->cache, BRW_CC_VP, &ccv, NULL, 0,
+ &brw->cc.vp_bo );
+ if (ret)
+ return ret;
+
+ return PIPE_OK;
}
const struct brw_tracked_state brw_cc_vp = {
/**
* Creates the state cache entry for the given CC unit key.
*/
-static struct brw_winsys_buffer *
-cc_unit_create_from_key(struct brw_context *brw, struct brw_cc_unit_key *key)
+static enum pipe_error
+cc_unit_create_from_key(struct brw_context *brw,
+ struct brw_cc_unit_key *key,
+ struct brw_winsys_buffer **bo_out)
{
struct brw_cc_unit_state cc;
- struct brw_winsys_buffer *bo;
+ enum pipe_error ret;
memset(&cc, 0, sizeof(cc));
cc.cc6 = key->cc6;
cc.cc7 = key->cc7;
- bo = brw_upload_cache(&brw->cache, BRW_CC_UNIT,
- key, sizeof(*key),
- &brw->cc.vp_bo, 1,
- &cc, sizeof(cc),
- NULL, NULL);
+ ret = brw_upload_cache(&brw->cache, BRW_CC_UNIT,
+ key, sizeof(*key),
+ &brw->cc.vp_bo, 1,
+ &cc, sizeof(cc),
+ NULL, NULL,
+ bo_out);
+ if (ret)
+ return ret;
- /* Emit CC viewport relocation */
- brw->sws->bo_emit_reloc(bo,
- BRW_USAGE_STATE,
- 0,
- offsetof(struct brw_cc_unit_state, cc4),
- brw->cc.vp_bo);
- return bo;
+ /* 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;
+ enum pipe_error ret;
cc_unit_populate_key(brw, &key);
- brw->sws->bo_unreference(brw->cc.state_bo);
- brw->cc.state_bo = brw_search_cache(&brw->cache, BRW_CC_UNIT,
- &key, sizeof(key),
- &brw->cc.vp_bo, 1,
- NULL);
-
- if (brw->cc.state_bo == NULL)
- brw->cc.state_bo = cc_unit_create_from_key(brw, &key);
+ if (brw_search_cache(&brw->cache, BRW_CC_UNIT,
+ &key, sizeof(key),
+ &brw->cc.vp_bo, 1,
+ NULL,
+ &brw->cc.state_bo))
+ return PIPE_OK;
+
+ ret = cc_unit_create_from_key(brw, &key,
+ &brw->cc.state_bo);
+ if (ret)
+ return ret;
- return 0;
+ return PIPE_OK;
}
const struct brw_tracked_state brw_cc_unit = {
#define BACK_UNFILLED_BIT 0x2
-static void compile_clip_prog( struct brw_context *brw,
- struct brw_clip_prog_key *key )
+static enum pipe_error
+compile_clip_prog( struct brw_context *brw,
+ struct brw_clip_prog_key *key,
+ struct brw_winsys_buffer **bo_out )
{
+ enum pipe_error ret;
struct brw_clip_compile c;
const GLuint *program;
GLuint program_size;
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->clip.prog_bo);
- brw->clip.prog_bo = brw_upload_cache( &brw->cache,
- BRW_CLIP_PROG,
- &c.key, sizeof(c.key),
- NULL, 0,
- program, program_size,
- &c.prog_data,
- &brw->clip.prog_data );
+ ret = brw_upload_cache( &brw->cache,
+ BRW_CLIP_PROG,
+ &c.key, sizeof(c.key),
+ NULL, 0,
+ program, program_size,
+ &c.prog_data,
+ &brw->clip.prog_data,
+ bo_out );
+ if (ret)
+ return ret;
+
+ return PIPE_OK;
}
/* Calculate interpolants for triangle and line rasterization.
*/
-static int upload_clip_prog(struct brw_context *brw)
+static enum pipe_error
+upload_clip_prog(struct brw_context *brw)
{
+ enum pipe_error ret;
struct brw_clip_prog_key key;
/* Populate the key, starting from the almost-complete version from
/* PIPE_NEW_CLIP */
key.nr_userclip = brw->curr.ucp.nr;
- brw->sws->bo_unreference(brw->clip.prog_bo);
- brw->clip.prog_bo = brw_search_cache(&brw->cache, BRW_CLIP_PROG,
- &key, sizeof(key),
- NULL, 0,
- &brw->clip.prog_data);
- if (brw->clip.prog_bo == NULL)
- compile_clip_prog( brw, &key );
+ /* Already cached?
+ */
+ if (brw_search_cache(&brw->cache, BRW_CLIP_PROG,
+ &key, sizeof(key),
+ NULL, 0,
+ &brw->clip.prog_data,
+ &brw->clip.prog_bo))
+ return PIPE_OK;
+
+ /* Compile new program:
+ */
+ ret = compile_clip_prog( brw, &key, &brw->clip.prog_bo );
+ if (ret)
+ return ret;
- return 0;
+ return PIPE_OK;
}
key->depth_clamp = 0; // XXX: add this to gallium: ctx->Transform.DepthClamp;
}
-static struct brw_winsys_buffer *
+static enum pipe_error
clip_unit_create_from_key(struct brw_context *brw,
- struct brw_clip_unit_key *key)
+ struct brw_clip_unit_key *key,
+ struct brw_winsys_buffer **bo_out)
{
struct brw_clip_unit_state clip;
- struct brw_winsys_buffer *bo;
+ enum pipe_error ret;
memset(&clip, 0, sizeof(clip));
clip.viewport_ymin = -1;
clip.viewport_ymax = 1;
- bo = brw_upload_cache(&brw->cache, BRW_CLIP_UNIT,
- key, sizeof(*key),
- &brw->clip.prog_bo, 1,
- &clip, sizeof(clip),
- NULL, NULL);
+ ret = brw_upload_cache(&brw->cache, BRW_CLIP_UNIT,
+ key, sizeof(*key),
+ &brw->clip.prog_bo, 1,
+ &clip, sizeof(clip),
+ NULL, NULL,
+ bo_out);
+ if (ret)
+ return ret;
/* Emit clip program relocation */
assert(brw->clip.prog_bo);
- brw->sws->bo_emit_reloc(bo,
- BRW_USAGE_STATE,
- clip.thread0.grf_reg_count << 1,
- offsetof(struct brw_clip_unit_state, thread0),
- brw->clip.prog_bo);
-
- return 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;
+ enum pipe_error ret;
clip_unit_populate_key(brw, &key);
- brw->sws->bo_unreference(brw->clip.state_bo);
- brw->clip.state_bo = brw_search_cache(&brw->cache, BRW_CLIP_UNIT,
- &key, sizeof(key),
- &brw->clip.prog_bo, 1,
- NULL);
- if (brw->clip.state_bo == NULL) {
- brw->clip.state_bo = clip_unit_create_from_key(brw, &key);
- }
+ if (brw_search_cache(&brw->cache, BRW_CLIP_UNIT,
+ &key, sizeof(key),
+ &brw->clip.prog_bo, 1,
+ NULL,
+ &brw->clip.state_bo))
+ return PIPE_OK;
+
+ /* Create new:
+ */
+ ret = clip_unit_create_from_key(brw, &key,
+ &brw->clip.state_bo);
+ if (ret)
+ return ret;
- return 0;
+ return PIPE_OK;
}
const struct brw_tracked_state brw_clip_unit = {
brw->curr.fb.nr_cbufs = 0;
pipe_surface_reference(&brw->curr.fb.zsbuf, NULL);
- brw->sws->bo_unreference(brw->curbe.curbe_bo);
- brw->sws->bo_unreference(brw->vs.prog_bo);
- brw->sws->bo_unreference(brw->vs.state_bo);
- brw->sws->bo_unreference(brw->vs.bind_bo);
- brw->sws->bo_unreference(brw->gs.prog_bo);
- brw->sws->bo_unreference(brw->gs.state_bo);
- brw->sws->bo_unreference(brw->clip.prog_bo);
- brw->sws->bo_unreference(brw->clip.state_bo);
- brw->sws->bo_unreference(brw->clip.vp_bo);
- brw->sws->bo_unreference(brw->sf.prog_bo);
- brw->sws->bo_unreference(brw->sf.state_bo);
- brw->sws->bo_unreference(brw->sf.vp_bo);
+ bo_reference(&brw->curbe.curbe_bo, NULL);
+ bo_reference(&brw->vs.prog_bo, NULL);
+ bo_reference(&brw->vs.state_bo, NULL);
+ bo_reference(&brw->vs.bind_bo, NULL);
+ bo_reference(&brw->gs.prog_bo, NULL);
+ bo_reference(&brw->gs.state_bo, NULL);
+ bo_reference(&brw->clip.prog_bo, NULL);
+ bo_reference(&brw->clip.state_bo, NULL);
+ bo_reference(&brw->clip.vp_bo, NULL);
+ bo_reference(&brw->sf.prog_bo, NULL);
+ bo_reference(&brw->sf.state_bo, NULL);
+ bo_reference(&brw->sf.vp_bo, NULL);
+
for (i = 0; i < BRW_MAX_TEX_UNIT; i++)
- brw->sws->bo_unreference(brw->wm.sdc_bo[i]);
- brw->sws->bo_unreference(brw->wm.bind_bo);
+ bo_reference(&brw->wm.sdc_bo[i], NULL);
+
+ bo_reference(&brw->wm.bind_bo, NULL);
+
for (i = 0; i < BRW_WM_MAX_SURF; i++)
- brw->sws->bo_unreference(brw->wm.surf_bo[i]);
- brw->sws->bo_unreference(brw->wm.sampler_bo);
- brw->sws->bo_unreference(brw->wm.prog_bo);
- brw->sws->bo_unreference(brw->wm.state_bo);
- brw->sws->bo_unreference(brw->cc.prog_bo);
- brw->sws->bo_unreference(brw->cc.state_bo);
- brw->sws->bo_unreference(brw->cc.vp_bo);
+ bo_reference(&brw->wm.surf_bo[i], NULL);
+
+ bo_reference(&brw->wm.sampler_bo, NULL);
+ bo_reference(&brw->wm.prog_bo, NULL);
+ bo_reference(&brw->wm.state_bo, NULL);
+ bo_reference(&brw->cc.prog_bo, NULL);
+ bo_reference(&brw->cc.state_bo, NULL);
+ bo_reference(&brw->cc.vp_bo, NULL);
}
* brw_queryobj.c
*/
void brw_init_query(struct brw_context *brw);
-void brw_prepare_query_begin(struct brw_context *brw);
+enum pipe_error brw_prepare_query_begin(struct brw_context *brw);
void brw_emit_query_begin(struct brw_context *brw);
void brw_emit_query_end(struct brw_context *brw);
* cache mechanism, but maybe would benefit from a comparison against
* the current uploaded set of constants.
*/
-static int prepare_curbe_buffer(struct brw_context *brw)
+static enum pipe_error prepare_curbe_buffer(struct brw_context *brw)
{
const GLuint sz = brw->curbe.total_size;
const GLuint bufsz = sz * 16 * sizeof(GLfloat);
+ enum pipe_error ret;
GLfloat *buf;
GLuint i;
(brw->curbe.need_new_bo ||
brw->curbe.curbe_next_offset + bufsz > brw->curbe.curbe_bo->size))
{
- brw->sws->bo_unreference(brw->curbe.curbe_bo);
- brw->curbe.curbe_bo = NULL;
+ bo_reference(&brw->curbe.curbe_bo, NULL);
}
if (brw->curbe.curbe_bo == NULL) {
/* Allocate a single page for CURBE entries for this batchbuffer.
* They're generally around 64b.
*/
- brw->curbe.curbe_bo = brw->sws->bo_alloc(brw->sws,
- BRW_BUFFER_TYPE_CURBE,
- 4096, 1 << 6);
+ ret = brw->sws->bo_alloc(brw->sws,
+ BRW_BUFFER_TYPE_CURBE,
+ 4096, 1 << 6,
+ &brw->curbe.curbe_bo);
+ if (ret)
+ return ret;
+
brw->curbe.curbe_next_offset = 0;
}
return 0;
}
-static int emit_curbe_buffer(struct brw_context *brw)
+static enum pipe_error emit_curbe_buffer(struct brw_context *brw)
{
GLuint sz = brw->curbe.total_size;
u_upload_destroy( brw->vb.upload_vertex );
u_upload_destroy( brw->vb.upload_index );
- brw->sws->bo_unreference(brw->ib.bo);
- brw->ib.bo = NULL;
+ bo_reference(&brw->ib.bo, NULL);
}
brw->vb.vb[i].vertex_count = (vb->stride == 0 ?
1 :
(bo->size - offset) / vb->stride);
- brw->sws->bo_unreference(brw->vb.vb[i].bo);
- brw->vb.vb[i].bo = bo;
- brw->sws->bo_reference(brw->vb.vb[i].bo);
+
+ bo_reference( &brw->vb.vb[i].bo, bo );
/* Don't need to retain this reference. We have a reference on
* the underlying winsys buffer:
static int brw_prepare_indices(struct brw_context *brw)
{
struct pipe_buffer *index_buffer = brw->curr.index_buffer;
+ struct pipe_buffer *upload_buf = NULL;
struct brw_winsys_buffer *bo = NULL;
GLuint offset;
GLuint index_size;
/* Turn userbuffer into a proper hardware buffer?
*/
if (brw_buffer_is_user_buffer(index_buffer)) {
- struct pipe_buffer *upload_buf;
ret = u_upload_buffer( brw->vb.upload_index,
0,
return ret;
bo = brw_buffer(upload_buf)->bo;
- brw->sws->bo_reference(bo);
- pipe_buffer_reference( &upload_buf, NULL );
/* XXX: annotate the userbuffer with the upload information so
* that successive calls don't get re-uploaded.
}
else {
bo = brw_buffer(index_buffer)->bo;
- brw->sws->bo_reference(bo);
-
ib_size = bo->size;
offset = 0;
}
if (brw->ib.bo != bo ||
brw->ib.size != ib_size)
{
- brw->sws->bo_unreference(brw->ib.bo);
- brw->ib.bo = bo;
+ bo_reference(&brw->ib.bo, bo);
brw->ib.size = ib_size;
brw->state.dirty.brw |= BRW_NEW_INDEX_BUFFER;
}
- else {
- brw->sws->bo_unreference(bo);
- }
+ pipe_buffer_reference( &upload_buf, NULL );
brw_add_validated_bo(brw, brw->ib.bo);
return 0;
}
}
-const GLuint *brw_get_program( struct brw_compile *p,
- GLuint *sz )
+enum pipe_error brw_get_program( struct brw_compile *p,
+ const GLuint **data,
+ GLuint *sz )
{
GLuint i;
for (i = 0; i < 8; i++)
brw_NOP(p);
+ /* Is the generated program malformed for some reason?
+ */
+ if (p->error)
+ return PIPE_ERROR_BAD_INPUT;
+
*sz = p->nr_insn * sizeof(struct brw_instruction);
- return (const GLuint *)p->store;
+ *data = (const GLuint *)p->store;
+ return PIPE_OK;
}
#define BRW_EU_H
#include "util/u_debug.h"
+#include "pipe/p_error.h"
#include "brw_structs.h"
#include "brw_defines.h"
struct brw_eu_label *first_label; /**< linked list of labels */
struct brw_eu_call *first_call; /**< linked list of CALs */
+
+ boolean error;
};
void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional );
void brw_init_compile( struct brw_context *, struct brw_compile *p );
-const GLuint *brw_get_program( struct brw_compile *p, GLuint *sz );
+
+enum pipe_error brw_get_program( struct brw_compile *p,
+ const GLuint **program,
+ GLuint *sz );
/* Helpers for regular instructions:
-static void compile_gs_prog( struct brw_context *brw,
- struct brw_gs_prog_key *key )
+static enum pipe_error compile_gs_prog( struct brw_context *brw,
+ struct brw_gs_prog_key *key,
+ struct brw_winsys_buffer **bo_out )
{
struct brw_gs_compile c;
+ enum pipe_error ret;
const GLuint *program;
GLuint program_size;
c.nr_attrs = c.key.nr_attrs;
if (BRW_IS_IGDNG(brw))
- c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */
+ c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */
else
- c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */
+ c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */
c.nr_bytes = c.nr_regs * REG_SIZE;
if (key->hint_gs_always)
brw_gs_lines( &c );
else {
- return;
+ return PIPE_OK;
}
break;
case PIPE_PRIM_TRIANGLES:
if (key->hint_gs_always)
brw_gs_tris( &c );
else {
- return;
+ return PIPE_OK;
}
break;
case PIPE_PRIM_POINTS:
if (key->hint_gs_always)
brw_gs_points( &c );
else {
- return;
+ return PIPE_OK;
}
- break;
+ break;
default:
- return;
+ assert(0);
+ 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->gs.prog_bo);
- brw->gs.prog_bo = brw_upload_cache( &brw->cache, BRW_GS_PROG,
- &c.key, sizeof(c.key),
- NULL, 0,
- program, program_size,
- &c.prog_data,
- &brw->gs.prog_data );
+ ret = brw_upload_cache( &brw->cache, BRW_GS_PROG,
+ &c.key, sizeof(c.key),
+ NULL, 0,
+ program, program_size,
+ &c.prog_data,
+ &brw->gs.prog_data,
+ bo_out );
+ if (ret)
+ return ret;
+
+ return PIPE_OK;
}
static const unsigned gs_prim[PIPE_PRIM_MAX] = {
static int prepare_gs_prog(struct brw_context *brw)
{
struct brw_gs_prog_key key;
+ enum pipe_error ret;
+
/* Populate the key:
*/
populate_key(brw, &key);
brw->gs.prog_active = key.need_gs_prog;
}
- if (brw->gs.prog_active) {
- brw->sws->bo_unreference(brw->gs.prog_bo);
- brw->gs.prog_bo = brw_search_cache(&brw->cache, BRW_GS_PROG,
- &key, sizeof(key),
- NULL, 0,
- &brw->gs.prog_data);
- if (brw->gs.prog_bo == NULL)
- compile_gs_prog( brw, &key );
- }
+ if (!brw->gs.prog_active)
+ return PIPE_OK;
+
+ if (brw_search_cache(&brw->cache, BRW_GS_PROG,
+ &key, sizeof(key),
+ NULL, 0,
+ &brw->gs.prog_data,
+ &brw->gs.prog_bo))
+ return PIPE_OK;
+
+ ret = compile_gs_prog( brw, &key, &brw->gs.prog_bo );
+ if (ret)
+ return ret;
- return 0;
+ return PIPE_OK;
}
key->urb_size = brw->urb.vsize;
}
-static struct brw_winsys_buffer *
-gs_unit_create_from_key(struct brw_context *brw, struct brw_gs_unit_key *key)
+static enum pipe_error
+gs_unit_create_from_key(struct brw_context *brw,
+ struct brw_gs_unit_key *key,
+ struct brw_winsys_buffer **bo_out)
{
struct brw_gs_unit_state gs;
- struct brw_winsys_buffer *bo;
+ enum pipe_error ret;
memset(&gs, 0, sizeof(gs));
if (BRW_DEBUG & DEBUG_STATS)
gs.thread4.stats_enable = 1;
- bo = brw_upload_cache(&brw->cache, BRW_GS_UNIT,
- key, sizeof(*key),
- &brw->gs.prog_bo, 1,
- &gs, sizeof(gs),
- NULL, NULL);
+ ret = brw_upload_cache(&brw->cache, BRW_GS_UNIT,
+ key, sizeof(*key),
+ &brw->gs.prog_bo, 1,
+ &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,
+ 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 bo;
+ return PIPE_OK;
}
-static int prepare_gs_unit(struct brw_context *brw)
+static enum pipe_error prepare_gs_unit(struct brw_context *brw)
{
struct brw_gs_unit_key key;
+ enum pipe_error ret;
gs_unit_populate_key(brw, &key);
- brw->sws->bo_unreference(brw->gs.state_bo);
- brw->gs.state_bo = brw_search_cache(&brw->cache, BRW_GS_UNIT,
- &key, sizeof(key),
- &brw->gs.prog_bo, 1,
- NULL);
- if (brw->gs.state_bo == NULL) {
- brw->gs.state_bo = gs_unit_create_from_key(brw, &key);
- }
+ if (brw_search_cache(&brw->cache, BRW_GS_UNIT,
+ &key, sizeof(key),
+ &brw->gs.prog_bo, 1,
+ NULL,
+ &brw->gs.state_bo))
+ return PIPE_OK;
+
+ ret = gs_unit_create_from_key(brw, &key, &brw->gs.state_bo);
+ if (ret)
+ return ret;
- return 0;
+ return PIPE_OK;
}
const struct brw_tracked_state brw_gs_unit = {
}
brw->sws->bo_unmap(query->bo);
- brw->sws->bo_unreference(query->bo);
- query->bo = NULL;
+ bo_reference(&query->bo, NULL);
}
*result = query->result;
static void
brw_query_destroy(struct pipe_context *pipe, struct pipe_query *q)
{
- struct brw_context *brw = brw_context(pipe);
struct brw_query_object *query = (struct brw_query_object *)q;
- brw->sws->bo_unreference(query->bo);
+ bo_reference(&query->bo, NULL);
FREE(query);
}
struct brw_query_object *query = (struct brw_query_object *)q;
/* Reset our driver's tracking of query state. */
- brw->sws->bo_unreference(query->bo);
+ bo_reference(&query->bo, NULL);
query->result = 0;
- query->bo = NULL;
query->first_index = -1;
query->last_index = -1;
brw_emit_query_end(brw);
brw_context_flush( brw );
- brw->sws->bo_unreference(brw->query.bo);
- brw->query.bo = NULL;
+ bo_reference(&brw->query.bo, NULL);
}
remove_from_list(query);
*/
/** Called to set up the query BO and account for its aperture space */
-void
+enum pipe_error
brw_prepare_query_begin(struct brw_context *brw)
{
+ enum pipe_error ret;
+
/* Skip if we're not doing any queries. */
if (is_empty_list(&brw->query.active_head))
- return;
+ return PIPE_OK;
/* Get a new query BO if we're going to need it. */
if (brw->query.bo == NULL ||
brw->query.index * 2 + 1 >= 4096 / sizeof(uint64_t)) {
- brw->sws->bo_unreference(brw->query.bo);
- brw->query.bo = NULL;
- brw->query.bo = brw->sws->bo_alloc(brw->sws, BRW_BUFFER_TYPE_QUERY, 4096, 1);
+ ret = brw->sws->bo_alloc(brw->sws, BRW_BUFFER_TYPE_QUERY, 4096, 1,
+ &brw->query.bo);
+ if (ret)
+ return ret;
+
brw->query.index = 0;
}
brw_add_validated_bo(brw, brw->query.bo);
+
+ return PIPE_OK;
}
/** Called just before primitive drawing to get a beginning PS_DEPTH_COUNT. */
FALSE,
&tmp );
- brw->sws->bo_reference(brw->query.bo);
- query->bo = brw->query.bo;
+ bo_reference( &query->bo, brw->query.bo );
query->first_index = brw->query.index;
}
query->last_index = brw->query.index;
static void brw_delete_fs_state( struct pipe_context *pipe, void *prog )
{
- struct brw_context *brw = brw_context(pipe);
struct brw_fragment_shader *fs = (struct brw_fragment_shader *)prog;
- brw->sws->bo_unreference(fs->const_buffer);
+ bo_reference(&fs->const_buffer, NULL);
FREE( (void *)fs->tokens );
FREE( fs );
}
*/
#if 0
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
- brw->sws->bo_unreference(brw->vb.inputs[i].bo);
+ bo_reference(&brw->vb.inputs[i].bo, NULL);
brw->vb.inputs[i].bo = NULL;
}
#endif
static void
brw_buffer_destroy( struct pipe_buffer *buffer )
{
- struct brw_screen *bscreen = brw_screen( buffer->screen );
- struct brw_winsys_screen *sws = bscreen->sws;
struct brw_buffer *buf = brw_buffer( buffer );
assert(!p_atomic_read(&buffer->reference.count));
- if (buf->bo)
- sws->bo_unreference(buf->bo);
-
+ bo_reference(&buf->bo, NULL);
FREE(buf);
}
struct brw_winsys_screen *sws = bscreen->sws;
struct brw_buffer *buf;
unsigned buffer_type;
+ enum pipe_error ret;
buf = CALLOC_STRUCT(brw_buffer);
if (!buf)
break;
}
- buf->bo = sws->bo_alloc( sws,
- buffer_type,
- size,
- alignment );
+ ret = sws->bo_alloc( sws, buffer_type,
+ size, alignment,
+ &buf->bo );
+ if (ret != PIPE_OK)
+ return NULL;
return &buf->base;
}
surface->pitch = tex->pitch;
surface->tiling = tex->tiling;
- surface->bo = tex->bo;
- brw_screen->sws->bo_reference(surface->bo);
-
+ bo_reference( &surface->bo, tex->bo );
pipe_texture_reference( &surface->base.texture, &tex->base );
surface->ss.ss0.surface_format = tex->ss.ss0.surface_format;
static void brw_tex_surface_destroy( struct pipe_surface *surf )
{
struct brw_surface *surface = brw_surface(surf);
- struct brw_screen *screen = brw_screen(surf->texture->screen);
/* Unreference texture, shared buffer:
*/
- screen->sws->bo_unreference(surface->bo);
+ bo_reference(&surface->bo, NULL);
pipe_texture_reference( &surface->base.texture, NULL );
struct brw_screen *bscreen = brw_screen(screen);
struct brw_texture *tex;
enum brw_buffer_type buffer_type;
+ enum pipe_error ret;
tex = CALLOC_STRUCT(brw_texture);
if (tex == NULL)
buffer_type = BRW_BUFFER_TYPE_TEXTURE;
}
- tex->bo = bscreen->sws->bo_alloc( bscreen->sws,
- buffer_type,
- tex->pitch * tex->total_height * tex->cpp,
- 64 );
+ ret = bscreen->sws->bo_alloc( bscreen->sws,
+ buffer_type,
+ tex->pitch * tex->total_height * tex->cpp,
+ 64,
+ &tex->bo );
+ if (ret)
+ goto fail;
tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
tex->ss.ss0.surface_type = translate_tex_target(tex->base.target);
return &tex->base;
fail:
- bscreen->sws->bo_unreference(tex->bo);
+ bo_reference(&tex->bo, NULL);
FREE(tex);
return NULL;
}
static void brw_texture_destroy(struct pipe_texture *pt)
{
- //bscreen->sws->bo_unreference(tex->bo);
+ struct brw_texture *tex = brw_texture(pt);
+ bo_reference(&tex->bo, NULL);
FREE(pt);
}
#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;
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));
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;
}
#include "brw_debug.h"
#include "brw_pipe_rast.h"
-static int upload_sf_vp(struct brw_context *brw)
+static enum pipe_error upload_sf_vp(struct brw_context *brw)
{
const struct pipe_viewport_state *vp = &brw->curr.vp;
const struct pipe_scissor_state *scissor = &brw->curr.scissor;
struct brw_sf_viewport sfv;
+ enum pipe_error ret;
memset(&sfv, 0, sizeof(sfv));
sfv.scissor.ymin = scissor->miny;
sfv.scissor.ymax = scissor->maxy; /* -1 ?? */
- brw->sws->bo_unreference(brw->sf.vp_bo);
- brw->sf.vp_bo = brw_cache_data( &brw->cache, BRW_SF_VP, &sfv, NULL, 0 );
+ ret = brw_cache_data( &brw->cache, BRW_SF_VP, &sfv, NULL, 0,
+ &brw->sf.vp_bo );
+ if (ret)
+ return ret;
- return 0;
+ return PIPE_OK;
}
const struct brw_tracked_state brw_sf_vp = {
rast->point_size_max);
}
-static struct brw_winsys_buffer *
+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)
+ struct brw_winsys_buffer **reloc_bufs,
+ struct brw_winsys_buffer **bo_out)
{
struct brw_sf_unit_state sf;
- struct brw_winsys_buffer *bo;
+ enum pipe_error ret;
int chipset_max_threads;
memset(&sf, 0, sizeof(sf));
sf.sf6.dest_org_hbias = 0x0;
}
- bo = brw_upload_cache(&brw->cache, BRW_SF_UNIT,
- key, sizeof(*key),
- reloc_bufs, 2,
- &sf, sizeof(sf),
- NULL, NULL);
+ ret = brw_upload_cache(&brw->cache, BRW_SF_UNIT,
+ key, sizeof(*key),
+ reloc_bufs, 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 */
- brw->sws->bo_emit_reloc(bo,
- BRW_USAGE_STATE,
- sf.thread0.grf_reg_count << 1,
- offsetof(struct brw_sf_unit_state, thread0),
- brw->sf.prog_bo);
+ 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 */
- brw->sws->bo_emit_reloc(bo,
- BRW_USAGE_STATE,
- sf.sf5.front_winding | (sf.sf5.viewport_transform << 1),
- offsetof(struct brw_sf_unit_state, sf5),
- brw->sf.vp_bo);
- return bo;
+ /* 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 int upload_sf_unit( struct brw_context *brw )
+static enum pipe_error upload_sf_unit( struct brw_context *brw )
{
struct brw_sf_unit_key key;
struct brw_winsys_buffer *reloc_bufs[2];
+ enum pipe_error ret;
sf_unit_populate_key(brw, &key);
reloc_bufs[0] = brw->sf.prog_bo;
reloc_bufs[1] = brw->sf.vp_bo;
- brw->sws->bo_unreference(brw->sf.state_bo);
- brw->sf.state_bo = brw_search_cache(&brw->cache, BRW_SF_UNIT,
- &key, sizeof(key),
- reloc_bufs, 2,
- NULL);
- if (brw->sf.state_bo == NULL) {
- brw->sf.state_bo = sf_unit_create_from_key(brw, &key, reloc_bufs);
- }
- return 0;
+ if (brw_search_cache(&brw->cache, BRW_SF_UNIT,
+ &key, sizeof(key),
+ reloc_bufs, 2,
+ NULL,
+ &brw->sf.state_bo))
+ return PIPE_OK;
+
+
+ ret = sf_unit_create_from_key(brw, &key, reloc_bufs,
+ &brw->sf.state_bo);
+ if (ret)
+ return ret;
+
+ return PIPE_OK;
}
const struct brw_tracked_state brw_sf_unit = {
assert(brw->state.validated_bo_count < Elements(brw->state.validated_bos));
if (bo != NULL) {
- brw->sws->bo_reference(bo);
- brw->state.validated_bos[brw->state.validated_bo_count++] = bo;
+ bo_reference( &brw->state.validated_bos[brw->state.validated_bo_count++],
+ bo );
}
}
/***********************************************************************
* brw_state_cache.c
*/
-struct brw_winsys_buffer *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_buffer *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_buffer *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,
- const void *data,
- GLuint data_sz,
- const void *aux,
- void *aux_return );
-
-struct brw_winsys_buffer *brw_search_cache( struct brw_cache *cache,
- enum brw_cache_id cache_id,
- const void *key,
- GLuint key_size,
- struct brw_winsys_buffer **reloc_bufs,
- GLuint nr_reloc_bufs,
- void *aux_return);
+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_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_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,
+ const void *data,
+ GLuint data_sz,
+ const void *aux,
+ void *aux_return ,
+ struct brw_winsys_buffer **bo_out);
+
+boolean brw_search_cache( struct brw_cache *cache,
+ enum brw_cache_id cache_id,
+ const void *key,
+ GLuint key_size,
+ struct brw_winsys_buffer **reloc_bufs,
+ GLuint nr_reloc_bufs,
+ void *aux_return,
+ struct brw_winsys_buffer **bo_out);
+
void brw_state_cache_check_size( struct brw_context *brw );
void brw_init_caches( struct brw_context *brw );
if (bo == cache->last_bo[cache_id])
return; /* no change */
- cache->sws->bo_unreference(cache->last_bo[cache_id]);
- cache->last_bo[cache_id] = bo;
- cache->sws->bo_reference(cache->last_bo[cache_id]);
+ bo_reference( &cache->last_bo[cache_id], bo );
+
cache->brw->state.dirty.cache |= 1 << cache_id;
}
/**
* Returns the buffer object matching cache_id and key, or NULL.
*/
-struct brw_winsys_buffer *
+boolean
brw_search_cache(struct brw_cache *cache,
enum brw_cache_id cache_id,
const void *key,
GLuint key_size,
struct brw_winsys_buffer **reloc_bufs,
GLuint nr_reloc_bufs,
- void *aux_return)
+ 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);
item = search_cache(cache, cache_id, hash, key, key_size,
reloc_bufs, nr_reloc_bufs);
- if (item == NULL)
- return NULL;
-
- if (aux_return)
- *(void **)aux_return = (void *)((char *)item->key + item->key_size);
-
- update_cache_last(cache, cache_id, item->bo);
-
- cache->sws->bo_reference(item->bo);
- return item->bo;
+ if (item) {
+ if (aux_return)
+ *(void **)aux_return = (void *)((char *)item->key + item->key_size);
+
+ update_cache_last(cache, cache_id, item->bo);
+ bo_reference(bo_out, item->bo);
+ return TRUE;
+ }
+
+ return FALSE;
}
-struct brw_winsys_buffer *
+enum pipe_error
brw_upload_cache( struct brw_cache *cache,
enum brw_cache_id cache_id,
const void *key,
const void *data,
GLuint data_size,
const void *aux,
- void *aux_return )
+ void *aux_return,
+ 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 aux_size = cache->aux_size[cache_id];
+ enum pipe_error ret;
void *tmp;
- struct brw_winsys_buffer *bo;
int i;
/* Create the buffer object to contain the data. For now, use a
* may want to take advantage of hardware distinctions between
* these various entities.
*/
- bo = cache->sws->bo_alloc(cache->sws,
- cache->buffer_type,
- data_size, 1 << 6);
+ ret = cache->sws->bo_alloc(cache->sws,
+ cache->buffer_type,
+ data_size, 1 << 6,
+ bo_out);
+ if (ret)
+ return ret;
/* Set up the memory containing the key, aux_data, and reloc_bufs */
memcpy((char *)tmp + key_size + aux_size, reloc_bufs, relocs_size);
for (i = 0; i < nr_reloc_bufs; i++) {
if (reloc_bufs[i] != NULL)
- cache->sws->bo_reference(reloc_bufs[i]);
+ p_atomic_inc(&reloc_bufs[i]->reference.count);
}
item->cache_id = cache_id;
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->bo = bo;
- cache->sws->bo_reference(bo);
+ bo_reference( &item->bo, *bo_out );
item->data_size = data_size;
if (cache->n_items > cache->size * 1.5)
data_size, cache_id);
/* Copy data to the buffer */
- cache->sws->bo_subdata(bo,
+ cache->sws->bo_subdata(item->bo,
cache_id,
0, data_size, data);
- update_cache_last(cache, cache_id, bo);
+ update_cache_last(cache, cache_id, item->bo);
- return bo;
+ return PIPE_OK;
}
/**
* This doesn't really work with aux data. Use search/upload instead
*/
-struct brw_winsys_buffer *
+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)
+ GLuint nr_reloc_bufs,
+ struct brw_winsys_buffer **bo_out)
{
- struct brw_winsys_buffer *bo;
struct brw_cache_item *item;
GLuint hash = hash_key(data, data_size, reloc_bufs, nr_reloc_bufs);
reloc_bufs, nr_reloc_bufs);
if (item) {
update_cache_last(cache, cache_id, item->bo);
- cache->sws->bo_reference(item->bo);
- return item->bo;
- }
- bo = brw_upload_cache(cache, cache_id,
- data, data_size,
- reloc_bufs, nr_reloc_bufs,
- data, data_size,
- NULL, NULL);
+ bo_reference(bo_out, item->bo);
+ return PIPE_OK;
+ }
- return bo;
+ return brw_upload_cache(cache, cache_id,
+ data, data_size,
+ reloc_bufs, nr_reloc_bufs,
+ data, data_size,
+ NULL, NULL,
+ bo_out);
}
* better to use, as the potentially changing offsets in the data-used-as-key
* will result in excessive cache misses.
*/
-struct brw_winsys_buffer *
+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)
+ GLuint nr_reloc_bufs,
+ 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);
+ reloc_bufs, nr_reloc_bufs, bo_out);
}
int j;
next = c->next;
+
for (j = 0; j < c->nr_reloc_bufs; j++)
- brw->sws->bo_unreference(c->reloc_bufs[j]);
- brw->sws->bo_unreference(c->bo);
- free((void *)c->key);
- free(c);
+ bo_reference(&c->reloc_bufs[j], NULL);
+
+ bo_reference(&c->bo, NULL);
+ FREE((void *)c->key);
+ FREE(c);
}
cache->items[i] = NULL;
}
*prev = c->next;
for (j = 0; j < c->nr_reloc_bufs; j++)
- cache->sws->bo_unreference(c->reloc_bufs[j]);
- cache->sws->bo_unreference(c->bo);
- free((void *)c->key);
- free(c);
+ bo_reference(&c->reloc_bufs[j], NULL);
+
+ bo_reference(&c->bo, NULL);
+
+ FREE((void *)c->key);
+ FREE(c);
cache->n_items--;
} else {
prev = &c->next;
brw_clear_cache(brw, cache);
for (i = 0; i < BRW_MAX_CACHE; i++) {
- brw->sws->bo_unreference(cache->last_bo[i]);
- free(cache->name[i]);
+ bo_reference(&cache->last_bo[i], NULL);
+ FREE(cache->name[i]);
}
- free(cache->items);
+ FREE(cache->items);
cache->items = NULL;
cache->size = 0;
}
/* Clear the last round of validated bos */
for (i = 0; i < brw->state.validated_bo_count; i++) {
- brw->sws->bo_unreference(brw->state.validated_bos[i]);
- brw->state.validated_bos[i] = NULL;
+ bo_reference(&brw->state.validated_bos[i], NULL);
}
brw->state.validated_bo_count = 0;
}
-static void do_vs_prog( struct brw_context *brw,
- struct brw_vertex_shader *vp,
- struct brw_vs_prog_key *key )
+static enum pipe_error do_vs_prog( struct brw_context *brw,
+ struct brw_vertex_shader *vp,
+ struct brw_vs_prog_key *key,
+ struct brw_winsys_buffer **bo_out)
{
+ enum pipe_error ret;
GLuint program_size;
const GLuint *program;
struct brw_vs_compile c;
/* get the program
*/
- program = brw_get_program(&c.func, &program_size);
-
- brw->sws->bo_unreference(brw->vs.prog_bo);
- brw->vs.prog_bo = brw_upload_cache( &brw->cache, BRW_VS_PROG,
- &c.key, sizeof(c.key),
- NULL, 0,
- program, program_size,
- &c.prog_data,
- &brw->vs.prog_data );
+ ret = brw_get_program(&c.func, &program, &program_size);
+ if (ret)
+ return ret;
+
+ ret = brw_upload_cache( &brw->cache, BRW_VS_PROG,
+ &c.key, sizeof(c.key),
+ NULL, 0,
+ program, program_size,
+ &c.prog_data,
+ &brw->vs.prog_data,
+ bo_out);
+ if (ret)
+ return ret;
+
+ return PIPE_OK;
}
-static int brw_upload_vs_prog(struct brw_context *brw)
+static enum pipe_error brw_upload_vs_prog(struct brw_context *brw)
{
struct brw_vs_prog_key key;
struct brw_vertex_shader *vp = brw->curr.vertex_shader;
+ enum pipe_error ret;
memset(&key, 0, sizeof(key));
/* Make an early check for the key.
*/
- brw->sws->bo_unreference(brw->vs.prog_bo);
- brw->vs.prog_bo = brw_search_cache(&brw->cache, BRW_VS_PROG,
- &key, sizeof(key),
- NULL, 0,
- &brw->vs.prog_data);
- if (brw->vs.prog_bo == NULL)
- do_vs_prog(brw, vp, &key);
-
- return 0;
+ if (brw_search_cache(&brw->cache, BRW_VS_PROG,
+ &key, sizeof(key),
+ NULL, 0,
+ &brw->vs.prog_data,
+ &brw->vs.prog_bo))
+ return PIPE_OK;
+
+ ret = do_vs_prog(brw, vp, &key, &brw->vs.prog_bo);
+ if (ret)
+ return ret;
+
+ return PIPE_OK;
}
}
}
-static struct brw_winsys_buffer *
-vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key)
+static enum pipe_error
+vs_unit_create_from_key(struct brw_context *brw,
+ struct brw_vs_unit_key *key,
+ struct brw_winsys_buffer **bo_out)
{
+ enum pipe_error ret;
struct brw_vs_unit_state vs;
- struct brw_winsys_buffer *bo;
int chipset_max_threads;
memset(&vs, 0, sizeof(vs));
*/
vs.vs6.vs_enable = 1;
- bo = brw_upload_cache(&brw->cache, BRW_VS_UNIT,
- key, sizeof(*key),
- &brw->vs.prog_bo, 1,
- &vs, sizeof(vs),
- NULL, NULL);
+ ret = brw_upload_cache(&brw->cache, BRW_VS_UNIT,
+ key, sizeof(*key),
+ &brw->vs.prog_bo, 1,
+ &vs, sizeof(vs),
+ NULL, NULL,
+ bo_out);
+ if (ret)
+ return ret;
/* Emit VS program relocation */
- brw->sws->bo_emit_reloc(bo,
- BRW_USAGE_STATE,
- vs.thread0.grf_reg_count << 1,
- offsetof(struct brw_vs_unit_state, thread0),
- brw->vs.prog_bo);
-
- return bo;
+ 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;
}
static int prepare_vs_unit(struct brw_context *brw)
{
struct brw_vs_unit_key key;
+ enum pipe_error ret;
vs_unit_populate_key(brw, &key);
- brw->sws->bo_unreference(brw->vs.state_bo);
- brw->vs.state_bo = brw_search_cache(&brw->cache, BRW_VS_UNIT,
- &key, sizeof(key),
- &brw->vs.prog_bo, 1,
- NULL);
- if (brw->vs.state_bo == NULL) {
- brw->vs.state_bo = vs_unit_create_from_key(brw, &key);
- }
+ if (brw_search_cache(&brw->cache, BRW_VS_UNIT,
+ &key, sizeof(key),
+ &brw->vs.prog_bo, 1,
+ NULL,
+ &brw->vs.state_bo))
+ return PIPE_OK;
+
+ ret = vs_unit_create_from_key(brw, &key, &brw->vs.state_bo);
+ if (ret)
+ return ret;
- return 0;
+ return PIPE_OK;
}
const struct brw_tracked_state brw_vs_unit = {
{
struct brw_surface_key key;
struct pipe_buffer *cb = brw->curr.vs_constants;
+ enum pipe_error ret;
assert(surf == 0);
/* If we're in this state update atom, we need to update VS constants, so
* free the old buffer and create a new one for the new contents.
*/
- brw->sws->bo_unreference(vp->const_buffer);
- vp->const_buffer = brw_vs_update_constant_buffer(brw);
+ ret = brw_vs_update_constant_buffer(brw, &vp->const_buffer);
+ if (ret)
+ return ret;
/* If there's no constant buffer, then no surface BO is needed to point at
* it.
*/
- if (vp->const_buffer == 0) {
- drm_intel_bo_unreference(brw->vs.surf_bo[surf]);
- brw->vs.surf_bo[surf] = NULL;
- return;
+ if (vp->const_buffer == NULL) {
+ bo_reference(brw->vs.surf_bo[surf], NULL);
+ return PIPE_OK;
}
memset(&key, 0, sizeof(key));
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, key.bo ? 1 : 0,
- NULL);
- if (brw->vs.surf_bo[surf] == NULL) {
- brw->vs.surf_bo[surf] = brw_create_constant_surface(brw, &key);
- }
+ if (brw_search_cache(&brw->surface_cache,
+ BRW_SS_SURFACE,
+ &key, sizeof(key),
+ &key.bo, key.bo ? 1 : 0,
+ NULL,
+ &brw->vs.surf_bo[surf]))
+ return PIPE_OK;
+
+ ret = brw_create_constant_surface(brw, &key
+ &brw->vs.surf_bo[surf]);
+ if (ret)
+ return ret;
+
+ return PIPE_OK;
}
#endif
/**
* Constructs the binding table for the VS surface state.
*/
-static struct brw_winsys_buffer *
-brw_vs_get_binding_table(struct brw_context *brw)
+static enum pipe_error
+brw_vs_get_binding_table(struct brw_context *brw,
+ struct brw_winsys_buffer **bo_out)
{
#if 0
- struct brw_winsys_buffer *bind_bo;
-
- bind_bo = brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND,
- NULL, 0,
- brw->vs.surf_bo, BRW_VS_MAX_SURF,
- NULL);
-
- if (bind_bo == NULL) {
+ 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;
else
data[i] = 0;
- bind_bo = 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);
+ 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++) {
/* The presumed offsets were set in the data values for
* brw_upload_cache.
*/
- drm_intel_bo_emit_reloc(bind_bo, i * 4,
- brw->vs.surf_bo[i], 0,
- BRW_USAGE_STATE);
+ ret = sws->bo_emit_reloc(*bo_out, i * 4,
+ brw->vs.surf_bo[i], 0,
+ BRW_USAGE_STATE);
+ if (ret)
+ return ret;
}
}
- free(data);
+ FREE(data);
+ return PIPE_OK;
}
-
- return bind_bo;
#else
- return NULL;
+ return PIPE_OK;
#endif
}
* to be updated, and produces BRW_NEW_NR_VS_SURFACES for the VS unit and
* CACHE_NEW_SURF_BIND for the binding table upload.
*/
-static int prepare_vs_surfaces(struct brw_context *brw )
+static enum pipe_error prepare_vs_surfaces(struct brw_context *brw )
{
+ enum pipe_error ret;
+
#if 0
int i;
int nr_surfaces = 0;
* just slightly increases our working set size.
*/
if (brw->vs.nr_surfaces != 0) {
- brw->sws->bo_unreference(brw->vs.bind_bo);
- brw->vs.bind_bo = brw_vs_get_binding_table(brw);
+ ret = brw_vs_get_binding_table(brw, &brw->vs.bind_bo);
+ if (ret)
+ return ret;
}
- return 0;
+ return PIPE_OK;
}
const struct brw_tracked_state brw_vs_surfaces = {
#include "pipe/p_compiler.h"
#include "pipe/p_error.h"
+#include "pipe/p_refcnt.h"
struct brw_winsys;
struct pipe_fence_handle;
*/
#define BRW_BATCH_SIZE (32*1024)
+struct brw_winsys_screen;
/* Need a tiny bit of information inside the abstract buffer struct:
*/
struct brw_winsys_buffer {
+ struct pipe_reference reference;
+ struct brw_winsys_screen *sws;
unsigned *offset;
unsigned size;
};
BRW_DATA_MAX
};
+
+
+
+
struct brw_winsys_screen {
/**
* Create a buffer.
*/
- struct brw_winsys_buffer *(*bo_alloc)( struct brw_winsys_screen *sws,
- enum brw_buffer_type type,
- unsigned size,
- unsigned alignment );
+ enum pipe_error (*bo_alloc)( struct brw_winsys_screen *sws,
+ enum brw_buffer_type type,
+ unsigned size,
+ unsigned alignment,
+ struct brw_winsys_buffer **bo_out );
- /* Reference and unreference buffers:
+ /* Destroy a buffer when our refcount goes to zero:
*/
- void (*bo_reference)( struct brw_winsys_buffer *buffer );
- void (*bo_unreference)( struct brw_winsys_buffer *buffer );
+ void (*bo_destroy)( struct brw_winsys_buffer *buffer );
/* delta -- added to b2->offset, and written into buffer
* offset -- location above value is written to within buffer
*/
- int (*bo_emit_reloc)( struct brw_winsys_buffer *buffer,
- enum brw_buffer_usage usage,
- unsigned delta,
- unsigned offset,
- struct brw_winsys_buffer *b2);
+ enum pipe_error (*bo_emit_reloc)( struct brw_winsys_buffer *buffer,
+ enum brw_buffer_usage usage,
+ unsigned delta,
+ unsigned offset,
+ struct brw_winsys_buffer *b2);
- int (*bo_exec)( struct brw_winsys_buffer *buffer,
- unsigned bytes_used );
+ enum pipe_error (*bo_exec)( struct brw_winsys_buffer *buffer,
+ unsigned bytes_used );
- int (*bo_subdata)(struct brw_winsys_buffer *buffer,
- enum brw_buffer_data_type data_type,
- size_t offset,
- size_t size,
- const void *data);
+ enum pipe_error (*bo_subdata)(struct brw_winsys_buffer *buffer,
+ enum brw_buffer_data_type data_type,
+ size_t offset,
+ size_t size,
+ const void *data);
boolean (*bo_is_busy)(struct brw_winsys_buffer *buffer);
boolean (*bo_references)(struct brw_winsys_buffer *a,
};
+static INLINE void
+bo_reference(struct brw_winsys_buffer **ptr, struct brw_winsys_buffer *buf)
+{
+ struct brw_winsys_buffer *old_buf = *ptr;
+
+ if (pipe_reference((struct pipe_reference **)ptr, &buf->reference))
+ old_buf->sws->bo_destroy(old_buf);
+}
+
+
/**
* Create brw pipe_screen.
*/
* Depending on the instructions used (i.e. flow control instructions)
* we'll use one of two code generators.
*/
-static int do_wm_prog( struct brw_context *brw,
- struct brw_fragment_shader *fp,
- struct brw_wm_prog_key *key)
+static enum pipe_error do_wm_prog( struct brw_context *brw,
+ struct brw_fragment_shader *fp,
+ struct brw_wm_prog_key *key,
+ struct brw_winsys_buffer **bo_out)
{
+ enum pipe_error ret;
struct brw_wm_compile *c;
const GLuint *program;
GLuint program_size;
- c = brw->wm.compile_data;
- if (c == NULL) {
- brw->wm.compile_data = calloc(1, sizeof(*brw->wm.compile_data));
- c = brw->wm.compile_data;
- if (c == NULL) {
- /* Ouch - big out of memory problem. Can't continue
- * without triggering a segfault, no way to signal,
- * so just return.
- */
+ if (brw->wm.compile_data == NULL) {
+ brw->wm.compile_data = MALLOC(sizeof(*brw->wm.compile_data));
+ if (!brw->wm.compile_data)
return PIPE_ERROR_OUT_OF_MEMORY;
- }
- } else {
- memset(c, 0, sizeof(*brw->wm.compile_data));
}
- memcpy(&c->key, key, sizeof(*key));
+ c = brw->wm.compile_data;
+ memset(c, 0, sizeof *c);
+
+ c->key = *key;
c->fp = fp;
c->env_param = NULL; /*brw->intel.ctx.FragmentProgram.Parameters;*/
/* get the program
*/
- program = brw_get_program(&c->func, &program_size);
-
- brw->sws->bo_unreference(brw->wm.prog_bo);
- brw->wm.prog_bo = brw_upload_cache( &brw->cache, BRW_WM_PROG,
- &c->key, sizeof(c->key),
- NULL, 0,
- program, program_size,
- &c->prog_data,
- &brw->wm.prog_data );
-
- return 0;
+ ret = brw_get_program(&c->func, &program, &program_size);
+ if (ret)
+ return ret;
+
+ ret = brw_upload_cache( &brw->cache, BRW_WM_PROG,
+ &c->key, sizeof(c->key),
+ NULL, 0,
+ program, program_size,
+ &c->prog_data,
+ &brw->wm.prog_data,
+ bo_out );
+ if (ret)
+ return ret;
+
+ return PIPE_OK;
}
}
-static int brw_prepare_wm_prog(struct brw_context *brw)
+static enum pipe_error brw_prepare_wm_prog(struct brw_context *brw)
{
struct brw_wm_prog_key key;
struct brw_fragment_shader *fs = brw->curr.fragment_shader;
+ enum pipe_error ret;
brw_wm_populate_key(brw, &key);
/* Make an early check for the key.
*/
- brw->sws->bo_unreference(brw->wm.prog_bo);
- brw->wm.prog_bo = brw_search_cache(&brw->cache, BRW_WM_PROG,
- &key, sizeof(key),
- NULL, 0,
- &brw->wm.prog_data);
- if (brw->wm.prog_bo == NULL)
- return do_wm_prog(brw, fs, &key);
-
- return 0;
+ if (brw_search_cache(&brw->cache, BRW_WM_PROG,
+ &key, sizeof(key),
+ NULL, 0,
+ &brw->wm.prog_data,
+ &brw->wm.prog_bo))
+ return PIPE_OK;
+
+ ret = do_wm_prog(brw, fs, &key, &brw->wm.prog_bo);
+ if (ret)
+ return ret;
+
+ return PIPE_OK;
}
* 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));
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;
}
* 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)
{
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));
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;
}
/**
* 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 = {
-static struct brw_winsys_buffer *
+static enum pipe_error
upload_default_color( struct brw_context *brw,
- const GLfloat *color )
+ const GLfloat *color,
+ struct brw_winsys_buffer **bo_out )
{
struct brw_sampler_default_color sdc;
+ enum pipe_error ret;
COPY_4V(sdc.color, color);
- return brw_cache_data( &brw->cache, BRW_SAMPLER_DEFAULT_COLOR, &sdc,
- NULL, 0 );
+ ret = brw_cache_data( &brw->cache, BRW_SAMPLER_DEFAULT_COLOR, &sdc,
+ NULL, 0, bo_out );
+ if (ret)
+ return ret;
+
+ return PIPE_OK;
}
}
-static void
+static enum pipe_error
brw_wm_sampler_update_default_colors(struct brw_context *brw)
{
+ enum pipe_error ret;
int nr = MIN2(brw->curr.num_textures,
brw->curr.num_samplers);
int i;
for (i = 0; i < nr; i++) {
const struct brw_texture *tex = brw_texture(brw->curr.texture[i]);
const struct brw_sampler *sampler = brw->curr.sampler[i];
-
- brw->sws->bo_unreference(brw->wm.sdc_bo[i]);
+ const float *bc;
if (pf_is_depth_or_stencil(tex->base.format)) {
float bordercolor[4] = {
sampler->border_color[0],
sampler->border_color[0]
};
- /* GL specs that border color for depth textures is taken from the
- * R channel, while the hardware uses A. Spam R into all the
- * channels for safety.
- */
- brw->wm.sdc_bo[i] = upload_default_color(brw, bordercolor);
- } else {
- brw->wm.sdc_bo[i] = upload_default_color(brw, sampler->border_color);
+
+ bc = bordercolor;
+ }
+ else {
+ bc = sampler->border_color;
}
+
+ /* GL specs that border color for depth textures is taken from the
+ * R channel, while the hardware uses A. Spam R into all the
+ * channels for safety.
+ */
+ ret = upload_default_color(brw,
+ bc,
+ &brw->wm.sdc_bo[i]);
+ if (ret)
+ return ret;
}
+
+ return PIPE_OK;
}
static int upload_wm_samplers( struct brw_context *brw )
{
struct wm_sampler_key key;
+ enum pipe_error ret;
int i;
brw_wm_sampler_update_default_colors(brw);
brw->state.dirty.cache |= CACHE_NEW_SAMPLER;
}
- brw->sws->bo_unreference(brw->wm.sampler_bo);
- brw->wm.sampler_bo = NULL;
- if (brw->wm.sampler_count == 0)
- return 0;
+ if (brw->wm.sampler_count == 0) {
+ bo_reference(&brw->wm.sampler_bo, NULL);
+ return PIPE_OK;
+ }
- brw->wm.sampler_bo = brw_search_cache(&brw->cache, BRW_SAMPLER,
- &key, sizeof(key),
- brw->wm.sdc_bo, key.sampler_count,
- NULL);
+ if (brw_search_cache(&brw->cache, BRW_SAMPLER,
+ &key, sizeof(key),
+ brw->wm.sdc_bo, key.sampler_count,
+ NULL,
+ &brw->wm.sampler_bo))
+ return PIPE_OK;
/* If we didnt find it in the cache, compute the state and put it in the
* cache.
*/
- if (brw->wm.sampler_bo == NULL) {
- brw->wm.sampler_bo = brw_upload_cache(&brw->cache, BRW_SAMPLER,
- &key, sizeof(key),
- brw->wm.sdc_bo, key.sampler_count,
- &key.sampler, sizeof(key.sampler),
- NULL, NULL);
-
- /* Emit SDC relocations */
- for (i = 0; i < key.sampler_count; i++) {
- 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]);
- }
+ ret = brw_upload_cache(&brw->cache, BRW_SAMPLER,
+ &key, sizeof(key),
+ brw->wm.sdc_bo, 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;
/**
* Setup wm hardware state. See page 225 of Volume 2
*/
-static struct brw_winsys_buffer *
+static enum pipe_error
wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key,
- struct brw_winsys_buffer **reloc_bufs)
+ struct brw_winsys_buffer **reloc_bufs,
+ struct brw_winsys_buffer **bo_out)
{
struct brw_wm_unit_state wm;
- struct brw_winsys_buffer *bo;
+ enum pipe_error ret;
memset(&wm, 0, sizeof(wm));
if (BRW_DEBUG & DEBUG_STATS || key->stats_wm)
wm.wm4.stats_enable = 1;
- bo = brw_upload_cache(&brw->cache, BRW_WM_UNIT,
- key, sizeof(*key),
- reloc_bufs, 3,
- &wm, sizeof(wm),
- NULL, NULL);
+ ret = brw_upload_cache(&brw->cache, BRW_WM_UNIT,
+ key, sizeof(*key),
+ reloc_bufs, 3,
+ &wm, sizeof(wm),
+ NULL, NULL,
+ bo_out);
+ if (ret)
+ return ret;
/* Emit WM program relocation */
- brw->sws->bo_emit_reloc(bo,
- BRW_USAGE_STATE,
- wm.thread0.grf_reg_count << 1,
- offsetof(struct brw_wm_unit_state, thread0),
- brw->wm.prog_bo);
+ 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) {
- brw->sws->bo_emit_reloc(bo,
- BRW_USAGE_SCRATCH,
- wm.thread2.per_thread_scratch_space,
- offsetof(struct brw_wm_unit_state, thread2),
- brw->wm.scratch_bo);
+ 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) {
- brw->sws->bo_emit_reloc(bo,
- BRW_USAGE_STATE,
- wm.wm4.stats_enable | (wm.wm4.sampler_count << 2),
- offsetof(struct brw_wm_unit_state, wm4),
- brw->wm.sampler_bo);
+ 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 bo;
+ return PIPE_OK;
}
-static int upload_wm_unit( struct brw_context *brw )
+static enum pipe_error upload_wm_unit( struct brw_context *brw )
{
struct brw_wm_unit_key key;
struct brw_winsys_buffer *reloc_bufs[3];
+ enum pipe_error ret;
+
wm_unit_populate_key(brw, &key);
/* Allocate the necessary scratch space if we haven't already. Don't
if (key.total_scratch) {
GLuint total = key.total_scratch * key.max_threads;
- if (brw->wm.scratch_bo && total > brw->wm.scratch_bo->size) {
- brw->sws->bo_unreference(brw->wm.scratch_bo);
- brw->wm.scratch_bo = NULL;
- }
+ /* Do we need a new buffer:
+ */
+ if (brw->wm.scratch_bo && total > brw->wm.scratch_bo->size)
+ bo_reference(&brw->wm.scratch_bo, NULL);
+
if (brw->wm.scratch_bo == NULL) {
- brw->wm.scratch_bo = brw->sws->bo_alloc(brw->sws,
- BRW_BUFFER_TYPE_SHADER_SCRATCH,
- total,
- 4096);
+ ret = brw->sws->bo_alloc(brw->sws,
+ BRW_BUFFER_TYPE_SHADER_SCRATCH,
+ total,
+ 4096,
+ &brw->wm.scratch_bo);
+ if (ret)
+ return ret;
}
}
reloc_bufs[1] = brw->wm.scratch_bo;
reloc_bufs[2] = brw->wm.sampler_bo;
- brw->sws->bo_unreference(brw->wm.state_bo);
- brw->wm.state_bo = brw_search_cache(&brw->cache, BRW_WM_UNIT,
- &key, sizeof(key),
- reloc_bufs, 3,
- NULL);
- if (brw->wm.state_bo == NULL) {
- brw->wm.state_bo = wm_unit_create_from_key(brw, &key, reloc_bufs);
- }
+ if (brw_search_cache(&brw->cache, BRW_WM_UNIT,
+ &key, sizeof(key),
+ reloc_bufs, 3,
+ NULL,
+ &brw->wm.state_bo))
+ return PIPE_OK;
+
+ ret = wm_unit_create_from_key(brw, &key, reloc_bufs,
+ &brw->wm.state_bo);
+ if (ret)
+ return ret;
- return 0;
+ return PIPE_OK;
}
const struct brw_tracked_state brw_wm_unit = {
-static void
+static enum pipe_error
brw_update_texture_surface( struct brw_context *brw,
struct brw_texture *tex,
- GLuint surf )
+ struct brw_winsys_buffer **bo_out)
{
- brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache,
- BRW_SS_SURFACE,
- &tex->ss, sizeof tex->ss,
- &tex->bo, 1,
- NULL);
-
- if (brw->wm.surf_bo[surf] == NULL) {
- brw->wm.surf_bo[surf] = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
- &tex->ss, sizeof tex->ss,
- &tex->bo, 1,
- &tex->ss, sizeof tex->ss,
- NULL, NULL);
+ enum pipe_error ret;
+
+ if (brw_search_cache(&brw->surface_cache,
+ BRW_SS_SURFACE,
+ &tex->ss, sizeof tex->ss,
+ &tex->bo, 1,
+ NULL,
+ bo_out))
+ return PIPE_OK;
+
+ ret = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
+ &tex->ss, sizeof tex->ss,
+ &tex->bo, 1,
+ &tex->ss, sizeof tex->ss,
+ NULL, NULL,
+ bo_out);
+ if (ret)
+ return ret;
- /* Emit relocation to surface contents */
- brw->sws->bo_emit_reloc(brw->wm.surf_bo[surf],
- BRW_USAGE_SAMPLER,
- 0,
- offsetof(struct brw_surface_state, ss1),
- tex->bo);
- }
+ /* 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;
}
* 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
-brw_update_renderbuffer_surface(struct brw_context *brw,
- struct brw_surface *surface,
- unsigned int unit)
+static enum pipe_error
+brw_update_render_surface(struct brw_context *brw,
+ struct brw_surface *surface,
+ struct brw_winsys_buffer **bo_out)
{
struct brw_surf_ss0 blend_ss0 = brw->curr.blend->ss0;
struct brw_surface_state ss;
+ enum pipe_error ret;
/* Surfaces are potentially shared between contexts, so can't
* scribble the in-place ss0 value in the surface.
ss.ss0.writedisable_red = blend_ss0.writedisable_red;
ss.ss0.writedisable_alpha = blend_ss0.writedisable_alpha;
- brw->sws->bo_unreference(brw->wm.surf_bo[unit]);
- brw->wm.surf_bo[unit] = brw_search_cache(&brw->surface_cache,
- BRW_SS_SURFACE,
- &ss, sizeof(ss),
- &surface->bo, 1,
- NULL);
-
- if (brw->wm.surf_bo[unit] == NULL) {
-
- brw->wm.surf_bo[unit] = brw_upload_cache(&brw->surface_cache,
- BRW_SS_SURFACE,
- &ss, sizeof ss,
- &surface->bo, 1,
- &ss, sizeof ss,
- NULL, NULL);
+ if (brw_search_cache(&brw->surface_cache,
+ BRW_SS_SURFACE,
+ &ss, sizeof(ss),
+ &surface->bo, 1,
+ NULL,
+ bo_out))
+ return PIPE_OK;
+
+ ret = brw_upload_cache(&brw->surface_cache,
+ BRW_SS_SURFACE,
+ &ss, sizeof ss,
+ &surface->bo, 1,
+ &ss, sizeof ss,
+ NULL, NULL,
+ bo_out);
+ if (ret)
+ return ret;
/* XXX: we will only be rendering to this surface:
*/
- brw->sws->bo_emit_reloc(brw->wm.surf_bo[unit],
- BRW_USAGE_RENDER_TARGET,
- ss.ss1.base_addr - surface->bo->offset[0], /* XXX */
- offsetof(struct brw_surface_state, ss1),
- surface->bo);
- }
+ ret = brw->sws->bo_emit_reloc(*bo_out,
+ BRW_USAGE_RENDER_TARGET,
+ ss.ss1.base_addr - surface->bo->offset[0], /* XXX */
+ offsetof(struct brw_surface_state, ss1),
+ surface->bo);
+ if (ret)
+ return ret;
+
+ return PIPE_OK;
}
* Constructs the binding table for the WM surface state, which maps unit
* numbers to surface state objects.
*/
-static struct brw_winsys_buffer *
-brw_wm_get_binding_table(struct brw_context *brw)
+static enum pipe_error
+brw_wm_get_binding_table(struct brw_context *brw,
+ struct brw_winsys_buffer **bo_out )
{
- struct brw_winsys_buffer *bind_bo;
+ enum pipe_error ret;
+ 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);
/* Note there is no key for this search beyond the values in the
* relocation array:
*/
- bind_bo = brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND,
- NULL, 0,
- brw->wm.surf_bo, brw->wm.nr_surfaces,
- NULL);
-
- if (bind_bo == NULL) {
- uint32_t data[BRW_WM_MAX_SURF];
- GLuint data_size = brw->wm.nr_surfaces * sizeof data[0];
- int i;
-
- for (i = 0; i < brw->wm.nr_surfaces; i++)
- data[i] = brw->wm.surf_bo[i]->offset[0];
-
- bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND,
- NULL, 0,
- brw->wm.surf_bo, brw->wm.nr_surfaces,
- data, data_size,
- NULL, NULL);
-
- /* Emit binding table relocations to surface state */
- for (i = 0; i < brw->wm.nr_surfaces; i++) {
- brw->sws->bo_emit_reloc(bind_bo,
- BRW_USAGE_STATE,
- 0,
- i * sizeof(GLuint),
- brw->wm.surf_bo[i]);
- }
+ if (brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND,
+ NULL, 0,
+ brw->wm.surf_bo,
+ brw->wm.nr_surfaces,
+ NULL,
+ bo_out))
+ return PIPE_OK;
+
+ for (i = 0; i < brw->wm.nr_surfaces; i++)
+ data[i] = brw->wm.surf_bo[i]->offset[0];
+
+ ret = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND,
+ NULL, 0,
+ brw->wm.surf_bo, 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 bind_bo;
+ return PIPE_OK;
}
-static int prepare_wm_surfaces(struct brw_context *brw )
+static enum pipe_error prepare_wm_surfaces(struct brw_context *brw )
{
- GLuint i;
+ enum pipe_error ret;
int nr_surfaces = 0;
-
- /* Unreference old buffers
- */
- for (i = 0; i < brw->wm.nr_surfaces; i++) {
- brw->sws->bo_unreference(brw->wm.surf_bo[i]);
- brw->wm.surf_bo[i] = NULL;
- }
-
+ GLuint i;
/* PIPE_NEW_COLOR_BUFFERS | PIPE_NEW_BLEND
*
* XXX: no color buffer case
*/
for (i = 0; i < brw->curr.fb.nr_cbufs; i++) {
- brw_update_renderbuffer_surface(brw,
- brw_surface(brw->curr.fb.cbufs[i]),
- nr_surfaces++);
+ ret = brw_update_render_surface(brw,
+ brw_surface(brw->curr.fb.cbufs[i]),
+ &brw->wm.surf_bo[nr_surfaces++]);
+ if (ret)
+ return ret;
}
/* PIPE_NEW_TEXTURE
*/
for (i = 0; i < brw->curr.num_textures; i++) {
- brw_update_texture_surface(brw,
- brw_texture(brw->curr.texture[i]),
- nr_surfaces++);
+ ret = brw_update_texture_surface(brw,
+ brw_texture(brw->curr.texture[i]),
+ &brw->wm.surf_bo[nr_surfaces++]);
+ if (ret)
+ return ret;
}
/* PIPE_NEW_FRAGMENT_CONSTANTS
*/
#if 0
if (brw->curr.fragment_constants) {
- brw_update_fragment_constant_surface(brw,
- brw->curr.fragment_constants,
- nr_surfaces++);
+ ret = brw_update_fragment_constant_surface(brw,
+ brw->curr.fragment_constants,
+ &brw->wm.surf_bo[nr_surfaces++]);
+ if (ret)
+ return ret;
}
#endif
if (brw->wm.nr_surfaces != nr_surfaces) {
+
+ /* Unreference any left-over old buffers
+ */
+ for (i = nr_surfaces; i < brw->wm.nr_surfaces; i++)
+ bo_reference(&brw->wm.surf_bo[i], NULL);
+
brw->wm.nr_surfaces = nr_surfaces;
brw->state.dirty.brw |= BRW_NEW_NR_WM_SURFACES;
}
- brw->sws->bo_unreference(brw->wm.bind_bo);
- brw->wm.bind_bo = brw_wm_get_binding_table(brw);
+ ret = brw_wm_get_binding_table(brw, &brw->wm.bind_bo);
+ if (ret)
+ return ret;
- return 0;
+ return PIPE_OK;
}
const struct brw_tracked_state brw_wm_surfaces = {
};
-static struct brw_winsys_buffer *
+static enum pipe_error
xlib_brw_bo_alloc( struct brw_winsys_screen *sws,
- enum brw_buffer_type type,
- unsigned size,
- unsigned alignment )
+ enum brw_buffer_type type,
+ unsigned size,
+ unsigned alignment,
+ struct brw_winsys_buffer **bo_out )
{
struct xlib_brw_winsys *xbw = xlib_brw_winsys(sws);
struct xlib_brw_buffer *buf;
buf = CALLOC_STRUCT(xlib_brw_buffer);
if (!buf)
- return NULL;
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ pipe_reference_init(&buf->base.reference, 1);
buf->offset = align(xbw->offset, alignment);
buf->type = type;
buf->virtual = MALLOC(size);
- buf->cheesy_refcount = 1;
buf->base.offset = &buf->offset; /* hmm, cheesy */
buf->base.size = size;
if (xbw->offset > MAX_VRAM)
goto err;
- return &buf->base;
+ /* XXX: possibly rentrant call to bo_destroy:
+ */
+ bo_reference(bo_out, &buf->base);
+ return PIPE_OK;
err:
assert(0);
+ FREE(buf->virtual);
FREE(buf);
- return NULL;
-}
-
-static void
-xlib_brw_bo_reference( struct brw_winsys_buffer *buffer )
-{
- struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
-
- buf->cheesy_refcount++;
+ return PIPE_ERROR_OUT_OF_MEMORY;
}
static void
-xlib_brw_bo_unreference( struct brw_winsys_buffer *buffer )
+xlib_brw_bo_destroy( struct brw_winsys_buffer *buffer )
{
struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
- /* As a special favor in this call only, buffer is allowed to be
- * NULL:
- */
- if (buffer == NULL)
- return;
-
- if (--buf->cheesy_refcount == 0) {
- FREE(buffer);
- }
+ FREE(buf->virtual);
+ FREE(buf);
}
static int
ws->base.destroy = xlib_brw_winsys_destroy;
ws->base.bo_alloc = xlib_brw_bo_alloc;
- ws->base.bo_reference = xlib_brw_bo_reference;
- ws->base.bo_unreference = xlib_brw_bo_unreference;
+ ws->base.bo_destroy = xlib_brw_bo_destroy;
ws->base.bo_emit_reloc = xlib_brw_bo_emit_reloc;
ws->base.bo_exec = xlib_brw_bo_exec;
ws->base.bo_subdata = xlib_brw_bo_subdata;