From: Dave Airlie Date: Tue, 17 Aug 2010 03:40:15 +0000 (+1000) Subject: r600g: add user clip plane support. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3e58007892cb2e89cb979ab172b7160adc84a44d;p=mesa.git r600g: add user clip plane support. Apart from the fact that the radeon.h/r600_states.h editing is a nightmare, this wasn't so bad. passes piglit user-clip test now also trivial tests. Signed-off-by: Dave Airlie --- diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index f4eedfe4cb1..db7aef7ebd2 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -47,12 +47,14 @@ static void r600_blitter_save_states(struct r600_context *rctx) if (rctx->viewport) { util_blitter_save_viewport(rctx->blitter, &rctx->viewport->state.viewport); } - /* XXX util_blitter_save_clip(rctx->blitter, &rctx->clip); */ + if (rctx->clip) + util_blitter_save_clip(rctx->blitter, &rctx->clip->state.clip); util_blitter_save_vertex_buffers(rctx->blitter, rctx->nvertex_buffer, rctx->vertex_buffer); /* remove ptr so they don't get deleted */ rctx->blend = NULL; + rctx->clip = NULL; rctx->vs_shader = NULL; rctx->ps_shader = NULL; rctx->rasterizer = NULL; diff --git a/src/gallium/drivers/r600/r600_context.h b/src/gallium/drivers/r600/r600_context.h index 76d5de86532..2ce29720d9c 100644 --- a/src/gallium/drivers/r600/r600_context.h +++ b/src/gallium/drivers/r600/r600_context.h @@ -98,6 +98,7 @@ struct r600_context_hw_states { struct radeon_state *config; struct radeon_state *cb_cntl; struct radeon_state *db; + struct radeon_state *ucp[6]; unsigned ps_nresource; unsigned ps_nsampler; struct radeon_state *ps_resource[160]; diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 3efd409ae0d..cbbc93c04a3 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -268,6 +268,14 @@ static void r600_set_blend_color(struct pipe_context *ctx, static void r600_set_clip_state(struct pipe_context *ctx, const struct pipe_clip_state *state) { + struct r600_screen *rscreen = r600_screen(ctx->screen); + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + + rstate = r600_context_state(rctx, pipe_clip_type, state); + r600_bind_state(ctx, rstate); + /* refcount is taken care of this */ + r600_delete_state(ctx, rstate); } static void r600_set_constant_buffer(struct pipe_context *ctx, @@ -668,6 +676,29 @@ static struct radeon_state *r600_blend(struct r600_context *rctx) return rstate; } +static struct radeon_state *r600_ucp(struct r600_context *rctx, int clip) +{ + struct r600_screen *rscreen = rctx->screen; + struct radeon_state *rstate; + const struct pipe_clip_state *state = &rctx->clip->state.clip; + + rstate = radeon_state(rscreen->rw, R600_CLIP_TYPE, R600_CLIP + clip); + if (rstate == NULL) + return NULL; + + rstate->states[R600_CLIP__PA_CL_UCP_X_0] = fui(state->ucp[clip][0]); + rstate->states[R600_CLIP__PA_CL_UCP_Y_0] = fui(state->ucp[clip][1]); + rstate->states[R600_CLIP__PA_CL_UCP_Z_0] = fui(state->ucp[clip][2]); + rstate->states[R600_CLIP__PA_CL_UCP_W_0] = fui(state->ucp[clip][3]); + + if (radeon_state_pm4(rstate)) { + radeon_state_decref(rstate); + return NULL; + } + return rstate; + +} + static struct radeon_state *r600_cb(struct r600_context *rctx, int cb) { struct r600_screen *rscreen = rctx->screen; @@ -769,6 +800,7 @@ 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; + const struct pipe_clip_state *clip = NULL; struct r600_screen *rscreen = rctx->screen; struct radeon_state *rstate; float offset_units = 0, offset_scale = 0; @@ -776,6 +808,9 @@ static struct radeon_state *r600_rasterizer(struct r600_context *rctx) unsigned offset_db_fmt_cntl = 0; unsigned tmp; unsigned prov_vtx = 1; + + if (rctx->clip) + clip = &rctx->clip->state.clip; if (fb->zsbuf) { offset_units = state->offset_units; offset_scale = state->offset_scale * 12.0f; @@ -821,7 +856,11 @@ static struct radeon_state *r600_rasterizer(struct r600_context *rctx) S_0286D4_PNT_SPRITE_TOP_1(1); } } - rstate->states[R600_RASTERIZER__PA_CL_CLIP_CNTL] = 0x00000000; + rstate->states[R600_RASTERIZER__PA_CL_CLIP_CNTL] = 0; + if (clip && clip->nr) { + rstate->states[R600_RASTERIZER__PA_CL_CLIP_CNTL] = S_028810_PS_UCP_MODE(3) | ((1 << clip->nr) - 1); + rstate->states[R600_RASTERIZER__PA_CL_CLIP_CNTL] |= S_028810_CLIP_DISABLE(clip->depth_clamp); + } rstate->states[R600_RASTERIZER__PA_SU_SC_MODE_CNTL] = S_028814_PROVOKING_VTX_LAST(prov_vtx) | S_028814_CULL_FRONT((state->cull_face & PIPE_FACE_FRONT) ? 1 : 0) | @@ -1301,6 +1340,10 @@ int r600_context_hw_states(struct r600_context *rctx) unsigned i; int r; int nr_cbufs = rctx->framebuffer->state.framebuffer.nr_cbufs; + int ucp_nclip = 0; + + if (rctx->clip) + ucp_nclip = rctx->clip->state.clip.nr; /* free previous TODO determine what need to be updated, what * doesn't @@ -1316,6 +1359,9 @@ int r600_context_hw_states(struct r600_context *rctx) for (i = 0; i < 8; i++) { rctx->hw_states.cb[i] = radeon_state_decref(rctx->hw_states.cb[i]); } + for (i = 0; i < 6; i++) { + rctx->hw_states.ucp[i] = radeon_state_decref(rctx->hw_states.ucp[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; @@ -1336,6 +1382,9 @@ int r600_context_hw_states(struct r600_context *rctx) for (i = 0; i < nr_cbufs; i++) { rctx->hw_states.cb[i] = r600_cb(rctx, i); } + for (i = 0; i < ucp_nclip; i++) { + rctx->hw_states.ucp[i] = r600_ucp(rctx, i); + } rctx->hw_states.db = r600_db(rctx); rctx->hw_states.cb_cntl = r600_cb_cntl(rctx); @@ -1357,6 +1406,11 @@ int r600_context_hw_states(struct r600_context *rctx) rctx->hw_states.ps_nresource = rctx->ps_nsampler_view; /* bind states */ + for (i = 0; i < ucp_nclip; i++) { + r = radeon_draw_set(rctx->draw, rctx->hw_states.ucp[i]); + if (r) + return r; + } r = radeon_draw_set(rctx->draw, rctx->hw_states.db); if (r) return r; diff --git a/src/gallium/drivers/r600/radeon.h b/src/gallium/drivers/r600/radeon.h index 8f00a4895a0..d36c89d6a72 100644 --- a/src/gallium/drivers/r600/radeon.h +++ b/src/gallium/drivers/r600/radeon.h @@ -191,8 +191,8 @@ struct radeon_ctx { * R600/R700 */ -#define R600_NSTATE 1280 -#define R600_NTYPE 32 +#define R600_NSTATE 1286 +#define R600_NTYPE 33 #define R600_CONFIG 0 #define R600_CONFIG_TYPE 0 @@ -254,10 +254,13 @@ struct radeon_ctx { #define R600_CB7_TYPE 28 #define R600_DB 1277 #define R600_DB_TYPE 29 -#define R600_VGT 1278 -#define R600_VGT_TYPE 30 -#define R600_DRAW 1279 -#define R600_DRAW_TYPE 31 +#define R600_CLIP 1278 +#define R600_CLIP_TYPE 30 +#define R600_VGT 1284 +#define R600_VGT_TYPE 31 +#define R600_DRAW 1285 +#define R600_DRAW_TYPE 32 + /* R600_CONFIG */ #define R600_CONFIG__SQ_CONFIG 0 #define R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1 1 @@ -643,5 +646,11 @@ struct radeon_ctx { #define R600_DRAW__VGT_DRAW_INITIATOR 3 #define R600_DRAW_SIZE 4 #define R600_DRAW_PM4 128 - +/* R600_CLIP */ +#define R600_CLIP__PA_CL_UCP_X_0 0 +#define R600_CLIP__PA_CL_UCP_Y_0 1 +#define R600_CLIP__PA_CL_UCP_Z_0 2 +#define R600_CLIP__PA_CL_UCP_W_0 3 +#define R600_CLIP_SIZE 4 +#define R600_CLIP_PM4 128 #endif diff --git a/src/gallium/winsys/r600/drm/r600_states.h b/src/gallium/winsys/r600/drm/r600_states.h index e40c77d8f6c..2d7a1d31c8c 100644 --- a/src/gallium/winsys/r600/drm/r600_states.h +++ b/src/gallium/winsys/r600/drm/r600_states.h @@ -283,6 +283,13 @@ static const struct radeon_register R600_VS_CONSTANT_names[] = { {0x0003100C, 0, 0, "SQ_ALU_CONSTANT3_256"}, }; +static const struct radeon_register R600_UCP_names[] = { + {0x00028e20, 0, 0, "PA_CL_UCP0_X"}, + {0x00028e24, 0, 0, "PA_CL_UCP0_Y"}, + {0x00028e28, 0, 0, "PA_CL_UCP0_Z"}, + {0x00028e2c, 0, 0, "PA_CL_UCP0_W"}, +}; + static const struct radeon_register R600_PS_RESOURCE_names[] = { {0x00038000, 0, 0, "RESOURCE0_WORD0"}, {0x00038004, 0, 0, "RESOURCE0_WORD1"}, @@ -503,8 +510,10 @@ static struct radeon_type R600_types[] = { { 128, 1275, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB6", 7, r600_state_pm4_cb0, R600_CB6_names}, { 128, 1276, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB7", 7, r600_state_pm4_cb0, R600_CB7_names}, { 128, 1277, 0x00000000, 0x00000000, 0x0000, 0, "R600_DB", 6, r600_state_pm4_db, R600_DB_names}, - { 128, 1278, 0x00000000, 0x00000000, 0x0000, 0, "R600_VGT", 11, r600_state_pm4_vgt, R600_VGT_names}, - { 128, 1279, 0x00000000, 0x00000000, 0x0000, 0, "R600_DRAW", 4, r600_state_pm4_draw, R600_DRAW_names}, + { 128, 1278, 0x00028e20, 0x00028e70, 0x0010, 0, "R600_UCP", 4, r600_state_pm4_generic, R600_UCP_names}, + { 128, 1284, 0x00000000, 0x00000000, 0x0000, 0, "R600_VGT", 11, r600_state_pm4_vgt, R600_VGT_names}, + { 128, 1285, 0x00000000, 0x00000000, 0x0000, 0, "R600_DRAW", 4, r600_state_pm4_draw, R600_DRAW_names}, + }; static struct radeon_type R700_types[] = { @@ -538,8 +547,9 @@ static struct radeon_type R700_types[] = { { 128, 1275, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB6", 7, r600_state_pm4_cb0, R600_CB6_names}, { 128, 1276, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB7", 7, r600_state_pm4_cb0, R600_CB7_names}, { 128, 1277, 0x00000000, 0x00000000, 0x0000, 0, "R600_DB", 6, r700_state_pm4_db, R600_DB_names}, - { 128, 1278, 0x00000000, 0x00000000, 0x0000, 0, "R600_VGT", 11, r600_state_pm4_vgt, R600_VGT_names}, - { 128, 1279, 0x00000000, 0x00000000, 0x0000, 0, "R600_DRAW", 4, r600_state_pm4_draw, R600_DRAW_names}, + { 128, 1278, 0x00028e20, 0x00028e70, 0x0010, 0, "R600_UCP", 4, r600_state_pm4_generic, R600_UCP_names}, + { 128, 1284, 0x00000000, 0x00000000, 0x0000, 0, "R600_VGT", 11, r600_state_pm4_vgt, R600_VGT_names}, + { 128, 1285, 0x00000000, 0x00000000, 0x0000, 0, "R600_DRAW", 4, r600_state_pm4_draw, R600_DRAW_names}, }; #endif