r600g: start to fix up multiple targets.
authorDave Airlie <airlied@redhat.com>
Fri, 6 Aug 2010 05:29:50 +0000 (15:29 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 6 Aug 2010 06:05:24 +0000 (16:05 +1000)
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
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/r600/r600_state.c

index 78da88fef5e5720a0af22384e22548e19055897a..c83949de4255c433c71450a00da45e921bf3a99a 100644 (file)
@@ -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;
index f38aa7b46369a1bf788b9a2ce0e422236ee9f979..d925dcbe4bbd5d0cf8d837a67bc21d32ec09b9ae 100644 (file)
@@ -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;
index 1a8ec48936142be3b5f5c42bf39180eafb134160..c5e74d1efcb8cb3847a2f02f72bdcc88512406a9 100644 (file)
@@ -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;