diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gallium/drivers/r600/r600_context.c | 141 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_context.h | 29 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_draw.c | 104 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_shader.c | 34 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_state.c | 283 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/radeon.h | 52 | ||||
| -rw-r--r-- | src/gallium/targets/dri-r600/Makefile | 4 | ||||
| -rw-r--r-- | src/gallium/winsys/r600/drm/radeon.c | 11 | ||||
| -rw-r--r-- | src/gallium/winsys/r600/drm/radeon_ctx.c | 160 | ||||
| -rw-r--r-- | src/gallium/winsys/r600/drm/radeon_draw.c | 92 | ||||
| -rw-r--r-- | src/gallium/winsys/r600/drm/radeon_priv.h | 29 | ||||
| -rw-r--r-- | src/gallium/winsys/r600/drm/radeon_state.c | 70 | 
12 files changed, 647 insertions, 362 deletions
| diff --git a/src/gallium/drivers/r600/r600_context.c b/src/gallium/drivers/r600/r600_context.c index f7732d8952..ae1780a1d4 100644 --- a/src/gallium/drivers/r600/r600_context.c +++ b/src/gallium/drivers/r600/r600_context.c @@ -48,14 +48,18 @@ void r600_flush(struct pipe_context *ctx, unsigned flags,  	struct r600_screen *rscreen = rctx->screen;  	static int dc = 0; -	if (radeon_ctx_pm4(&rctx->ctx)) +	if (radeon_ctx_pm4(rctx->ctx))  		return;  	/* FIXME dumping should be removed once shader support instructions  	 * without throwing bad code  	 */  	if (!dc) -		radeon_ctx_dump_bof(&rctx->ctx, "gallium.bof"); -	radeon_ctx_submit(&rctx->ctx); +		radeon_ctx_dump_bof(rctx->ctx, "gallium.bof"); +#if 1 +	radeon_ctx_submit(rctx->ctx); +#endif +	rctx->ctx = radeon_ctx_decref(rctx->ctx); +	rctx->ctx = radeon_ctx(rscreen->rw);  	dc++;  } @@ -216,8 +220,9 @@ static void r600_init_config(struct r600_context *rctx)  	printf("num_gs_stack_entries : %d\n", num_gs_stack_entries);  	printf("num_es_stack_entries : %d\n", num_es_stack_entries); -	radeon_state_init(&rctx->config, rctx->rw, R600_CONFIG_TYPE, R600_CONFIG); -	rctx->config.states[R600_CONFIG__SQ_CONFIG] = 0x00000000; +	rctx->hw_states.config = radeon_state(rctx->rw, R600_CONFIG_TYPE, R600_CONFIG); + +	rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] = 0x00000000;  	switch (family) {  	case CHIP_RV610:  	case CHIP_RV620: @@ -226,75 +231,75 @@ static void r600_init_config(struct r600_context *rctx)  	case CHIP_RV710:  		break;  	default: -		rctx->config.states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VC_ENABLE(1); +		rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VC_ENABLE(1);  		break;  	} -	rctx->config.states[R600_CONFIG__SQ_CONFIG] |= S_008C00_DX9_CONSTS(1); -	rctx->config.states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ALU_INST_PREFER_VECTOR(1); -	rctx->config.states[R600_CONFIG__SQ_CONFIG] |= S_008C00_PS_PRIO(ps_prio); -	rctx->config.states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VS_PRIO(vs_prio); -	rctx->config.states[R600_CONFIG__SQ_CONFIG] |= S_008C00_GS_PRIO(gs_prio); -	rctx->config.states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ES_PRIO(es_prio); +	rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_DX9_CONSTS(1); +	rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ALU_INST_PREFER_VECTOR(1); +	rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_PS_PRIO(ps_prio); +	rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VS_PRIO(vs_prio); +	rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_GS_PRIO(gs_prio); +	rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ES_PRIO(es_prio); -	rctx->config.states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] = 0; -	rctx->config.states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_PS_GPRS(num_ps_gprs); -	rctx->config.states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_VS_GPRS(num_vs_gprs); -	rctx->config.states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs); +	rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] = 0; +	rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_PS_GPRS(num_ps_gprs); +	rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_VS_GPRS(num_vs_gprs); +	rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs); -	rctx->config.states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] = 0; -	rctx->config.states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_gs_gprs); -	rctx->config.states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_es_gprs); +	rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] = 0; +	rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_gs_gprs); +	rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_es_gprs); -	rctx->config.states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] = 0; -	rctx->config.states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_PS_THREADS(num_ps_threads); -	rctx->config.states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_VS_THREADS(num_vs_threads); -	rctx->config.states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_GS_THREADS(num_gs_threads); -	rctx->config.states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_ES_THREADS(num_es_threads); +	rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] = 0; +	rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_PS_THREADS(num_ps_threads); +	rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_VS_THREADS(num_vs_threads); +	rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_GS_THREADS(num_gs_threads); +	rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_ES_THREADS(num_es_threads); -	rctx->config.states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] = 0; -	rctx->config.states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_PS_STACK_ENTRIES(num_ps_stack_entries); -	rctx->config.states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_VS_STACK_ENTRIES(num_vs_stack_entries); +	rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] = 0; +	rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_PS_STACK_ENTRIES(num_ps_stack_entries); +	rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_VS_STACK_ENTRIES(num_vs_stack_entries); -	rctx->config.states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] = 0; -	rctx->config.states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_GS_STACK_ENTRIES(num_gs_stack_entries); -	rctx->config.states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_ES_STACK_ENTRIES(num_es_stack_entries); +	rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] = 0; +	rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_GS_STACK_ENTRIES(num_gs_stack_entries); +	rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_ES_STACK_ENTRIES(num_es_stack_entries); -	rctx->config.states[R600_CONFIG__SQ_DYN_GPR_CNTL_PS_FLUSH_REQ] = 0x00004000; -	rctx->config.states[R600_CONFIG__TA_CNTL_AUX] = 0x07000002; -	rctx->config.states[R600_CONFIG__VC_ENHANCE] = 0x00000000; -	rctx->config.states[R600_CONFIG__DB_DEBUG] = 0x00000000; -	rctx->config.states[R600_CONFIG__DB_WATERMARKS] = 0x00420204; -	rctx->config.states[R600_CONFIG__SX_MISC] = 0x00000000; -	rctx->config.states[R600_CONFIG__SPI_THREAD_GROUPING] = 0x00000001; -	rctx->config.states[R600_CONFIG__CB_SHADER_CONTROL] = 0x00000003; -	rctx->config.states[R600_CONFIG__SQ_ESGS_RING_ITEMSIZE] = 0x00000000; -	rctx->config.states[R600_CONFIG__SQ_GSVS_RING_ITEMSIZE] = 0x00000000; -	rctx->config.states[R600_CONFIG__SQ_ESTMP_RING_ITEMSIZE] = 0x00000000; -	rctx->config.states[R600_CONFIG__SQ_GSTMP_RING_ITEMSIZE] = 0x00000000; -	rctx->config.states[R600_CONFIG__SQ_VSTMP_RING_ITEMSIZE] = 0x00000000; -	rctx->config.states[R600_CONFIG__SQ_PSTMP_RING_ITEMSIZE] = 0x00000000; -	rctx->config.states[R600_CONFIG__SQ_FBUF_RING_ITEMSIZE] = 0x00000000; -	rctx->config.states[R600_CONFIG__SQ_REDUC_RING_ITEMSIZE] = 0x00000000; -	rctx->config.states[R600_CONFIG__SQ_GS_VERT_ITEMSIZE] = 0x00000000; -	rctx->config.states[R600_CONFIG__VGT_OUTPUT_PATH_CNTL] = 0x00000000; -	rctx->config.states[R600_CONFIG__VGT_HOS_CNTL] = 0x00000000; -	rctx->config.states[R600_CONFIG__VGT_HOS_MAX_TESS_LEVEL] = 0x00000000; -	rctx->config.states[R600_CONFIG__VGT_HOS_MIN_TESS_LEVEL] = 0x00000000; -	rctx->config.states[R600_CONFIG__VGT_HOS_REUSE_DEPTH] = 0x00000000; -	rctx->config.states[R600_CONFIG__VGT_GROUP_PRIM_TYPE] = 0x00000000; -	rctx->config.states[R600_CONFIG__VGT_GROUP_FIRST_DECR] = 0x00000000; -	rctx->config.states[R600_CONFIG__VGT_GROUP_DECR] = 0x00000000; -	rctx->config.states[R600_CONFIG__VGT_GROUP_VECT_0_CNTL] = 0x00000000; -	rctx->config.states[R600_CONFIG__VGT_GROUP_VECT_1_CNTL] = 0x00000000; -	rctx->config.states[R600_CONFIG__VGT_GROUP_VECT_0_FMT_CNTL] = 0x00000000; -	rctx->config.states[R600_CONFIG__VGT_GROUP_VECT_1_FMT_CNTL] = 0x00000000; -	rctx->config.states[R600_CONFIG__VGT_GS_MODE] = 0x00000000; -	rctx->config.states[R600_CONFIG__PA_SC_MODE_CNTL] = 0x00514000; -	rctx->config.states[R600_CONFIG__VGT_STRMOUT_EN] = 0x00000000; -	rctx->config.states[R600_CONFIG__VGT_REUSE_OFF] = 0x00000001; -	rctx->config.states[R600_CONFIG__VGT_VTX_CNT_EN] = 0x00000000; -	rctx->config.states[R600_CONFIG__VGT_STRMOUT_BUFFER_EN] = 0x00000000; -	radeon_state_pm4(&rctx->config); +	rctx->hw_states.config->states[R600_CONFIG__SQ_DYN_GPR_CNTL_PS_FLUSH_REQ] = 0x00004000; +	rctx->hw_states.config->states[R600_CONFIG__TA_CNTL_AUX] = 0x07000002; +	rctx->hw_states.config->states[R600_CONFIG__VC_ENHANCE] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__DB_DEBUG] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__DB_WATERMARKS] = 0x00420204; +	rctx->hw_states.config->states[R600_CONFIG__SX_MISC] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__SPI_THREAD_GROUPING] = 0x00000001; +	rctx->hw_states.config->states[R600_CONFIG__CB_SHADER_CONTROL] = 0x00000003; +	rctx->hw_states.config->states[R600_CONFIG__SQ_ESGS_RING_ITEMSIZE] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__SQ_GSVS_RING_ITEMSIZE] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__SQ_ESTMP_RING_ITEMSIZE] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__SQ_GSTMP_RING_ITEMSIZE] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__SQ_VSTMP_RING_ITEMSIZE] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__SQ_PSTMP_RING_ITEMSIZE] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__SQ_FBUF_RING_ITEMSIZE] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__SQ_REDUC_RING_ITEMSIZE] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__SQ_GS_VERT_ITEMSIZE] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__VGT_OUTPUT_PATH_CNTL] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_CNTL] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_MAX_TESS_LEVEL] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_MIN_TESS_LEVEL] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_REUSE_DEPTH] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_PRIM_TYPE] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_FIRST_DECR] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_DECR] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_0_CNTL] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_1_CNTL] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_0_FMT_CNTL] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_1_FMT_CNTL] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__VGT_GS_MODE] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__PA_SC_MODE_CNTL] = 0x00514000; +	rctx->hw_states.config->states[R600_CONFIG__VGT_STRMOUT_EN] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__VGT_REUSE_OFF] = 0x00000001; +	rctx->hw_states.config->states[R600_CONFIG__VGT_VTX_CNT_EN] = 0x00000000; +	rctx->hw_states.config->states[R600_CONFIG__VGT_STRMOUT_BUFFER_EN] = 0x00000000; +	radeon_state_pm4(rctx->hw_states.config);  }  struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv) @@ -328,7 +333,7 @@ struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)  	r600_init_config(rctx); -	radeon_ctx_init(&rctx->ctx, rscreen->rw); -	radeon_draw_init(&rctx->draw, rscreen->rw); +	rctx->ctx = radeon_ctx(rscreen->rw); +	rctx->draw = radeon_draw(rscreen->rw);  	return &rctx->context;  } diff --git a/src/gallium/drivers/r600/r600_context.h b/src/gallium/drivers/r600/r600_context.h index c83949de42..431f8951b2 100644 --- a/src/gallium/drivers/r600/r600_context.h +++ b/src/gallium/drivers/r600/r600_context.h @@ -76,7 +76,7 @@ struct r600_context_state {  	union pipe_states		state;  	unsigned			refcount;  	unsigned			type; -	struct radeon_state		rstate; +	struct radeon_state		*rstate;  	struct r600_shader		shader;  	struct radeon_bo		*bo;  }; @@ -89,28 +89,28 @@ struct r600_vertex_element  };  struct r600_context_hw_states { -	struct radeon_state	rasterizer; -	struct radeon_state	scissor; -	struct radeon_state	dsa; -	struct radeon_state	blend; -	struct radeon_state	viewport; -	struct radeon_state	cb[7]; -	struct radeon_state	config; -	struct radeon_state	cb_cntl; -	struct radeon_state	db; +	struct radeon_state	*rasterizer; +	struct radeon_state	*scissor; +	struct radeon_state	*dsa; +	struct radeon_state	*blend; +	struct radeon_state	*viewport; +	struct radeon_state	*cb[7]; +	struct radeon_state	*config; +	struct radeon_state	*cb_cntl; +	struct radeon_state	*db;  	unsigned		ps_nresource;  	unsigned		ps_nsampler; -	struct radeon_state	ps_resource[160]; -	struct radeon_state	ps_sampler[16]; +	struct radeon_state	*ps_resource[160]; +	struct radeon_state	*ps_sampler[16];  };  struct r600_context {  	struct pipe_context		context;  	struct r600_screen		*screen;  	struct radeon			*rw; -	struct radeon_ctx		ctx; +	struct radeon_ctx		*ctx;  	struct blitter_context		*blitter; -	struct radeon_draw		draw; +	struct radeon_draw		*draw;  	/* hw states */  	struct r600_context_hw_states	hw_states;  	/* pipe states */ @@ -120,7 +120,6 @@ struct r600_context {  	unsigned			ps_nsampler_view;  	unsigned			vs_nsampler_view;  	unsigned			nvertex_buffer; -	struct radeon_state		config;  	struct r600_context_state	*rasterizer;  	struct r600_context_state	*poly_stipple;  	struct r600_context_state	*scissor; diff --git a/src/gallium/drivers/r600/r600_draw.c b/src/gallium/drivers/r600/r600_draw.c index 3a54cee2d9..2420b76318 100644 --- a/src/gallium/drivers/r600/r600_draw.c +++ b/src/gallium/drivers/r600/r600_draw.c @@ -38,8 +38,8 @@  struct r600_draw {  	struct pipe_context	*ctx; -	struct radeon_state	draw; -	struct radeon_state	vgt; +	struct radeon_state	*draw; +	struct radeon_state	*vgt;  	unsigned		mode;  	unsigned		start;  	unsigned		count; @@ -51,7 +51,7 @@ static int r600_draw_common(struct r600_draw *draw)  {  	struct r600_context *rctx = r600_context(draw->ctx);  	struct r600_screen *rscreen = rctx->screen; -	struct radeon_state vs_resource; +	struct radeon_state *vs_resource;  	struct r600_resource *rbuffer;  	unsigned i, j, offset, format, prim;  	u32 vgt_dma_index_type, vgt_draw_initiator; @@ -88,10 +88,10 @@ static int r600_draw_common(struct r600_draw *draw)  	r = r600_pipe_shader_update(draw->ctx, rctx->ps_shader);  	if (r)  		return r; -	r = radeon_draw_set(&rctx->draw, &rctx->vs_shader->rstate); +	r = radeon_draw_set(rctx->draw, rctx->vs_shader->rstate);  	if (r)  		return r; -	r = radeon_draw_set(&rctx->draw, &rctx->ps_shader->rstate); +	r = radeon_draw_set(rctx->draw, rctx->ps_shader->rstate);  	if (r)  		return r; @@ -101,68 +101,68 @@ static int r600_draw_common(struct r600_draw *draw)  		rbuffer = (struct r600_resource*)vertex_buffer->buffer;  		offset = rctx->vertex_elements->elements[i].src_offset + vertex_buffer->buffer_offset;  		format = r600_translate_colorformat(rctx->vertex_elements->elements[i].src_format); -		r = radeon_state_init(&vs_resource, rscreen->rw, R600_VS_RESOURCE_TYPE, R600_VS_RESOURCE + i); -		if (r) -			return r; -		vs_resource.bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); -		vs_resource.nbo = 1; -		vs_resource.states[R600_PS_RESOURCE__RESOURCE0_WORD0] = offset; -		vs_resource.states[R600_PS_RESOURCE__RESOURCE0_WORD1] = rbuffer->bo->size - offset; -		vs_resource.states[R600_PS_RESOURCE__RESOURCE0_WORD2] = S_038008_STRIDE(vertex_buffer->stride) | +		vs_resource = radeon_state(rscreen->rw, R600_VS_RESOURCE_TYPE, R600_VS_RESOURCE + i); +		if (vs_resource == NULL) +			return -ENOMEM; +		vs_resource->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); +		vs_resource->nbo = 1; +		vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD0] = offset; +		vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD1] = rbuffer->bo->size - offset; +		vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = S_038008_STRIDE(vertex_buffer->stride) |  								S_038008_DATA_FORMAT(format); -		vs_resource.states[R600_PS_RESOURCE__RESOURCE0_WORD3] = 0x00000000; -		vs_resource.states[R600_PS_RESOURCE__RESOURCE0_WORD4] = 0x00000000; -		vs_resource.states[R600_PS_RESOURCE__RESOURCE0_WORD5] = 0x00000000; -		vs_resource.states[R600_PS_RESOURCE__RESOURCE0_WORD6] = 0xC0000000; -		vs_resource.placement[0] = RADEON_GEM_DOMAIN_GTT; -		vs_resource.placement[1] = RADEON_GEM_DOMAIN_GTT; -		radeon_state_pm4(&vs_resource); -		r = radeon_draw_set(&rctx->draw, &vs_resource); +		vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD3] = 0x00000000; +		vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD4] = 0x00000000; +		vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD5] = 0x00000000; +		vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD6] = 0xC0000000; +		vs_resource->placement[0] = RADEON_GEM_DOMAIN_GTT; +		vs_resource->placement[1] = RADEON_GEM_DOMAIN_GTT; +		r = radeon_draw_set_new(rctx->draw, vs_resource);  		if (r)  			return r;  	}  	/* FIXME start need to change winsys */ -	r = radeon_state_init(&draw->draw, rscreen->rw, R600_DRAW_TYPE, R600_DRAW); -	if (r) -		return r; -	draw->draw.states[R600_DRAW__VGT_NUM_INDICES] = draw->count; -	draw->draw.states[R600_DRAW__VGT_DRAW_INITIATOR] = vgt_draw_initiator; +	draw->draw = radeon_state(rscreen->rw, R600_DRAW_TYPE, R600_DRAW); +	if (draw->draw == NULL) +		return -ENOMEM; +	draw->draw->states[R600_DRAW__VGT_NUM_INDICES] = draw->count; +	draw->draw->states[R600_DRAW__VGT_DRAW_INITIATOR] = vgt_draw_initiator;  	if (draw->index_buffer) { -		rbuffer = (struct r600_resource*)draw->index_buffer; -		draw->draw.bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); -		draw->draw.placement[0] = RADEON_GEM_DOMAIN_GTT; -		draw->draw.placement[1] = RADEON_GEM_DOMAIN_GTT; -		draw->draw.nbo = 1; +		rbuffer = (struct r600_buffer*)draw->index_buffer; +		draw->draw->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); +		draw->draw->placement[0] = RADEON_GEM_DOMAIN_GTT; +		draw->draw->placement[1] = RADEON_GEM_DOMAIN_GTT; +		draw->draw->nbo = 1;  	} -	radeon_state_pm4(&draw->draw); -	r = radeon_draw_set(&rctx->draw, &draw->draw); +	r = radeon_draw_set_new(rctx->draw, draw->draw);  	if (r)  		return r; -	r = radeon_state_init(&draw->vgt, rscreen->rw, R600_VGT_TYPE, R600_VGT); -	if (r) -		return r; -	draw->vgt.states[R600_VGT__VGT_PRIMITIVE_TYPE] = prim; -	draw->vgt.states[R600_VGT__VGT_MAX_VTX_INDX] = 0x00FFFFFF; -	draw->vgt.states[R600_VGT__VGT_MIN_VTX_INDX] = 0x00000000; -	draw->vgt.states[R600_VGT__VGT_INDX_OFFSET] = draw->start; -	draw->vgt.states[R600_VGT__VGT_MULTI_PRIM_IB_RESET_INDX] = 0x00000000; -	draw->vgt.states[R600_VGT__VGT_DMA_INDEX_TYPE] = vgt_dma_index_type; -	draw->vgt.states[R600_VGT__VGT_PRIMITIVEID_EN] = 0x00000000; -	draw->vgt.states[R600_VGT__VGT_DMA_NUM_INSTANCES] = 0x00000001; -	draw->vgt.states[R600_VGT__VGT_MULTI_PRIM_IB_RESET_EN] = 0x00000000; -	draw->vgt.states[R600_VGT__VGT_INSTANCE_STEP_RATE_0] = 0x00000000; -	draw->vgt.states[R600_VGT__VGT_INSTANCE_STEP_RATE_1] = 0x00000000; -	radeon_state_pm4(&draw->vgt); -	r = radeon_draw_set(&rctx->draw, &draw->vgt); +	draw->vgt = radeon_state(rscreen->rw, R600_VGT_TYPE, R600_VGT); +	if (draw->vgt == NULL) +		return -ENOMEM; +	draw->vgt->states[R600_VGT__VGT_PRIMITIVE_TYPE] = prim; +	draw->vgt->states[R600_VGT__VGT_MAX_VTX_INDX] = 0x00FFFFFF; +	draw->vgt->states[R600_VGT__VGT_MIN_VTX_INDX] = 0x00000000; +	draw->vgt->states[R600_VGT__VGT_INDX_OFFSET] = draw->start; +	draw->vgt->states[R600_VGT__VGT_MULTI_PRIM_IB_RESET_INDX] = 0x00000000; +	draw->vgt->states[R600_VGT__VGT_DMA_INDEX_TYPE] = vgt_dma_index_type; +	draw->vgt->states[R600_VGT__VGT_PRIMITIVEID_EN] = 0x00000000; +	draw->vgt->states[R600_VGT__VGT_DMA_NUM_INSTANCES] = 0x00000001; +	draw->vgt->states[R600_VGT__VGT_MULTI_PRIM_IB_RESET_EN] = 0x00000000; +	draw->vgt->states[R600_VGT__VGT_INSTANCE_STEP_RATE_0] = 0x00000000; +	draw->vgt->states[R600_VGT__VGT_INSTANCE_STEP_RATE_1] = 0x00000000; +	r = radeon_draw_set_new(rctx->draw, draw->vgt);  	if (r)  		return r;  	/* FIXME */ -	r = radeon_ctx_set_draw(&rctx->ctx, &rctx->draw); +	r = radeon_ctx_set_draw_new(rctx->ctx, rctx->draw);  	if (r == -EBUSY) {  		r600_flush(draw->ctx, 0, NULL); -		r = radeon_ctx_set_draw(&rctx->ctx, &rctx->draw); +		r = radeon_ctx_set_draw_new(rctx->ctx, rctx->draw);  	} -	return r; +	if (r) +		return r; +	rctx->draw = radeon_draw_duplicate(rctx->draw); +	return 0;  }  void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index d925dcbe4b..dc8d4cb315 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -130,12 +130,11 @@ static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_context_sta  	struct r600_shader *rshader = &rpshader->shader;  	struct radeon_state *state;  	unsigned i, tmp; -	int r; -	r = radeon_state_init(&rpshader->rstate, rscreen->rw, R600_VS_SHADER_TYPE, R600_VS_SHADER); -	if (r) -		return r; -	state = &rpshader->rstate; +	rpshader->rstate = radeon_state_decref(rpshader->rstate); +	state = radeon_state(rscreen->rw, R600_VS_SHADER_TYPE, R600_VS_SHADER); +	if (state == NULL) +		return -ENOMEM;  	for (i = 0; i < 10; i++) {  		state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i] = 0;  	} @@ -146,10 +145,11 @@ static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_context_sta  	}  	state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 2);  	state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->bc.ngpr); -	rpshader->rstate.bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo); -	rpshader->rstate.bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo); -	rpshader->rstate.nbo = 2; -	rpshader->rstate.placement[0] = RADEON_GEM_DOMAIN_GTT; +	rpshader->rstate = state; +	rpshader->rstate->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo); +	rpshader->rstate->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo); +	rpshader->rstate->nbo = 2; +	rpshader->rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;  	return radeon_state_pm4(state);  } @@ -159,12 +159,11 @@ static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_context_sta  	struct r600_shader *rshader = &rpshader->shader;  	struct radeon_state *state;  	unsigned i, tmp, exports_ps, num_cout; -	int r; -	r = radeon_state_init(&rpshader->rstate, rscreen->rw, R600_PS_SHADER_TYPE, R600_PS_SHADER); -	if (r) -		return r; -	state = &rpshader->rstate; +	rpshader->rstate = radeon_state_decref(rpshader->rstate); +	state = radeon_state(rscreen->rw, R600_PS_SHADER_TYPE, R600_PS_SHADER); +	if (state == NULL) +		return -ENOMEM;  	for (i = 0; i < rshader->ninput; i++) {  		tmp = S_028644_SEMANTIC(i);  		tmp |= S_028644_SEL_CENTROID(1); @@ -190,9 +189,10 @@ static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_context_sta  	state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_1] = 0x00000000;  	state->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->bc.ngpr);  	state->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = exports_ps; -	rpshader->rstate.bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo); -	rpshader->rstate.nbo = 1; -	rpshader->rstate.placement[0] = RADEON_GEM_DOMAIN_GTT; +	rpshader->rstate = state; +	rpshader->rstate->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo); +	rpshader->rstate->nbo = 1; +	rpshader->rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;  	return radeon_state_pm4(state);  } diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index c5e74d1efc..e8871cd748 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -277,10 +277,9 @@ static void r600_set_constant_buffer(struct pipe_context *ctx,  	struct r600_screen *rscreen = r600_screen(ctx->screen);  	struct r600_context *rctx = r600_context(ctx);  	unsigned nconstant = 0, i, type, id; -	struct radeon_state rstate; +	struct radeon_state *rstate;  	struct pipe_transfer *transfer;  	u32 *ptr; -	int r;  	switch (shader) {  	case PIPE_SHADER_VERTEX: @@ -301,16 +300,16 @@ static void r600_set_constant_buffer(struct pipe_context *ctx,  		if (ptr == NULL)  			return;  		for (i = 0; i < nconstant; i++) { -			r = radeon_state_init(&rstate, rscreen->rw, type, id + i); -			if (r) +			rstate = radeon_state(rscreen->rw, type, id + i); +			if (rstate == NULL)  				return; -			rstate.states[R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0] = ptr[i * 4 + 0]; -			rstate.states[R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0] = ptr[i * 4 + 1]; -			rstate.states[R600_PS_CONSTANT__SQ_ALU_CONSTANT2_0] = ptr[i * 4 + 2]; -			rstate.states[R600_PS_CONSTANT__SQ_ALU_CONSTANT3_0] = ptr[i * 4 + 3]; -			if (radeon_state_pm4(&rstate)) +			rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0] = ptr[i * 4 + 0]; +			rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0] = ptr[i * 4 + 1]; +			rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT2_0] = ptr[i * 4 + 2]; +			rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT3_0] = ptr[i * 4 + 3]; +			if (radeon_state_pm4(rstate))  				return; -			if (radeon_draw_set(&rctx->draw, &rstate)) +			if (radeon_draw_set_new(rctx->draw, rstate))  				return;  		}  		pipe_buffer_unmap(ctx, buffer, transfer); @@ -521,6 +520,7 @@ struct r600_context_state *r600_context_state_decref(struct r600_context_state *  		R600_ERR("invalid type %d\n", rstate->type);  		return NULL;  	} +	radeon_state_decref(rstate->rstate);  	FREE(rstate);  	return NULL;  } @@ -603,17 +603,16 @@ struct r600_context_state *r600_context_state(struct r600_context *rctx, unsigne  	return rstate;  } -static int r600_blend(struct r600_context *rctx, struct radeon_state *rstate) +static struct radeon_state *r600_blend(struct r600_context *rctx)  {  	struct r600_screen *rscreen = rctx->screen; +	struct radeon_state *rstate;  	const struct pipe_blend_state *state = &rctx->blend->state.blend;  	int i; -	int r; - -	r = radeon_state_init(rstate, rscreen->rw, R600_BLEND_TYPE, R600_BLEND); -	if (r) -		return r; +	rstate = radeon_state(rscreen->rw, R600_BLEND_TYPE, R600_BLEND); +	if (rstate == NULL) +		return NULL;  	rstate->states[R600_BLEND__CB_BLEND_RED] = fui(rctx->blend_color.color[0]);  	rstate->states[R600_BLEND__CB_BLEND_GREEN] = fui(rctx->blend_color.color[1]);  	rstate->states[R600_BLEND__CB_BLEND_BLUE] = fui(rctx->blend_color.color[2]); @@ -657,27 +656,30 @@ static int r600_blend(struct r600_context *rctx, struct radeon_state *rstate)  			rstate->states[R600_BLEND__CB_BLEND_CONTROL] = bc;  	} -	return radeon_state_pm4(rstate); +	if (radeon_state_pm4(rstate)) { +		radeon_state_decref(rstate); +		return NULL; +	} +	return rstate;  } -static int r600_cb(struct r600_context *rctx, struct radeon_state *rstate, int cb) +static struct radeon_state *r600_cb(struct r600_context *rctx, int cb)  {  	struct r600_screen *rscreen = rctx->screen;  	struct r600_resource_texture *rtex;  	struct r600_resource *rbuffer; +	struct radeon_state *rstate;  	const struct pipe_framebuffer_state *state = &rctx->framebuffer->state.framebuffer;  	unsigned level = state->cbufs[cb]->level;  	unsigned pitch, slice;  	unsigned color_info;  	unsigned format, swap, ntype; -	int r;  	const struct util_format_description *desc;  	int id = R600_CB0 + cb; -	r = radeon_state_init(rstate, rscreen->rw, R600_CB0_TYPE, id); -	if (r) -		return r; - +	rstate = radeon_state(rscreen->rw, R600_CB0_TYPE, id); +	if (rstate == NULL) +		return NULL;  	rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture;  	rbuffer = &rtex->resource;  	rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); @@ -712,25 +714,30 @@ static int r600_cb(struct r600_context *rctx, struct radeon_state *rstate, int c  	rstate->states[R600_CB0__CB_COLOR0_FRAG] = 0x00000000;  	rstate->states[R600_CB0__CB_COLOR0_TILE] = 0x00000000;  	rstate->states[R600_CB0__CB_COLOR0_MASK] = 0x00000000; -	return radeon_state_pm4(rstate); +	if (radeon_state_pm4(rstate)) { +		radeon_state_decref(rstate); +		return NULL; +	} +	return rstate;  } -static int r600_db(struct r600_context *rctx, struct radeon_state *rstate) +static struct radeon_state *r600_db(struct r600_context *rctx)  {  	struct r600_screen *rscreen = rctx->screen;  	struct r600_resource_texture *rtex;  	struct r600_resource *rbuffer; +	struct radeon_state *rstate;  	const struct pipe_framebuffer_state *state = &rctx->framebuffer->state.framebuffer;  	unsigned level = state->cbufs[0]->level;  	unsigned pitch, slice, format; -	int r; - -	r = radeon_state_init(rstate, rscreen->rw, R600_DB_TYPE, R600_DB); -	if (r) -		return r;  	if (state->zsbuf == NULL) -		return 0; +		return NULL; + +	rstate = radeon_state(rscreen->rw, R600_DB_TYPE, R600_DB); +	if (rstate == NULL) +		return NULL; +  	rtex = (struct r600_resource_texture*)state->zsbuf->texture;  	rbuffer = &rtex->resource;  	rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); @@ -747,22 +754,23 @@ static int r600_db(struct r600_context *rctx, struct radeon_state *rstate)  	rstate->states[R600_DB__DB_PREFETCH_LIMIT] = (state->zsbuf->height / 8) -1;  	rstate->states[R600_DB__DB_DEPTH_SIZE] = S_028000_PITCH_TILE_MAX(pitch) |  						S_028000_SLICE_TILE_MAX(slice); -	return radeon_state_pm4(rstate); +	if (radeon_state_pm4(rstate)) { +		radeon_state_decref(rstate); +		return NULL; +	} +	return rstate;  } -static int r600_rasterizer(struct r600_context *rctx, struct radeon_state *rstate) +static struct radeon_state *r600_rasterizer(struct r600_context *rctx)  {  	const struct pipe_rasterizer_state *state = &rctx->rasterizer->state.rasterizer;  	const struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer;  	struct r600_screen *rscreen = rctx->screen; +	struct radeon_state *rstate;  	float offset_units = 0, offset_scale = 0;  	char depth = 0;  	unsigned offset_db_fmt_cntl = 0; -	int r; -	r = radeon_state_init(rstate, rscreen->rw, R600_RASTERIZER_TYPE, R600_RASTERIZER); -	if (r) -		return r;  	if (fb->zsbuf) {  		offset_units = state->offset_units;  		offset_scale = state->offset_scale * 12.0f; @@ -783,12 +791,15 @@ static int r600_rasterizer(struct r600_context *rctx, struct radeon_state *rstat  			break;  		default:  			R600_ERR("unsupported %d\n", fb->zsbuf->texture->format); -			return -EINVAL; +			return NULL;  		}  	}  	offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(depth);  	rctx->flat_shade = state->flatshade; +	rstate = radeon_state(rscreen->rw, R600_RASTERIZER_TYPE, R600_RASTERIZER); +	if (rstate == NULL) +		return NULL;  	rstate->states[R600_RASTERIZER__SPI_INTERP_CONTROL_0] = 0x00000001;  	rstate->states[R600_RASTERIZER__PA_CL_CLIP_CNTL] = 0x00000000;  	rstate->states[R600_RASTERIZER__PA_SU_SC_MODE_CNTL] = 0x00080000 | @@ -816,21 +827,25 @@ static int r600_rasterizer(struct r600_context *rctx, struct radeon_state *rstat  	rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_OFFSET] = fui(offset_units);  	rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_SCALE] = fui(offset_scale);  	rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_OFFSET] = fui(offset_units); -	return radeon_state_pm4(rstate); +	if (radeon_state_pm4(rstate)) { +		radeon_state_decref(rstate); +		return NULL; +	} +	return rstate;  } -static int r600_scissor(struct r600_context *rctx, struct radeon_state *rstate) +static struct radeon_state *r600_scissor(struct r600_context *rctx)  {  	const struct pipe_scissor_state *state = &rctx->scissor->state.scissor;  	struct r600_screen *rscreen = rctx->screen; +	struct radeon_state *rstate;  	u32 tl, br; -	int r; -	r = radeon_state_init(rstate, rscreen->rw, R600_SCISSOR_TYPE, R600_SCISSOR); -	if (r) -		return r;  	tl = S_028240_TL_X(state->minx) | S_028240_TL_Y(state->miny) | S_028240_WINDOW_OFFSET_DISABLE(1);  	br = S_028244_BR_X(state->maxx) | S_028244_BR_Y(state->maxy); +	rstate = radeon_state(rscreen->rw, R600_SCISSOR_TYPE, R600_SCISSOR); +	if (rstate == NULL) +		return NULL;  	rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_TL] = tl;  	rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_BR] = br;  	rstate->states[R600_SCISSOR__PA_SC_WINDOW_OFFSET] = 0x00000000; @@ -850,18 +865,22 @@ static int r600_scissor(struct r600_context *rctx, struct radeon_state *rstate)  	rstate->states[R600_SCISSOR__PA_SC_GENERIC_SCISSOR_BR] = br;  	rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_TL] = tl;  	rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_BR] = br; -	return radeon_state_pm4(rstate); +	if (radeon_state_pm4(rstate)) { +		radeon_state_decref(rstate); +		return NULL; +	} +	return rstate;  } -static int r600_viewport(struct r600_context *rctx, struct radeon_state *rstate) +static struct radeon_state *r600_viewport(struct r600_context *rctx)  {  	const struct pipe_viewport_state *state = &rctx->viewport->state.viewport;  	struct r600_screen *rscreen = rctx->screen; -	int r; +	struct radeon_state *rstate; -	r = radeon_state_init(rstate, rscreen->rw, R600_VIEWPORT_TYPE, R600_VIEWPORT); -	if (r) -		return r; +	rstate = radeon_state(rscreen->rw, R600_VIEWPORT_TYPE, R600_VIEWPORT); +	if (rstate == NULL) +		return NULL;  	rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMIN_0] = 0x00000000;  	rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMAX_0] = 0x3F800000;  	rstate->states[R600_VIEWPORT__PA_CL_VPORT_XSCALE_0] = fui(state->scale[0]); @@ -871,22 +890,27 @@ static int r600_viewport(struct r600_context *rctx, struct radeon_state *rstate)  	rstate->states[R600_VIEWPORT__PA_CL_VPORT_YOFFSET_0] = fui(state->translate[1]);  	rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZOFFSET_0] = fui(state->translate[2]);  	rstate->states[R600_VIEWPORT__PA_CL_VTE_CNTL] = 0x0000043F; -	return radeon_state_pm4(rstate); +	if (radeon_state_pm4(rstate)) { +		radeon_state_decref(rstate); +		return NULL; +	} +	return rstate;  } -static int r600_dsa(struct r600_context *rctx, struct radeon_state *rstate) +static struct radeon_state *r600_dsa(struct r600_context *rctx)  {  	const struct pipe_depth_stencil_alpha_state *state = &rctx->dsa->state.dsa;  	const struct pipe_stencil_ref *stencil_ref = &rctx->stencil_ref->state.stencil_ref;  	struct r600_screen *rscreen = rctx->screen;  	unsigned db_depth_control, alpha_test_control, alpha_ref, db_shader_control;  	unsigned stencil_ref_mask, stencil_ref_mask_bf; -	int r, i;  	struct r600_shader *rshader = &rctx->ps_shader->shader; +	struct radeon_state *rstate; +	int i; -	r = radeon_state_init(rstate, rscreen->rw, R600_DSA_TYPE, R600_DSA); -	if (r) -		return r; +	rstate = radeon_state(rscreen->rw, R600_DSA_TYPE, R600_DSA); +	if (rstate == NULL) +		return NULL;  	db_shader_control = 0x210;  	for (i = 0; i < rshader->noutput; i++) { @@ -898,8 +922,8 @@ static int r600_dsa(struct r600_context *rctx, struct radeon_state *rstate)  	db_depth_control = S_028800_Z_ENABLE(state->depth.enabled) |  		S_028800_Z_WRITE_ENABLE(state->depth.writemask) |  		S_028800_ZFUNC(state->depth.func); -  	/* set stencil enable */ +  	if (state->stencil[0].enabled) {  		db_depth_control |= S_028800_STENCIL_ENABLE(1);  		db_depth_control |= S_028800_STENCILFUNC(r600_translate_ds_func(state->stencil[0].func)); @@ -946,7 +970,11 @@ static int r600_dsa(struct r600_context *rctx, struct radeon_state *rstate)  	rstate->states[R600_DSA__DB_SRESULTS_COMPARE_STATE1] = 0x00000000;  	rstate->states[R600_DSA__DB_PRELOAD_CONTROL] = 0x00000000;  	rstate->states[R600_DSA__DB_ALPHA_TO_MASK] = 0x0000AA00; -	return radeon_state_pm4(rstate); +	if (radeon_state_pm4(rstate)) { +		radeon_state_decref(rstate); +		return NULL; +	} +	return rstate;  }  static inline unsigned r600_tex_wrap(unsigned wrap) @@ -1024,15 +1052,16 @@ static INLINE u32 S_FIXED(float value, u32 frac_bits)  	return value * (1 << frac_bits);  } -static int r600_sampler(struct r600_context *rctx, struct radeon_state *rstate, -			const struct pipe_sampler_state *state, unsigned id) +static struct radeon_state *r600_sampler(struct r600_context *rctx, +				const struct pipe_sampler_state *state, +				unsigned id)  {  	struct r600_screen *rscreen = rctx->screen; -	int r; +	struct radeon_state *rstate; -	r = radeon_state_init(rstate, rscreen->rw, R600_PS_SAMPLER_TYPE, id); -	if (r) -		return r; +	rstate = radeon_state(rscreen->rw, R600_PS_SAMPLER_TYPE, id); +	if (rstate == NULL) +		return NULL;  	rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD0_0] =  			S_03C000_CLAMP_X(r600_tex_wrap(state->wrap_s)) |  			S_03C000_CLAMP_Y(r600_tex_wrap(state->wrap_t)) | @@ -1047,7 +1076,11 @@ static int r600_sampler(struct r600_context *rctx, struct radeon_state *rstate,  			S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 6)) |  			S_03C004_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 6));  	rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD2_0] = S_03C008_TYPE(1); -	return radeon_state_pm4(rstate); +	if (radeon_state_pm4(rstate)) { +		radeon_state_decref(rstate); +		return NULL; +	} +	return rstate;  }  static inline unsigned r600_tex_swizzle(unsigned swizzle) @@ -1097,26 +1130,28 @@ static inline unsigned r600_tex_dim(unsigned dim)  	}  } -static int r600_resource(struct r600_context *rctx, struct radeon_state *rstate, -			const struct pipe_sampler_view *view, unsigned id) +static struct radeon_state *r600_resource(struct r600_context *rctx, +					const struct pipe_sampler_view *view, +					unsigned id)  {  	struct r600_screen *rscreen = rctx->screen;  	const struct util_format_description *desc;  	struct r600_resource_texture *tmp;  	struct r600_resource *rbuffer; +	struct radeon_state *rstate;  	unsigned format; -	int r; -	r = radeon_state_init(rstate, rscreen->rw, R600_PS_RESOURCE_TYPE, id); -	if (r) -		return r;  	format = r600_translate_colorformat(view->texture->format);  	if (format == ~0) -		return -EINVAL; +		return NULL;  	desc = util_format_description(view->texture->format);  	if (desc == NULL) {  		R600_ERR("unknow format %d\n", view->texture->format); -		return -EINVAL; +		return NULL; +	} +	rstate = radeon_state(rscreen->rw, R600_PS_RESOURCE_TYPE, id); +	if (rstate == NULL) { +		return NULL;  	}  	tmp = (struct r600_resource_texture*)view->texture;  	rbuffer = &tmp->resource; @@ -1159,16 +1194,21 @@ static int r600_resource(struct r600_context *rctx, struct radeon_state *rstate,  			S_038014_LAST_ARRAY(0);  	rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD6] =  			S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE); -	return radeon_state_pm4(rstate); +	if (radeon_state_pm4(rstate)) { +		radeon_state_decref(rstate); +		return NULL; +	} +	return rstate;  } -static int r600_cb_cntl(struct r600_context *rctx, struct radeon_state *rstate) +static struct radeon_state *r600_cb_cntl(struct r600_context *rctx)  {  	struct r600_screen *rscreen = rctx->screen; +	struct radeon_state *rstate;  	const struct pipe_blend_state *pbs = &rctx->blend->state.blend;  	int nr_cbufs = rctx->framebuffer->state.framebuffer.nr_cbufs;	  	uint32_t color_control, target_mask, shader_mask; -	int i, r; +	int i;  	target_mask = 0;  	shader_mask = 0; @@ -1190,10 +1230,7 @@ static int r600_cb_cntl(struct r600_context *rctx, struct radeon_state *rstate)  		target_mask |= (pbs->rt[i].colormask << (4 * i));  	} -	r = radeon_state_init(rstate, rscreen->rw, R600_CB_CNTL_TYPE, R600_CB_CNTL); -	if (r) -		return r; - +	rstate = radeon_state(rscreen->rw, R600_CB_CNTL_TYPE, R600_CB_CNTL);  	rstate->states[R600_CB_CNTL__CB_SHADER_MASK] = shader_mask;  	rstate->states[R600_CB_CNTL__CB_TARGET_MASK] = target_mask;  	rstate->states[R600_CB_CNTL__CB_COLOR_CONTROL] = color_control; @@ -1205,7 +1242,11 @@ static int r600_cb_cntl(struct r600_context *rctx, struct radeon_state *rstate)  	rstate->states[R600_CB_CNTL__CB_CLRCMP_DST] = 0x000000FF;  	rstate->states[R600_CB_CNTL__CB_CLRCMP_MSK] = 0xFFFFFFFF;  	rstate->states[R600_CB_CNTL__PA_SC_AA_MASK] = 0xFFFFFFFF; -	return radeon_state_pm4(rstate); +	if (radeon_state_pm4(rstate)) { +		radeon_state_decref(rstate); +		return NULL; +	} +	return rstate;  }  int r600_context_hw_states(struct r600_context *rctx) @@ -1217,77 +1258,97 @@ int r600_context_hw_states(struct r600_context *rctx)  	/* free previous TODO determine what need to be updated, what  	 * doesn't  	 */ -	memset(&rctx->hw_states, 0, sizeof(struct r600_context_hw_states)); +	//radeon_state_decref(rctx->hw_states.config); +	rctx->hw_states.cb_cntl = radeon_state_decref(rctx->hw_states.cb_cntl); +	rctx->hw_states.db = radeon_state_decref(rctx->hw_states.db); +	rctx->hw_states.rasterizer = radeon_state_decref(rctx->hw_states.rasterizer); +	rctx->hw_states.scissor = radeon_state_decref(rctx->hw_states.scissor); +	rctx->hw_states.dsa = radeon_state_decref(rctx->hw_states.dsa); +	rctx->hw_states.blend = radeon_state_decref(rctx->hw_states.blend); +	rctx->hw_states.viewport = radeon_state_decref(rctx->hw_states.viewport); +	for (i = 0; i < 8; i++) { +		rctx->hw_states.cb[i] = radeon_state_decref(rctx->hw_states.cb[i]); +	} +	for (i = 0; i < rctx->hw_states.ps_nresource; i++) { +		radeon_state_decref(rctx->hw_states.ps_resource[i]); +		rctx->hw_states.ps_resource[i] = NULL; +	} +	rctx->hw_states.ps_nresource = 0; +	for (i = 0; i < rctx->hw_states.ps_nsampler; i++) { +		radeon_state_decref(rctx->hw_states.ps_sampler[i]); +		rctx->hw_states.ps_sampler[i] = NULL; +	} +	rctx->hw_states.ps_nsampler = 0;  	/* build new states */ -	rctx->hw_states.config = rctx->config; -	r600_rasterizer(rctx, &rctx->hw_states.rasterizer); -	r600_scissor(rctx, &rctx->hw_states.scissor); -	r600_dsa(rctx, &rctx->hw_states.dsa); -	r600_blend(rctx, &rctx->hw_states.blend); -	r600_viewport(rctx, &rctx->hw_states.viewport); -	for (i = 0; i < nr_cbufs; i++) -		r600_cb(rctx, &rctx->hw_states.cb[i], i); -	r600_db(rctx, &rctx->hw_states.db); -	r600_cb_cntl(rctx, &rctx->hw_states.cb_cntl); +	rctx->hw_states.rasterizer = r600_rasterizer(rctx); +	rctx->hw_states.scissor = r600_scissor(rctx); +	rctx->hw_states.dsa = r600_dsa(rctx); +	rctx->hw_states.blend = r600_blend(rctx); +	rctx->hw_states.viewport = r600_viewport(rctx); +	for (i = 0; i < nr_cbufs; i++) { +		rctx->hw_states.cb[i] = r600_cb(rctx, i); +	} +	rctx->hw_states.db = r600_db(rctx); +	rctx->hw_states.cb_cntl = r600_cb_cntl(rctx);  	for (i = 0; i < rctx->ps_nsampler; i++) {  		if (rctx->ps_sampler[i]) { -			r600_sampler(rctx, &rctx->hw_states.ps_sampler[i], -					&rctx->ps_sampler[i]->state.sampler, -					R600_PS_SAMPLER + i); +			rctx->hw_states.ps_sampler[i] = r600_sampler(rctx, +							&rctx->ps_sampler[i]->state.sampler, +							R600_PS_SAMPLER + i);  		}  	}  	rctx->hw_states.ps_nsampler = rctx->ps_nsampler;  	for (i = 0; i < rctx->ps_nsampler_view; i++) {  		if (rctx->ps_sampler_view[i]) { -			r600_resource(rctx, &rctx->hw_states.ps_resource[i], -					&rctx->ps_sampler_view[i]->state.sampler_view, -					R600_PS_RESOURCE + i); +			rctx->hw_states.ps_resource[i] = r600_resource(rctx, +							&rctx->ps_sampler_view[i]->state.sampler_view, +							R600_PS_RESOURCE + i);  		}  	}  	rctx->hw_states.ps_nresource = rctx->ps_nsampler_view;  	/* bind states */ -	r = radeon_draw_set(&rctx->draw, &rctx->hw_states.db); +	r = radeon_draw_set(rctx->draw, rctx->hw_states.db);  	if (r)  		return r; -	r = radeon_draw_set(&rctx->draw, &rctx->hw_states.rasterizer); +	r = radeon_draw_set(rctx->draw, rctx->hw_states.rasterizer);  	if (r)  		return r; -	r = radeon_draw_set(&rctx->draw, &rctx->hw_states.scissor); +	r = radeon_draw_set(rctx->draw, rctx->hw_states.scissor);  	if (r)  		return r; -	r = radeon_draw_set(&rctx->draw, &rctx->hw_states.dsa); +	r = radeon_draw_set(rctx->draw, rctx->hw_states.dsa);  	if (r)  		return r; -	r = radeon_draw_set(&rctx->draw, &rctx->hw_states.blend); +	r = radeon_draw_set(rctx->draw, rctx->hw_states.blend);  	if (r)  		return r; -	r = radeon_draw_set(&rctx->draw, &rctx->hw_states.viewport); +	r = radeon_draw_set(rctx->draw, rctx->hw_states.viewport);  	if (r)  		return r;  	for (i = 0; i < nr_cbufs; i++) { -		r = radeon_draw_set(&rctx->draw, &rctx->hw_states.cb[i]); +		r = radeon_draw_set(rctx->draw, rctx->hw_states.cb[i]);  		if (r)  			return r;  	} -	r = radeon_draw_set(&rctx->draw, &rctx->hw_states.config); +	r = radeon_draw_set(rctx->draw, rctx->hw_states.config);  	if (r)  		return r; -	r = radeon_draw_set(&rctx->draw, &rctx->hw_states.cb_cntl); +	r = radeon_draw_set(rctx->draw, rctx->hw_states.cb_cntl);  	if (r)  		return r;  	for (i = 0; i < rctx->hw_states.ps_nresource; i++) { -		if (rctx->hw_states.ps_resource[i].valid) { -			r = radeon_draw_set(&rctx->draw, &rctx->hw_states.ps_resource[i]); +		if (rctx->hw_states.ps_resource[i]) { +			r = radeon_draw_set(rctx->draw, rctx->hw_states.ps_resource[i]);  			if (r)  				return r;  		}  	}  	for (i = 0; i < rctx->hw_states.ps_nsampler; i++) { -		if (rctx->hw_states.ps_sampler[i].valid) { -			r = radeon_draw_set(&rctx->draw, &rctx->hw_states.ps_sampler[i]); +		if (rctx->hw_states.ps_sampler[i]) { +			r = radeon_draw_set(rctx->draw, rctx->hw_states.ps_sampler[i]);  			if (r)  				return r;  		} diff --git a/src/gallium/drivers/r600/radeon.h b/src/gallium/drivers/r600/radeon.h index 709ef8a85a..3a8405f9b4 100644 --- a/src/gallium/drivers/r600/radeon.h +++ b/src/gallium/drivers/r600/radeon.h @@ -103,17 +103,17 @@ int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo);   */  struct radeon_state {  	struct radeon			*radeon; -	unsigned			valid; +	unsigned			refcount;  	unsigned			type;  	unsigned			id;  	unsigned			nstates; -	u32				states[64]; +	u32				*states;  	unsigned			npm4;  	unsigned			cpm4;  	u32				pm4_crc; -	u32				pm4[128]; +	u32				*pm4;  	u32				nimmd; -	u32				immd[64]; +	u32				*immd;  	unsigned			nbo;  	struct radeon_bo		*bo[4];  	unsigned			nreloc; @@ -123,51 +123,35 @@ struct radeon_state {  	unsigned			bo_dirty[4];  }; -int radeon_state_init(struct radeon_state *state, struct radeon *radeon, u32 type, u32 id); +struct radeon_state *radeon_state(struct radeon *radeon, u32 type, u32 id); +struct radeon_state *radeon_state_incref(struct radeon_state *state); +struct radeon_state *radeon_state_decref(struct radeon_state *state);  int radeon_state_pm4(struct radeon_state *state);  /*   * draw functions   */  struct radeon_draw { +	unsigned			refcount;  	struct radeon			*radeon;  	unsigned			nstate; -	struct radeon_state		state[1273]; +	struct radeon_state		**state;  	unsigned			cpm4;  }; -int radeon_draw_init(struct radeon_draw *draw, struct radeon *radeon); +struct radeon_draw *radeon_draw(struct radeon *radeon); +struct radeon_draw *radeon_draw_duplicate(struct radeon_draw *draw); +struct radeon_draw *radeon_draw_incref(struct radeon_draw *draw); +struct radeon_draw *radeon_draw_decref(struct radeon_draw *draw);  int radeon_draw_set(struct radeon_draw *draw, struct radeon_state *state); +int radeon_draw_set_new(struct radeon_draw *draw, struct radeon_state *state);  int radeon_draw_check(struct radeon_draw *draw); -/* - * Context - */ -#pragma pack(1) -struct radeon_cs_reloc { -	uint32_t	handle; -	uint32_t	read_domain; -	uint32_t	write_domain; -	uint32_t	flags; -}; -#pragma pack() - -struct radeon_ctx { -	struct radeon			*radeon; -	u32				*pm4; -	u32				cpm4; -	u32				draw_cpm4; -	unsigned			id; -	unsigned			nreloc; -	struct radeon_cs_reloc		reloc[2048]; -	unsigned			nbo; -	struct radeon_bo		*bo[2048]; -	unsigned			ndraw; -	struct radeon_draw		draw[128]; -}; - -int radeon_ctx_init(struct radeon_ctx *ctx, struct radeon *radeon); +struct radeon_ctx *radeon_ctx(struct radeon *radeon); +struct radeon_ctx *radeon_ctx_decref(struct radeon_ctx *ctx); +struct radeon_ctx *radeon_ctx_incref(struct radeon_ctx *ctx);  int radeon_ctx_set_draw(struct radeon_ctx *ctx, struct radeon_draw *draw); +int radeon_ctx_set_draw_new(struct radeon_ctx *ctx, struct radeon_draw *draw);  int radeon_ctx_pm4(struct radeon_ctx *ctx);  int radeon_ctx_submit(struct radeon_ctx *ctx);  void radeon_ctx_dump_bof(struct radeon_ctx *ctx, const char *file); diff --git a/src/gallium/targets/dri-r600/Makefile b/src/gallium/targets/dri-r600/Makefile index 9c8b4ab252..932303d194 100644 --- a/src/gallium/targets/dri-r600/Makefile +++ b/src/gallium/targets/dri-r600/Makefile @@ -4,12 +4,12 @@ include $(TOP)/configs/current  LIBNAME = r600_dri.so  PIPE_DRIVERS = \ -	$(TOP)/src/gallium/drivers/r600/libr600.a \  	$(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \  	$(TOP)/src/gallium/winsys/r600/drm/libr600winsys.a \  	$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \  	$(TOP)/src/gallium/drivers/trace/libtrace.a \ -	$(TOP)/src/gallium/drivers/rbug/librbug.a +	$(TOP)/src/gallium/drivers/rbug/librbug.a \ +	$(TOP)/src/gallium/drivers/r600/libr600.a  C_SOURCES = \  	target.c \ diff --git a/src/gallium/winsys/r600/drm/radeon.c b/src/gallium/winsys/r600/drm/radeon.c index 24d821d5cf..7e65669806 100644 --- a/src/gallium/winsys/r600/drm/radeon.c +++ b/src/gallium/winsys/r600/drm/radeon.c @@ -43,6 +43,16 @@ static int radeon_get_device(struct radeon *radeon)  	return r;  } +/* symbol missing drove me crazy hack to get symbol exported */ +static void fake(void) +{ +	struct radeon_ctx *ctx; +	struct radeon_draw *draw; + +	ctx = radeon_ctx(NULL); +	draw = radeon_draw(NULL); +} +  struct radeon *radeon_new(int fd, unsigned device)  {  	struct radeon *radeon; @@ -50,6 +60,7 @@ struct radeon *radeon_new(int fd, unsigned device)  	radeon = calloc(1, sizeof(*radeon));  	if (radeon == NULL) { +		fake();  		return NULL;  	}  	radeon->fd = fd; diff --git a/src/gallium/winsys/r600/drm/radeon_ctx.c b/src/gallium/winsys/r600/drm/radeon_ctx.c index af270d5d20..6b0eba0b28 100644 --- a/src/gallium/winsys/r600/drm/radeon_ctx.c +++ b/src/gallium/winsys/r600/drm/radeon_ctx.c @@ -32,8 +32,13 @@  int radeon_ctx_set_bo_new(struct radeon_ctx *ctx, struct radeon_bo *bo)  { -	if (ctx->nbo >= 2048) -		return -EBUSY; +	void *ptr; + +	ptr = realloc(ctx->bo, sizeof(struct radeon_bo) * (ctx->nbo + 1)); +	if (ptr == NULL) { +		return -ENOMEM; +	} +	ctx->bo = ptr;  	ctx->bo[ctx->nbo] = bo;  	ctx->nbo++;  	return 0; @@ -71,26 +76,49 @@ void radeon_ctx_get_placement(struct radeon_ctx *ctx, unsigned reloc, u32 *place  	}  } -static void radeon_ctx_clear(struct radeon_ctx *ctx) +struct radeon_ctx *radeon_ctx(struct radeon *radeon)  { -	ctx->draw_cpm4 = 0; -	ctx->cpm4 = 0; -	ctx->ndraw = 0; -	ctx->nbo = 0; -	ctx->nreloc = 0; +	struct radeon_ctx *ctx; + +	if (radeon == NULL) +		return NULL; +	ctx = calloc(1, sizeof(*ctx)); +	if (ctx == NULL) +		return NULL; +	ctx->radeon = radeon_incref(radeon); +	return ctx;  } -int radeon_ctx_init(struct radeon_ctx *ctx, struct radeon *radeon) +struct radeon_ctx *radeon_ctx_incref(struct radeon_ctx *ctx)  { -	memset(ctx, 0, sizeof(struct radeon_ctx)); -	ctx->radeon = radeon_incref(radeon); -	radeon_ctx_clear(ctx); +	ctx->refcount++; +	return ctx; +} + +struct radeon_ctx *radeon_ctx_decref(struct radeon_ctx *ctx) +{ +	unsigned i; + +	if (ctx == NULL) +		return NULL; +	if (--ctx->refcount > 0) { +		return NULL; +	} + +	for (i = 0; i < ctx->ndraw; i++) { +		ctx->draw[i] = radeon_draw_decref(ctx->draw[i]); +	} +	for (i = 0; i < ctx->nbo; i++) { +		ctx->bo[i] = radeon_bo_decref(ctx->radeon, ctx->bo[i]); +	} +	ctx->radeon = radeon_decref(ctx->radeon); +	free(ctx->draw); +	free(ctx->bo);  	free(ctx->pm4); -	ctx->cpm4 = 0; -	ctx->pm4 = malloc(64 * 1024); -	if (ctx->pm4 == NULL) -		return -ENOMEM; -	return 0; +	free(ctx->reloc); +	memset(ctx, 0, sizeof(*ctx)); +	free(ctx); +	return NULL;  }  static int radeon_ctx_state_bo(struct radeon_ctx *ctx, struct radeon_state *state) @@ -115,6 +143,7 @@ static int radeon_ctx_state_bo(struct radeon_ctx *ctx, struct radeon_state *stat  	return 0;  } +  int radeon_ctx_submit(struct radeon_ctx *ctx)  {  	struct drm_radeon_cs drmib; @@ -141,7 +170,6 @@ int radeon_ctx_submit(struct radeon_ctx *ctx)  	r = drmCommandWriteRead(ctx->radeon->fd, DRM_RADEON_CS, &drmib,  				sizeof(struct drm_radeon_cs));  #endif -	radeon_ctx_clear(ctx);  	return r;  } @@ -149,6 +177,7 @@ static int radeon_ctx_reloc(struct radeon_ctx *ctx, struct radeon_bo *bo,  			unsigned id, unsigned *placement)  {  	unsigned i; +	struct radeon_cs_reloc *ptr;  	for (i = 0; i < ctx->nreloc; i++) {  		if (ctx->reloc[i].handle == bo->handle) { @@ -156,12 +185,14 @@ static int radeon_ctx_reloc(struct radeon_ctx *ctx, struct radeon_bo *bo,  			return 0;  		}  	} -	if (ctx->nreloc >= 2048) -		return -EINVAL; -	ctx->reloc[ctx->nreloc].handle = bo->handle; -	ctx->reloc[ctx->nreloc].read_domain = placement[0] | placement [1]; -	ctx->reloc[ctx->nreloc].write_domain = placement[0] | placement [1]; -	ctx->reloc[ctx->nreloc].flags = 0; +	ptr = realloc(ctx->reloc, sizeof(struct radeon_cs_reloc) * (ctx->nreloc + 1)); +	if (ptr == NULL) +		return -ENOMEM; +	ctx->reloc = ptr; +	ptr[ctx->nreloc].handle = bo->handle; +	ptr[ctx->nreloc].read_domain = placement[0] | placement [1]; +	ptr[ctx->nreloc].write_domain = placement[0] | placement [1]; +	ptr[ctx->nreloc].flags = 0;  	ctx->pm4[id] = ctx->nreloc * sizeof(struct radeon_cs_reloc) / 4;  	ctx->nreloc++;  	return 0; @@ -190,13 +221,21 @@ static int radeon_ctx_state_schedule(struct radeon_ctx *ctx, struct radeon_state  	return 0;  } -int radeon_ctx_set_draw(struct radeon_ctx *ctx, struct radeon_draw *draw) +int radeon_ctx_set_draw_new(struct radeon_ctx *ctx, struct radeon_draw *draw)  { -	unsigned cpm4, i; +	struct radeon_draw *pdraw = NULL; +	struct radeon_draw **ndraw; +	struct radeon_state *nstate, *ostate; +	unsigned cpm4, i, cstate; +	void *tmp;  	int r = 0; +	ndraw = realloc(ctx->draw, sizeof(void*) * (ctx->ndraw + 1)); +	if (ndraw == NULL) +		return -ENOMEM; +	ctx->draw = ndraw;  	for (i = 0; i < draw->nstate; i++) { -		r = radeon_ctx_state_bo(ctx, &draw->state[i]); +		r = radeon_ctx_state_bo(ctx, draw->state[i]);  		if (r)  			return r;  	} @@ -208,48 +247,69 @@ int radeon_ctx_set_draw(struct radeon_ctx *ctx, struct radeon_draw *draw)  			__func__, draw->cpm4, RADEON_CTX_MAX_PM4);  		return -EINVAL;  	} -	ctx->draw[ctx->ndraw] = *draw; -	for (i = 0, cpm4 = 0; i < draw->nstate - 1; i++) { -		ctx->draw[ctx->ndraw].state[i].valid &= ~2; -		if (ctx->draw[ctx->ndraw].state[i].valid) { -			if (ctx->ndraw > 1 && ctx->draw[ctx->ndraw - 1].state[i].valid) { -				if (ctx->draw[ctx->ndraw - 1].state[i].pm4_crc == draw->state[i].pm4_crc) -					continue; +	tmp = realloc(ctx->state, (ctx->nstate + draw->nstate) * sizeof(void*)); +	if (tmp == NULL) +		return -ENOMEM; +	ctx->state = tmp; +	pdraw = ctx->cdraw; +	for (i = 0, cpm4 = 0, cstate = ctx->nstate; i < draw->nstate - 1; i++) { +		nstate = draw->state[i]; +		if (nstate) { +			if (pdraw && pdraw->state[i]) { +				ostate = pdraw->state[i]; +				if (ostate->pm4_crc != nstate->pm4_crc) { +					ctx->state[cstate++] = nstate; +					cpm4 += nstate->cpm4; +				} +			} else { +				ctx->state[cstate++] = nstate; +				cpm4 += nstate->cpm4;  			} -			ctx->draw[ctx->ndraw].state[i].valid |= 2; -			cpm4 += ctx->draw[ctx->ndraw].state[i].cpm4;  		}  	}  	/* The last state is the draw state always add it */ -	if (!draw->state[i].valid) { +	if (draw->state[i] == NULL) {  		fprintf(stderr, "%s no draw command\n", __func__);  		return -EINVAL;  	} -	ctx->draw[ctx->ndraw].state[i].valid |= 2; -	cpm4 += ctx->draw[ctx->ndraw].state[i].cpm4; +	ctx->state[cstate++] = draw->state[i]; +	cpm4 += draw->state[i]->cpm4;  	if ((ctx->draw_cpm4 + cpm4) > RADEON_CTX_MAX_PM4) {  		/* need to flush */  		return -EBUSY;  	}  	ctx->draw_cpm4 += cpm4; -	ctx->ndraw++; +	ctx->nstate = cstate; +	ctx->draw[ctx->ndraw++] = draw; +	ctx->cdraw = draw;  	return 0;  } +int radeon_ctx_set_draw(struct radeon_ctx *ctx, struct radeon_draw *draw) +{ +	int r; + +	radeon_draw_incref(draw); +	r = radeon_ctx_set_draw_new(ctx, draw); +	if (r) +		radeon_draw_decref(draw); +	return r; +} +  int radeon_ctx_pm4(struct radeon_ctx *ctx)  { -	unsigned i, j, c; +	unsigned i;  	int r; -	for (i = 0, c = 0, ctx->id = 0; i < ctx->ndraw; i++) { -		for (j = 0; j < ctx->draw[i].nstate; j++) { -			if (ctx->draw[i].state[j].valid & 2) { -				r = radeon_ctx_state_schedule(ctx, &ctx->draw[i].state[j]); -				if (r) -					return r; -				c += ctx->draw[i].state[j].cpm4; -			} -		} +	free(ctx->pm4); +	ctx->cpm4 = 0; +	ctx->pm4 = malloc(ctx->draw_cpm4 * 4); +	if (ctx->pm4 == NULL) +		return -EINVAL; +	for (i = 0, ctx->id = 0; i < ctx->nstate; i++) { +		r = radeon_ctx_state_schedule(ctx, ctx->state[i]); +		if (r) +			return r;  	}  	if (ctx->id != ctx->draw_cpm4) {  		fprintf(stderr, "%s miss predicted pm4 size %d for %d\n", diff --git a/src/gallium/winsys/r600/drm/radeon_draw.c b/src/gallium/winsys/r600/drm/radeon_draw.c index 53699eb0b1..4413ed79fb 100644 --- a/src/gallium/winsys/r600/drm/radeon_draw.c +++ b/src/gallium/winsys/r600/drm/radeon_draw.c @@ -31,33 +31,111 @@  /*   * draw functions   */ -int radeon_draw_init(struct radeon_draw *draw, struct radeon *radeon) +struct radeon_draw *radeon_draw(struct radeon *radeon)  { -	memset(draw, 0, sizeof(struct radeon_draw)); +	struct radeon_draw *draw; + +	draw = calloc(1, sizeof(*draw)); +	if (draw == NULL) +		return NULL;  	draw->nstate = radeon->nstate;  	draw->radeon = radeon; -	return 0; +	draw->refcount = 1; +	draw->state = calloc(1, sizeof(void*) * draw->nstate); +	if (draw->state == NULL) { +		free(draw); +		return NULL; +	} +	return draw;  } -int radeon_draw_set(struct radeon_draw *draw, struct radeon_state *state) +struct radeon_draw *radeon_draw_incref(struct radeon_draw *draw) +{ +	draw->refcount++; +	return draw; +} + +struct radeon_draw *radeon_draw_decref(struct radeon_draw *draw) +{ +	unsigned i; + +	if (draw == NULL) +		return NULL; +	if (--draw->refcount > 0) +		return NULL; +	for (i = 0; i < draw->nstate; i++) { +		draw->state[i] = radeon_state_decref(draw->state[i]); +	} +	free(draw->state); +	memset(draw, 0, sizeof(*draw)); +	free(draw); +	return NULL; +} + +int radeon_draw_set_new(struct radeon_draw *draw, struct radeon_state *state)  {  	if (state == NULL)  		return 0;  	if (state->type >= draw->radeon->ntype)  		return -EINVAL; -	draw->state[state->id] = *state; +	draw->state[state->id] = radeon_state_decref(draw->state[state->id]); +	draw->state[state->id] = state;  	return 0;  } +int radeon_draw_set(struct radeon_draw *draw, struct radeon_state *state) +{ +	if (state == NULL) +		return 0; +	radeon_state_incref(state); +	return radeon_draw_set_new(draw, state); +} +  int radeon_draw_check(struct radeon_draw *draw)  {  	unsigned i;  	int r; +	r = radeon_draw_pm4(draw); +	if (r) +		return r;  	for (i = 0, draw->cpm4 = 0; i < draw->nstate; i++) { -		if (draw->state[i].valid) { -			draw->cpm4 += draw->state[i].cpm4; +		if (draw->state[i]) { +			draw->cpm4 += draw->state[i]->cpm4;  		}  	}  	return 0;  } + +struct radeon_draw *radeon_draw_duplicate(struct radeon_draw *draw) +{ +	struct radeon_draw *ndraw; +	unsigned i; + +	if (draw == NULL) +		return NULL; +	ndraw = radeon_draw(draw->radeon); +	if (ndraw == NULL) { +		return NULL; +	} +	for (i = 0; i < draw->nstate; i++) { +		if (radeon_draw_set(ndraw, draw->state[i])) { +			radeon_draw_decref(ndraw); +			return NULL; +		} +	} +	return ndraw; +} + +int radeon_draw_pm4(struct radeon_draw *draw) +{ +	unsigned i; +	int r; + +	for (i = 0; i < draw->nstate; i++) { +		r = radeon_state_pm4(draw->state[i]); +		if (r) +			return r; +	} +	return 0; +} diff --git a/src/gallium/winsys/r600/drm/radeon_priv.h b/src/gallium/winsys/r600/drm/radeon_priv.h index 80392cda96..b91421f438 100644 --- a/src/gallium/winsys/r600/drm/radeon_priv.h +++ b/src/gallium/winsys/r600/drm/radeon_priv.h @@ -24,6 +24,7 @@  #include "radeon.h"  struct radeon; +struct radeon_ctx;  /*   * radeon functions @@ -70,6 +71,34 @@ extern unsigned radeon_type_from_id(struct radeon *radeon, unsigned id);  /*   * radeon context functions   */ +#pragma pack(1) +struct radeon_cs_reloc { +	uint32_t	handle; +	uint32_t	read_domain; +	uint32_t	write_domain; +	uint32_t	flags; +}; +#pragma pack() + +struct radeon_ctx { +	int				refcount; +	struct radeon			*radeon; +	u32				*pm4; +	u32				cpm4; +	u32				draw_cpm4; +	unsigned			id; +	unsigned			next_id; +	unsigned			nreloc; +	struct radeon_cs_reloc		*reloc; +	unsigned			nbo; +	struct radeon_bo		**bo; +	unsigned			ndraw; +	struct radeon_draw		*cdraw; +	struct radeon_draw		**draw; +	unsigned			nstate; +	struct radeon_state		**state; +}; +  int radeon_ctx_set_bo_new(struct radeon_ctx *ctx, struct radeon_bo *bo);  struct radeon_bo *radeon_ctx_get_bo(struct radeon_ctx *ctx, unsigned reloc);  void radeon_ctx_get_placement(struct radeon_ctx *ctx, unsigned reloc, u32 *placement); diff --git a/src/gallium/winsys/r600/drm/radeon_state.c b/src/gallium/winsys/r600/drm/radeon_state.c index d7cd1d7a94..308288557a 100644 --- a/src/gallium/winsys/r600/drm/radeon_state.c +++ b/src/gallium/winsys/r600/drm/radeon_state.c @@ -32,23 +32,82 @@  /*   * state core functions   */ -int radeon_state_init(struct radeon_state *state, struct radeon *radeon, u32 type, u32 id) +struct radeon_state *radeon_state(struct radeon *radeon, u32 type, u32 id)  { +	struct radeon_state *state; +  	if (type > radeon->ntype) {  		fprintf(stderr, "%s invalid type %d\n", __func__, type); -		return -EINVAL; +		return NULL;  	}  	if (id > radeon->nstate) {  		fprintf(stderr, "%s invalid state id %d\n", __func__, id); -		return -EINVAL; +		return NULL;  	} -	memset(state, 0, sizeof(struct radeon_state)); +	state = calloc(1, sizeof(*state)); +	if (state == NULL) +		return NULL;  	state->radeon = radeon;  	state->type = type;  	state->id = id; +	state->refcount = 1;  	state->npm4 = radeon->type[type].npm4;  	state->nstates = radeon->type[type].nstates; -	return 0; +	state->states = calloc(1, state->nstates * 4); +	state->pm4 = calloc(1, radeon->type[type].npm4 * 4); +	if (state->states == NULL || state->pm4 == NULL) { +		radeon_state_decref(state); +		return NULL; +	} +	return state; +} + +struct radeon_state *radeon_state_duplicate(struct radeon_state *state) +{ +	struct radeon_state *nstate = radeon_state(state->radeon, state->type, state->id); +	unsigned i; + +	if (state == NULL) +		return NULL; +	nstate->cpm4 = state->cpm4; +	nstate->nbo = state->nbo; +	nstate->nreloc = state->nreloc; +	memcpy(nstate->states, state->states, state->nstates * 4); +	memcpy(nstate->pm4, state->pm4, state->npm4 * 4); +	memcpy(nstate->placement, state->placement, 8 * 4); +	memcpy(nstate->reloc_pm4_id, state->reloc_pm4_id, 8 * 4); +	memcpy(nstate->reloc_bo_id, state->reloc_bo_id, 8 * 4); +	memcpy(nstate->bo_dirty, state->bo_dirty, 4 * 4); +	for (i = 0; i < state->nbo; i++) { +		nstate->bo[i] = radeon_bo_incref(state->radeon, state->bo[i]); +	} +	return nstate; +} + +struct radeon_state *radeon_state_incref(struct radeon_state *state) +{ +	state->refcount++; +	return state; +} + +struct radeon_state *radeon_state_decref(struct radeon_state *state) +{ +	unsigned i; + +	if (state == NULL) +		return NULL; +	if (--state->refcount > 0) { +		return NULL; +	} +	for (i = 0; i < state->nbo; i++) { +		state->bo[i] = radeon_bo_decref(state->radeon, state->bo[i]); +	} +	free(state->immd); +	free(state->states); +	free(state->pm4); +	memset(state, 0, sizeof(*state)); +	free(state); +	return NULL;  }  int radeon_state_replace_always(struct radeon_state *ostate, @@ -97,7 +156,6 @@ int radeon_state_pm4(struct radeon_state *state)  		return r;  	}  	state->pm4_crc = crc32(state->pm4, state->cpm4 * 4); -	state->valid = 1;  	return 0;  } | 
