summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2010-08-17 13:40:15 +1000
committerDave Airlie <[email protected]>2010-08-17 14:19:09 +1000
commit3e58007892cb2e89cb979ab172b7160adc84a44d (patch)
tree105329196e5b32c339b62760e1315b13f390e084 /src/gallium/drivers/r600
parent00ce188eb8d6f5c3f345ad674f1aa49ee5940db5 (diff)
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 <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r600')
-rw-r--r--src/gallium/drivers/r600/r600_blit.c4
-rw-r--r--src/gallium/drivers/r600/r600_context.h1
-rw-r--r--src/gallium/drivers/r600/r600_state.c56
-rw-r--r--src/gallium/drivers/r600/radeon.h23
4 files changed, 75 insertions, 9 deletions
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