aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r600')
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c55
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c4
-rw-r--r--src/gallium/drivers/r600/r600_shader.c36
-rw-r--r--src/gallium/drivers/r600/r600_shader.h1
-rw-r--r--src/gallium/drivers/r600/r600_state.c50
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c6
-rw-r--r--src/gallium/drivers/r600/r600_translate.c3
7 files changed, 108 insertions, 47 deletions
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index b313d525012..feb30f3f25d 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -1239,6 +1239,7 @@ void evergreen_polygon_offset_update(struct r600_pipe_context *rctx)
default:
return;
}
+ /* FIXME some of those reg can be computed with cso */
offset_db_fmt_cntl |= S_028B78_POLY_OFFSET_NEG_NUM_DB_BITS(depth);
r600_pipe_state_add_reg(&state,
R_028B80_PA_SU_POLY_OFFSET_FRONT_SCALE,
@@ -1259,6 +1260,30 @@ void evergreen_polygon_offset_update(struct r600_pipe_context *rctx)
}
}
+static void evergreen_spi_update(struct r600_pipe_context *rctx)
+{
+ struct r600_pipe_shader *shader = rctx->ps_shader;
+ struct r600_pipe_state rstate;
+ struct r600_shader *rshader = &shader->shader;
+ unsigned i, tmp;
+
+ rstate.nregs = 0;
+ for (i = 0; i < rshader->ninput; i++) {
+ tmp = S_028644_SEMANTIC(r600_find_vs_semantic_index(&rctx->vs_shader->shader, rshader, i));
+ if (rshader->input[i].name == TGSI_SEMANTIC_COLOR ||
+ rshader->input[i].name == TGSI_SEMANTIC_BCOLOR ||
+ rshader->input[i].name == TGSI_SEMANTIC_POSITION) {
+ tmp |= S_028644_FLAT_SHADE(rctx->flatshade);
+ }
+ if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
+ rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) {
+ tmp |= S_028644_PT_SPRITE_TEX(1);
+ }
+ r600_pipe_state_add_reg(&rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, tmp, 0xFFFFFFFF, NULL);
+ }
+ r600_context_pipe_state_set(&rctx->ctx, &rstate);
+}
+
void evergreen_vertex_buffer_update(struct r600_pipe_context *rctx)
{
struct r600_pipe_state *rstate;
@@ -1417,12 +1442,30 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info)
}
if (r600_conv_pipe_prim(draw.mode, &prim))
return;
+ if (unlikely(rctx->ps_shader == NULL)) {
+ R600_ERR("missing vertex shader\n");
+ return;
+ }
+ if (unlikely(rctx->vs_shader == NULL)) {
+ R600_ERR("missing vertex shader\n");
+ return;
+ }
+ /* there should be enough input */
+ if (rctx->vertex_elements->count < rctx->vs_shader->shader.bc.nresource) {
+ R600_ERR("%d resources provided, expecting %d\n",
+ rctx->vertex_elements->count, rctx->vs_shader->shader.bc.nresource);
+ return;
+ }
+#if 0
/* rebuild vertex shader if input format changed */
if (r600_pipe_shader_update(&rctx->context, rctx->vs_shader))
return;
if (r600_pipe_shader_update(&rctx->context, rctx->ps_shader))
return;
+#endif
+
+ evergreen_spi_update(rctx);
#if 0
for (i = 0 ; i < rctx->vertex_elements->count; i++) {
@@ -1506,11 +1549,9 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader
boolean have_linear = FALSE, have_centroid = FALSE, have_perspective = FALSE;
unsigned spi_baryc_cntl;
- /* clear previous register */
rstate->nregs = 0;
for (i = 0; i < rshader->ninput; i++) {
- tmp = S_028644_SEMANTIC(r600_find_vs_semantic_index(&rctx->vs_shader->shader, rshader, i));
/* evergreen NUM_INTERP only contains values interpolated into the LDS,
POSITION goes via GPRs from the SC so isn't counted */
if (rshader->input[i].name == TGSI_SEMANTIC_POSITION)
@@ -1528,16 +1569,6 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader
if (rshader->input[i].centroid)
have_centroid = TRUE;
}
- if (rshader->input[i].name == TGSI_SEMANTIC_COLOR ||
- rshader->input[i].name == TGSI_SEMANTIC_BCOLOR ||
- rshader->input[i].name == TGSI_SEMANTIC_POSITION) {
- tmp |= S_028644_FLAT_SHADE(rshader->flat_shade);
- }
- if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
- rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) {
- tmp |= S_028644_PT_SPRITE_TEX(1);
- }
- r600_pipe_state_add_reg(rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, tmp, 0xFFFFFFFF, NULL);
}
for (i = 0; i < rshader->noutput; i++) {
if (rshader->output[i].name == TGSI_SEMANTIC_POSITION)
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index ea57fba8e47..6842571044d 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -79,6 +79,8 @@ static void r600_destroy_context(struct pipe_context *context)
rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush);
+ r600_end_vertex_translate(rctx);
+
r600_context_fini(&rctx->ctx);
util_blitter_destroy(rctx->blitter);
@@ -90,8 +92,6 @@ static void r600_destroy_context(struct pipe_context *context)
u_upload_destroy(rctx->upload_vb);
u_upload_destroy(rctx->upload_ib);
- r600_end_vertex_translate(rctx);
-
if (rctx->tran.translate_cache)
translate_cache_destroy(rctx->tran.translate_cache);
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index e40cd1dbcf1..ab401e0f69b 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -44,6 +44,9 @@ static void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shade
rstate->nregs = 0;
/* so far never got proper semantic id from tgsi */
+ /* FIXME better to move this in config things so they get emited
+ * only one time per cs
+ */
for (i = 0; i < 10; i++) {
spi_vs_out_id[i] = 0;
}
@@ -112,31 +115,15 @@ static void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shade
unsigned i, tmp, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1;
int pos_index = -1, face_index = -1;
- /* clear previous register */
rstate->nregs = 0;
for (i = 0; i < rshader->ninput; i++) {
- tmp = S_028644_SEMANTIC(r600_find_vs_semantic_index(&rctx->vs_shader->shader, rshader, i));
- if (rshader->input[i].centroid)
- tmp |= S_028644_SEL_CENTROID(1);
- if (rshader->input[i].interpolate == TGSI_INTERPOLATE_LINEAR)
- tmp |= S_028644_SEL_LINEAR(1);
-
if (rshader->input[i].name == TGSI_SEMANTIC_POSITION)
pos_index = i;
- if (rshader->input[i].name == TGSI_SEMANTIC_COLOR ||
- rshader->input[i].name == TGSI_SEMANTIC_BCOLOR ||
- rshader->input[i].name == TGSI_SEMANTIC_POSITION) {
- tmp |= S_028644_FLAT_SHADE(rshader->flat_shade);
- }
if (rshader->input[i].name == TGSI_SEMANTIC_FACE)
face_index = i;
- if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
- rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) {
- tmp |= S_028644_PT_SPRITE_TEX(1);
- }
- r600_pipe_state_add_reg(rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, tmp, 0xFFFFFFFF, NULL);
}
+
for (i = 0; i < rshader->noutput; i++) {
if (rshader->output[i].name == TGSI_SEMANTIC_POSITION)
r600_pipe_state_add_reg(rstate,
@@ -238,7 +225,6 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s
r600_bo_unmap(rctx->radeon, shader->bo);
}
/* build state */
- rshader->flat_shade = rctx->flatshade;
switch (rshader->processor_type) {
case TGSI_PROCESSOR_VERTEX:
if (rshader->family >= CHIP_CEDAR) {
@@ -257,7 +243,6 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s
default:
return -EINVAL;
}
- r600_context_pipe_state_set(&rctx->ctx, &shader->rstate);
return 0;
}
@@ -317,17 +302,6 @@ int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *s
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
int r;
- if (shader == NULL)
- return -EINVAL;
- /* there should be enough input */
- if (rctx->vertex_elements->count < shader->shader.bc.nresource) {
- R600_ERR("%d resources provided, expecting %d\n",
- rctx->vertex_elements->count, shader->shader.bc.nresource);
- return -EINVAL;
- }
- r = r600_shader_update(ctx, shader);
- if (r)
- return r;
return r600_pipe_shader(ctx, shader);
}
@@ -359,7 +333,7 @@ int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *s
}
//r600_bc_dump(&shader->shader.bc);
//fprintf(stderr, "______________________________________________________________\n");
- return 0;
+ return r600_pipe_shader(ctx, shader);
}
void
diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h
index cd108da4915..e8742b59a44 100644
--- a/src/gallium/drivers/r600/r600_shader.h
+++ b/src/gallium/drivers/r600/r600_shader.h
@@ -38,7 +38,6 @@ struct r600_shader_io {
struct r600_shader {
unsigned processor_type;
struct r600_bc bc;
- boolean flat_shade;
unsigned ninput;
unsigned noutput;
unsigned nlds;
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 9b70942eebf..2ba15b818aa 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -74,6 +74,7 @@ void r600_polygon_offset_update(struct r600_pipe_context *rctx)
default:
return;
}
+ /* FIXME some of those reg can be computed with cso */
offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(depth);
r600_pipe_state_add_reg(&state,
R_028E00_PA_SU_POLY_OFFSET_FRONT_SCALE,
@@ -94,6 +95,36 @@ void r600_polygon_offset_update(struct r600_pipe_context *rctx)
}
}
+/* FIXME optimize away spi update when it's not needed */
+static void r600_spi_update(struct r600_pipe_context *rctx)
+{
+ struct r600_pipe_shader *shader = rctx->ps_shader;
+ struct r600_pipe_state rstate;
+ struct r600_shader *rshader = &shader->shader;
+ unsigned i, tmp;
+
+ rstate.nregs = 0;
+ for (i = 0; i < rshader->ninput; i++) {
+ tmp = S_028644_SEMANTIC(r600_find_vs_semantic_index(&rctx->vs_shader->shader, rshader, i));
+ if (rshader->input[i].centroid)
+ tmp |= S_028644_SEL_CENTROID(1);
+ if (rshader->input[i].interpolate == TGSI_INTERPOLATE_LINEAR)
+ tmp |= S_028644_SEL_LINEAR(1);
+
+ if (rshader->input[i].name == TGSI_SEMANTIC_COLOR ||
+ rshader->input[i].name == TGSI_SEMANTIC_BCOLOR ||
+ rshader->input[i].name == TGSI_SEMANTIC_POSITION) {
+ tmp |= S_028644_FLAT_SHADE(rctx->flatshade);
+ }
+ if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
+ rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) {
+ tmp |= S_028644_PT_SPRITE_TEX(1);
+ }
+ r600_pipe_state_add_reg(&rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, tmp, 0xFFFFFFFF, NULL);
+ }
+ r600_context_pipe_state_set(&rctx->ctx, &rstate);
+}
+
void r600_vertex_buffer_update(struct r600_pipe_context *rctx)
{
struct r600_pipe_state *rstate;
@@ -202,13 +233,30 @@ static void r600_draw_common(struct r600_drawl *draw)
}
if (r600_conv_pipe_prim(draw->mode, &prim))
return;
+ if (unlikely(rctx->ps_shader == NULL)) {
+ R600_ERR("missing vertex shader\n");
+ return;
+ }
+ if (unlikely(rctx->vs_shader == NULL)) {
+ R600_ERR("missing vertex shader\n");
+ return;
+ }
+ /* there should be enough input */
+ if (rctx->vertex_elements->count < rctx->vs_shader->shader.bc.nresource) {
+ R600_ERR("%d resources provided, expecting %d\n",
+ rctx->vertex_elements->count, rctx->vs_shader->shader.bc.nresource);
+ return;
+ }
-
+#if 0
/* rebuild vertex shader if input format changed */
if (r600_pipe_shader_update(&rctx->context, rctx->vs_shader))
return;
if (r600_pipe_shader_update(&rctx->context, rctx->ps_shader))
return;
+#endif
+
+ r600_spi_update(rctx);
#if 0
for (i = 0 ; i < rctx->vertex_elements->count; i++) {
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index 889432732cf..c647e77b373 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -269,6 +269,9 @@ void r600_bind_ps_shader(struct pipe_context *ctx, void *state)
/* TODO delete old shader */
rctx->ps_shader = (struct r600_pipe_shader *)state;
+ if (state) {
+ r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_shader->rstate);
+ }
}
void r600_bind_vs_shader(struct pipe_context *ctx, void *state)
@@ -277,6 +280,9 @@ void r600_bind_vs_shader(struct pipe_context *ctx, void *state)
/* TODO delete old shader */
rctx->vs_shader = (struct r600_pipe_shader *)state;
+ if (state) {
+ r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_shader->rstate);
+ }
}
void r600_delete_ps_shader(struct pipe_context *ctx, void *state)
diff --git a/src/gallium/drivers/r600/r600_translate.c b/src/gallium/drivers/r600/r600_translate.c
index d927f53398d..1c227d32151 100644
--- a/src/gallium/drivers/r600/r600_translate.c
+++ b/src/gallium/drivers/r600/r600_translate.c
@@ -169,6 +169,9 @@ void r600_end_vertex_translate(struct r600_pipe_context *rctx)
{
struct pipe_context *pipe = &rctx->context;
+ if (rctx->tran.new_velems == NULL) {
+ return;
+ }
/* Restore vertex elements. */
if (rctx->vertex_elements == rctx->tran.new_velems) {
pipe->bind_vertex_elements_state(pipe, NULL);