From 5f6ab5e259de826bb3795d90fdb0235c8997acb9 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 6 Aug 2010 15:29:50 +1000 Subject: [PATCH] r600g: start to fix up multiple targets. fixup exports from pixel shader for multi-cbs + depth buffer writing. Still crashes GPU running any of the multi-buffer or depth writing --- src/gallium/drivers/r600/r600_context.h | 2 +- src/gallium/drivers/r600/r600_shader.c | 18 ++++++++-- src/gallium/drivers/r600/r600_state.c | 47 +++++++++++++++++-------- 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/gallium/drivers/r600/r600_context.h b/src/gallium/drivers/r600/r600_context.h index 78da88fef5e..c83949de425 100644 --- a/src/gallium/drivers/r600/r600_context.h +++ b/src/gallium/drivers/r600/r600_context.h @@ -94,7 +94,7 @@ struct r600_context_hw_states { struct radeon_state dsa; struct radeon_state blend; struct radeon_state viewport; - struct radeon_state cb0; + struct radeon_state cb[7]; struct radeon_state config; struct radeon_state cb_cntl; struct radeon_state db; diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index f38aa7b4636..d925dcbe4bb 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -158,7 +158,7 @@ static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_context_sta struct r600_screen *rscreen = r600_screen(ctx->screen); struct r600_shader *rshader = &rpshader->shader; struct radeon_state *state; - unsigned i, tmp; + unsigned i, tmp, exports_ps, num_cout; int r; r = radeon_state_init(&rpshader->rstate, rscreen->rw, R600_PS_SHADER_TYPE, R600_PS_SHADER); @@ -174,11 +174,22 @@ static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_context_sta } state->states[R600_PS_SHADER__SPI_PS_INPUT_CNTL_0 + i] = tmp; } + + exports_ps = 0; + num_cout = 0; + for (i = 0; i < rshader->noutput; i++) { + if (rshader->output[i].name == TGSI_SEMANTIC_POSITION) + exports_ps |= 1; + else if (rshader->output[i].name == TGSI_SEMANTIC_COLOR) { + exports_ps |= (1 << (num_cout+1)); + num_cout++; + } + } state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_0] = S_0286CC_NUM_INTERP(rshader->ninput) | S_0286CC_PERSP_GRADIENT_ENA(1); 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] = 0x00000002; + 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; @@ -431,6 +442,9 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s if (shader->output[i].name == TGSI_SEMANTIC_COLOR) { output.array_base = 0; output.type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL; + } else if (shader->output[i].name == TGSI_SEMANTIC_POSITION) { + output.array_base = 61; + output.type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL; } else { R600_ERR("unsupported fragment output name %d\n", shader->output[i].name); r = -EINVAL; diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 1a8ec489361..c5e74d1efcb 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -660,24 +660,25 @@ static int r600_blend(struct r600_context *rctx, struct radeon_state *rstate) return radeon_state_pm4(rstate); } -static int r600_cb0(struct r600_context *rctx, struct radeon_state *rstate) +static int r600_cb(struct r600_context *rctx, struct radeon_state *rstate, int cb) { struct r600_screen *rscreen = rctx->screen; struct r600_resource_texture *rtex; struct r600_resource *rbuffer; const struct pipe_framebuffer_state *state = &rctx->framebuffer->state.framebuffer; - unsigned level = state->cbufs[0]->level; + 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, R600_CB0); + r = radeon_state_init(rstate, rscreen->rw, R600_CB0_TYPE, id); if (r) return r; - rtex = (struct r600_resource_texture*)state->cbufs[0]->texture; + rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture; rbuffer = &rtex->resource; rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); rstate->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo); @@ -687,7 +688,7 @@ static int r600_cb0(struct r600_context *rctx, struct radeon_state *rstate) rstate->placement[4] = RADEON_GEM_DOMAIN_GTT; rstate->nbo = 3; pitch = (rtex->pitch[level] / rtex->bpt) / 8 - 1; - slice = (rtex->pitch[level] / rtex->bpt) * state->cbufs[0]->height / 64 - 1; + slice = (rtex->pitch[level] / rtex->bpt) * state->cbufs[cb]->height / 64 - 1; ntype = 0; desc = util_format_description(rtex->resource.base.b.format); @@ -878,14 +879,20 @@ static int r600_dsa(struct r600_context *rctx, struct radeon_state *rstate) 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; + unsigned db_depth_control, alpha_test_control, alpha_ref, db_shader_control; unsigned stencil_ref_mask, stencil_ref_mask_bf; - int r; + int r, i; + struct r600_shader *rshader = &rctx->ps_shader->shader; r = radeon_state_init(rstate, rscreen->rw, R600_DSA_TYPE, R600_DSA); if (r) return r; + db_shader_control = 0x210; + for (i = 0; i < rshader->noutput; i++) { + if (rshader->output[i].name == TGSI_SEMANTIC_POSITION) + db_shader_control |= 1; + } stencil_ref_mask = 0; stencil_ref_mask_bf = 0; db_depth_control = S_028800_Z_ENABLE(state->depth.enabled) | @@ -933,7 +940,7 @@ static int r600_dsa(struct r600_context *rctx, struct radeon_state *rstate) rstate->states[R600_DSA__SPI_FOG_FUNC_BIAS] = 0x00000000; rstate->states[R600_DSA__SPI_FOG_CNTL] = 0x00000000; rstate->states[R600_DSA__DB_DEPTH_CONTROL] = db_depth_control; - rstate->states[R600_DSA__DB_SHADER_CONTROL] = 0x00000210; + rstate->states[R600_DSA__DB_SHADER_CONTROL] = db_shader_control; rstate->states[R600_DSA__DB_RENDER_CONTROL] = 0x00000060; rstate->states[R600_DSA__DB_RENDER_OVERRIDE] = 0x0000002A; rstate->states[R600_DSA__DB_SRESULTS_COMPARE_STATE1] = 0x00000000; @@ -1159,12 +1166,18 @@ static int r600_cb_cntl(struct r600_context *rctx, struct radeon_state *rstate) { struct r600_screen *rscreen = rctx->screen; const struct pipe_blend_state *pbs = &rctx->blend->state.blend; - uint32_t color_control, target_mask; + int nr_cbufs = rctx->framebuffer->state.framebuffer.nr_cbufs; + uint32_t color_control, target_mask, shader_mask; int i, r; target_mask = 0; + shader_mask = 0; color_control = S_028808_PER_MRT_BLEND(1); + for (i = 0; i < nr_cbufs; i++) { + shader_mask |= 0xf << i; + } + if (pbs->logicop_enable) { color_control |= (pbs->logicop_func) << 16; } else @@ -1175,11 +1188,13 @@ static int r600_cb_cntl(struct r600_context *rctx, struct radeon_state *rstate) color_control |= S_028808_TARGET_BLEND_ENABLE(1 << i); } 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->states[R600_CB_CNTL__CB_SHADER_MASK] = 0x0000000F; + + 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; rstate->states[R600_CB_CNTL__PA_SC_AA_CONFIG] = 0x00000000; @@ -1197,6 +1212,7 @@ int r600_context_hw_states(struct r600_context *rctx) { unsigned i; int r; + int nr_cbufs = rctx->framebuffer->state.framebuffer.nr_cbufs; /* free previous TODO determine what need to be updated, what * doesn't @@ -1210,7 +1226,8 @@ int r600_context_hw_states(struct r600_context *rctx) r600_dsa(rctx, &rctx->hw_states.dsa); r600_blend(rctx, &rctx->hw_states.blend); r600_viewport(rctx, &rctx->hw_states.viewport); - r600_cb0(rctx, &rctx->hw_states.cb0); + 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); @@ -1250,9 +1267,11 @@ int r600_context_hw_states(struct r600_context *rctx) r = radeon_draw_set(&rctx->draw, &rctx->hw_states.viewport); if (r) return r; - r = radeon_draw_set(&rctx->draw, &rctx->hw_states.cb0); - if (r) - return r; + for (i = 0; i < nr_cbufs; 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); if (r) return r; -- 2.30.2