r600g: if pixel shader is NULL, bind a dummy one
[mesa.git] / src / gallium / drivers / r600 / r600_state_common.c
index cadb07943c42b8dac1f831c29f03ae1dcc3482b0..9b8a2296ee8931fc527b4bb742fc434581a61453 100644 (file)
@@ -269,6 +269,18 @@ void r600_bind_dsa_state(struct pipe_context *ctx, void *state)
        }
 }
 
+void r600_set_max_scissor(struct r600_context *rctx)
+{
+       /* Set a scissor state such that it doesn't do anything. */
+       struct pipe_scissor_state scissor;
+       scissor.minx = 0;
+       scissor.miny = 0;
+       scissor.maxx = 8192;
+       scissor.maxy = 8192;
+
+       r600_set_scissor_state(rctx, &scissor);
+}
+
 void r600_bind_rs_state(struct pipe_context *ctx, void *state)
 {
        struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state;
@@ -289,9 +301,23 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state)
 
        if (rctx->chip_class >= EVERGREEN) {
                evergreen_polygon_offset_update(rctx);
+               evergreen_set_rasterizer_discard(ctx, rs->rasterizer_discard);
        } else {
                r600_polygon_offset_update(rctx);
        }
+
+       /* Workaround for a missing scissor enable on r600. */
+       if (rctx->chip_class == R600) {
+               if (rs->scissor_enable != rctx->scissor_enable) {
+                       rctx->scissor_enable = rs->scissor_enable;
+
+                       if (rs->scissor_enable) {
+                               r600_set_scissor_state(rctx, &rctx->scissor_state);
+                       } else {
+                               r600_set_max_scissor(rctx);
+                       }
+               }
+       }
 }
 
 void r600_delete_rs_state(struct pipe_context *ctx, void *state)
@@ -381,19 +407,11 @@ void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count,
        /* Zero states. */
        for (i = 0; i < count; i++) {
                if (!buffers[i].buffer) {
-                       if (rctx->chip_class >= EVERGREEN) {
-                               evergreen_context_pipe_state_set_fs_resource(rctx, NULL, i);
-                       } else {
-                               r600_context_pipe_state_set_fs_resource(rctx, NULL, i);
-                       }
+                       r600_context_pipe_state_set_fs_resource(rctx, NULL, i);
                }
        }
        for (; i < rctx->vbuf_mgr->nr_real_vertex_buffers; i++) {
-               if (rctx->chip_class >= EVERGREEN) {
-                       evergreen_context_pipe_state_set_fs_resource(rctx, NULL, i);
-               } else {
-                       r600_context_pipe_state_set_fs_resource(rctx, NULL, i);
-               }
+               r600_context_pipe_state_set_fs_resource(rctx, NULL, i);
        }
 
        u_vbuf_set_vertex_buffers(rctx->vbuf_mgr, count, buffers);
@@ -443,15 +461,18 @@ void r600_bind_ps_shader(struct pipe_context *ctx, void *state)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
 
-       /* TODO delete old shader */
+       if (!state) {
+               state = rctx->dummy_pixel_shader;
+       }
+
        rctx->ps_shader = (struct r600_pipe_shader *)state;
-       if (state) {
-               r600_inval_shader_cache(rctx);
-               r600_context_pipe_state_set(rctx, &rctx->ps_shader->rstate);
 
-               rctx->cb_color_control &= C_028808_MULTIWRITE_ENABLE;
-               rctx->cb_color_control |= S_028808_MULTIWRITE_ENABLE(!!rctx->ps_shader->shader.fs_write_all);
-       }
+       r600_inval_shader_cache(rctx);
+       r600_context_pipe_state_set(rctx, &rctx->ps_shader->rstate);
+
+       rctx->cb_color_control &= C_028808_MULTIWRITE_ENABLE;
+       rctx->cb_color_control |= S_028808_MULTIWRITE_ENABLE(!!rctx->ps_shader->shader.fs_write_all);
+
        if (rctx->ps_shader && rctx->vs_shader) {
                r600_adjust_gprs(rctx);
        }
@@ -461,7 +482,6 @@ void r600_bind_vs_shader(struct pipe_context *ctx, void *state)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
 
-       /* TODO delete old shader */
        rctx->vs_shader = (struct r600_pipe_shader *)state;
        if (state) {
                r600_inval_shader_cache(rctx);
@@ -561,11 +581,10 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
 
                if (rctx->chip_class >= EVERGREEN) {
                        evergreen_pipe_mod_buffer_resource(ctx, rstate, rbuffer, offset, 16, RADEON_USAGE_READ);
-                       evergreen_context_pipe_state_set_vs_resource(rctx, rstate, index);
                } else {
                        r600_pipe_mod_buffer_resource(rstate, rbuffer, offset, 16, RADEON_USAGE_READ);
-                       r600_context_pipe_state_set_vs_resource(rctx, rstate, index);
                }
+               r600_context_pipe_state_set_vs_resource(rctx, rstate, index);
                break;
        case PIPE_SHADER_FRAGMENT:
                rctx->ps_const_buffer.nregs = 0;
@@ -588,11 +607,10 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
                }
                if (rctx->chip_class >= EVERGREEN) {
                        evergreen_pipe_mod_buffer_resource(ctx, rstate, rbuffer, offset, 16, RADEON_USAGE_READ);
-                       evergreen_context_pipe_state_set_ps_resource(rctx, rstate, index);
                } else {
                        r600_pipe_mod_buffer_resource(rstate, rbuffer, offset, 16, RADEON_USAGE_READ);
-                       r600_context_pipe_state_set_ps_resource(rctx, rstate, index);
                }
+               r600_context_pipe_state_set_ps_resource(rctx, rstate, index);
                break;
        default:
                R600_ERR("unsupported %d\n", shader);
@@ -715,11 +733,10 @@ static void r600_vertex_buffer_update(struct r600_context *rctx)
 
                if (rctx->chip_class >= EVERGREEN) {
                        evergreen_pipe_mod_buffer_resource(&rctx->context, rstate, rbuffer, offset, vertex_buffer->stride, RADEON_USAGE_READ);
-                       evergreen_context_pipe_state_set_fs_resource(rctx, rstate, i);
                } else {
                        r600_pipe_mod_buffer_resource(rstate, rbuffer, offset, vertex_buffer->stride, RADEON_USAGE_READ);
-                       r600_context_pipe_state_set_fs_resource(rctx, rstate, i);
                }
+               r600_context_pipe_state_set_fs_resource(rctx, rstate, i);
        }
 }
 
@@ -795,11 +812,14 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
        if ((!info.count && (info.indexed || !info.count_from_stream_output)) ||
            (info.indexed && !rctx->vbuf_mgr->index_buffer.buffer) ||
            !r600_conv_pipe_prim(info.mode, &prim)) {
+               assert(0);
                return;
        }
 
-       if (!rctx->ps_shader || !rctx->vs_shader)
+       if (!rctx->vs_shader) {
+               assert(0);
                return;
+       }
 
        r600_update_derived_state(rctx);